Get started
Path 3 SQLite session artifact family
Path 3 SQLite Session Artifact Family
This note scopes clawdbot-d63.2 while clawdbot-d63.1 owns the overlapping
reset/delete archive helper in src/config/sessions/session-accessor.sqlite.ts.
The implementation file was dirty during this pass, so this artifact records
the exact contract and patch points without racing the sibling worker.
Authoritative family
After the SQLite flip, active session transcripts are SQLite rows. A session's archive family is:
- The
transcript_events,transcript_event_identities, andsessionsrows for the entry's currentsessionId. - The same SQLite transcript row set for every
sessionIdreferenced byentry.compactionCheckpoints[*].preCompaction.sessionId. - The same SQLite transcript row set for every
sessionIdreferenced byentry.compactionCheckpoints[*].postCompaction.sessionId. - The same SQLite transcript row set for every
sessionIdinentry.usageFamilySessionIds.
Archive only rows that are no longer referenced by any remaining
session_entries row or by any remaining entry's compaction or usage-family
metadata. This preserves checkpoint branch/restore and usage rollup state until
the final live reference is gone.
Non-family artifacts after the flip
Generated topic transcript file variants and trajectory sidecars are not active SQLite runtime state. They are legacy file artifacts:
- Topic variants such as
<sessionId>-topic-<thread>.jsonlonly exist for the file-backed transcript format. SQLite uses the canonical session id plussession_routes/entry delivery metadata instead of per-topic JSONL files. - Trajectory sidecars such as
.trajectory.jsonland.trajectory-path.jsonare named from real JSONLsessionFilepaths. SQLitesessionFilevalues aresqlite:<agentId>:<sessionId>:<storePath>markers and do not name sidecar files. - Archive-tier readers must keep reading legacy archived JSONL files, but runtime retention must not scan active sessions directories or reopen JSONL transcript files for SQLite sessions.
Doctor import remains the migration owner for legacy primary JSONL files and their adjacent trajectory sidecars. Runtime SQLite retention should not add a second importer or file fallback.
Patch points
Extend the SQLite archive helper introduced by clawdbot-d63.1 rather than
adding a parallel path.
-
Add a local collector near
deleteSqliteSessionStateIfUnreferenced:collectSqliteSessionArtifactFamily(entry: SessionEntry): Set<string>- Include
entry.sessionId, checkpoint pre/post session ids, andusageFamilySessionIds. - Filter empty strings and dedupe deterministically.
-
Add a reference collector for the post-removal store:
readReferencedSqliteSessionArtifactFamilyIds(database): Set<string>- Iterate current
session_entries, parse eachentry_json, and collect the same family ids from every surviving entry.
-
Change the reset/delete/maintenance callers that currently archive one removed
sessionIdto pass the removed entry's full family. -
For each family id, archive the SQLite transcript rows with the caller's reason (
resetordeleted), then delete thesessionsrow only when the family id is absent from the post-removal reference set. -
Keep transcript event deletion centralized through the existing SQLite session-row cleanup path. Do not add active JSONL reads.
Focused tests
Add SQLite-only tests to src/config/sessions/session-accessor.conformance.test.ts
or the sibling lifecycle test after clawdbot-d63.1 commits:
- Deleting an entry with a pre-compaction transcript archives both the current session and the pre-compaction session, then removes both SQLite row sets.
- Deleting one of two entries that share a compaction pre-session archives nothing for the shared pre-session until the final referencing entry is removed.
- Deleting an entry with
usageFamilySessionIdsarchives predecessor SQLite transcript rows when no other entry references that usage family. - A topic-shaped session key with a SQLite marker does not cause any generated topic JSONL read or sidecar lookup.
The focused proof should use:
node scripts/run-vitest.mjs src/config/sessions/session-accessor.conformance.test.tsIf the final tests live in store.session-lifecycle-mutation.test.ts, run that
file explicitly with the same wrapper. Broad pnpm gates should stay on
Crabbox/Testbox for this Codex worktree.