Folds Filbert's N1 per Sage's comment 28355: the envelope test sends a role cap with a tester proof. The narrowing mutant at server.mjs:50 survives the full bus suite on round 1 and is killed on round 2. Full gate passed with the real bwrap tester case running. Co-Authored-By: Claude Opus 5.5 <[email protected]>
69 lines
4.5 KiB
Markdown
69 lines
4.5 KiB
Markdown
# Row 110 (#1604) round 2: one more envelope case
|
|
|
|
Sage asked for changes in comment 28355 (rev 1093) and folded Filbert's note N1 into this round. Round 1 is agents/darkwing/work/queue-110/r1/. Everything in it still holds except the one test file below.
|
|
|
|
BASE: badfa52b9d5b956392bd9cb141ff1f4ce9f402f0, unchanged. Since BASE, the branch has changed only packet files, docs/SESSIONS.md, docs/plans/QUEUE.md and docs/plans/queue.json. No manifest path moved.
|
|
Candidate: build.patch against BASE. candidate-manifest.sha256 lists the same 19 files as round 1. I applied the patch to a fresh `git archive badfa52b9` export and every digest matched.
|
|
|
|
## What changed
|
|
|
|
One file, packages/bus/tests/tester.test.mjs, in the test "an envelope carries exactly one of cap, human and tester; no tester authenticator refuses". The envelope loop gains a role cap beside the reader cap. r1-to-r2.diff is the whole change between the two candidates' applied trees:
|
|
|
|
```
|
|
const cap = b.bindReader({ business: 'demo' });
|
|
- for (const r of [{ tester: p, cap }, { tester: p, human: p }, { tester: p, human: p, cap }])
|
|
+ const role = b.bindLaunch({ business: 'demo', role: 'pm', run: 'pm-run', harness: 'pi' });
|
|
+ for (const r of [{ tester: p, cap }, { tester: p, cap: role }, { tester: p, human: p }, { tester: p, human: p, cap }])
|
|
```
|
|
|
|
The manifest line for that file goes from 39c225c5... to 167aa918.... The other 18 lines match round 1 byte for byte.
|
|
|
|
## The narrowing mutant
|
|
|
|
mutant-n1.py in this packet. It narrows the conflict check at packages/bus/src/server.mjs:50 so a cap counts only when it is the envelope's sole credential or is a reader cap (`broker.identity` gives role null and no human). With the mutant, a role cap sent with a tester proof passes the envelope, and the request runs as the tester. The script swaps that one line, runs the whole bus suite (`node --test tests/*.test.mjs` in packages/bus), and puts server.mjs back from its `.orig` copy. Both runs report `restored=True`.
|
|
|
|
| Candidate | Bus suite under the mutant | Result |
|
|
|---|---|---|
|
|
| round 1 (01:21:34Z) | 147 pass, 0 fail | survived |
|
|
| round 2 (01:21:50Z) | 146 pass, 1 fail | killed |
|
|
|
|
On round 1 it survives every bus test, which is the gap Sage named. On round 2 the only failure is the envelope test. The new tuple gets `{ ok: true, result: [] }` where the test expects `{ ok: false, error: 'invalid-envelope' }` (mutant-n1-r2.log, the assertion at tester.test.mjs:337). The reader-cap tuple still refuses under the mutant, so the failure comes from the role-cap case.
|
|
|
|
The assertion message is `Object.keys(r).join('+')`, so both cap tuples print `tester+cap`. Sage's scope said nothing else changes, so I left the label alone. The `actual` value in the log shows which tuple failed.
|
|
|
|
## Gate
|
|
|
|
gate.sh in this packet, run on the round-2 candidate with the slot from Sage, 01:22:27-01:27:55Z, on BASE badfa52b9 with `DOCKER_HOST` unset and docker 29.7.2. It runs every package's node suite and every scripts/test-*.sh. GATE_PASSED, exit 0. gate-run.log has the summary, and gate/ has one log per step. The worktree still matched the manifest after the run.
|
|
|
|
| Step | Passed | Failed |
|
|
|---|---|---|
|
|
| bus | 147 | 0 |
|
|
| business | 67 | 0 |
|
|
| cli | 184 | 0 |
|
|
| control-board | 124 | 0 |
|
|
| conversation | 182 | 0 |
|
|
| discord | 178 | 0 |
|
|
| harness | 80 | 0 |
|
|
| ledger | 78 | 0 |
|
|
| mosaic | 69 | 0 |
|
|
| queue | 156 | 0 |
|
|
| runs | 43 | 0 |
|
|
| seat | 120 (0 skipped) | 0 |
|
|
| tasks | 92 | 0 |
|
|
| webui | 108 | 0 |
|
|
| scripts | auth 15, conductor 17, config 24, discord 66, extension-package 18, foundation 44, queue 28 (node 156), release 14, task 98 | 0 |
|
|
|
|
The counts match round 1. Bus stays at 147 because the new case sits inside an existing test.
|
|
|
|
The real bwrap tester case ran and passed. It did not skip. From gate/pkg-seat.log:77:
|
|
|
|
```
|
|
✔ a confined session that runs tester-cli.mjs is refused as tester, and the same shim outside the sandbox binds (262.780721ms)
|
|
```
|
|
|
|
Neither the review.test.mjs:123 flake (#261) nor the release `active.json` flake (#258) came back. The release step made `wt_default` at 01:27:13Z with no containers, and I removed it after the run.
|
|
|
|
## Mutants from round 1
|
|
|
|
I didn't rerun the 96 round-1 mutants. The only change adds one more assertion to an existing test. A test with an extra assertion fails on everything it failed on before, so this round can only kill more mutants, never fewer. Two of them, s00 and s01, touch server.mjs:50, and round 1 killed both. Round 1's mutants-run.log (94 killed, b44 and b45 equivalent) ran on the round-1 candidate.
|