frankensqlite (fsqlite) database is canonical state.
JSONL is an adjunct audit/export medium for:
- git-friendly review,
- cross-machine transfer,
- recovery workflows.
Tables:
runssegmentsevents
JSONL channels:
runs.jsonlsegments.jsonlevents.jsonl
Allowed operations:
db -> jsonlexport snapshotjsonl -> dbimport replay
Disallowed:
- implicit two-way merge
- concurrent export+import against same DB
Before sync, create lock file under .franken_whisper/locks/sync.lock.
Rules:
- lock acquisition is mandatory.
- stale lock detection based on timestamp + PID verification.
- sync aborts if lock is active and not stale.
- Acquire lock.
- Write export manifest (
manifest.json) with:
- schema version
- created timestamp
- source DB path
- row counts
- checksum placeholders
- Stream each table to temp
*.jsonl.tmp. - Flush + fsync temp files.
- Atomic rename
*.tmp -> *.jsonl. - Update manifest checksums.
- Release lock.
- Acquire lock.
- Validate manifest + schema compatibility.
- Begin DB transaction.
- Replay JSONL in deterministic order (
runs,segments,events). - Apply conflict policy by stable keys (
rejectdefault,overwrite/overwrite-strictopt-in). - Enforce overwrite safety constraints in current runtime:
runsparent-row replacement is allowed.overwriteis fail-closed for child-rowUPDATE/DELETEonsegments/events.overwrite-strictperforms verified child-row replacement for imported runs:- conflicting child rows are replaced via delete+insert,
- stale child rows not present in import are pruned.
- Commit transaction.
- Release lock.
Default import mode: reject (sync import-jsonl --conflict-policy reject).
Rules:
- same primary key + same payload: no-op.
- same primary key + different payload: reject unless explicitly set to overwrite via
sync import-jsonl --conflict-policy overwriteor strict overwrite viasync import-jsonl --conflict-policy overwrite-strict. overwritedoes not imply unrestricted in-place mutation:- if resolving a conflict requires child-row
UPDATE(segments/eventssame key, different payload), import fails closed. - if strict replacement requires deleting stale child rows not present in import, import fails closed.
- if resolving a conflict requires child-row
overwrite-strictis the explicit in-place strict replacement mode for imported runs.- all conflicts logged to
sync_conflicts.jsonl.
Integrity checks:
- per-file SHA-256 checksum in manifest.
- row-count reconciliation.
- referential checks:
segments.run_idandevents.run_idmust reference existingruns.id.
Manifest carries:
schema_versionexport_format_version
Import rules:
- exact major match required.
- minor mismatch allowed only with backward-compatible fields.
Any failed sync operation must:
- preserve previous committed DB state,
- keep temp artifacts for forensic analysis,
- emit machine-readable error with operation stage.
See RECOVERY_RUNBOOK.md for exact procedures.