bus, harness: decision.raise takes one recommendation key and says which field failed (row 112, #1606)

A recommendation that isn't exactly one option key now refuses
invalid-recommendation, checked after the options, instead of sharing
invalid-options with bad option lists. The raise_decision tool text says
recommendation is one key with the reason in question, and that
approvalChoice defaults to yes. The bus README lists the three codes,
the field each names and the check order; a malformed option object
refuses invalid-request. No schema change.

Candidate manifest 013c82c2fd99d23d92f6bed543a788aa04ff97b164019ccb15252ae808b4138e
(Darkwing round 2, packet fee89d52f), BASE 96656dd21. Approved by Filbert
(comment 28383) and Sage (comment 28384). Sage gate rerun at f63fc20e4
plus the candidate passed.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
2026-10-14 11:07:12 -05:00
co-authored by Claude Opus 5.5
parent f63fc20e48
commit cc48b124f1
5 changed files with 52 additions and 5 deletions
+11
View File
@@ -208,6 +208,17 @@ requires a strict task ref. `role.launch` is gated unless the business launch
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 of these codes names one field:
| Code | Field | Refused when |
|---|---|---|
| `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.
Inbox projections expose `{action,target,approvalChoice}` as `authorization`: