gizmoduck: row 307 BUILD.md: commits, old-test edits against mos-1459, new tests and the empty-session correction to test B, expected red on 1f6db1589, run plan with mos-1275 limits, mutants M1-M4

This commit is contained in:
jason.woltje committed 2026-10-23 08:27:32 -05:00
1 parent 44104adb19
commit 1f00d4f91e
1 file changed
+111
+111
View File
@@ -0,0 +1,111 @@
# Row 307 (#1814, Vikunja 598): move row 270's pi compaction reading behind the harness kind
Owner Gizmoduck. Reviewer Duckworth. Gate owner Sage. Brief:
docs/plans/2026-10-23_harness-kind-compactions.md. Base 1e629c892. Design: DESIGN.md beside this file,
approved (static) by Duckworth on 67daf6403 (duckworth-0280), with C1, C2, N1 and N2 folded in at
cb048b93c. Mos ruled go on the four old-test edits in mos-1459, with the bounds below.
## Commits
1. 1f6db1589, red first. The two new test files and capture.mjs. Its product files are base's:
`git diff --stat 1e629c892 1f6db1589` lists only this packet, capture.mjs and the two tests.
2. 44104adb1, the build. The product files and the four old-test edits.
## What the build does
- `packages/plugins/src/kinds.mjs:52-57`: the harness kind's exports end in `"compactions"`, and the
comment gains its contract line. `interfaceVersion` stays 1 (DESIGN.md "interfaceVersion stays 1").
- New `packages/plugins/harness/pi/compactions.mjs`: base's `scanPi`, `readRange`, `digest`, `STREAM`,
`TAIL`, the chunk size, `PI_VERSION` and `claudeHistory`, unchanged in behaviour, plus the export.
`scanPi` is no longer exported and takes no defaults: its one caller passes all four arguments.
- `pi/index.mjs` re-exports it. `claude-code/index.mjs` answers harness-unsupported with version null.
- `packages/seat/src/compactions.mjs`: keeps the ledger. `readLedger` sets `unsupported` on
`r.reason === "harness-unsupported"` only (:113). `checkAnswer` (:147-164) refuses an answer out of
contract. `collectCompactions(store, { name, compactions }, opts)` (:174-205) calls the export, checks
it, and writes the same lines in the same order as base.
- `packages/cli/src/launcher.mjs`: the `compactions` closure takes the loaded module and calls the
export directly, with the N1 comment on why it skips `call()`. Both call sites pass `harness`.
- `packages/plugins/README.md`: the Harness section gains the `compactions` bullet.
## Old-test edits (mos-1459 bounds)
| File | Edit | Bound |
| --- | --- | --- |
| plugins/tests/kinds.test.mjs | `"compactions"` appended to the pinned list | :17-21, append only |
| seat/tests/compactions.test.mjs | two module imports; `collect` passes `{ name, compactions }` | :11/:21, helper only |
| seat/tests/compactions-budget.test.mjs | pi import; `collect` passes `{ name, compactions }` | :13/:24-25, helper only |
| cli/tests/compactions-launch.test.mjs | pi import; base :344's call (now :345) passes `{ name: "pi", compactions: pi }` | call only, `.count === 1` kept |
No call or expected value in those files changed. harness.test.mjs, cli helpers.mjs:133-151,
launch-routes.test.mjs:17-23 and launcher.test.mjs:694-697 are unedited.
## New tests
- `packages/seat/tests/compactions-ledger.test.mjs`:
- FIXTURES: seven ledgers row 270's code writes (known, store-incomplete, store-unreadable,
not-collected, harness-unsupported from claude-code, harness-unsupported from Claude history, and
torn), each with its streams, projects and steps. Per fixture, test A reads `compactionCount` and
test B runs one collection through `{ name: "pi", compactions: pi.compactions }`.
- Test B runs over the fixture's own streams, not an empty session as DESIGN.md:189 says. Over an
empty session every fixture with a cursor would go store-incomplete (the stream went away), so
"the others go known" could not hold. The expected answers: known stays known (1), store-unreadable
goes known with 0 (the cursor is at the end), not-collected goes known with 1, and
store-incomplete, torn and both harness-unsupported fixtures stay unknown.
- The malformed-answer test (17 answers, plus a module that throws, over a fresh store and over the
known fixture) and the argument test (exact keys; core passes a copy of the cursors).
- `packages/plugins/tests/harness-compactions.test.mjs`: CASES plain, budget (100 bytes), cap (1
stream of 2), shrank and header against pi; pi's `first` with and without Claude history;
claude-code; and a module re-exporting every pi export but `compactions`, refused `missing-export`.
- capture.mjs reads both capture blocks from the test files. It replays each fixture with base's
`collectCompactions(store, "<name>", ...)` and compares the ledger byte for byte, and it runs base's
`scanPi` per case and compares the answer under base's reason order (:301 at base) and
`PI_VERSION`. It prints base's `compactionCount` per fixture: that is the before half.
## Expected red on 1f6db1589
- seat compactions-ledger: the seven test A pass (the ledger rules are base's). Test B fails for known,
store-unreadable and not-collected: base takes the object as a harness that isn't pi and writes
harness-unsupported. Test B passes on base for the other four, whose expected answer is unknown with
the same reason. The malformed-answer and argument tests fail: base never calls the module.
- plugins harness-compactions: the five CASES, the `first` test and the claude-code test fail with a
TypeError (`compactions` isn't exported on base). The missing-export test fails: base's loader loads
the module.
- harness.test.mjs:192 is already red on base. That's the brief's starting point.
## Run plan (mos-1275, `timeout -k 10`)
All on a CLEAR from Sage. TMPDIR comes from `mktemp -d /mnt/storage/scratch/tmp/gXXX`. Gate worktrees
under /mnt/storage/scratch, node_modules linked right after `git worktree add`, pipefail and tee.
| Run | Longest recorded | LIMIT |
| --- | --- | --- |
| capture.mjs on a 1f6db1589 worktree (base and candidate both it) | none | 120 s |
| red first: the two new files on 1f6db1589, each whole | none (seat suite 7 s) | 300 s |
| the touched test files whole on 44104adb1, one at a time | compactions-launch alone: none; other files 15 s | 600 s |
| bus suite | 25 s (270 r5) | 900 s |
| cli suite | 682 s (270 r5) | 2100 s |
| plugins suite | none recorded | 900 s |
| webui suite | 58.2 s (294) | 600 s |
| business suite | none recorded | 900 s |
| seat suite whole, `node --test tests/` (Duckworth C1) | 7 s (270 r5) | 600 s |
| each scripts/test-*.sh | 42 s (test-foundation) | 900 s |
| each mutant, its kill files whole | 1 s (264a probes) | 300 s |
- In the cli run, compactions-launch's T3 tests (base :206, and :305 with the :344 edit; :207, :306
and :345 after the import line) must show as run, not skipped on `sandboxProblem()` (base :36, now
:37). The report names every skip (Duckworth C2).
- Plugins must have zero failures.
- A timeout with no failed test is a hang and goes to Sage. A timeout in the shell phase goes to Mos
unplaced. A first-run red in a new 307 test is placed and reported after (mos-1272). A red in an old
test goes to Sage, unfixed.
## Mutants
Each on an isolated copy of the file, restore checked by sha256, only on a green base.
| # | Change | Kill files |
| --- | --- | --- |
| M1 | `readLedger`: `if (r.harness !== "pi" \|\| r.reason === "harness-unsupported")` restored | plugins harness.test.mjs (:192) |
| M2 | pi `compactions` drops the `first && claudeHistory(store)` branch | seat compactions-budget.test.mjs (base :86, now :87), plugins harness-compactions.test.mjs |
| M3 | `readLedger` never sets `unsupported` | seat compactions-ledger.test.mjs, seat compactions.test.mjs (base :197, now :199) |
| M4 | `collectCompactions` skips `checkAnswer` | seat compactions-ledger.test.mjs |