informed-decision/SCOPE.md

337 lines
19 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/`.
## Lifecycle production boundary — 2026-10-05
The headless lifecycle service and browser workspace are deployed at
`decisions.coulomb.social` under the founder-approved initial audience:
net-kingdom-admins humans and system:serviceaccount:state-hub:state-hub.
Service image 7f5c6cb2 runs schema 5; Access Engine owns lifecycle v1 and
compact-sitting v13 policy decisions. Approval Engine remains the approval-state
owner. The UI uses the shared service foundation; the private bearer API listens
on 8081 through informed-decision-workload and is absent from public ingress.
Native proof registered two records, retained sources/evaluation/comment, revised
and published one, and sent its exact review envelope through the private State
Hub dispatcher to native approval 22b30fe7-c565-46f2-8193-d8875975ad9e. No image,
configuration or policy change was required for these decisions. Service and
dispatcher pod recreation retained revision 2, custody and the same receipt.
Missing/crossed-audience/unregistered callers are refused. Independent Audit
Core counts match; prior 24 confirmed submissions were preserved.
Human acceptance of source revision 2 is confirmed at 2026-10-04T22:17:19Z,
with an exact presentation/disposition link and independent audit reconciliation.
The initial lifecycle delivery is complete in INFD-WP-0007; broader profiles
and external identity/source integrations are tracked in INFD-WP-0008; intake
initial delivery is completed in INFD-WP-0005. Issuer rotation is separately governed under Platform
RPF-IN-0004. Automatic Hub resolution write-back remains disabled.
Release/cutover procedure: `deploy/lifecycle/README.md`. Native receipts:
`docs/evidence/2026-10-05-lifecycle-cutover/`. Earlier statuses below are historical.
## Lifecycle authoring and discovery deployed — 2026-10-05
Deployed: browser approval/discussion drafts, immutable
supporting text documents with required acknowledgments, document/revision
comparison, and retained review-request downloads. The private API can retrieve
an exact revision's handoff under the existing events permission. These adapters
use the headless service; request preparation creates no native approval.
Review overview discovery now uses recipient-scoped compact-sitting v13 admission;
read and act retain fresh, separate authorization. Native replay verifies list
allow for the retained recipient, another-recipient refusal and stale-read refusal.
This is not a new human login or disposition.
Validation: 671 tests passed (one skipped), 32 owner policy checks, 13 installed
container checks, zero HIGH/CRITICAL scan findings and the authoring increment's
16 Chromium checks. Fresh backup/restore and native outcome retrieval preserve
all 25 confirmed submissions. Argo is Synced/Healthy. Evidence:
`docs/evidence/2026-10-05-lifecycle-authoring/` and
`docs/evidence/2026-10-05-lifecycle-discovery/`.
## Status — 2026-09-27
**Deployed and in live use.** `decisions.coulomb.social` serves
`forgejo.coulomb.social/coulomb/informed-decision@sha256:0557edff...`
in namespace `informed-decision` on railiance01, behind `key-cape` and the
`informed-decision.compact-sitting` Flex Auth package (currently v6). As
observed today: the durable evidence store carries 99 delivered audit events
and 15 confirmed human submissions; platform-root signed in and approved a
memo through this exact surface. This status was last "not deployed" on
2026-09-11 — everything below it in this section was written against a
production system, not a plan.
382 tests pass locally (66 skipped — the opt-in real-Approval-Engine suite,
`INFD_APPROVAL_ENGINE_SOURCE`); 440 pass with that suite enabled, 8 skipped.
11/11 container checks. The 2026-09-21 milestone passed Chromium 13/13 and
433 tests against real Flex Auth/Approval Engine/Audit Core; no newer
Chromium run has been recorded since. Four unrelated, pre-existing failures
persist in both configurations (`waitress` not installed locally; one
clock-adjacent browser-auth test) and are not this repository's regression.
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;
- the **decision overview** on the signed-in home page (`INFD-WP-0003`):
the reviewer's memos grouped as open, accepted, declined, returned, closed,
needing attention or not available. Each row now asks `list`, not `read`
(`INFD-WP-0004`) — a comfortable, 12-hour-fresh identity bar for *seeing*
your decisions, separate from the strict 900-second bar `read`/`accept`/etc.
keep for actually binding one. As of today each row also names the
**requesting party** — approval-engine's `binding.principal`, the party the
approval was issued on behalf of, distinct from the memo's own
`binding.principal` (the reviewer being bound). The overview records
nothing and never presents or binds;
- `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 durable `Store` supplies transactional atomicity for every write path;
the legacy in-memory `evidence.Outbox` is a test double only, not part of the
deployed path. `/readyz` requires an owner runtime configuration and recent
audit delivery health — without either it returns 503 and rollouts are
refused by the readiness probe, not merely warned.
Two production incidents this repository did not cause, both diagnosed by
reading `policy_observations` directly on the live pod rather than guessing:
(1) `key-cape` was backdating a freshly-verified MFA to a stale `kc_login`
session cookie (`INFD-IN-0005`), and, separately, (2) `key-cape`'s
provider-metadata/JWKS discovery fetch was missing the split-horizon
`X-Forwarded-Proto`/`X-Forwarded-Host` headers its token exchange already
carried, which broke every login on Authelia 4.38 the moment a routine
restart hit that code path. Both are fixed and deployed in `key-cape`
(`911e9de`, `8be8065`); this repository's own review correctly treated both
as upstream `policy_denied`/`LoginError` outcomes to relay, not decide.
See [browser-authentication.md](docs/browser-authentication.md),
[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) documents the render/dry-run candidate
path; the actual live rollout is `docker build` → push to the Forgejo OCI
registry → pin the digest in `deploy/sitting-admission.json` → `kubectl set
image` (Recreate) → `kubectl exec` backup/inspect before and after, since
there is no CI pipeline in this repository (unlike `key-cape`'s Forgejo
Actions build-on-push).
## 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
**Declared `layer: Staff`, role `pep-shaped`**, in `INTENT.md` frontmatter
(governing) and `layer.yaml` (derived, marked as such, agreeing) —
`GH-DEC-2026-017`, correcting the `layer: surface` this repository declared
by elimination from 2026-09-09 to 2026-09-21 (§3's vocabulary is closed at
four tokens; `surface` was never one of them). Not an Engine. Companion §5
owed, statute §6.4 in full — `GH-DEC-2026-012`'s shape ruling is unchanged by
the layer correction.
Open, no deadline, nothing waits on it: `INFD-IN-0007` asks how §3.4's
"Staff is interactive and non-deterministic, and MUST NOT hold state another
layer depends on at runtime" reaches a repository that is deterministic by
test and holds presentation evidence `audit-core` depends on. The value is
applied unconditionally either way; this asks only about the *fit*, for the
next repository in this position. Coupled to this repository's own requested
(not yet drafted) §4 catalog row. Separately, this repository approved two
narrow §11 declaration-form amendments on 2026-09-27 (`GH-DEC-2026-021`: A11
r2 — `INTENT.md` frontmatter governs, a derived file must agree and disagreement
is itself a finding; A12 r3 — no version *pin* in a declaration, but a prose
citation like "outside §5 by the v0.5 scope rule" is provenance, not reached).
Both were already this repository's practice; approving changed no file.
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
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 backed by `approval-engine`.** Foreclosed upstream as
well as here: `approval-engine` exposes get-by-id only and will not add a
list. The decision overview (Status, above) is not this — it lists *this
repository's own memos*, sourced from the local `Store` plus a per-row
`list` PDP check and get-by-id engine status, never a listing capability
approval-engine itself provides.
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
- 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`. `FLEX-WP-0024` (finished, 2026-09-14) now
lets flex-auth sign an envelope when a key is configured — but this
repository does not verify a signature anywhere in `policy.py`, and
`store.py`'s schema hard-constrains `decision_attributable` to `0`
(`CHECK(decision_attributable=0)`). The gap flex-auth closed on its side is
still fully open on this one; nothing here must describe validation as
complete.
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 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.
- **Deployed does not mean contained.** This surface is live in production
and observed there (see Status), but that observation is manual —
`kubectl exec` plus `informed-decision-admin inspect`/`backup` around each
rollout. There is no automated post-deploy verification, no CI pipeline in
this repository, and no alerting wired to `/readyz` degrading.
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
- **`INFD-IN-0005`, narrowed.** The two live-blocking defects it predicted
(MFA backdated on reuse; a downstream fetch missing split-horizon headers)
are fixed and deployed. The original ask — Authelia `prompt=login`/`max_age`
support, so a step-up can be requested rather than merely checked after the
fact, is complete in INFD-WP-0006, with live fresh-login/p01 acceptance.
An actionable freshness error in the browser instead of the flat
"Review unavailable" remains open in the existing intake record.
- **`INFD-IN-0007`** — see Layer. No deadline.
- **A reusable account/session-status component**, requested of `user-engine`
as `USER-IN-0002` on 2026-09-27: identity, MFA-freshness, logout, to replace
the bare "Signed in as uid=..." string and make the `list`-vs-`read`
freshness split (see Status) legible instead of a silent wall. Not started;
`user-engine` owns the data/API contract and whether it lands as a new
small repository or inside an existing one.
- **The decision_attributable gap** — see "What this repository does not
claim." Unowned by anyone as an active task; recorded so it is not
mistaken for closed now that flex-auth can sign.
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`).
*Closed since, not previously recorded here:* native browser registration and
human proof (`INFD-WP-0001-T08`) and `audit-core` custody/live delivery
(`AUDIT-IN-0003`, `AUDIT-WP-0009`) — both live and observed in production as
of this Status section.
## Offline workload intake — 2026-10-03
INFD-WP-0005 implements a separate workload-only WSGI intake application,
injected TokenReview and create-only approval transports, per-request grant
reload, per-submitter daily limits, and a schema-3 durable ledger. It atomically
loads pinned memos and packet bytes and queues notification/posed jobs. Human
terminal dispositions atomically queue optional hub resolution; a leased worker
retries delivery with stable ids and leaves disabled/unconfigured adapters pending.
An uncertain approval create never reposts automatically; retained receipts can
resume local loading. Tests cover schema-1/2 upgrade, rollback, replay/restart,
revocation and write-back. T07 also supplies opt-in scheduled delivery, matching
hub message receipts and stable write keys, and immutable posed audit evidence
with receipts, readiness, heartbeat and reconciliation. Actual Audit Core
component tests exercise lost-reply deduplication and counts. This is local
implementation, not a deployed intake listener. Attribute contracts, forwarding,
workload custody, private listener composition and live acceptance are tracked
as blocked tasks in INFD-WP-0005, with acceptance requirements in
`docs/intake-dependency-requirements.md`.
## Initial lifecycle production candidate — 2026-10-04
The private workload listener is now composed and tested with CA-verified
Kubernetes TokenReview, rotating projections and a shared single-writer runtime.
Initial audience is net-kingdom-admins humans plus the exact State Hub service
account. Attribute review now verifies native requester/human-control and receipt
pins before policy evaluation. FLEX-WP-0033 supplies separately pinned lifecycle
and v12 review policy candidates. Published immutable artifacts, security scans,
server dry-runs and recovery steps are retained in `deploy/lifecycle/README.md`.
These changes are not deployed. Requester custody, production State Hub forwarding
and native acceptance remain live tasks in INFD-WP-0005/0007 and RPF-WP-0051.