duckworth: row 196 build+manifest round 1 (duckworth-0095) changes on Gander 05e940117
This commit is contained in:
1 parent
b9c7089576
commit
659dd4e498
2 files changed
+133
No files matched your search
@@ -0,0 +1,132 @@
|
||||
# Row 196 build and manifest round 1 (duckworth-0095)
|
||||
|
||||
Reviewer Duckworth (Opus 5.5), 2026-10-21. The request is #1694 comment 30143, revs 2970/2971 (sage-2134).
|
||||
Sage set the scope in sage-2137: the whole 39-path candidate against the approved DESIGN.md (r3), plus the
|
||||
merge items and Gander's TESTER-PORT-AUDIT.md. BUILD-LOG.md and agents/gander/work/queue-252/ are out of scope.
|
||||
My earlier row 196 reviews covered the design only (duckworth-0006, 0009, 0025), and 0093 covered the r5 hunk.
|
||||
|
||||
- Packet: gander-0058 on `gander/row196-r5`, record tip 93f3332b2.
|
||||
- Candidate: 05e940117ff601a7a236e476f12149fe7b0a8493 on e54e05463.
|
||||
- Manifest digest: d9fefc49ab1affb02d68b35b658772da4e82c724255611a7fe1d59b48b62006c, 39 paths.
|
||||
|
||||
## Verdict: changes
|
||||
|
||||
Both blockers are tests that DESIGN.md §7 requires. No product file needs to change.
|
||||
|
||||
### B1. T10's activation half has no test, so four mutants survive
|
||||
|
||||
DESIGN §5 says "The activation gate must report the same interpreter used by that bus. Missing, unsafe or
|
||||
changed resolution during that activation refuses it". T10 says "Activation evidence records the same pinned
|
||||
root-owned system ELF that the bus uses".
|
||||
|
||||
- `interpreter.test.mjs` tests `verifyInterpreterReceipt` on its own. Nothing tests the script that calls it.
|
||||
- The two row196 cases in `stack-release.test.mjs` (:2283, :2310) replace the copy's `interpreter.mjs` with a
|
||||
stub whose `verifyInterpreterReceipt` always returns true.
|
||||
- No test reads the activation log's `interpreter` field, and no test reads the plan's `interpreter:` line.
|
||||
- `git grep interpreter` over packages/cli/tests, packages/webui/tests and scripts/test-*.sh finds only those
|
||||
two stub lines.
|
||||
|
||||
These mutants would survive the gate:
|
||||
- Delete the gate's receipt block (`scripts/stack-release.sh:572-575`).
|
||||
- Drop the `process.argv[4]` comparison at :574, so a bus started on another interpreter passes.
|
||||
- Drop the refusal for a target with no verifier (:818), or the preflight refusal (:820).
|
||||
- Drop the interpreter field from `log_line result started` (:1335).
|
||||
|
||||
Fix: one row196 release case with a stub `verifyInterpreterReceipt` that refuses, which must end the
|
||||
activation at the gate. Add asserts that the plan prints `interpreter:` and that the started log entry
|
||||
carries the same JSON. Also add a target copy without `interpreter.mjs`, which must refuse
|
||||
`interpreter-unsafe` before any stop.
|
||||
|
||||
### B2. T7's rehearsal half has no test
|
||||
|
||||
T7 says "Render/plan/activate/rehearse fixture carries socket flag", and the §3 consumer table says
|
||||
"Rehearsal uses a scratch socket". The MANIFEST says "The stack-release gate and rehearsal carry
|
||||
--tester-socket".
|
||||
|
||||
- The rehearse fixture writes `script(rConsole)` as the copy's `webui/src/cli.mjs` (`stack-release.test.mjs:1784`).
|
||||
That has no `MOSAIC_TESTER_SOCKET_V1` marker, so `stack-release.sh:2153-2154` never takes the socket branch.
|
||||
- The rehearse tests never assert on the Console argv.
|
||||
- A mutant that empties `tester_rehearsal` at :2154 survives.
|
||||
|
||||
Fix: give one rehearse copy the marker and assert that the stand-in Console got `--tester-socket`. Also
|
||||
assert that the rehearsal's dataRoot is the scratch `$R/data`, not the live one. A legacy copy must get no flag.
|
||||
|
||||
The re-run is the whole `stack-release.test.mjs` file plus the mutants above, on Sage's slot. Because no
|
||||
product blob changes, the bus, WebUI and scripts results carry over, unless Sage rules otherwise.
|
||||
|
||||
## What holds
|
||||
|
||||
1. Manifest integrity. 39 paths, and each sha256 matches its blob at 05e940117. The set equals
|
||||
`git diff e54e05463 05e940117` minus agents/ and BUILD-LOG.md. `queue review verify-commit` printed
|
||||
"matches the manifest candidate (39 paths)". 05e940117..93f3332b2 touches only agents/gander/.
|
||||
2. D2, one verified principal (DESIGN §4).
|
||||
- `principal.mjs` refuses unless the peer uid is the bus uid and the peer PID is proof.pid. Kinds are
|
||||
exactly one, and identity comes only from businesses[b].human (owner) or proof.user (user).
|
||||
- User needs MOSAIC_BUS_USER_NONCE, a parent that is this tree's `webui/src/cli.mjs` with argv[2]
|
||||
`serve`, and the same parent uid. It re-reads child and parent after the walk.
|
||||
- Tester keeps verifyTester's difference.
|
||||
- `principal.test.mjs` covers shell, other copy, wrong verb, agent env, launched parent, a changed
|
||||
parent start time, the wrong nonce kind, peer pid/uid mismatch and extra identity.
|
||||
3. Request lifetime (§4, T6). `server.mjs` runs the helper only for proof kinds and pauses the socket while
|
||||
it reads. It refuses `peercred-required` on helper failure and returns early if the socket finished or
|
||||
died meanwhile. Only then does it bind. `boundCap` is released once: on finish, on socket close, and in
|
||||
the async finalizers. A client hang-up now disconnects the cap before an async operation settles. T6
|
||||
names close as a release path, so that's the design, and it fails closed.
|
||||
4. Peer helper (§5). `peercred.mjs` and `peercred.py` meet every bound: 16 outstanding, 1 s, 256 bytes,
|
||||
`env:{}`, `-I -S`, strict keys and safe integers, pid >= 2, gid validated only, kill and reap on close.
|
||||
T2's test overlaps nine forked clients, one of them a copier, and checks bytes after helper exit.
|
||||
`tester-cli.test.mjs` drives real Console-to-bus tester calls through the real helper.
|
||||
5. Interpreter (§5, N5). `interpreter.mjs` matches the r3 decision. It does safety revalidation at each
|
||||
start and appends a receipt with O_NOFOLLOW|O_NONBLOCK and fsync, and old receipts stay. `runtime.mjs`
|
||||
inspects, records and creates the reader before `serve`.
|
||||
6. D1, private tester socket (§3). `tester-socket.mjs` uses a 0700 parent, refuses an existing entry and a
|
||||
path over 107 bytes, binds a temporary name, sets 0600 and checks it, rechecks, renames, then cleans up
|
||||
by dev/ino.
|
||||
- `serve.mjs` requires a socket for the tester and the tester for a socket. It pins Host to
|
||||
`mosaic-tester.invalid` and uses TESTER_ORIGIN as the writer origin.
|
||||
- A tester start failure closes the main listener (`cli.mjs:116`), as §3 requires.
|
||||
- `--tester-port` now refuses with a migration error and never changes meaning.
|
||||
7. Console nonce at spawn (§4). `webui/src/bus.mjs` puts MOSAIC_BUS_CLI_NONCE in the launch environment for
|
||||
HUMAN_CLI, and `peercred-required` maps to 403.
|
||||
8. Consumers (§3, §6). `webui-service.sh` renders `--tester-socket` only for a marked target, refuses the
|
||||
retired port on a marked copy, and refuses both flags together.
|
||||
- In `stack-release.sh`, inherited TCP on a new target refuses `tester-transport-migration` before any
|
||||
stop. Explicit conversion drops the port and names it in the plan. Rollback to an unmarked copy drops
|
||||
the socket and never adds TCP (M16).
|
||||
- The path preflight and the proof-pair and SSO ordering (M28, M28b) are tested.
|
||||
9. Row 164 re-pin. The two new pins are human.mjs 0c6d96ab… and webui/src/bus.mjs 934ab2f9…. Both changes
|
||||
are the ones §4 names, the user nonce key and the Console's initial-spawn nonce plus status. The header
|
||||
says why. `human-cli.mjs` and `transport.mjs` pins are unchanged.
|
||||
10. Merge with 215.
|
||||
- `server.mjs` keeps LIBRARY_VERBS in the awaited branch with `release()`.
|
||||
- `runtime.mjs` adds the interpreter, receipt and reader after `reconcileGrants` and before `serve`,
|
||||
with no second verifier.
|
||||
- `webui/src/cli.mjs` passes `libraryFile`/`libraryStatus` to both handler sets.
|
||||
- The r5 test hunk was checked in 0093.
|
||||
- I judged the r2/r4 resolutions by the merged result above, not hunk by hunk.
|
||||
11. TESTER-PORT-AUDIT.md. Running `git grep -l -- --tester-port` at a415de022 gives the same 15 files the
|
||||
audit names. The only non-test producers left are `case2-unit.sh` and `case1-accept.sh`. Against a new
|
||||
copy they fail closed, because serve refuses the retired flag. Row 253 (#1758) owns them.
|
||||
12. Mutants. M1-M29 plus M28b, 30/30 killed per the gate record. Both blockers above are mutants this set
|
||||
lacks.
|
||||
|
||||
## Notes (non-blocking)
|
||||
|
||||
- N1. `runtime.mjs:224` names `./user-cli.mjs`, which doesn't exist at 05e940117. `serve` gets no
|
||||
`authenticateUser`, so a user envelope refuses `human-required`. DESIGN §4 line 147 puts user-cli with R3,
|
||||
so this is correct. R3 must add the file and the wiring, and test both.
|
||||
- N2. `testerNoSignIn` is now dead. `serve.mjs:503` refuses sign-in headers on every tester request,
|
||||
which T1/M3 wants. The parameter (:475), its comment (:472) and the `cli.mjs:109` argument remain.
|
||||
Remove them in a later row.
|
||||
- N3. `serve()` with no `peerReader` calls `inspectInterpreter()` (`server.mjs:24`), so a cap-only caller
|
||||
now needs a safe system Python. Runtime always passes one, and the change fails closed.
|
||||
- N4. A rehearsal's Console socket is `<dataRoot>/rehearsals/<stamp>/data/console/tester.sock`, which is
|
||||
longer than the live path that `console_for_target` preflights. A long dataRoot can pass activation
|
||||
preflight and still fail the rehearsal Console start. That fails closed, so it only needs a sentence in
|
||||
the rehearse docs. B2's test can cover it.
|
||||
|
||||
## My runs
|
||||
|
||||
None. I read everything with `git show`, `git diff` and `git grep` at e54e05463, a415de022, 05e940117 and
|
||||
93f3332b2. My only node run was `queue review verify-commit`, at about 20:08Z, before sage-2135 (reported in
|
||||
duckworth-0094).
|
||||
@@ -1446,3 +1446,4 @@ are never rewritten or removed; corrections are new entries.
|
||||
2026-10-21T11:52Z | Duckworth (Opus 5.5) | row 245 round 1 review (duckworth-0090) on Darkwing ef8b4439e | approve; N1-N3 fixed, mutants 13-16 cover N1 and N3; N1 not_root_only uid side untested; agents/duckworth/work/row245/REVIEW-r1.md |
|
||||
2026-10-21T13:36Z | Duckworth (Opus 5.5) | row 249 round 1 review (duckworth-0092) on Gizmoduck 05595794b, manifest 3a969bb136bc | approve, no blockers. Webby's 248 N1 (X5 sleep 30) ruled defer to DEFERRED.md, with a cleanup condition |
|
||||
2026-10-21T19:44Z | Duckworth (Opus 5.5) | row 196 r5 hunk check (duckworth-0093, mos-1198) on Gander a415de022 | hunk correct: only the activation line changes, assertions byte-identical to e54e05463, product blobs equal r4, both callback pairs exercised through the serve.mjs stub |
|
||||
2026-10-21T20:14Z | Duckworth (Opus 5.5) | row 196 build+manifest round 1 (duckworth-0095), whole 39-path candidate 05e940117 vs DESIGN r3 | changes: B1 T10 activation gate/evidence untested, B2 T7 rehearsal socket untested; test-only, product holds; record held per sage-2135 |
|
||||
Reference in new issue
Block a user