diff --git a/WORK-RECORDS.md b/WORK-RECORDS.md index 48544fe..555cda8 100644 --- a/WORK-RECORDS.md +++ b/WORK-RECORDS.md @@ -359,7 +359,7 @@ | task | NK-WP-0056-T14 | todo | — | workplans/NK-WP-0056-bounded-executor-path.md | | task | NK-WP-0056-T15 | todo | — | workplans/NK-WP-0056-bounded-executor-path.md | | task | NK-WP-0056-T16 | wait | — | workplans/NK-WP-0056-bounded-executor-path.md | -| task | NK-WP-0056-T17 | todo | — | workplans/NK-WP-0056-bounded-executor-path.md | +| task | NK-WP-0056-T17 | done | — | workplans/NK-WP-0056-bounded-executor-path.md | | intake | NK-IN-0001 | closed | blue | docs/intakes/activity-core-ops-sso-operators.md | | intake | NK-IN-0002 | closed | blue | docs/intakes/activity-core-ops-sso-operators.md | | intake | NET-IN-0001 | open | — | intakes/intakes.md | diff --git a/docs/proposals/2026-10-31-nk56-t17-founder-approval-path.md b/docs/proposals/2026-10-31-nk56-t17-founder-approval-path.md new file mode 100644 index 0000000..7b6f8c3 --- /dev/null +++ b/docs/proposals/2026-10-31-nk56-t17-founder-approval-path.md @@ -0,0 +1,52 @@ +# NK-WP-0056-T17: the founder's aal2 approval path for an admission (2026-10-31) + +**Question:** how does the founder approve one Bounded Execution Admission? The approval must be a human entry made +with an `aal2` token that carries `approval:approve` for audience `approval-engine`. + +## What exists (evidence) + +**approval-engine (`docs/bounded-execution-admission-carrier.md`):** + +- `POST /v1/approvals` refuses unless `binding.actor` equals the authenticated token subject. Only the actor can + create the approval. +- `human_control: true` makes `add_entry` refuse non-human approvers. +- Consume requires `approval:consume` and a service principal. It does not check that the consumer is the actor; + that check is APPROVAL-WP-0007-T02, which is waiting. +- Human approvers use "the existing KeyCape human flow" with `approval:approve`. The engine names informed-decision + as that surface. + +**informed-decision (live at `decisions.coulomb.social`):** + +- It is the deployed L3 approver surface. platform-root has signed in and approved memos through it. +- Accepting a presented memo posts `POST /v1/approvals/{id}/entries` with the human's token, scopes + `openid approval:read approval:approve` (`informed_decision/approval_client.py`). +- **Its intake always creates the approval itself:** + - `intake_approval.py` refuses any binding whose `actor` is not `informed-decision`; + - `intake.py` refuses a memo that pins `approval_id` or `approval_binding_digest`, with reason + `approval_pinned_by_submitter`; + - validity is fixed at 24 h and `pdp_path` at false. + +**net-kingdom executor (`bounded-executor/executor.py`, BEA standard):** preflight refuses unless the approval names +`service:nk-bind-executor` as actor, binds the admission digest, and has only listed HUMAN approvers at aal2. + +## The conflict + +An approval the executor creates (actor `service:nk-bind-executor`) cannot be presented through informed-decision, +because intake refuses a pinned approval. An approval informed-decision creates has actor `informed-decision`, and +the executor and BEA canon refuse that. Neither surface can carry an admission end to end today. + +## Options + +| Option | Change | Owner | Effect | +| --- | --- | --- | --- | +| **A. informed-decision presents an existing approval** (recommended) | An intake profile for a registered submitter (the executor) that accepts an existing `approval_id`. informed-decision would `GET` it and require `human_control: true`, status `requested`, no entries, and a binding digest equal to the memo's; then present it, and post the founder's entry on accept. | informed-decision (INFD) | Keeps BEA's actor binding and approval-engine's create rule. The executor files the request (T14 as planned). The founder approves in the existing UI with presentation evidence. | +| B. Executor accepts actor `informed-decision` | Relax the executor and BEA so that the actor is the approver surface and the admission digest carries the binding. | net-kingdom (canon change) | No informed-decision change, and T14 shrinks to a consume-only client. But the approval no longer names who may run it, and until APPROVAL-WP-0007-T02 any `approval:consume` service could spend it. That weakens BEA-C4. | +| C. A founder CLI approver | A net-kingdom tool gets a human aal2 token (KeyCape PKCE, new client with a loopback redirect) and posts the entry. | net-kingdom + KeyCape | Works without INFD, but it is a second approver surface without informed-decision's presentation and acknowledgement evidence. It needs a new KeyCape client and security case. | + +## Recommendation + +**Option A.** It changes only the presenting surface, keeps every existing guarantee, and leaves T14's design as +written. Ask the INFD owner for a "present existing approval" intake profile, scoped to a registered submitter +(`service:nk-bind-executor`) and to `action: bounded-execution`. + +Until A exists, the pilot (T06) has no approval path. Option C is the fallback if A is declined. diff --git a/workplans/NK-WP-0056-bounded-executor-path.md b/workplans/NK-WP-0056-bounded-executor-path.md index 51b8e5a..cf44c4f 100644 --- a/workplans/NK-WP-0056-bounded-executor-path.md +++ b/workplans/NK-WP-0056-bounded-executor-path.md @@ -771,7 +771,7 @@ executor pod. ```task id: NK-WP-0056-T17 -status: todo +status: done priority: high assignee: claude-code depends_on: [NK-WP-0056-T10] @@ -786,6 +786,23 @@ to end. Then name the missing pieces and their owners. **Done when:** the approval path is described with evidence (works today, or what is missing and who owns it). +**Done 2026-10-31** ([finding](../docs/proposals/2026-10-31-nk56-t17-founder-approval-path.md)): it does not work +today. + +- informed-decision is the live approver surface. It posts the human `approval:approve` entry. +- But its intake always creates the approval itself with `actor: informed-decision`, and refuses a pinned + `approval_id`. +- approval-engine only lets the actor create. +- The executor and BEA require the actor `service:nk-bind-executor`. + +Options: + +- A, recommended: informed-decision presents an existing approval filed by a registered submitter. +- B: relax the actor binding in the executor and BEA. +- C: a founder CLI approver. + +Founder decision needed before T14. + ## Pilot: unattended bind rotation under one admission ```task