README invalid-options cell lists only count, key, text and duplicates; a
non-{key,text} option refuses invalid-request (Sage 28378, Filbert C1 28379).
Broker test pins the option shape cases. m1 and m2 killed; full gate passed
15:53:56-15:59:33Z on BASE 96656dd21.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
4.7 KiB
Row 112 (#1606) round 2: the invalid-options row names only what it refuses
Sage asked for changes in comment 28378, which replaces their approve in 28377, and Filbert asked for the same change as C1 in comment 28379. Round 1 is agents/darkwing/work/queue-112/r1/. Everything in it still holds except the two files below and one sentence of its build.md, corrected at the end of this file.
BASE: 96656dd210, unchanged. origin/refactor is still 28c08328e, and no manifest path moved after BASE.
Candidate: build.patch against BASE. candidate-manifest.sha256 lists the same five files as round 1. I applied the patch to a fresh git archive 96656dd21 export and every digest matched.
What changed
r1-to-r2.diff is the whole change between the two candidates' applied trees. The manifest lines for packages/bus/README.md and packages/bus/tests/broker.test.mjs change. The other three lines match round 1 byte for byte, so broker.mjs, tools.mjs and tools.test.mjs are the round-1 code.
packages/bus/README.md, the refusal-code table:
- The
invalid-optionscell now lists only whatdecision.raiserefuses with that code. That coversoptionsthat isn't an array, fewer than 2 or more than 9 options, akeythat isn't 1 to 160 letters, digits or_.:/-starting with a letter or digit,textthat isn't a string of 1 to 1024 characters with no NUL, and duplicate keys. These are theid()andtext(x, 1024)rules at broker.mjs:79-80. - A new line under the table says an option that isn't an object with exactly
keyandtextrefusesinvalid-request, like any other malformed argument. That iskeys(o, ['key','text'], ['key','text'])at broker.mjs:81-84, which runs before the option's key and text are checked. - The lead-in said "each refusal names one field". It now says "each of these codes names one field", since
invalid-requestnames none.
packages/bus/tests/broker.test.mjs. Sage said a test that pins one shape case would be welcome, and Filbert said none is needed. I added five assertions to the round-1 test, which is still "a recommendation that is not exactly one option key refuses invalid-recommendation after the options". Each case pairs a good yes option with one other option:
| Second option | Refusal |
|---|---|
{ key: 'no bad', text: 'b' } |
invalid-options |
{ key: 'no', text: '' } |
invalid-options |
{ key: 'no' } |
invalid-request |
{ key: 'no', text: 'b', why: 'c' } |
invalid-request |
'no' |
invalid-request |
This matches Filbert's probe in 28379. The counts check that follows also covers these cases, so a shape refusal writes no decision and no message either.
Mutants
The same mutants.py, rerun on the round-2 candidate with the slot from Sage, 15:53:44-15:53:53Z. mutants-run.log has the summary. Both report restored=True.
| Mutant | Bus suite | Result | Fails at |
|---|---|---|---|
| m1, the old shared line | 147 pass, 1 fail | killed | broker.test.mjs:168, "yes: it matches the direction" gets invalid-options |
| m2, recommendation before duplicates | 147 pass, 1 fail | killed | broker.test.mjs:174, duplicate keys with "yes: a reason" get invalid-recommendation |
The new shape assertions sit after line 174 and don't depend on either mutant, so the failure lines match round 1.
Gate
gate.sh, the same script as round 1, ran on the round-2 candidate with the slot from Sage, 15:53:56-15:59:33Z. It used BASE 96656dd21, with DOCKER_HOST unset and docker 29.7.2. 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.
Every count matches round 1. That's bus 148, business 67, cli 184, control-board 124, conversation 182, discord 178, harness 80, ledger 78, mosaic 69, queue 156, runs 43, seat 120 (0 skipped), tasks 92 and webui 108. The scripts gave auth 15, conductor 17, config 24, discord 66, extension-package 18, foundation 44, queue 28 (node 156), release 14 and task 98. Nothing failed. Bus stays at 148 because the new assertions sit in the round-1 test.
The real bwrap tester case ran and passed, 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 (260.732818ms)
None of #258, #261, #262 or #263 came back. The release step made wt_default at 15:58:44Z with no containers, and I removed it at 15:59:39Z.
Correction to round 1
Round 1's build.md said "The option count and shape checks above it still refuse invalid-options." The count and value checks do. The shape check doesn't. keys() refuses a malformed option object with invalid-request, which is the error both reviewers found in the README. The round-1 file stays as it was, and this note is the correction.