docs(plans): S2b brief, gated approvals are single-use
Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
# Slice 1 S2b: gated approvals are single-use (2026-10-05)
|
||||
|
||||
Status: written by Sage, lead, under lead decision 63. It follows
|
||||
`docs/plans/BRIEF-TEMPLATE.md`, and it amends no section of the slice 1
|
||||
brief.
|
||||
|
||||
## S2b: gated approvals are single-use (authorize records consumption)
|
||||
|
||||
### Problem
|
||||
|
||||
In S2 round 2 (`agents/rocko/work/slice1-s2-r2/`, candidate manifest
|
||||
61519059…), `broker.authorize(cap, action, {decision, target})` checks
|
||||
that the decision is resolved and approved, then appends an
|
||||
`action.allowed` event. Nothing stops a second call with the same
|
||||
decision. Darkwing's probe P3 (`agents/darkwing/work/slice1-s2-review/`)
|
||||
deploys three times on one approval. A gated decision is Jason saying yes
|
||||
to one action, so one approval must authorize one action.
|
||||
|
||||
### Owner and reviewer
|
||||
|
||||
- Owner: rocko.
|
||||
- Reviewer: darkwing.
|
||||
|
||||
### Files owned
|
||||
|
||||
- `packages/bus/src/broker.mjs` and `packages/bus/src/store.mjs`, for the
|
||||
check.
|
||||
- `packages/bus/tests/broker.test.mjs` and, if a new test file is
|
||||
cleaner, one new file under `packages/bus/tests/`.
|
||||
- `packages/bus/README.md`, the paragraph on `authorize`.
|
||||
|
||||
### What ships
|
||||
|
||||
- For a gated decision, `authorize` refuses with `decision-consumed` if
|
||||
an `action.allowed` event already names that decision. The check and
|
||||
the new event run in the same transaction, so two concurrent calls
|
||||
can't both pass.
|
||||
- Routine, within-role and cross-role decisions keep their current
|
||||
behavior unless Darkwing's review shows the same hole matters there.
|
||||
If it does, the review names it and I rule on it.
|
||||
- No schema change is expected, because the `action.allowed` event
|
||||
already carries the decision. If one is needed, Darkwing writes it as
|
||||
schema v3c and S2b pins it.
|
||||
- Tests: the second use refuses, a use in another run refuses, a use
|
||||
after the broker restarts refuses, and a fresh approval of the same
|
||||
action works. Add a mutant that drops the check.
|
||||
- Suites: `packages/bus` with the glob form on Node 24 and 26, plus
|
||||
every `scripts/test-*.sh`.
|
||||
|
||||
### Out of scope
|
||||
|
||||
- Who calls `authorize` and when. That's S3's tasks and S6's launches.
|
||||
- Expiring an approval that is never used.
|
||||
|
||||
### Gate
|
||||
|
||||
Darkwing approves on the row's issue. Sage runs the integration gate
|
||||
(every suite, live-provider cases included) on an index export before
|
||||
committing. This has to land before S3 or S6 calls `authorize` for a
|
||||
gated action.
|
||||
Reference in New Issue
Block a user