informed-decision/SCOPE.md

190 lines
10 KiB
Markdown
Raw Normal View History

# SCOPE
> Implemented-and-first-cut boundary for agents and contributors. Aspirational
> direction belongs in `INTENT.md`; the current stage belongs in `GOAL.md`;
> current work and gates belong in `workplans/`.
## Status — 2026-09-11
**The protected browser review, policy consumer, Approval Engine adapter,
durable evidence store and scheduled Audit Core delivery are implemented.
The approval surface is not deployed.**
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
2026-09-10 20:38:20 +02:00
What exists and is tested (371 automated tests and 11 container checks; the
previous browser milestone passed 12 Chromium checks). Component tests use
actual Flex Auth, Approval Engine and Audit Core with synthetic identity/custody:
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
2026-09-10 20:38:20 +02:00
- layer and stance declarations — `layer.yaml`, `pep-stance.yaml`,
`informed_decision/stance.py`, with published-equals-shipped asserted;
- the governed canonicalizer and schema, with the three published vectors
reproducing byte for byte and all four isolation properties pinned;
- the **domain core**: `memo.py` (the Decision Memo, its versions and the
binding document), `presentation.py` (the sole writer of `view_hash`),
`disposition.py` (the verb vocabulary and guards `G_NOAGENT`, `G_STEP`,
`G_PRES`, `G_ACTOR`, `G_ACK`, `G_REASONS`, `G_SEALED`), `provenance.py` (claim routes,
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
2026-09-10 20:38:20 +02:00
A-16), `evidence.py` (the local outbox and commitment records);
- `approval_client.py` — the seam to `approval-engine` plus a fake;
- `oidc.py` and `web.py` — public-client PKCE sign-in, verified human/MFA
profile, bounded server-side sessions, protected cookies and CSRF sign-out;
- `approval_http.py` and `http_transport.py` — get-by-id and human-entry
transport, declared-control checks, real entry correlation, no consume route
or automatic mutation retry. Protected browser actions use this adapter;
- `store.py` / `records.py` — private durable packet/memo/presentation/
disposition storage, append-only acknowledgments, transactional outbox and
submission correlation, safe reservation and backup/restore;
- `audit.py` — idempotent Audit Core delivery, bounded retry/blocked states,
explicit per-class count/time-basis comparison. Heartbeats are generated
without hiding undelivered evidence;
- `policy.py` / `review.py` / `ui.py` — fresh entitlement before rendering and
actions, exact response pins, immutable observations, required highlights,
accept/return/discuss/decline and visible original/unresolved entry state;
- `runtime.py` — explicit owner configuration, rotating credential-file readers,
30-second audit draining, heartbeat/reconciliation and delivery readiness.
- `Containerfile`, `container.py`, `requirements.lock` and deployment renderer —
a locally built/scanned image, private projected-config handoff, one serving
writer, backup/inspection commands and eight review-only Kubernetes objects.
Network-isolated container restart/restore preserves unresolved submissions.
The 2026-09-11 fsGroup startup correction handles newly created private
directories on Kubernetes volumes; unsafe existing directories still refuse.
Its full local suite passes 335 tests with 39 optional checks skipped. The
corrected local image 92cde609 passes 11 container checks, and its source
adapter passes native audit delivery/retry/scope checks. Independent archive
readback, bearer lifecycle and service image scan/publication remain open.
Remaining: native policy package/caller/assignment admission, registered human
login and deployed binding, independent production audit custody, image
publication/cutover, platform backup/restore and operator recovery admission.
The legacy `evidence.Outbox` remains an
in-memory test double; the new `Store` supplies durable atomicity. Browser
sessions are ephemeral, with no approval state.
Without owner runtime configuration `/readyz` returns 503. With it, readiness
requires recent audit delivery health; it does not assert native admission.
The origin's last observed deployment was an nginx placeholder on 2026-09-10.
See [browser-authentication.md](docs/browser-authentication.md) and
[durable-review-evidence.md](docs/durable-review-evidence.md) and
[protected-browser-review.md](docs/protected-browser-review.md).
The [deployment packet](deploy/README.md) records native wiring observations,
the missing Approval Engine namespace and remaining owner admission.
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
2026-09-10 20:38:20 +02:00
`INFD-WP-0001-T08` remains open for the live end-to-end proof, which is gated on
`APPROVAL-WP-0002-T01` and a deployed `approval-engine`.
## One-liner
informed-decision is the presentation and binding surface for decisions: it
renders a Decision Memo to the human who holds the mandate, records what was
shown, and binds their identity to the act — and owns the browser-facing
approver UI that `approval-engine` deliberately does not contain.
Architecture Blueprint and rewritten SCOPE; close T05 and T06 T05 written after the ruling rather than before it, which was the point of gating it. GH-DEC-2026-012 limit 3 did most of the shaping: the evidence copy must reach audit-core independently of this component, because here the actor being audited and the evidence source are the same. Booked as four binding implementation consequences plus O-02, which must be resolved before T08 ships — "we will add the independent path later" is how limit 3 becomes limit-3-in-principle. Other constraints fixed in the blueprint: presentation/ is the only writer of view_hash; the approval-engine client exposes no validity cache; a fail-closed outcome is never recorded as an approver's decline, since the human made none; the assurance shape is cited from key-cape's contract rather than restated so it cannot drift; and no polling loop may synthesise the inbox approval-engine refuses to provide. T06 closed with the SCOPE.md rewrite the ruling unblocked. It carries a "What this repository does not claim" section, because a scope file listing only capabilities overstates them: the decision path is not validated while GH-DEC-2026-010 is open, the residual is not closed, view_hash is not inside the approval entry, and nothing is deployed. Two open items block the remainder. O-01, the human token tenant, blocks T07 and is not ours alone to decide. O-02, the independent evidence path, blocks T08. 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
2026-09-09 22:29:06 +02:00
## Layer
**PEP-shaped**, ruled by `GH-DEC-2026-012`. Not an Engine. Companion §5 owed,
statute §6.4 in full. Declared in `layer.yaml` in this repository's own voice.
It emits one PIP-like fact — *what was presented* — as a claim, under three
limits that are the substance of the permission rather than caveats on it:
1. the claim carries presentation and nothing else, and must never carry,
restate, summarise or imply a decision or verdict;
2. the claim must never be an input to the decision it presents for;
3. the evidence copy reaches `audit-core` **independently** of this repository.
Limit 2 is load-bearing: the argument that a renderer attesting its own
rendering is not self-dealing was accepted *because* that limit holds.
## Core Idea
A decision surface is not a workflow engine and not a decision point. This
repository owns the Decision Memo object, the presentation record, the
Architecture Blueprint and rewritten SCOPE; close T05 and T06 T05 written after the ruling rather than before it, which was the point of gating it. GH-DEC-2026-012 limit 3 did most of the shaping: the evidence copy must reach audit-core independently of this component, because here the actor being audited and the evidence source are the same. Booked as four binding implementation consequences plus O-02, which must be resolved before T08 ships — "we will add the independent path later" is how limit 3 becomes limit-3-in-principle. Other constraints fixed in the blueprint: presentation/ is the only writer of view_hash; the approval-engine client exposes no validity cache; a fail-closed outcome is never recorded as an approver's decline, since the human made none; the assurance shape is cited from key-cape's contract rather than restated so it cannot drift; and no polling loop may synthesise the inbox approval-engine refuses to provide. T06 closed with the SCOPE.md rewrite the ruling unblocked. It carries a "What this repository does not claim" section, because a scope file listing only capabilities overstates them: the decision path is not validated while GH-DEC-2026-010 is open, the residual is not closed, view_hash is not inside the approval entry, and nothing is deployed. Two open items block the remainder. O-01, the human token tenant, blocks T07 and is not ours alone to decide. O-02, the independent evidence path, blocks T08. 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
2026-09-09 22:29:06 +02:00
canonicalization producing `view_hash` / `awareness_hash`, the disposition
vocabulary, and the evidence bundle export. It does not evaluate whether an act
is permitted, does not hold approval current-state, and does not archive the
trail.
Architecture Blueprint and rewritten SCOPE; close T05 and T06 T05 written after the ruling rather than before it, which was the point of gating it. GH-DEC-2026-012 limit 3 did most of the shaping: the evidence copy must reach audit-core independently of this component, because here the actor being audited and the evidence source are the same. Booked as four binding implementation consequences plus O-02, which must be resolved before T08 ships — "we will add the independent path later" is how limit 3 becomes limit-3-in-principle. Other constraints fixed in the blueprint: presentation/ is the only writer of view_hash; the approval-engine client exposes no validity cache; a fail-closed outcome is never recorded as an approver's decline, since the human made none; the assurance shape is cited from key-cape's contract rather than restated so it cannot drift; and no polling loop may synthesise the inbox approval-engine refuses to provide. T06 closed with the SCOPE.md rewrite the ruling unblocked. It carries a "What this repository does not claim" section, because a scope file listing only capabilities overstates them: the decision path is not validated while GH-DEC-2026-010 is open, the residual is not closed, view_hash is not inside the approval entry, and nothing is deployed. Two open items block the remainder. O-01, the human token tenant, blocks T07 and is not ours alone to decide. O-02, the independent evidence path, blocks T08. 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
2026-09-09 22:29:06 +02:00
## In Scope — first cut (Stage 1)
Architecture Blueprint and rewritten SCOPE; close T05 and T06 T05 written after the ruling rather than before it, which was the point of gating it. GH-DEC-2026-012 limit 3 did most of the shaping: the evidence copy must reach audit-core independently of this component, because here the actor being audited and the evidence source are the same. Booked as four binding implementation consequences plus O-02, which must be resolved before T08 ships — "we will add the independent path later" is how limit 3 becomes limit-3-in-principle. Other constraints fixed in the blueprint: presentation/ is the only writer of view_hash; the approval-engine client exposes no validity cache; a fail-closed outcome is never recorded as an approver's decline, since the human made none; the assurance shape is cited from key-cape's contract rather than restated so it cannot drift; and no polling loop may synthesise the inbox approval-engine refuses to provide. T06 closed with the SCOPE.md rewrite the ruling unblocked. It carries a "What this repository does not claim" section, because a scope file listing only capabilities overstates them: the decision path is not validated while GH-DEC-2026-010 is open, the residual is not closed, view_hash is not inside the approval entry, and nothing is deployed. Two open items block the remainder. O-01, the human token tenant, blocks T07 and is not ours alone to decide. O-02, the independent evidence path, blocks T08. 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
2026-09-09 22:29:06 +02:00
**Built and tested:**
- Canonicalization of the binding and awareness documents, with the three
published vectors reproducing byte for byte and all four isolation properties
pinned (`tests/test_canonicalize.py`).
- The Decision Memo schema and worked examples, governed under `schemas/`.
- The unreachable-engine stance map, built to v0.8 obligation 3, with
published-equals-shipped asserted by test (`tests/test_layer_conformance.py`).
**Built with durable custody and protected HTTP integration:**
Architecture Blueprint and rewritten SCOPE; close T05 and T06 T05 written after the ruling rather than before it, which was the point of gating it. GH-DEC-2026-012 limit 3 did most of the shaping: the evidence copy must reach audit-core independently of this component, because here the actor being audited and the evidence source are the same. Booked as four binding implementation consequences plus O-02, which must be resolved before T08 ships — "we will add the independent path later" is how limit 3 becomes limit-3-in-principle. Other constraints fixed in the blueprint: presentation/ is the only writer of view_hash; the approval-engine client exposes no validity cache; a fail-closed outcome is never recorded as an approver's decline, since the human made none; the assurance shape is cited from key-cape's contract rather than restated so it cannot drift; and no polling loop may synthesise the inbox approval-engine refuses to provide. T06 closed with the SCOPE.md rewrite the ruling unblocked. It carries a "What this repository does not claim" section, because a scope file listing only capabilities overstates them: the decision path is not validated while GH-DEC-2026-010 is open, the residual is not closed, view_hash is not inside the approval entry, and nothing is deployed. Two open items block the remainder. O-01, the human token tenant, blocks T07 and is not ours alone to decide. O-02, the independent evidence path, blocks T08. 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
2026-09-09 22:29:06 +02:00
- The presentation record: what was rendered, to whom, when, in which locale and
UI release.
- Required-highlight acknowledgment as a precondition of binding.
Architecture Blueprint and rewritten SCOPE; close T05 and T06 T05 written after the ruling rather than before it, which was the point of gating it. GH-DEC-2026-012 limit 3 did most of the shaping: the evidence copy must reach audit-core independently of this component, because here the actor being audited and the evidence source are the same. Booked as four binding implementation consequences plus O-02, which must be resolved before T08 ships — "we will add the independent path later" is how limit 3 becomes limit-3-in-principle. Other constraints fixed in the blueprint: presentation/ is the only writer of view_hash; the approval-engine client exposes no validity cache; a fail-closed outcome is never recorded as an approver's decline, since the human made none; the assurance shape is cited from key-cape's contract rather than restated so it cannot drift; and no polling loop may synthesise the inbox approval-engine refuses to provide. T06 closed with the SCOPE.md rewrite the ruling unblocked. It carries a "What this repository does not claim" section, because a scope file listing only capabilities overstates them: the decision path is not validated while GH-DEC-2026-010 is open, the residual is not closed, view_hash is not inside the approval entry, and nothing is deployed. Two open items block the remainder. O-01, the human token tenant, blocks T07 and is not ours alone to decide. O-02, the independent evidence path, blocks T08. 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
2026-09-09 22:29:06 +02:00
- The disposition vocabulary and its legality tables. Only `accept` reaches
`approval-engine`; `return`, `discuss`, `escalate` and the rest are
memo-level.
- The browser-facing OIDC client: authorization-code + S256 PKCE against
`key-cape`, scopes `[openid, approval:read, approval:approve]`.
- An L3 approver surface calling `approval-engine`'s approval-entry mutation.
**Specified, not built:**
- The evidence bundle as an offline-verifiable export.
- German browser acceptance and the broader step/awareness UI. The current
browser profile refuses unsupported locale/step/level rather than overstating it.
## Out of Scope
- Authorization decisions — `access-engine`, always and only (statute §6).
- The approval object, its state machine, validity and consumption —
Architecture Blueprint and rewritten SCOPE; close T05 and T06 T05 written after the ruling rather than before it, which was the point of gating it. GH-DEC-2026-012 limit 3 did most of the shaping: the evidence copy must reach audit-core independently of this component, because here the actor being audited and the evidence source are the same. Booked as four binding implementation consequences plus O-02, which must be resolved before T08 ships — "we will add the independent path later" is how limit 3 becomes limit-3-in-principle. Other constraints fixed in the blueprint: presentation/ is the only writer of view_hash; the approval-engine client exposes no validity cache; a fail-closed outcome is never recorded as an approver's decline, since the human made none; the assurance shape is cited from key-cape's contract rather than restated so it cannot drift; and no polling loop may synthesise the inbox approval-engine refuses to provide. T06 closed with the SCOPE.md rewrite the ruling unblocked. It carries a "What this repository does not claim" section, because a scope file listing only capabilities overstates them: the decision path is not validated while GH-DEC-2026-010 is open, the residual is not closed, view_hash is not inside the approval entry, and nothing is deployed. Two open items block the remainder. O-01, the human token tenant, blocks T07 and is not ours alone to decide. O-02, the independent evidence path, blocks T08. 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
2026-09-09 22:29:06 +02:00
`approval-engine`. Never cached, never inferred, never `approval:consume`.
- Approval doctrine — `gate-house`.
- Identity and authentication — `key-cape`. Imported, never invented. The
`assurance` shape is `key-cape`'s and is cited, not restated.
- The evidence archive — `audit-core`.
- Credentials materialized after a decision — `secrets-engine`.
Architecture Blueprint and rewritten SCOPE; close T05 and T06 T05 written after the ruling rather than before it, which was the point of gating it. GH-DEC-2026-012 limit 3 did most of the shaping: the evidence copy must reach audit-core independently of this component, because here the actor being audited and the evidence source are the same. Booked as four binding implementation consequences plus O-02, which must be resolved before T08 ships — "we will add the independent path later" is how limit 3 becomes limit-3-in-principle. Other constraints fixed in the blueprint: presentation/ is the only writer of view_hash; the approval-engine client exposes no validity cache; a fail-closed outcome is never recorded as an approver's decline, since the human made none; the assurance shape is cited from key-cape's contract rather than restated so it cannot drift; and no polling loop may synthesise the inbox approval-engine refuses to provide. T06 closed with the SCOPE.md rewrite the ruling unblocked. It carries a "What this repository does not claim" section, because a scope file listing only capabilities overstates them: the decision path is not validated while GH-DEC-2026-010 is open, the residual is not closed, view_hash is not inside the approval entry, and nothing is deployed. Two open items block the remainder. O-01, the human token tenant, blocks T07 and is not ours alone to decide. O-02, the independent evidence path, blocks T08. 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
2026-09-09 22:29:06 +02:00
- Notification transport, ticketing, general workflow.
- **An approvals inbox.** Foreclosed upstream as well as here:
`approval-engine` exposes get-by-id only and will not add a list.
- L4/L5, QES, QTSP, qualified archival retention.
- The mandate graph — so a Stage 1 `escalate` is an assertion, not a verified
claim.
## What this repository does not claim
Stated here because a scope file that only lists capabilities overstates them.
- **The decision path is not validated.** `GH-DEC-2026-010` requires a decision
be attributable to `access-engine`; no consumer can satisfy that today because
the envelope is unsigned (`FLEX-WP-0024`). This surface records
`decision_attributable: false` and must not describe validation as complete.
- **The residual is open.** A compromised surface can present X and attest Y.
`GH-DEC-2026-012` states it is not closed and does not credit this repository
with closing it.
- **`view_hash` is not inside the approval entry.** `POST /entries` discards its
body by design. Correlation is `(approval_id, subject, approved_at)`, so an
auditor holding only the approval object cannot reach the presentation.
Apply GH-DEC-2026-013 and GH-DEC-2026-014; close INFD-IN-0002 Two rulings landed and both corrected something. GH-DEC-2026-013 accepted our binding-versus-awareness argument, wrote it into the record as its §6, and did not change the outcome — it sharpened the defect. Two different facts share one field named tenant: the act-scope, a property of the act that our binding slice commits, and the principal's membership, a property of the person that approval-engine exact-matches. Gate House's correction stands: a binding slice that must commit the scope being entered should commit that scope, not borrow a membership claim to stand in for it. Our schema already does — binding.target IS the act-scope and is inside view_hash — so no field was added, only a statement (PR-08) and a provenance record (PR-09), since key-cape emits tenant as a bare string. key-cape had already implemented registration-bound tenancy on 2026-09-09, correct under both candidate rulings, so the fail-closed-at-first-use risk that made us withhold the client strings was already retired. IN-0002 closed. The one remaining input to T07 is the deployed origin. GH-DEC-2026-014 granted commitment-only evidence and bounded it. It satisfies non-alteration and NOT reconstructability, and must not be described otherwise anywhere. It also corrected our wording of the gap: we wrote that it leaves us able to erase the content, which understates it. Commitment-only moves integrity out of our control and leaves availability entirely inside it — the party that can withhold the content is the party the evidence is about. Limit 3's condition reduced, not removed. The grant carries a condition we did not propose and would not have thought of: the path must assert that committed content exists and where custody sits, so non-production is a finding attributable to the custodian rather than an unremarkable blank. A commitment with no assertion that something is being committed to is indistinguishable from a commitment to nothing. Booked as PR-53, and marked not-a-reversal-candidate. Recorded the meta-rule Gate House named, now in its third setting here: unknown versus absent in the stance map, directory-asserted versus registration-supplied in the tenant claim, erased versus never held in the evidence path. Wherever a system reaches one appearance by two routes, the record must say which route. 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
2026-09-10 07:57:57 +02:00
- **Commitment-only evidence is not reconstructability.** `GH-DEC-2026-014`
granted it for Stage 1 and bounded it: it satisfies non-alteration, and moves
integrity out of our control while leaving *availability* entirely inside it.
The party that can withhold the content is the party the evidence is about.
Narrowed by the required existence assertion; not closed.
- **The registration-bound tenant is a declared bounded gap**, not the terminal
state. `GH-DEC-2026-013` ruled directory-sourced terminal and admitted
`key-cape`'s shape because its distinguishing case fails closed. Build to it
as transitional.
Architecture Blueprint and rewritten SCOPE; close T05 and T06 T05 written after the ruling rather than before it, which was the point of gating it. GH-DEC-2026-012 limit 3 did most of the shaping: the evidence copy must reach audit-core independently of this component, because here the actor being audited and the evidence source are the same. Booked as four binding implementation consequences plus O-02, which must be resolved before T08 ships — "we will add the independent path later" is how limit 3 becomes limit-3-in-principle. Other constraints fixed in the blueprint: presentation/ is the only writer of view_hash; the approval-engine client exposes no validity cache; a fail-closed outcome is never recorded as an approver's decline, since the human made none; the assurance shape is cited from key-cape's contract rather than restated so it cannot drift; and no polling loop may synthesise the inbox approval-engine refuses to provide. T06 closed with the SCOPE.md rewrite the ruling unblocked. It carries a "What this repository does not claim" section, because a scope file listing only capabilities overstates them: the decision path is not validated while GH-DEC-2026-010 is open, the residual is not closed, view_hash is not inside the approval entry, and nothing is deployed. Two open items block the remainder. O-01, the human token tenant, blocks T07 and is not ours alone to decide. O-02, the independent evidence path, blocks T08. 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
2026-09-09 22:29:06 +02:00
- **Nothing is deployed**, so nothing is observed in production and nothing is
contained automatically.
Architecture Blueprint and rewritten SCOPE; close T05 and T06 T05 written after the ruling rather than before it, which was the point of gating it. GH-DEC-2026-012 limit 3 did most of the shaping: the evidence copy must reach audit-core independently of this component, because here the actor being audited and the evidence source are the same. Booked as four binding implementation consequences plus O-02, which must be resolved before T08 ships — "we will add the independent path later" is how limit 3 becomes limit-3-in-principle. Other constraints fixed in the blueprint: presentation/ is the only writer of view_hash; the approval-engine client exposes no validity cache; a fail-closed outcome is never recorded as an approver's decline, since the human made none; the assurance shape is cited from key-cape's contract rather than restated so it cannot drift; and no polling loop may synthesise the inbox approval-engine refuses to provide. T06 closed with the SCOPE.md rewrite the ruling unblocked. It carries a "What this repository does not claim" section, because a scope file listing only capabilities overstates them: the decision path is not validated while GH-DEC-2026-010 is open, the residual is not closed, view_hash is not inside the approval entry, and nothing is deployed. Two open items block the remainder. O-01, the human token tenant, blocks T07 and is not ours alone to decide. O-02, the independent evidence path, blocks T08. 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
2026-09-09 22:29:06 +02:00
## Open
- **Native browser registration and human proof** — T07 supplied the real
origin and submitted the contract. T08 retains registration rollout and a real
human login accepted by the deployed Approval Engine.
- **`audit-core` custody and live delivery** — source registration and cadence
have owner returns (`AUDIT-IN-0003`, `AUDIT-WP-0009` T04/T06/T07); native
credentials, independent receipt and reconciliation still require proof before
T08 ships.
Apply GH-DEC-2026-013 and GH-DEC-2026-014; close INFD-IN-0002 Two rulings landed and both corrected something. GH-DEC-2026-013 accepted our binding-versus-awareness argument, wrote it into the record as its §6, and did not change the outcome — it sharpened the defect. Two different facts share one field named tenant: the act-scope, a property of the act that our binding slice commits, and the principal's membership, a property of the person that approval-engine exact-matches. Gate House's correction stands: a binding slice that must commit the scope being entered should commit that scope, not borrow a membership claim to stand in for it. Our schema already does — binding.target IS the act-scope and is inside view_hash — so no field was added, only a statement (PR-08) and a provenance record (PR-09), since key-cape emits tenant as a bare string. key-cape had already implemented registration-bound tenancy on 2026-09-09, correct under both candidate rulings, so the fail-closed-at-first-use risk that made us withhold the client strings was already retired. IN-0002 closed. The one remaining input to T07 is the deployed origin. GH-DEC-2026-014 granted commitment-only evidence and bounded it. It satisfies non-alteration and NOT reconstructability, and must not be described otherwise anywhere. It also corrected our wording of the gap: we wrote that it leaves us able to erase the content, which understates it. Commitment-only moves integrity out of our control and leaves availability entirely inside it — the party that can withhold the content is the party the evidence is about. Limit 3's condition reduced, not removed. The grant carries a condition we did not propose and would not have thought of: the path must assert that committed content exists and where custody sits, so non-production is a finding attributable to the custodian rather than an unremarkable blank. A commitment with no assertion that something is being committed to is indistinguishable from a commitment to nothing. Booked as PR-53, and marked not-a-reversal-candidate. Recorded the meta-rule Gate House named, now in its third setting here: unknown versus absent in the stance map, directory-asserted versus registration-supplied in the tenant claim, erased versus never held in the evidence path. Wherever a system reaches one appearance by two routes, the record must say which route. 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
2026-09-10 07:57:57 +02:00
*Closed 2026-09-10:* the human token tenant (`GH-DEC-2026-013`, `key-cape`
`329e48f`) and the evidence payload question (`GH-DEC-2026-014`).