--- id: APPROVAL-WP-0007 type: workplan title: "Bounded-execution admission carrier: assurance floor, correspondence and revoker evidence" domain: infotech repo: approval-engine status: proposed flavor: implementation owner: approval-engine topic_slug: netkingdom created: "2026-10-31" updated: "2026-10-31" depends_on: [] --- Demand: NetKingdom NK-WP-0056-T02 owner request (hub message 40344380-ea33-4670-9b27-dafca1699d36) to carry a Bounded Execution Admission v0.1 (proposed) as an approval. Owner answer: `docs/bounded-execution-admission-carrier.md`. The binding, consume and revoke already work. This plan closes the engine-side gaps the answer found. Every change is opt-in at issue, so existing approvals and consumers keep their behavior. Native digest, CAS consumption and no-unconsume are unchanged. ## Declared minimum approver assurance ```task id: APPROVAL-WP-0007-T01 status: todo priority: high ``` Add an optional `required_assurance` (minimum `level`, ordered aal1 < aal2 < aal3) to `POST /v1/approvals`. Store it and serve it in the object and the claim, and inherit it on supersede. `add_entry` refuses an entry whose verified token `assurance.level` is weaker or missing. `_evaluate` and `consume` refuse when an existing entry does not meet it. Schema migration leaves old rows NULL, meaning no floor. Tests cover aal1 refused, aal2 accepted, missing level refused, supersede inheritance and the claim reason_code. Serves BEA-C4. Whether KeyCape emits `aal2` is KeyCape's question, outside this plan. ## Opt-in approver and consumer correspondence ```task id: APPROVAL-WP-0007-T02 status: wait priority: medium ``` Proposal for owner and Gate House agreement before implementation, because it gives `principal` and `actor` an enforced meaning. Two optional issue flags: - `principal_approves`: every entry subject must equal `binding.principal`. - `actor_consumes`: the consuming subject must equal `binding.actor`. Today any human with `approval:approve` can approve, and any tenant service with `approval:consume` can spend the object (a denial-of-run risk). Wait reason: semantic decision. NetKingdom's actor and principal strings must also match KeyCape subjects exactly. ## Revoker identity in revocation evidence ```task id: APPROVAL-WP-0007-T03 status: todo priority: medium ``` Record the verified revoker's subject, principal_type and assurance, plus an optional bounded `reason`, in the `approval.revocation` outbox event. Persist them on the object (the `revoked_by` fields) without changing the CAS or terminal semantics. This is the evidence for the founder's pre-start kill switch (NK-WP-0056-T07). Do not require the revoker to equal the principal: revocation must stay possible without the holder. ## Synthetic bounded-execution carrier proof ```task id: APPROVAL-WP-0007-T04 status: todo priority: medium ``` Add an in-process test and an example request covering the full path: the executor (service) creates the request (`action: bounded-execution`, `target: {admission_id, admission_digest}`, `human_control: true`, `pdp_path: false`); a human aal2 entry approves it; GET binding comparison; consume with `request_digest` = admission digest; idempotent retry; a different digest returns 409; revoke before consume gives 409 on consume; consumption outside the window is refused. Synthetic fixtures only, with no live service.