Repository navigation
fix(compact): stop duplicating archived Companion content - #536
Kutadelios wants to merge 1 commit into
Conversation
A compact retry after the archive append but before the live rewrite wrote the same moved block twice, and every small edit to an over-limit file appended another full backup. Moved blocks now carry a beyin-compact-v1 marker with a stable operation id and SHA-256, so a retry recognises the verified record instead of appending it again. Backups store one full base plus verified difflib deltas, falling back to a full copy when the delta is not smaller. Reuse of the previous month's backup (avenoxai#460) and the shared lock order (avenoxai#527) are unchanged. scripts/restore_v3_compact_backup.py rebuilds any stored version read-only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
Katkı için teşekkürler. Kesinti sonrası arşiv tekrarını önlemek yararlı; ancak |
What was seen
companion-compactcan store the same Companion text more than once in the monthly archive (main@d7a6875):Threads.mdappends a new full backup, so an unchanged heading ends up stored once per edit.Reproduction with a synthetic vault: let a
Threads.mdexceed its limit, run compact four times with a one-line edit before each run. The archive then holds the unchanged heading four times (45,137 bytes in the synthetic fixture). For the retry case, make the live rewrite fail after the archive append, then run compact again: the moved block appears twice.What changed
beyin-compact-v1marker with the source path, a stable operation id (derived from the source path and the full moved text, not from time or month), the length and a SHA-256. The marker and the text are written in the same atomic archive write; no extra state file is needed. A retry recognises a verified record and skips the append. A marker alone, or a damaged or partial record, does not count.difflib.SequenceMatcherdeltas whose reconstruction is verified by SHA-256 before they are used. If a delta is not smaller than the text, a full copy is written. Line endings, BOM, Unicode, repeated lines and the trailing newline are preserved. The same synthetic run above stores 13,282 bytes, and all four versions rebuild byte for byte..beyin-note-write/writer.lock→.beyin-compact.lock) is unchanged.scripts/restore_v3_compact_backup.py: a read-only tool that lists verified backup versions and writes a chosen version to a new file outside the vault.Still stdlib-only, with no model or network calls. Existing archives are not rewritten.
Tests
Run on Windows 11 with Python 3.12, from this branch:
v3_note_compact_lock_test.pyv3_compact_retention_test.py(new)v3_compact_archive_reuse_test.pyv3_hygiene_test.pyv3_companion*test.pyv3_compact_retention_test.pyfails againstmain'sbeyin_v3_compact.py(6 failures, 13 errors), so it covers both regressions. Two assertions inv3_compact_archive_reuse_test.pynow check the reconstructed full version instead of raw bytes, because a changed backup may now be stored as a delta. I did not run the suite on macOS or Linux.🤖 Generated with Claude Code