docs: brief for decision closes and messaging lists (#1627), row 120 follow-up
Ruling: the business validator refuses a messaging-limited arbiter, and decision.raise checks that the route may message the raiser. The close insert stays unchecked, so no decision is left that its resolver can't close. Owner dewey, reviewer filbert. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
@@ -298,6 +298,77 @@ its code (`role-end-refused` for the chief's own run, a validation
|
||||
code for an invalid change); the chief's bundle text differs from
|
||||
another role's as item 3 says. Mutants for each.
|
||||
|
||||
## Decision closes and messaging lists
|
||||
|
||||
Follow-up to row 120, small. Gitea #1627. Filbert raised it in comment
|
||||
28548 on #1614, and my ruling in 28540 kept it out of row 120.
|
||||
|
||||
- Owner: dewey. They may start on refactor now. Rows 123 and 121 touch
|
||||
`broker.mjs` and `business.mjs` as well, so whichever lands second
|
||||
rebases and reruns its gate.
|
||||
- Reviewer: filbert.
|
||||
- Requirements: REQ-ASSIST-2.
|
||||
|
||||
Row 120 checks messaging lists on `message.send`, `review.request` and
|
||||
`review.verdict`. A decision close by anyone but the raising run also
|
||||
stores a message, a DECISION from the closer to the raising role, and
|
||||
that insert isn't checked. Filbert probed row 120's candidate with
|
||||
`arbiters.delivery` set to `assistant`. A coder raised a delivery
|
||||
decision, the assistant resolved it, and the DECISION message to the
|
||||
coder was stored, even though the assistant's `message.send` to the
|
||||
coder is refused.
|
||||
|
||||
Nothing reaches this today. Only `roles/assistant.json` declares
|
||||
messaging lists. Jason's file names pm and cto as arbiters. The
|
||||
assistant's grants (`message.send` within its role, nothing cross-role)
|
||||
make every decision it raises either within-role or gated, never
|
||||
routed to an arbiter.
|
||||
|
||||
**Ruling.** Check at load and at raise, not at close. A refusal at close
|
||||
would leave a decision that its resolver can't close, and only the
|
||||
raiser's withdraw would clear it.
|
||||
|
||||
**What ships.**
|
||||
|
||||
1. The business validator refuses an arbiter whose role definition
|
||||
declares messaging lists. The message names the arbiter kind, the
|
||||
instance and the definition. An arbiter answers whichever role
|
||||
raises, so a limited one can't do the job. Definitions are resolved
|
||||
before arbiters are checked (`business.mjs:150`), so this is a few
|
||||
lines after line 158. Jason's file passes, because pm and cto declare
|
||||
no lists.
|
||||
2. `decision.raise` checks that the route may message the raiser,
|
||||
before it stores anything. For a cross-role decision the sender is
|
||||
the arbiter. For a gated one it's the human. The rules are
|
||||
`#checkMessaging`'s, with the route as sender and the raiser as
|
||||
target, so in practice the raiser's `receiveFrom` must list the
|
||||
arbiter's definition or `human`. A refusal has its own code, logs
|
||||
`action.refused` and stores no decision. A within-role decision,
|
||||
routed to the raiser's own role, is exempt. Make `#checkMessaging`
|
||||
take a sender as well as a target. `message.send`, `review.request`
|
||||
and `review.verdict` keep their behaviour, and row 120's tests pass
|
||||
unchanged.
|
||||
3. The close insert stays as it is. Definitions change only with a
|
||||
pinned copy, and arbiters only through the validator, so a decision
|
||||
that passed item 2 can still be closed. Add a comment at the insert
|
||||
saying so.
|
||||
4. Row 120's packet. `agents/researcher/work/queue-120/build.md`, Round 2
|
||||
section, says the assistant "can't be the raiser", but test 1 has the
|
||||
assistant raise a decision. A committed packet is evidence and isn't
|
||||
edited. This row's BUILD.md carries the correction with Filbert's
|
||||
replacement text from 28548.
|
||||
|
||||
**Acceptance.** Tests:
|
||||
- The validator refuses a messaging-limited arbiter for each kind. It
|
||||
accepts the shipped example and an arbiter without lists.
|
||||
- A raise whose route can't message the raiser is refused with the code
|
||||
and stores no decision. Cover a cross-role route and a gated route.
|
||||
- The assistant's within-role and gated raises still work.
|
||||
- Row 120's messaging tests pass unchanged.
|
||||
|
||||
Mutants: drop the validator check; drop the raise check; check the
|
||||
raiser-to-route direction instead; drop the within-role exemption.
|
||||
|
||||
## The plug-in layer: kind registry and loader
|
||||
|
||||
Build step 6b, medium. Gitea #1626.
|
||||
|
||||
Reference in New Issue
Block a user