feat(bus): a within-role message cites a decision without consuming it (row 44, S2c, rocko)

A within-role message.send stores its decision as a citation: the broker
checks it exists in the business, and doesn't class-match it, consume it
or put it in action.allowed (lead decision 65). Sends that aren't
within-role keep the S2b authority rules. The README wording on
within-role sends is fixed.

Candidate agents/rocko/work/slice1-s2c-r1, build.patch 2c4f8d9f,
manifest aa249ad9. Darkwing approved round 1 on #1526 (comment 26778).
Integration gate in a worktree on ac4a6499: every package green on
Node 26; bus 58/58 on Node 24; every scripts/test-*.sh green. Node 24
failures in conversation, ledger, queue, seat and webui match the base.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
2026-10-05 18:13:46 -05:00
co-authored by Claude Opus 5.5
parent ac4a6499f2
commit d27042faf2
3 changed files with 126 additions and 5 deletions
+7 -3
View File
@@ -552,9 +552,13 @@ export class Broker {
}
case 'message.send': {
keys(a, ['to', 'body', 'class', 'in_reply_to', 'corrects', 'decision'], ['to', 'body']);
if (!s.human)
this.#consumeAuthority(s, 'message.send', { decision: a.decision ?? null, target: a.to });
else this.#human(s);
if (!s.human) {
const withinRole = this.#classification(s, 'message.send') === 'within-role';
this.#consumeAuthority(s, 'message.send', {
decision: withinRole ? null : (a.decision ?? null),
target: a.to,
});
} else this.#human(s);
if (a.to !== 'human' && !Object.hasOwn(b.roles, a.to)) fail('unknown-role');
string(a.body, 32768);
if (