Unclaimed files left in the canonical checkout. Inventory: canonical-cleanup-inventory.md (commit-as-evidence groups). detect-secrets scan clean on 2026-11-02: hits are sha256 pins, git object ids, test sentinels already in tracked tests and unit-file lines.
4.9 KiB
Dewey review, row 124 (#1618), token accounting per run. Verdict: CHANGES.
Base 9098c33f7. Candidate manifest b7139ea3909c49449436daee2eb45f542bca0ffce2515870e1f49ba27e918016 (37 files), applied to a detached worktree; sha256sum -c passed before and after the runs. Packet: agents/dewey/work/queue-124-review/ (run.sh, probes.mjs, run.log, single/, mutants/).
Runs, in Sage's slot (sage-0723), 2026-10-18T15:39:29Z to 15:40:18Z:
- The 20 candidate and touched test files, one
node --testeach (launcher with TMPDIR outside /tmp): all rc=0, 150 tests, 150 pass, 0 fail, 0 skipped. Per-file counts are in run.log. - probes.mjs, on scratch temp dirs only: rc=0, output in probes.log.
- One mutant, d1: SURVIVED (see (b)). The script restored transcript/index.mjs and checked its hash against the manifest (d09ae19db3eb...).
Changes
(a) usage_records has no timestamp guard. packages/bus/src/store.mjs:55 timedTables lists every other table with an at column. Row 141 added instance_names when it added that table. usage_records is not in the list, and its DDL in 3g-3h.sql has no CHECK on at. #verifyTimes therefore never sees it: not at open, not at migration, not at commit. Probe p1: a non-canonical at (2026-10-04T00:00:00Z) is refused in events (invalid-timestamp, the control), but usage_records accepts it. The row is stored, and the store reopens with it in place.
Needed: add usage_records to timedTables, a test that a non-canonical at refuses invalid-timestamp, and a mutant that removes the entry.
(b) The brief's claude-code fixtures are missing. The acceptance line asks for "fixture transcripts for both harnesses, including a cut line, a symlink and an oversized file". In packages/plugins/tests/transcript.test.mjs only the dedup test (line 22) loops over both harnesses. The guard table (lines 29-43) and the symlink-root test (line 44) use fixture(t), which defaults to pi. The claude-code walk has its own code path: at depth 0 it opens each project directory with openSync(at(fd, entry.name), DIR) (transcript/index.mjs:90). No test puts a symlink there. Probe p2 shows the code itself handles claude-code correctly: a symlinked project dir and a symlinked session file give transcript-path, a cut line gives transcript-parse, and an oversized file gives transcript-size. The gap is that no test checks any of this. Mutant d1 drops O_NOFOLLOW from that open (constants.O_RDONLY | constants.O_DIRECTORY). transcript.test.mjs still passes 24/24. From reading the code, d1 is not equivalent: readdir reports the symlink as a non-file, so the open follows it, and the session files under the target are anchored and read normally.
Needed: run the guard table over both harnesses (or add claude-code cases for the cut line, a symlinked project directory, a symlinked session file and the oversized file), with the project-directory symlink case killing d1.
Verified
- MIGRATION.md's claim that nothing earlier changes. usage-migration.test.mjs compares every prior column, row and sequence counter on a copy built from the pinned 3g DDL. The schema digest covers all of sqlite_master, so views and triggers are pinned too. 3g-3h.sql only creates usage_records and its three triggers.
- No transcript text is stored. The reader returns counters and ids only. Ids are capped at 512 chars, unknown codes go through a fixed whitelist (anything else becomes source-unknown), and the begin cursor holds the entries map (keys are relative file name and message id).
- Replays are idempotent: UNIQUE(business,run,turn,source,phase), and perform() returns early when a row exists.
- The webui route is read-only. serve.mjs adds
usageas GET only (405 otherwise), returns 400 on any query string, and checks the shape (502 on a malformed value). bus.js tokenUsage() escapes every value through txt(). - Rocko's evidence matches their logs: 914 tests, land-work 86, config 24, 64/64 mutants killed.
Notes (not blocking)
- A turn skipped because the state read failed (
unread) still calls usage.end. It is recorded unknown (baseline-unknown) though no harness ran. That is the safe direction, but the bus README says unknown means a harness turn whose usage could not be read. - Once a thread's transcript passes 8 MiB in total, or holds any line over 1 MiB, every later turn in it is unknown. That is fail-closed and correct, but long threads will lose accounting for good. Worth a line in the README or a follow-up.
- Each begin row stores the full entries map as its cursor. Storage grows with the square of thread length.
- With two sources enabled for one harness, both report the same turn and totals count it twice ("Totals sum reported records"). Only transcript ships now; worth a note before a second source.
- Doc-only, follow-up: MIGRATION.md calls Mos "his". It's a packet doc that no test reads.
Landing the webui route and public/ changes still needs Mos's decision 123 go after approval. Activation (offline 3g→3h migration and re-pin) is Mos's separate downtime window.