brief: Console inbox Approve and Deny for grant requests, Vikunja #435 (mos-1193)

This commit is contained in:
jason.woltje committed 2026-10-21 13:44:03 -05:00
1 parent a365237133
commit 640aa03f27
1 file changed
+57
@@ -0,0 +1,57 @@
# Brief: Console inbox Approve and Deny for grant requests (Vikunja #435, J2)
Sage, 2026-10-21, for Mos's order mos-1193 (Jason asked at 18:35Z to test J2 sooner). Vikunja #435, parent
#424, DECISIONS Q188. Owner Gander, reviewer Webby, gate owner Sage. Chained on row 196's candidate (Q177):
the design starts now on Gander's row 196 build. The code lands after row 196 lands and rebases onto that
landing. Design first. The first deliverable is `agents/gander/work/queue-ROW/DESIGN.md`.
## What Jason asked for
Q188, as #435 records it: the chief surfaces each grant request to Jason's inbox in the WebUI, and he clicks
Approve or Deny. It needs the Console to know who is signed in (Q175 SSO, #412). Until then Approve is
`mosaic decide`.
## Where things stand
- The Console inbox shows decisions and prints `mosaic decide <id> <key>` for each choice
(`packages/webui/README.md`, Inbox section). It takes no human writes: without `--send` every method
other than GET and HEAD answers 403 `read-only`, and the live unit runs without it (row 189).
- Q175 phase 1 (row 192, landed 4429a104f) builds the Console's own OIDC session. It is live only after the
phase 2 re-pin window turns on `--sso`. Under `--sso` every request other than `GET /healthz` needs a
verified session.
- Row 196 (Gander, Duckworth) settles how the bus tells the human's own call from a same-uid process. A
Console write that resolves a decision must go through whatever row 196 lands, not around it.
- The PRD doesn't allow this yet. REQ-DEC-3 says a human resolution comes only from a `mosaic` CLI session
started outside any agent run. Jason approved REQ-WEB-2 and the REQ-DEC-3 amendment in decision
00ed58e2 (Vikunja 19/266), and the PRD holds the id REQ-WEB-2 for it (1.8, "held for the Console decide
buttons amendment"). That amendment must land before this row's code does. PRD wording goes to Mos first,
then Jason. This row doesn't edit the PRD.
## What the design must settle
1. Which decisions get the buttons. #435 names grant requests (Q188). Say whether the first cut covers only
those or every open decision under REQ-WEB-2, and why.
2. The identity. The resolving human is the verified OIDC subject from the Console session (row 192), mapped to
an authorized human the bus knows. Nothing comes from a proxy header or a shared secret (Q175). A request
from an agent session or a seat credential is refused.
3. The write path. How the Console's POST reaches the bus's decide, using row 196's human boundary, and what
the decision event records: `via=console` and the subject.
4. The guards: CSRF, a confirmation step, a decision that is no longer open, a stale option key, a double
click, and the read-only and `--no-send` modes. State each refusal's status code and message.
5. Without `--sso` the buttons don't exist or are disabled. Say which, and what the inbox shows instead
(today's `mosaic decide` line).
6. Tests on stand-ins only: a fake OIDC provider and the test bus, as row 192's tests do.
## Boundaries
- No change to who can reach the Console from outside. That stays Jason's.
- No test touches `~/.mosaic-dev`, `~/.config/mosaic-dev`, the live units or a slot file. No request to the
live 127.0.0.1:7332 or 7333, mosaic.woltje.com or auth.diversecanvas.com.
- Turning the buttons on live needs the phase 2 window (`--sso`) and then a re-pin whose tree has this row.
Both are windows with Jason. This row ships the code and the tests.
## Gate
Webby approves DESIGN.md, then the manifest. The webui, bus and cli suites and every `scripts/test-*.sh` are
green on Sage's gate, and the mutants named in DESIGN.md are killed. The PRD amendment for REQ-WEB-2 has
landed first.