Claim ownership of the browser-facing approver UI that approval-engine deliberately does not contain. approval-engine's INTENT names an approvals inbox under Non-Goals, and docs/keycape-service-registrations.md records that the human approver client's client_id and callback URI "must come from its owner once it exists" — leaving key-cape's KEY-WP-0013-T02 blocked on an unassigned component. - INTENT.md: Decision Memo concept, the binding/awareness split and the two hashes, ownership and non-ownership against the named estate repositories, and a provisional PEP-shaped layer placement flagged for a gate-house ruling rather than asserted. - GOAL.md: Stage 1 is the L3 approval approver surface — the narrowest real consumer with a live blocking dependency — plus the written answer to who owns the approver UI. - workplans/INFD-WP-0001: founding documents, the gate-house layer/ownership ruling, the four specs (PRD, UseCaseCatalog, ArchitectureBlueprint, EvidenceModel), schema and canonicalizer promotion out of history/ with the isolation vectors under test, the key-cape client registration, and a walking skeleton that includes return and discuss. history/ is preserved unmodified as provenance. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01V3W1dQG7GFFM9d94jFx7iR Assistant: claude-code Assistant-Model: opus Assistant-Process: 1565372@bnt-lap001 Assistant-Session: 16bb2f25-b34c-49ef-8e94-5fec3567a568
8.9 KiB
Decision Memo state transitions v0.2
Actors: requester, assignee (current ready step), party (any listed party), subject (session principal after bind), system, agent.
Guards:
| Id | Meaning |
|---|---|
| G_STEP | Verb is in route.steps[current].required_verbs or is a always-on overlay verb for that step kind (table B) |
| G_PRES | presentation_id exists, memo_version matches, phase is pre_bind or bind |
| G_ACK | All highlights[required_ack=true] are in presentation.acked_highlight_ids |
| G_MAND | Actor mandate covers requested_act + legal/value constraints |
| G_LEVEL | Actor signature meets step.min_binding_level and memo binding_level |
| G_REASONS | return.reasons has ≥1 coded reason |
| G_TARGET | transfer.to is a resolvable party with compatible mandate |
| G_ESC | Target mandate is strictly higher than current assignee for this act |
| G_NOAGENT | actor.kind ≠ agent |
| G_SESSION | session.status = active and actor is session subject |
| G_HAT | configure.hat.id ∈ awareness.available_hats and hat.elevates = false |
| G_PROMOTE | Field moved from awareness → binding; new memo version; presentations invalidated |
Overlay verbs (always available when status allows, even if not in required_verbs): comment, discuss.
Requester-only overlay: withdraw while not terminal.
System-only: stamp, expiry.
A. Memo-level status machine
submit
draft ──────────────► submitted
▲ │
│ │ route.started
│ edit (ver++) ▼
│ circulating
│ │
│ ├── first ready step → awaiting_actor
│ ├── discuss → in_discussion
│ │ │
│ │ └── assignee resumes → awaiting_actor
│ │
│ ├── return → returned ──requester revises (ver++)──► submitted
│ ├── last binding verb → completed (+ outcome)
│ ├── withdraw → withdrawn
│ └── due passed → expired (outcome timed_out)
│
└── completed ── new memo relation.supersedes ──► superseded
L0/L1 extra:
completed + requested_act ∈ {login, elevate}
→ session.status = active (bound_configuring window)
→ configure / session.ended
→ session.status = ended
in_discussion is a substate of circulation. It does not reset the step.
B. Verb × status × step kind
Legend: ✓ allowed · — forbidden · C allowed and may complete the step · M allowed and may complete the memo · S session-only after bind.
Step kinds are grouped:
- Weak:
inform,comment,review,acknowledge - Co-sign:
mitzeichnung,approve - Bind:
schlusszeichnung,sign,seal,deposit
B1. Status draft
| Verb | requester | assignee | agent | Effect |
|---|---|---|---|---|
| comment | ✓ | — | ✓ | thread only |
| discuss | ✓ | — | — | stays draft |
| withdraw | ✓ | — | — | → withdrawn |
| accept / decline / acknowledge / return / forward / escalate / configure | — | — | — | not circulating |
| submit (system/requester) | ✓ | — | — | → submitted |
B2. Status submitted / circulating / awaiting_actor / in_discussion
| Verb | Weak step | Co-sign | Bind step | Guards | Status after |
|---|---|---|---|---|---|
| comment | ✓ any party | ✓ | ✓ | — | unchanged (in_discussion if was circulating) |
| discuss | ✓ any party | ✓ | ✓ | — | in_discussion |
| return | ✓ assignee | ✓ | ✓ | G_NOAGENT G_REASONS | returned |
| forward | ✓ assignee | ✓ | ✓ | G_NOAGENT G_TARGET | stays circulating; step assignee replaced |
| escalate | ✓ assignee | ✓ | ✓ | G_NOAGENT G_TARGET G_ESC | circulating; higher step inserted/activated |
| acknowledge | C assignee | C | ✓ overlay | G_NOAGENT G_PRES G_ACK | step complete; memo completes only if this was the last step and requested_act=acknowledge |
| accept | — | C assignee | M assignee | G_NOAGENT G_PRES G_ACK G_MAND G_LEVEL G_STEP | last bind/co-sign step → completed outcome=accepted |
| decline | — | C assignee | M assignee | G_NOAGENT G_PRES G_STEP | → completed outcome=declined (memo ends; later steps skipped) |
| abstain | — | C assignee | C assignee | G_NOAGENT G_PRES | step complete for this actor; parallel group may continue; if actor was sole bind step → completed outcome=abstained |
| recuse | ✓ | C | C | G_NOAGENT G_PRES | step unassigned; must forward/escalate or return |
| withdraw | requester only | same | same | not terminal | → withdrawn |
| stamp | system | system | system | after a bind disposition or on completion | unchanged |
| configure | — | — | — | not yet bound | — |
| promote | requester | requester | requester | G_PROMOTE | version++; back toward submitted |
accept on a weak step is illegal. Weak steps take acknowledge. That is how Kenntnisnahme stays distinct from Schlusszeichnung.
B3. Status returned
| Verb | Who | Effect |
|---|---|---|
| comment / discuss | any party | thread |
| revise + submit | requester | version++; → submitted; new route from policy |
| withdraw | requester | → withdrawn |
| binding verbs | — | illegal on a returned version |
B4. Status completed
| Verb | Who | Effect |
|---|---|---|
| comment | parties | thread; does not unseal |
| stamp | system | file.stamped / bundle.sealed |
| configure | subject | S session hat; see §C |
| promote | requester | not on this version; open child memo |
| accept / return / … | — | sealed |
If requested_act ∈ {login, elevate} then session.status becomes active at the completing accept/acknowledge.
B5. Terminal withdrawn | expired | superseded
No actor verbs except system stamp of the evidence bundle already accumulated.
C. Post-bind session transitions
Applies when session.status = active.
pre_bind presentation
│ actor chooses identity + bind-scope
│ sees proposed hat / other tenants as AWARENESS only
▼
bind disposition (accept | acknowledge)
│ view_hash covers binding_slice only
│ awareness_hash recorded alongside, not signed
▼
session.active
├── configure(hat) if hat.elevates=false ∧ hat in available_hats
├── attempt other scope
│ requires_new_bind=false → still configure (same bind)
│ requires_new_bind=true → emit scope.rebind_required, open child memo
└── session.ended logout / expiry / revoke
| Event | In view_hash? |
In awareness_hash? |
Evidence event |
|---|---|---|---|
| Chosen identity | yes | copy ok | identity.authenticated |
| Chosen bind-scope / tenant of this login | yes | copy ok | disposition.recorded |
| Privileges granted at the gate | yes | preview ok | disposition.recorded |
| Proposed / last-used hat shown | no | yes | awareness.shown |
| Hat selected after login | no | yes | session.hat_selected |
Hat with elevates=true |
must promote | — | promote + new bind |
Other tenant with requires_new_bind |
no | listed | scope.rebind_required |
Defaulting the hat to last_used or system_default is an awareness act. Showing it on the login banner is required for situational awareness and forbidden from silently entering view_hash.
D. Completing a step vs completing the memo
A step completes when the assignee records a verb in that step’s completion set:
| Step kind | Completion set |
|---|---|
| inform, review, acknowledge | acknowledge, return, recuse |
| comment | comment (if so configured) or acknowledge |
| mitzeichnung, approve | accept, decline, abstain, recuse, return |
| schlusszeichnung, sign, seal, deposit | accept, decline, abstain, recuse, return |
The memo completes when:
- A bind-step
declineis recorded, or - Every required step is
completedorskipped, and at least one completing verb in the memo’srequested_actfamily was recorded, or - Requester
withdraw, or system expiry.
Parallel groups: all members must reach a terminal step status before the next ordinal becomes ready.
E. Illegal combinations (explicit)
- Agent + any binding verb
acceptoninform/reviewconfigurebeforesession.activeconfigureof a hat withelevates=trueconfigureof a scope withrequires_new_bind=true- Binding verb whose presentation
phase=post_bind - Binding verb whose presentation
awareness_hashwas substituted forview_hash - Mutating
identity_context.bindingafter the first bind disposition of that version