INFD-WP-0010: record founder decisions 2026-11-01; outcome read for State Hub's pull (T04)

Founder decisions relayed 2026-11-01: GH-DEC-2026-026 accepted as drafted
(unblocks S4 doctrine; S4 now waits only on access-engine policy), and the
hub pulls decision outcomes through its STATE-WP-0096 dispatch worker.

S3 re-scoped: GET /v1/memos/{id}/outcome on the private listener returns
informed-decision.decision-outcome v1 for memos the caller posed, only for
a submitter row with outcome_read: true. Read-only and value-free.
T05 (enable after STATE-WP-0101) and T06 (retire push write-back) added.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 5502@bnt-lap001
Assistant-Session: 68b3b02f-5d0f-4e71-8421-796f62e50196
This commit is contained in:
tegwick 2026-11-01 00:37:59 +01:00
parent ba7a797160
commit 8787e1a14a
7 changed files with 515 additions and 36 deletions

View file

@ -5,13 +5,29 @@
trigger `docs/proposals/2026-10-31-nk56-t17-founder-approval-path.md`, hub message `6811164f`.
**Workplan:** `workplans/INFD-WP-0010-present-existing-and-proportionate-decisions.md`.
## Founder decisions, 2026-11-01
Relayed by the net-kingdom coordinator on 2026-11-01 (quoted as relayed):
1. **gate-house GH-DEC-2026-026 accepted as drafted:** decision classes C0–C3; a decision is at least C2 when
anyone relies on it as authority for an act its standing mandate doesn't cover; C3 reserved; the actor that
files a C2 approval may never approve it; agents never approve at C1+. This answers open question 1 and removes
S4's doctrine dependency. S4's only remaining external blocker is access-engine policy work (below).
2. **State Hub write-back:** the hub's existing STATE-WP-0096 dispatch worker fetches decision outcomes from
informed-decision (informed-decision gets no hub credential); state-hub needs an outcome read, record
`informed-decision.decision-outcome` v1 (fields: state-hub `docs/decision-services-alignment-answer.md`
§5.2). Switch informed-decision's hub write-back on once STATE-WP-0101 lands. This answers open question 2
and re-scopes S3 (below).
3. access-engine (review policy for requester `service:nk-bind-executor`) and key-cape (`approval:read` for
`informed-decision-sitting-requester`) are being asked by separate workers (open questions 3 and 4).
## Summary
| Item | Answer | Status |
| --- | --- | --- |
| S1 `present_existing` | **Accepted, adapted** as a submitter *profile* on the existing `/v1/memos` route | Implemented locally and tested; not deployed. Two owner dependencies outside this repository before live use (below) |
| S4 C1 single-screen confirm | **Accepted in principle** as a lighter memo profile on the same memo model | Not built. Needs gate-house class doctrine (S5) and an access-engine policy action first |
| S3 hub write-back | **Accepted.** The write-back already exists (`hub_writeback.py`, INFD-WP-0005) behind `INFD_HUB_WRITEBACK=1` | Enablement is a founder decision; structured links need state-hub's decision-link fields |
| S4 C1 single-screen confirm | **Accepted in principle** as a lighter memo profile on the same memo model | Not built. Doctrine settled 2026-11-01; waits only on an access-engine policy action |
| S3 hub write-back | **Accepted, as a pull** (founder decision 2026-11-01) | Outcome read implemented locally and tested (WP-0010-T04); enablement waits on STATE-WP-0101 (T05) |
The founder's direction (one surface, weight proportional to risk, a clear split with approval-engine) fits
`INTENT.md` directly: one memo model at every level is the thesis, and "never own approval state" makes the
@ -136,7 +152,11 @@ confirming with net-kingdom.
- `view_hash` and disposition as today, and no approval-engine object;
- it resolves the hub decision it serves (S3).
This is what `INTENT.md` calls the lower depth levels (L1/L2). It is not built because three things must exist first:
This is what `INTENT.md` calls the lower depth levels (L1/L2). **Update 2026-11-01:** items 1 and 3 below are
answered by GH-DEC-2026-026 (accepted as drafted). A C1 confirm is never authority for an act outside a standing
mandate (such reliance makes the decision C2), so it needs no approval object and does not bind for execution.
Item 2, access-engine policy work, is the only remaining blocker. S4 is not being implemented now.
It was not built because three things had to exist first:
1. gate-house doctrine for the C0–C3 classes and the rule that anything executed on the strength of a decision is
C2 (review S5). informed-decision must not decide which class a decision has;
@ -146,7 +166,36 @@ This is what `INTENT.md` calls the lower depth levels (L1/L2). It is not built b
## S3: hub write-back
**Accepted.** It exists already: an intake envelope's `serves: {hub_decision_id, resolves: on-answer}` queues a
### Outcome read (founder decision 2026-11-01, implemented locally)
The hub pulls. `GET /v1/memos/{memo_id}/outcome` on the private workload listener:
- **Who:** TokenReview with audience `informed-decision-intake` (the worker's existing token), and a submitter row
with `outcome_read: true`. Only State Hub's row (`system:serviceaccount:state-hub:state-hub`) is meant to carry
it; the flag cannot be combined with `present_existing`. Not yet set in shipped deployment data (T05).
- **What:** only memos that submitter posed (anything else is 404 `memo_not_found`, including other submitters'
memos), serving a hub decision with `resolves: on-answer` (else 409 `memo_does_not_resolve`).
- **When:** the first terminal human disposition (accept or decline) on any revision is the answer. An accept is
reported only once its approval-engine entry is confirmed; before that the answer is 202 `pending`, and a lost
entry response is 409 `approval_entry_unresolved` (needs the existing recovery, never a guess).
- **Record** (`informed-decision.decision-outcome` v1, `status: decided`): `hub_decision_id`, `memo_id`,
`memo_revision`, `verb`, `subject {issuer, sub}`, `assurance {aal, auth_time}` (from the policy observation
recorded for that act; 409 `assurance_unrecorded` if absent), `decided_at`, `view_hash`, `presentation_id`,
`approval_id`, and for an accept `approval_entry {approved_at}`; `audit_ref` once audit-core has receipted the
disposition. Bounded at 8 KiB.
- **Deliberate differences from state-hub §5.2**, for state-hub to confirm:
- `approval_entry_id`: approval-engine entries have no id. The record carries `approval_entry.approved_at`; with
`approval_id` and `subject.sub` it is approval-engine's correlation triple.
- `option`: not emitted until S4 adds options.
- `display_name` and `note`: not emitted (value-free; the memo's principal display name is the review group's,
not the human's). The hub fills `decided_by` from `subject`.
- **Read-only:** no budget spent, no row written, no outbound call.
`INFD_HUB_WRITEBACK` (the push below) stays off under decision 2 and is retired after the pull is live (T06).
### Push write-back (INFD-WP-0005, superseded)
It exists already: an intake envelope's `serves: {hub_decision_id, resolves: on-answer}` queues a
resolution atomically with a terminal human disposition (accept or decline). The worker posts
`/decisions/{id}/resolve` with `decided_by: "<reviewer> via informed-decision"` and a rationale naming the memo,
the version, the approval, the binding digest, the `view_hash` and the disposition. Remaining work:
@ -159,8 +208,10 @@ the version, the approval, the binding digest, the `view_hash` and the dispositi
## Open questions
1. **Founder:** are C0–C3 and "executed means C2" the right cut? This gates S4.
2. **Founder:** enable hub write-back in production now (S3)?
1. ~~**Founder:** are C0–C3 and "executed means C2" the right cut? This gates S4.~~ Answered 2026-11-01:
GH-DEC-2026-026 accepted as drafted.
2. ~~**Founder:** enable hub write-back in production now (S3)?~~ Answered 2026-11-01: hub pulls; switch on once
STATE-WP-0101 lands.
3. **access-engine owner:** policy version admitting present-existing requesters (blocker 1). Should aal2 be required
per memo class in policy, or by approval-engine's `required_assurance` once APPROVAL-WP-0007-T01 enforces it?
4. **key-cape owner:** add `approval:read` to the sitting requester client (blocker 2), or register a separate