Files
stack/agents/darkwing/work/queue-112/r2/r1-to-r2.diff
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

38 lines
2.7 KiB
Diff

diff -ru r1tree/packages/bus/README.md verify/packages/bus/README.md
--- r1tree/packages/bus/README.md 2026-10-14 10:53:39.557838852 -0500
+++ verify/packages/bus/README.md 2026-10-14 10:53:39.033151464 -0500
@@ -208,15 +208,16 @@
block's `by` names the acting role and refused when launch state is revoked. S6 still owns launch allowlists,
capacity and actual spawning.
-`decision.raise` checks its choices in this order, and each refusal names one field:
+`decision.raise` checks its choices in this order, and each of these codes names one field:
| Code | Field | Refused when |
|---|---|---|
-| `invalid-options` | `options` | fewer than 2 or more than 9 options, an option that isn't `{key,text}` with a valid key and text, or duplicate keys |
+| `invalid-options` | `options` | not an array, fewer than 2 or more than 9 options, an option whose `key` isn't 1 to 160 letters, digits or `_.:/-` starting with a letter or digit, or whose `text` isn't a string of 1 to 1024 characters with no NUL, or duplicate keys |
| `invalid-recommendation` | `recommendation` | the value isn't exactly one option key; `"yes: a reason"` refuses, so the reason goes in `question` |
| `invalid-approval-choice` | `approvalChoice` | the value, or the default `yes` when it is omitted, isn't an option key |
The options come first, so a bad option list refuses `invalid-options` even when the recommendation also misses.
+An option that isn't an object with exactly `key` and `text` refuses `invalid-request`, like any other malformed argument.
Authorization requires the resolved option identified by `approvalChoice`
(default `yes`, which must exist), the same raiser role/run, action and target.
diff -ru r1tree/packages/bus/tests/broker.test.mjs verify/packages/bus/tests/broker.test.mjs
--- r1tree/packages/bus/tests/broker.test.mjs 2026-10-14 10:53:39.557838852 -0500
+++ verify/packages/bus/tests/broker.test.mjs 2026-10-14 10:53:39.033151464 -0500
@@ -176,6 +176,11 @@
() => raise(b, c, 'prd.approve', { options: [{ key: 'yes', text: 'a' }], recommendation: 'no' }),
/invalid-options/,
);
+ const shaped = (o) => raise(b, c, 'prd.approve', { options: [{ key: 'yes', text: 'a' }, o], recommendation: 'no' });
+ assert.throws(() => shaped({ key: 'no bad', text: 'b' }), /invalid-options/);
+ assert.throws(() => shaped({ key: 'no', text: '' }), /invalid-options/);
+ for (const o of [{ key: 'no' }, { key: 'no', text: 'b', why: 'c' }, 'no'])
+ assert.throws(() => shaped(o), /invalid-request/, 'a malformed option object is a malformed argument');
assert.deepEqual(count(), before, 'a refused raise writes no decision and no message');
assert.equal(call(b, c, 'inbox').length, 0);
const d = raise(b, c, 'prd.approve', { recommendation: 'yes' });