Skip to content

Flight recorder 5/5: disk security (bodies off by default, clear-on-new-session) #53

Description

@mibrahimdev

Part of the flight-recorder persistence epic — design: docs/superpowers/specs/2026-08-21-flight-recorder-persistence-design.md, discussion #27. Sequenced after #52.

Scope reduced by #50 (PR #56, merged 2026-09-01). Slice 2 shipped this slice's default — no bodies on disk — ahead of schedule, because shipping the opposite default in the interim was judged worse than pulling the work forward. What remains is mostly the opt-in flag.

Deliverable

After this slice: a consumer can opt in to persisting bodies via persistBodies = true. The default (no bodies on disk) already ships.

Already shipped in slice 2 (#50)

  • Bodies/payloads dropped before the blob is written. toRow() copies the DTO with requestBody/responseBody (HTTP) and payload (MQTT/BLE) nulled. Note this landed in toRow() on the persistence path, not in EventDto.fromEvent() as originally scoped — EventDto deliberately stays capable of carrying bodies, so this slice only has to stop nulling them rather than re-add them. Pinned by three tests in PersistenceToRowTest.
  • Persisted events carry redacted •••• headers. Pinned in EventDtoTest — redaction is inherited from HttpLogger, as predicted.
  • Sharingan.clear() purges rows on disk. Routed store.clear() → onClear seam → PersistenceController.clear(). The clear travels as a command on the same channel as the writes, so the single flusher applies it in submission order and a pending batch cannot resurrect cleared rows. Pinned by Given a pending batch When clear is called Then no events are resurrected.

Remaining scope

  • The persistBodies gate. When true, toRow() stops nulling the three fields. Blocked on Flight recorder 4/5: retention + Sharingan.configure() (public knob) #52 shipping the configure() surface that carries the flag.
  • Decide clear()'s intended blast radius. It currently issues DELETE FROM event — every run, not just the current one. That is broader than this issue originally specified ("the current session's rows"). Confirm which is the contract.
  • Orphaned session rows. deleteAllEvents deletes only from event; the ON DELETE CASCADE runs session→event, not the reverse, so cleared runs linger as empty session rows. Decide whether to purge them.
  • Clear-on-new-session. Not implemented. Confirm it is still wanted now that clear() purges everything.

TDD / acceptance

  • RED→GREEN: with persistBodies=true, persisted HTTP events carry bodies. The false default is already pinned.
  • checkApiParity green (no new public symbol — persistBodies ships in slice 4).

Note

Encryption at rest is out of scope — deferred to a future additive epic behind the same configure() surface (see design doc + roadmap).

Workflow change since #56: :sharingan-db is no longer exempt from binary-compatibility-validator, so every schema edit in this slice needs ./gradlew apiDump committed or apiCheck fails.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions