Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions docs/ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,46 @@ Future enhancements, recorded but not scheduled. Items here are deliberately
out of scope for current work; pick one up when its motivating use case becomes
a priority.

## Storage & persistence β€” "flight recorder" (v2 epic)

**Status: needs a design session before any code β€” see [#27](https://github.com/mibrahimdev/Sharingan/issues/27).**

Today `SharinganStore` is an in-memory ring buffer (capacity 300); logs are lost
on process death. The proposal is to persist captured events to a local on-device
database so logs **survive crashes**, are grouped **per session**, and a consumer
can **dump previous sessions' logs anytime** (flight-recorder model).

Why it's worth doing: the logs you most want are the ones right before a crash β€”
exactly what an in-memory buffer loses. Per-session history also enables a "send
me the logs from your last run" QA workflow.

Design constraints to settle in the session (full list in #27):

- **Noop parity is sacred.** Persistence must live *entirely behind* the existing
`SharinganStore` surface (`record()` / `events: StateFlow` / `clear()`).
`:sharingan-noop` stays empty/in-memory with a byte-identical public API and
**zero DB dependency** β€” it ships in release builds. No DB type may leak into
the public API.
- **DB engine β€” decide:** SQLDelight (KMP-first, lean, mature on Native β€” current
lean) vs Room KMP (2.7+, Android-familiar, heavier on iOS).
- **Protect the hot path.** `record()` is a lock-free CAS on an in-memory list;
don't write to disk per event. Use a **write-behind buffer** β€” the in-memory
`StateFlow` stays the live UI window, batches flush to the DB on a background
dispatcher. The DB augments the ring buffer; it doesn't replace it.
- **Schema:** session table (id, started-at, app/build/device meta) + events table
(FK session, timestamp, type, indexed cols + `kotlinx.serialization` JSON blob).
Composes with the event ABI frozen in #15.
- **Retention policy** (max sessions / age / rows-per-session) is what
`configure(capacity)` (closed #18) becomes β€” added additively once persistence
exists, which is why the simple in-memory capacity knob was dropped.
- **Security must be designed in, not bolted on.** A SQLite file is extractable;
persisting request/response bodies can write tokens/PII to disk. Need
bodies-off-by-default for persistence, redaction, retention/auto-purge,
clear-on-new-session. Debug-only mitigates but isn't sufficient alone.

Sequencing: ship 1.0 on the in-memory architecture first (close the parity check
#12), then take persistence on as a deliberate v2 epic.

## iOS / Swift ergonomics

- **iOS-friendly Swift `log()` overload.** The pure-Swift capture path
Expand Down
Loading