Carry the records kept by 0.6 into the layout 0.7 reads #96

Merged
mph merged 1 commit from tools/copy-kept-transcripts into main 2026-10-19 12:04:59 +00:00
Member

Why

0.7 keeps a record by its session id, under the installation its CLI ran in, and does not read the cwd-keyed layout 0.6 wrote. A dashboard that upgrades therefore loses every page older than the vendor's own retention until its old archive is carried across. The live Gladys dashboard had 3660 such records, 1.8 GB.

What this adds

tools.CopyKeptTranscripts — unpublished, built against core, so the layout it writes cannot drift from the layout the library reads:

./mill tools.run <source-archive> <config-dir> [--root <custody-root>] [--write]
  • It only adds. A kept copy that agrees is left alone; one the old writer has grown is extended; one that disagrees with the source is reported, never merged. Nothing in the source is written or removed.
  • It verifies. Every record it writes is read back and compared byte for byte, with its sidechain files.
  • It is idempotent, and diffs by size, so it is cheap to run twice — which is how a live switchover uses it: once while the old writer still runs, once after it has stopped.
  • <id>.custody.json records when the old custody last held the record — the source file's modification time — not when the copy ran.
  • Without --write it reports what it would do and writes nothing.
  • A kept directory another installation holds is refused before anything is written.

Eleven tests cover the above, including that the source is left untouched and that a disagreeing copy is reported rather than merged.

Also here: custody restricts the files it writes itself

ArchiveMirror restricted the kept directories to their owner but left the installation marker and each record's custody.json with the umask's permissions, leaning on the directory alone. Both are now rw-------, set with the directories on every keep, so an installation that has them from an earlier version is repaired by its next keep. One test, proved fallible by mutation.

Run against the live data (2026-10-19)

source   /home/mph/.claude-gladys/transcript-archive
kept     /home/mph/.local/share/agent-transcripts/claude-code/-home-mph-.claude-gladys
records  3660   copied 3660   failed 0

A second run reports all 3660 present and writes nothing. The old tree is untouched, for Michal to delete by hand when he is satisfied.

~/.claude-archive (11 records of the cc-chat demo) is not copied: which installation those belong to is undecided.

Verification

./mill __.compile, __.test, __.checkFormat and __.fix --check are green.

🤖 Generated with Claude Code

## Why 0.7 keeps a record by its session id, under the installation its CLI ran in, and does not read the cwd-keyed layout 0.6 wrote. A dashboard that upgrades therefore loses every page older than the vendor's own retention until its old archive is carried across. The live Gladys dashboard had 3660 such records, 1.8 GB. ## What this adds `tools.CopyKeptTranscripts` — unpublished, built against `core`, so the layout it writes cannot drift from the layout the library reads: ``` ./mill tools.run <source-archive> <config-dir> [--root <custody-root>] [--write] ``` - **It only adds.** A kept copy that agrees is left alone; one the old writer has grown is extended; one that disagrees with the source is reported, never merged. Nothing in the source is written or removed. - **It verifies.** Every record it writes is read back and compared byte for byte, with its sidechain files. - **It is idempotent**, and diffs by size, so it is cheap to run twice — which is how a live switchover uses it: once while the old writer still runs, once after it has stopped. - **`<id>.custody.json`** records when the old custody last held the record — the source file's modification time — not when the copy ran. - **Without `--write`** it reports what it would do and writes nothing. - A kept directory another installation holds is refused before anything is written. Eleven tests cover the above, including that the source is left untouched and that a disagreeing copy is reported rather than merged. ## Also here: custody restricts the files it writes itself `ArchiveMirror` restricted the kept directories to their owner but left the installation marker and each record's `custody.json` with the umask's permissions, leaning on the directory alone. Both are now `rw-------`, set with the directories on every keep, so an installation that has them from an earlier version is repaired by its next keep. One test, proved fallible by mutation. ## Run against the live data (2026-10-19) ``` source /home/mph/.claude-gladys/transcript-archive kept /home/mph/.local/share/agent-transcripts/claude-code/-home-mph-.claude-gladys records 3660 copied 3660 failed 0 ``` A second run reports all 3660 present and writes nothing. The old tree is untouched, for Michal to delete by hand when he is satisfied. `~/.claude-archive` (11 records of the cc-chat demo) is not copied: which installation those belong to is undecided. ## Verification `./mill __.compile`, `__.test`, `__.checkFormat` and `__.fix --check` are green. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
feat(tools): copy the records kept in the 0.6 layout into the one 0.7 reads
All checks were successful
CI / Check Formatting (pull_request) Successful in 57s
CI / Compile (pull_request) Successful in 2m0s
CI / Check Linting (pull_request) Successful in 1m37s
CI / Run Tests (pull_request) Successful in 1m58s
CI / Run Integration Tests (pull_request) Successful in 1m55s
CI / Check Bundle Size (pull_request) Successful in 45s
42bb0de9f0
0.7 keeps a record by its session id under the installation its CLI ran in,
and does not read the cwd-keyed layout 0.6 wrote. So a dashboard that
upgrades loses every page older than the vendor's own retention until its
old archive is copied across.

tools.CopyKeptTranscripts does that copy against `core`'s own path code, so
the layout it writes cannot drift from the layout the library reads:

- It only adds. A kept copy that agrees is left alone, one the old writer
  has grown is extended, and one that disagrees is reported, never merged.
  Nothing in the source is written or removed.
- Every record it writes is read back and compared, byte for byte, with its
  sidechain files.
- `<id>.custody.json` records when the old custody last held the record, not
  when the copy ran.
- Without --write it reports what it would do.

Custody also restricts the two files it writes itself — the installation
marker and a record's facts — to their owner, with the directories, where
before they carried the umask's permissions and leaned on the directory
alone.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
mph merged commit 62436c0cd3 into main 2026-10-19 12:04:59 +00:00
mph deleted branch tools/copy-kept-transcripts 2026-10-19 12:05:05 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
iterative-works/claude-code-query!96
No description provided.