docs: brief for row 112, decision.raise recommendation fix (#1606)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
# decision.raise recommendation fix (2026-10-14)
|
||||
|
||||
Filed by Sage on Mos's report of 2026-10-14. Gitea #1606, Vikunja #205.
|
||||
|
||||
## Decision raise takes one recommendation key and says which field failed
|
||||
|
||||
### Problem
|
||||
|
||||
The PM couldn't raise Jason's Q139/Q140 organization direction as a
|
||||
`prd.approve` decision. The broker refused it four times with
|
||||
`invalid-options` (bus events 335-338, 15:32:34Z-15:32:54Z; PM reply message
|
||||
d6070b4f), so nothing reached the Inbox and no tasks were made.
|
||||
|
||||
`packages/harness/src/tools.mjs:139` describes `recommendation` as "Your
|
||||
recommended option key, with a reason". `packages/bus/src/broker.mjs:784-785`
|
||||
refuses unless `recommendation` equals an option key exactly. The PM run's
|
||||
transcript shows every call sent "key: reason", for example
|
||||
`"yes: it matches Jason's direction"`. The refusal code names `options`, so
|
||||
the PM changed its options three times and never the field that failed.
|
||||
|
||||
A second trap sits next to it. `approvalChoice` defaults to `yes`
|
||||
(broker.mjs:786-787, bus README "Authorization requires..."), but the tool
|
||||
text only says "The option key that approves the action". Attempt 1 used
|
||||
keys amend/rename-only/hold with no approvalChoice, so it would have been
|
||||
refused `invalid-approval-choice` next.
|
||||
|
||||
The same lines are in badfa52b9 (live), 179697a8a (staged copy) and
|
||||
refactor at 29d34fd1a.
|
||||
|
||||
### Owner and reviewer
|
||||
|
||||
- Owner: darkwing.
|
||||
- Reviewers: filbert (decision 130, not a sandbox row) and sage.
|
||||
|
||||
### Files owned
|
||||
|
||||
- `packages/harness/src/tools.mjs`
|
||||
- `packages/harness/tests/tools.test.mjs`
|
||||
- `packages/bus/src/broker.mjs`
|
||||
- `packages/bus/tests/broker.test.mjs`
|
||||
- `packages/bus/README.md`
|
||||
|
||||
### What ships
|
||||
|
||||
1. Tool text, `raise_decision` in tools.mjs:
|
||||
- `recommendation`: exactly one option key, as written in `options`,
|
||||
with nothing added; the reason goes in `question`.
|
||||
- `approvalChoice`: the option key that approves the action; it defaults
|
||||
to `yes`, so pass it whenever no option key is `yes`.
|
||||
- The tool description or the `question` text says the question carries
|
||||
the context and the reason for the recommendation.
|
||||
2. Broker, `decision.raise` in broker.mjs:
|
||||
- A `recommendation` that isn't one of the option keys refuses
|
||||
`invalid-recommendation`.
|
||||
- Fewer than 2 or more than 9 options, a malformed option, or duplicate
|
||||
keys still refuse `invalid-options`. Check the options before the
|
||||
recommendation, so a bad option list never reports as a bad
|
||||
recommendation.
|
||||
- `invalid-approval-choice` is unchanged.
|
||||
- No schema change: `decisions.recommendation` stays one key, which the
|
||||
CLI, notifier and Inbox already print as "recommended: KEY".
|
||||
3. Bus README: the `decision.raise` row or the decision section lists the
|
||||
three refusal codes and which field each one names.
|
||||
4. Tests:
|
||||
- broker.test.mjs: "key: reason" refuses `invalid-recommendation` and
|
||||
writes no decision row and no message; duplicate keys still refuse
|
||||
`invalid-options`, including when the recommendation also misses;
|
||||
a plain key is accepted. Split the existing duplicate-key case at
|
||||
broker.test.mjs:144-154 only as far as needed.
|
||||
- tools.test.mjs: the `raise_decision` schema text for `recommendation`
|
||||
says exactly one option key and no longer asks for a reason;
|
||||
`approvalChoice` names the `yes` default.
|
||||
- A mutant that restores the old shared code (recommendation miss
|
||||
refusing `invalid-options`) fails the broker test. Record it in the
|
||||
packet.
|
||||
5. Suites: every package suite (`node --test tests/*.test.mjs` in each
|
||||
`packages/*/`) and every `scripts/test-*.sh`, on the packet gate.
|
||||
|
||||
### Out of scope
|
||||
|
||||
- A separate recommendation-reason field. It would change the decision
|
||||
schema and the Inbox; if the question text proves too thin, that is a
|
||||
new row.
|
||||
- Detail beyond the code in broker refusals generally (Vikunja #205
|
||||
dogfood list).
|
||||
- The PRD amendment the PM proposed (REQ-ORG-1 and the rest). That waits
|
||||
for this row to go live and then runs through the PM and Jason's Inbox.
|
||||
- Going live. A new copy, re-pin and bus restart happen under Mos's go,
|
||||
shared with 179697a8a (row 110).
|
||||
|
||||
### Gate
|
||||
|
||||
Filbert and Sage approve on #1606 naming the candidate manifest. Sage
|
||||
reruns the full gate at the landing target. Mos gets notices before and
|
||||
after the landing (decision 109). Live only through `stack-copy.sh copy`
|
||||
and a bus restart under Mos's go; Mos re-raises the Q139/Q140 decision
|
||||
through the PM after the restart and confirms it reached the Inbox.
|
||||
Reference in New Issue
Block a user