Repository navigation
fix(T13891): one project snapshot per run for the unified cleo.db - #2364
Open
kryptobaseddev wants to merge 2 commits into
Open
kryptobaseddev wants to merge 2 commits into
kryptobaseddev wants to merge 2 commits into
Conversation
tasks, brain and conduit share the project cleo.db, and vacuumIntoBackupAll VACUUMed it once but then hard-linked the file under brain-* and conduit-* (a full copy where hard links are unsupported). Each prefix rotates on its own schedule, so the links diverged: on the cleocode store four old brain/conduit pairs (5.2 GB) outlived their tasks-* twins and were never pruned. Now the first target on the file writes the one tasks-*.db snapshot and the others report 'linked' (covered) without writing a file. listBrainBackups and backup verify treat the project snapshot as holding brain and conduit; older brain-*/conduit-* files stay listed. Tests assert one project snapshot per run, including where hard links are unsupported. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…shot After T13891 a run writes one tasks-*.db for the unified store, but three recovery readers matched only role-prefixed files, so `cleo backup recover brain|conduit` would pick the last pre-upgrade brain-* copy (a whole cleo.db, rolling the store back) or fail with E_NO_SNAPSHOT on a fresh install. vacuumSnapshotPrefixes() names tasks as a prefix that holds brain and conduit; buildVacuumSnapshotRegex (and with it collectSnapshotCandidatesForRole / recoverProjectStore), the snapshotMatchesPin vacuum branch and recover-brain-db's VACUUM_FILENAME_RE now pick the freshest file across both prefixes. Tests: brain and conduit recover from a newer tasks-* over an older role-prefixed file; recover-brain-db does the same; the real-process test asserts recovery finds the one project snapshot. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
T13891: session-end backups of the unified project store.
What the cleocode store actually shows
This is a read-only listing of
.cleo/backups/sqlite/(25 GB, 84 files), using inodes and link counts. It does not match the task's "three full copies per Stop" premise:vacuumIntoBackupAllalready VACUUMscleo.dbonce per run. It then hard-links that file underbrain-*andconduit-*;brain-20260930-135427.dbandconduit-20260930-135428.dbshare an inode, with link count 2.selectSnapshotsToKeep).tasks-*also takes the per-write routine checkpoints, so it rotated out its half of each link. Four oldbrain-/conduit-pairs (Sep 30 ×3, Oct 3; about 1.3 GB each, 5.2 GB in total) are still alive only through those names. They will never be pruned, because nothing writes those prefixes now.cleo backup add(createBackup, typesnapshot): tencleo.db.snapshot-*copies of about 1.35 GB each, roughly 13 GB in total. Beyond that, fivetasks-*.db(6.7 GB) and twocleo.db.migration-*(2.5 GB)..cleo/logs/session-end-snapshot.loghas none after then, so the recenttasks-*.dbfiles come fromvacuumIntoBackupcheckpoints. Worth a separate look.Fix
snapshotOne(packages/core/src/store/sqlite-backup.ts): when the physical file was already snapshotted earlier in the run, the target now returns'linked'(covered) and writes nothing. It no longer creates a hard link or copy. Every run, session end included, therefore leaves exactly onetasks-*.dbfor the unified store. The duplicate check now happens before a filename is chosen, so a covered prefix never waits for a free name either. The hard-link helpers are removed.tasks-*keeps its existing time-spread retention, unchanged.cleo restore backup --snapshotalready takestasks-*.db, unchanged.listBrainBackupsnow returns the project snapshots (tasks-*) plus olderbrain-*files, newest first.backup verifycountstasks-*.dbfor the brain and conduit roles, as it already countscleo.db.<backupId>.listSqliteBackupsAllstill lists the legacybrain-*/conduit-*buckets.snapshotted: ['tasks','brain','conduit'],linked: ['brain','conduit'].Tests (AC4)
In
sqlite-backup.test.ts:tasks-*file, and nobrain-*/conduit-*.listBrainBackupsreturns that file.listBrainBackupsto includetasks-*.sqlite-backup-real-process.test.ts(T10316) now asserts onetasks-*and zerobrain-*/conduit-*in a real process.These test changes are deliberate, because the snapshot layout changed.
No local heavy runs (owner directive). CI is the test evidence. Biome on the changed files and gates 28 and 32 (
--base origin/main) pass locally.Not in scope
brain-*/conduit-*files already on disk stay, so restore can still list them. Reclaiming the four orphaned pairs (5.2 GB here) needs a deliberate cleanup step, for example a doctor job.createBackupretention: ten fullcleo.dbcopies fromcleo backup addis the larger disk cost.🤖 Generated with Claude Code