APPROVAL-WP-0007: record the verified revoker and park the inactive plans

Schema v9 stores who revoked an approval and an optional bounded reason.
The bounded-execution carrier example is proven in process. APPROVAL-WP-0005,
0006, and 0007 are blocked because they are not current work. Task statuses
stay as they were, apart from T03 and T04, which are done in source.

Assistant: grok
Assistant-Session: 01a1b5fd-0c33-7ba1-b383-53937d525595
This commit is contained in:
tegwick 2026-11-07 14:10:01 +01:00
parent f41a9ca82c
commit 4aa0b75449
17 changed files with 599 additions and 36 deletions

View file

@ -448,6 +448,22 @@ call with no authenticated consumer fails closed. The check does not change
Migration leaves existing rows without the flag. The declaration is separate
from the five-field act digest.
### Revoker evidence — `revoked_by`
APPROVAL-WP-0007-T03, schema v9 store. `POST /v1/approvals/{id}/revoke` still
moves `requested` or `approved` to terminal `revoked` by the same
compare-and-swap. The body accepts only an optional `reason`: one line, at
most 200 characters. The verified token supplies `subject`, `principal_type`
and `assurance`. A body cannot name the revoker. The revoker is not required
to equal `binding.principal`.
When a verified revoker is present, `GET` serves `revoked_by` and the
`approval.revocation` outbox event carries the same object in
`details.revoked_by`. The event `actor` stays the bound actor. The claim does
not gain `revoked_by`: it stays a validity fact, and undeclared claim bytes
stay exact. An internal revoke with no verified revoker still revokes and
omits the member, which is also how legacy rows read after migration.
### Actor is never an approver under `human_control`
GH-DEC-2026-026 Ruling 6. Under `human_control: true`, `POST /entries` refuses