diff --git a/SCOPE.md b/SCOPE.md index 4498d84..093110a 100644 --- a/SCOPE.md +++ b/SCOPE.md @@ -1,15 +1,16 @@ # SCOPE -Reviewed 2026-09-09 against source revision `7a73352`. The preceding review was -2026-09-05 against `b989de4`; the [reassessment](history/2026-09-09-scope-reassessment.md) -records what changed and how each claim below was checked. +Reviewed 2026-09-10 against source revision `f247d35`. -The capability review was performed against `5ae80d3`. `7a73352` landed a minute -before it and changes documentation and workplans only, no source; its substance -reached this document as a peer report and was afterwards confirmed by reading -the commit, which is why the baseline names it. That distinction — read versus -told — is worth keeping in a header whose whole purpose is to let a reader ask -"what changed since?" and get a usable answer. +Review lineage, because "what changed since?" should have a usable answer. The +full capability review was 2026-09-09 against `5ae80d3` +([reassessment](history/2026-09-09-scope-reassessment.md)), superseding +2026-09-05 against `b989de4`. `7a73352` followed it by a minute — documentation +and workplans only — and was confirmed by reading the commit rather than by +report. Since then the tenant claim gained `tenant_source`, the approver client +was registered, and two guards were added that pin properties rather than +behaviours; each is described below. Read versus told, and reviewed versus merely +later, are distinctions this header is meant to preserve. ## Purpose and boundary @@ -101,10 +102,17 @@ Keycloak interchangeability are not established. unexercised, and credential/MFA migration is not supplied at all, so no harness can establish it. Subject continuity is explicitly not preserved: the canonical ID survives as an attribute while Keycloak mints its own `sub`. +- **All ten gaps from the 2026-09-05 assessment are now closed**, G10 last, on + 2026-09-10. Closure means the gap each named no longer holds; it does not mean + nothing is outstanding. The approver registration is published but no human has + logged in through it, the deployed image predates most of this revision, and the + Qonto rotation is deferred by owner decision on evidence. Those are open items + with owners and triggers, which is a different thing from a gap between what + this document claims and what is true. - **Source behaviour and deployed behaviour are not the same claim, and this document describes source.** Everything above is what the code in this revision - does, established by 390 Go tests across 23 packages plus the harness runs - named. What has been demonstrated against the live deployment is narrower and is + does, established by 394 Go tests across 23 packages plus the harness + runs named. What has been demonstrated against the live deployment is narrower and is recorded as committed receipts in `docs/evidence/`: the upstream issuer was probed and then pinned in `sso/keycape-config` (`2026-09-09-upstream-issuer-pin.json` — the pre-pin state did **not** match, so diff --git a/history/2026-09-05-011726-scope-intent-assessment.md b/history/2026-09-05-011726-scope-intent-assessment.md index df886a2..4f305e2 100644 --- a/history/2026-09-05-011726-scope-intent-assessment.md +++ b/history/2026-09-05-011726-scope-intent-assessment.md @@ -487,7 +487,43 @@ login against production. `docs/operations.md` documents pinning `authelia.issuer`/`jwksUrl`, and the failure now reports a specific `id_token_issuer_mismatch` reason so it is diagnosable in seconds. -The rest is owner work and stays open. +**Status 2026-09-10: closed.** Every closure criterion now has evidence, and the +criteria are taken one at a time rather than as an impression: + +1. *Named owners admit and provision exact lanes.* CCR-2026-0017/0018 approved by + the platform operator; both approval client secrets exist in `sso`, are wired + into the pod, and the registrations are in the deployed config. Receipt: + `docs/evidence/2026-09-09-keycape-verifier-admission.json`. +2. *Register the real callback.* `informed-decision-approver` with + `https://decisions.coulomb.social/auth/callback`, submitted 2026-09-10 with the + origin verified live by its owner, registered verbatim and pinned by test. +3. *Deploy and verify the new contracts.* The attended rollout of 2026-09-09 + reached `acceptance_phase: passed` at generation 38, with per-client live JWKS + signature verification, exact claims, excess-scope and wrong-secret denial at a + 900s lifetime, `human_client_consume_denied` and `existing_human_login_after` + both true, run verifier-side with `credential_values_emitted: false`. +4. *Reconcile token types at consumer boundaries.* ops-warden took option (a) — + the proxy yields an OpenBao token and `keycape login` an issuer JWT, so they + were never one thing to cut over between. Both lanes are `owner-confirmed`; no + route was changed. +5. *Retain handoff receipts.* Four committed receipts in `docs/evidence/`, plus + the outbound message receipts readable from the hub. + +The condition that named this gap — source capability running ahead of live +custody and consumer adoption — no longer holds. Custody is admitted, the +consumers have adopted, and the record is kept. + +**What remains unexercised, and is not claimed by closing this.** The approver +registration is published, not deployed: no human approver has logged in through +it, so the human approval path is registered rather than proved. The deployed +image predates the authorization-code bindings, upstream verification, readiness, +the tenant work and the guards, so several described behaviours are running +nowhere yet — see `docs/operations.md`. The verifier receipt declines +`real_predecessor_rotation_tested` and `observed_wall_clock_expiry`, and so do we. +The Qonto rotation is deferred by owner decision on evidence, not blocked. + +These are open items with owners and triggers, not a gap between what this +repository claims and what is true — which is what G10 measured. ## Deliberate exclusions are not defects