Build the T08 domain core with the engine behind a seam
approval-engine APPROVAL-WP-0002-T01 is still progress and its namespace has no pods, so the live end-to-end proof cannot run. Built everything that does not depend on it, with the engine behind a Protocol plus a fake carrying its real refusal semantics, so its arrival is a wiring change rather than a build. - memo.py: the Decision Memo, versions, binding document. Principal, Scope, Awareness and Hat are dataclasses rather than dicts because the canonicalizer requires a shape and a missing key should fail at construction rather than deep inside hashing — which is exactly how it failed twice while building this. Field names follow the governed canonicalizer (item_id, severity, locator): the published vectors are the contract, so the object was aligned to them rather than the reverse. - presentation.py: the sole writer of view_hash. One writer, one canonicalizer, one place to audit. Acknowledgment is an explicit method call and nothing infers it from scroll, dwell or focus. - disposition.py: verbs and guards G_NOAGENT, G_STEP, G_PRES, G_ACK, G_REASONS, G_SEALED. accept is ABSENT from weak steps rather than present-and-disabled, because a greyed-out accept still teaches the wrong model. Only accept reaches the engine; a memo return is not represented there at all. - provenance.py: claim routes per A-16. assert_human_control_dischargeable refuses a registration-supplied human, so PR-11's limitation fires at the point of use instead of sitting in a document. - evidence.py: local outbox, commitment-only records carrying the GH-DEC-2026-014 §4 existence assertion, per-class reconciliation counts, and a custody-locator guard that rejects credentialed URLs (PR-12). - approval_client.py: 409 duplicate_approver is success, 409 conflict terminal, 503 fail-closed, approval:consume refused before a token is requested. 87 tests pass, including every negative case in the Use Case Catalog and that a fail-closed outcome is recorded as a stance application with no verb field — never as a decline, because the human did not make one. T08 stays progress: the live proof is the remainder. 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
This commit is contained in:
parent
4379576abd
commit
9e1f77e32b
18 changed files with 1503 additions and 10 deletions
|
|
@ -429,7 +429,7 @@ issuer, so it is not this repository's to decide alone.
|
|||
|
||||
```task
|
||||
id: INFD-WP-0001-T08
|
||||
status: todo
|
||||
status: progress
|
||||
|
||||
priority: medium
|
||||
state_hub_task_id: "b5c1d329-9580-5672-9640-2930cbbb729a"
|
||||
|
|
@ -454,6 +454,39 @@ act is permitted.
|
|||
Gated externally on `approval-engine` `APPROVAL-WP-0002-T01` reaching `done` and
|
||||
on the service being deployed with an origin this surface can reach.
|
||||
|
||||
2026-09-10 — **domain core built and tested; the live proof remains gated.**
|
||||
`approval-engine` `APPROVAL-WP-0002-T01` is still `progress` and the namespace
|
||||
has no pods, so the end-to-end proof against a deployed engine cannot run. Built
|
||||
everything that does not depend on it, with the engine behind a seam so its
|
||||
arrival is a wiring change rather than a build:
|
||||
|
||||
- `memo.py` — the Decision Memo, versions, and the binding document.
|
||||
`Principal`, `Scope`, `Awareness` and `Hat` are dataclasses rather than dicts
|
||||
because the canonicalizer requires a shape, and a missing key should fail at
|
||||
construction rather than deep inside hashing. Field names follow the governed
|
||||
canonicalizer (`item_id`, `severity`, `locator`) — the vectors are the
|
||||
contract, so the object was aligned to them rather than the reverse.
|
||||
- `presentation.py` — the **sole writer** of `view_hash`. Acknowledgment is an
|
||||
explicit method call; nothing infers it.
|
||||
- `disposition.py` — the verb vocabulary and guards. `accept` is **absent** from
|
||||
weak steps rather than present-and-disabled, because a greyed-out accept still
|
||||
teaches the wrong model.
|
||||
- `provenance.py` — claim routes (A-16). `assert_human_control_dischargeable`
|
||||
refuses a registration-supplied `human`, so PR-11's limitation is visible at
|
||||
the point of use rather than buried in a document.
|
||||
- `evidence.py` — the local outbox, commitment-only records carrying the
|
||||
`GH-DEC-2026-014` §4 existence assertion, and a custody-locator guard that
|
||||
rejects secret-shaped values (PR-12).
|
||||
- `approval_client.py` — Protocol plus a fake with the engine's real semantics:
|
||||
`409 duplicate_approver` is success, `409 conflict` terminal, `503` fail-closed,
|
||||
and `approval:consume` refused before a token is ever requested.
|
||||
|
||||
87 tests pass, including every negative case in the Use Case Catalog: NC-01
|
||||
through NC-08, the humanity-provenance guard, the existence assertion, and that
|
||||
a fail-closed outcome is recorded as a stance application with no `verb` field —
|
||||
never as a decline, because the human did not make one.
|
||||
|
||||
Remaining for `done`: the live proof. Superseded context —
|
||||
2026-09-09: additionally gated on `INFD-IN-0003` — `GH-DEC-2026-012` limit 3
|
||||
requires the evidence copy to reach `audit-core` independently of this
|
||||
component, and the payload question is open. Design and decision request in
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue