Files
stack/agents/darkwing/work/queue-112/r2/build.md
T
jason.woltjeandClaude Opus 5.5 fee89d52fe darkwing: row 112 round 2 packet, invalid-options README row (#1606)
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]>
2026-10-14 10:59:57 -05:00

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-options cell now lists only what decision.raise refuses with that code. That covers options that isn't an array, fewer than 2 or more than 9 options, a key that isn't 1 to 160 letters, digits or _.:/- starting with a letter or digit, text that isn't a string of 1 to 1024 characters with no NUL, and duplicate keys. These are the id() and text(x, 1024) rules at broker.mjs:79-80.
  • A new line under the table says an option that isn't an object with exactly key and text refuses invalid-request, like any other malformed argument. That is keys(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-request names 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.