From e2a5a6bd380ddf44425c21c74e47b608c58bafe7 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Thu, 13 Aug 2026 18:34:59 +0900 Subject: [PATCH 01/70] Add account-derived LineageWeave RP profile --- AGENTS.md | 6 +- ARCHITECTURE.md | 22 +- CHANGELOG.md | 4 + CLAUDE.md | 16 +- README.md | 3 + deploy/templates/README.md | 16 ++ deploy/templates/oidc-rp-lineageweave.json | 86 +++++++ docs/PRD.md | 5 + docs/TRACEABILITY.md | 3 +- docs/TRD.md | 6 + ...0008-keyverse-rp-authorization-boundary.md | 5 +- ...-lineageweave-account-derived-rp-claims.md | 99 ++++++++ .../doctoring/oidc-rp-claim-mapper-profile.md | 25 ++ .../doctoring/oidc-rp-client-desired-state.md | 6 + docs/operations/oidc-rp-reconciliation.md | 31 ++- docs/rp-onboarding.md | 21 +- ...erse-lineageweave-account-claim-profile.md | 45 ++++ .../account_unification/app/relying_party.py | 141 ++++++++++- .../app/relying_party_state.py | 6 +- .../tests/test_relying_party_claim_mappers.py | 222 +++++++++++++++++- .../tests/test_relying_party_template.py | 39 +++ 21 files changed, 773 insertions(+), 34 deletions(-) create mode 100644 deploy/templates/oidc-rp-lineageweave.json create mode 100644 docs/adr/0009-lineageweave-account-derived-rp-claims.md create mode 100644 docs/superpowers/specs/2026-08-13-keyverse-lineageweave-account-claim-profile.md diff --git a/AGENTS.md b/AGENTS.md index 7620bd2..5fa1302 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -36,8 +36,10 @@ queue owner. - SAML/OIDC preflight performs no metadata/discovery fetch. LDAP preflight performs no DNS, socket, bind, search, storage, or Keycloak call. - OIDC relying-party mapper support stays closed: one self-pinned audience plus - only canonical `role`, `org`, and `workspace` hardcoded claims. Do not add - scripts, user attributes, groups, regex, arbitrary claims, new audiences, or + only canonical `role`, `org`, and `workspace` hardcoded claims, except the + ADR-0009 `lineageweave-web` profile which maps only a same-client account role + and the exact `org`/`workspace` account attributes. Do not add scripts, + other user attributes, groups, regex, arbitrary claims, new audiences, or extra token destinations without a separately reviewed profile and RED test. - Treat generated Keycloak mapper IDs and vendor ordering as normalization-only metadata. Unknown, malformed, duplicate, or semantically changed live mappers diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index 8a54a23..abb98b0 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -154,13 +154,18 @@ redirect/origin/logout policy, public/confidential client consistency, bounded token metadata, and an exact portable scope set. An optional closed `protocolMappers` profile carries exactly one self-pinned -`oidc-audience-mapper` plus zero to three canonical hardcoded claims named -`role`, `org`, and `workspace`. Mapper count, names, classes, destinations, -claim values, and ordering are bounded; scripts, user attributes, groups, regex, -arbitrary claims, unknown fields, and credential material are rejected. -`deploy/templates/oidc-rp-naruon.json` is the reviewed public-client instance of -that profile. Its routing claim values are deployment data and must not contain -credentials or personal secrets. +`oidc-audience-mapper` plus either zero to three canonical hardcoded claims or +the ADR-0009 LineageWeave account-derived trio. The latter is limited to a +same-client `oidc-usermodel-client-role-mapper` for multivalued `role` and two +scalar `oidc-usermodel-attribute-mapper` entries from exact `org` and +`workspace` account attributes. The three dynamic claims must appear together +and cannot mix with hardcoded claims. Mapper count, names, classes, +destinations, claim values, and ordering are bounded; scripts, other user +attributes, groups, regex, arbitrary claims, unknown fields, and credential +material are rejected. `deploy/templates/oidc-rp-naruon.json` is the reviewed +public-client instance of the static profile; `deploy/templates/oidc-rp-lineageweave.json` +is the confidential account-derived contract. Neither template contains a +credential or proves a live account login. Stateful reconciliation keys intent by validated `clientId`, classifies zero, one, or multiple exact Keycloak clients, and never mutates duplicates. Create or @@ -172,8 +177,7 @@ The accepted representation has no client-secret field; credential provisioning remains an independent secret-management responsibility. Native loopback/private-use redirects, different resource audiences, and claim -expansion beyond `role`, `org`, and `workspace` remain separate reviewed -profiles. +expansion beyond the two closed profiles remain separate reviewed profiles. Each downstream RP is a separate trust boundary. The RP must validate the Keyverse issuer, signature/algorithm, expiry, subject, and audience, map the diff --git a/CHANGELOG.md b/CHANGELOG.md index 5462dfb..8f7d0f6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,10 @@ Keep a Changelog, and releases use semantic versioning. access-token audience, bounded `role`, `org`, and `workspace` hardcoded claims, canonical mapper ordering, Keycloak-generated-ID/order normalization, and a secret-free `naruon-web` runtime desired-state template. +- ADR-0009's confidential `lineageweave-web` account-derived mapper profile: + same-client roles plus exact scalar `org` and `workspace` account attributes, + with no static/dynamic mixing, a secret-free deployment template, and + reconciliation regression coverage. - Durable, secret-free OIDC relying-party desired-state CRUD and reconciliation with exact `clientId` matching, duplicate fail-closed behavior, post-mutation re-observation, canonical apply receipts, realm-rebuild recovery, per-client diff --git a/CLAUDE.md b/CLAUDE.md index f53ebe3..31aff44 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -110,10 +110,11 @@ is required by the normal suite. `kcadm-bootstrap.sh`. The realm contains no employer-specific federation. - `deploy/templates/` — explicit private deployment contracts. SAML/OIDC use Keyverse desired-state endpoints. `oidc-rp-naruon.json` is the reviewed public - Naruon runtime RP profile with one audience mapper and bounded routing claims. - LDAP is preflighted through Keyverse and then applied through private Keycloak - Admin REST in this release. All `{{placeholders}}` are resolved from KV before - use. + Naruon runtime profile; `oidc-rp-lineageweave.json` is the ADR-0009 + confidential profile that projects an account's same-client role and exact + `org`/`workspace` attributes. LDAP is preflighted through Keyverse and then + applied through private Keycloak Admin REST in this release. All + `{{placeholders}}` are resolved from KV before use. - `deploy/bootstrap/` — the bootstrap pointer locating the KV/DB config store. - `helm/cwl-idp/` — the same three components; Keycloak and Postgres may be disabled in favor of externally managed services. Secrets come from @@ -142,9 +143,10 @@ is required by the normal suite. - **OIDC relying-party metadata is secret-free desired state.** Validate with `POST /clients/relying-parties:validate`, persist with `PUT`, and require exact post-mutation observation before accepting a receipt. The optional mapper - profile permits exactly one audience mapper plus only canonical `role`, `org`, - and `workspace` hardcoded claims. Never expand mapper classes, claim names, - resource audiences, or token destinations by configuration alone. + profile permits static canonical claims, plus the separately reviewed + ADR-0009 `lineageweave-web` account-derived profile. Never expand mapper + classes, claim names, resource audiences, or token destinations by + configuration alone. - **Treat mapper normalization narrowly.** Ignore only a valid generated mapper `id` and canonicalize known mapper order. Unknown, malformed, duplicate, or semantically changed live mapper state is drift. Mapper configuration does not diff --git a/README.md b/README.md index 5e24601..45a0100 100644 --- a/README.md +++ b/README.md @@ -96,6 +96,9 @@ See [`docs/federation-onboarding.md`](docs/federation-onboarding.md), ### Onboard a relying party See [`docs/rp-onboarding.md`](docs/rp-onboarding.md). +The ADR-0009 LineageWeave profile uses real account-derived role, company, and +PU claims; it is not enabled until private Keyverse apply and controlled +downstream authorization evidence are recorded. ## Account unification & merge diff --git a/deploy/templates/README.md b/deploy/templates/README.md index a95b8e5..69302d6 100644 --- a/deploy/templates/README.md +++ b/deploy/templates/README.md @@ -10,6 +10,7 @@ all `{{placeholders}}` must be resolved from the platform KV before use. | `ldap-source.json` | Keycloak component contract | external directory → Keycloak | `POST /federation/user-directories:validate` | `POST /admin/realms/{realm}/components` | | `oidc-rp-client.json` | Keyverse RP desired-state API | Keyverse → RP | `POST /clients/relying-parties:validate` | `PUT /clients/relying-parties/{client_id}` | | `oidc-rp-naruon.json` | Keyverse RP desired-state API | Keyverse → Naruon | `POST /clients/relying-parties:validate` | `PUT /clients/relying-parties/naruon-web` | +| `oidc-rp-lineageweave.json` | Keyverse RP desired-state API | Keyverse → LineageWeave | `POST /clients/relying-parties:validate` | `PUT /clients/relying-parties/lineageweave-web` | The portable realm contains no employer-specific federation. External SAML and OIDC providers are customer or deployment data stored in the Keyverse KV/DB @@ -172,6 +173,21 @@ routing users, run controlled authorization-code/PKCE acceptance and verify that the downstream boundary validates token signature, issuer, expiry, the reviewed `naruon-web` audience, and expected `role`, `org`, and `workspace` semantics. +### LineageWeave account-derived mapper profile + +`oidc-rp-lineageweave.json` is the ADR-0009 confidential `lineageweave-web` +artifact. It renders only the exact HTTPS redirect, origin, and post-logout URI. +The fixed mapper order projects a self-pinned audience, client roles from +`lineageweave-web`, and the exact `org` and `workspace` Keyverse account +attributes. The template never contains a role value, company/PU value, or +client secret. + +Before apply, provision a real account with both attributes and a recognized +client role through the approved Keyverse identity lifecycle. Preflight and +reconciliation validate issuer-side metadata only. Record a real +authorization-code/PKCE login and downstream tenant/resource ABAC, role +downgrade, logout, and rollback evidence before enabling production routing. + ## LDAP and Active Directory preflight pattern `ldap-source.json` is a private Keycloak component payload, not a Keyverse diff --git a/deploy/templates/oidc-rp-lineageweave.json b/deploy/templates/oidc-rp-lineageweave.json new file mode 100644 index 0000000..c13c289 --- /dev/null +++ b/deploy/templates/oidc-rp-lineageweave.json @@ -0,0 +1,86 @@ +{ + "clientId": "lineageweave-web", + "name": "lineageweave-web", + "enabled": true, + "protocol": "openid-connect", + "publicClient": false, + "clientAuthenticatorType": "client-secret", + "standardFlowEnabled": true, + "implicitFlowEnabled": false, + "directAccessGrantsEnabled": false, + "serviceAccountsEnabled": false, + "redirectUris": ["{{lineageweave_redirect_uri}}"], + "webOrigins": ["{{lineageweave_web_origin}}"], + "attributes": { + "pkce.code.challenge.method": "S256", + "post.logout.redirect.uris": "{{lineageweave_post_logout_uri}}", + "access.token.lifespan": "300", + "backchannel.logout.session.required": "true", + "require.pushed.authorization.requests": "false" + }, + "fullScopeAllowed": false, + "defaultClientScopes": ["basic", "profile", "email"], + "protocolMappers": [ + { + "name": "keyverse-audience", + "protocol": "openid-connect", + "protocolMapper": "oidc-audience-mapper", + "consentRequired": false, + "config": { + "included.client.audience": "lineageweave-web", + "access.token.claim": "true", + "id.token.claim": "false", + "introspection.token.claim": "true" + } + }, + { + "name": "keyverse-account-role", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-client-role-mapper", + "consentRequired": false, + "config": { + "usermodel.clientRoleMapping.clientId": "lineageweave-web", + "usermodel.clientRoleMapping.rolePrefix": "", + "multivalued": "true", + "claim.name": "role", + "jsonType.label": "String", + "access.token.claim": "true", + "id.token.claim": "true", + "userinfo.token.claim": "false", + "introspection.token.claim": "true" + } + }, + { + "name": "keyverse-account-org", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "user.attribute": "org", + "claim.name": "org", + "jsonType.label": "String", + "multivalued": "false", + "access.token.claim": "true", + "id.token.claim": "true", + "userinfo.token.claim": "false", + "introspection.token.claim": "true" + } + }, + { + "name": "keyverse-account-workspace", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": false, + "config": { + "user.attribute": "workspace", + "claim.name": "workspace", + "jsonType.label": "String", + "multivalued": "false", + "access.token.claim": "true", + "id.token.claim": "true", + "userinfo.token.claim": "false", + "introspection.token.claim": "true" + } + } + ] +} diff --git a/docs/PRD.md b/docs/PRD.md index 87278a0..68daa6a 100644 --- a/docs/PRD.md +++ b/docs/PRD.md @@ -84,6 +84,11 @@ RP registration SHALL validate exact HTTPS redirect/origin/logout and authorizat Optional claim expansion SHALL be closed and least-privilege. New audience/claim mapper profiles require explicit typed policy, no script/user-attribute/group/regex arbitrary mapper classes unless separately accepted, and downstream authorization acceptance tests before claiming application readiness. +ADR-0009 is the separately accepted `lineageweave-web` exception: one +self-pinned audience, roles from that client only, and scalar `org`/`workspace` +account attributes. It remains deployment-restricted until real-account Keyverse +apply and downstream tenant/resource ABAC plus role-lifecycle evidence exist. + ### PRD-FR-007 Downstream authorization boundary Every RP SHALL maintain an explicit Keyverse integration profile and SHALL diff --git a/docs/TRACEABILITY.md b/docs/TRACEABILITY.md index 4713bf5..44ac724 100644 --- a/docs/TRACEABILITY.md +++ b/docs/TRACEABILITY.md @@ -1,7 +1,7 @@ # Keyverse Requirements and Evidence Traceability **Status:** Accepted cross-cutting baseline -**Last reviewed:** 2026-08-12 +**Last reviewed:** 2026-08-13 | Requirement / decision | Standards / authoritative basis | Source/evidence boundary | Maturity | |---|---|---|---| @@ -13,6 +13,7 @@ | LDAPS directory profile | LDAP RFC 4511–4515 + Keycloak component docs | directory preflight/reconciliation tests | implemented-main | | secret-free RP desired state | OAuth/OIDC/PKCE/Keycloak client docs | RP preflight/reconciliation/integrity tests | implemented-main | | RP audience/role/org/workspace mapper profile | OIDC/JWT audience + Keycloak mapper docs | PR #72 protected-main source/tests; downstream RP acceptance remains required | implemented-main | +| LineageWeave account-derived RP claims | ADR-0009; Keycloak Protocol Mappers | closed branch profile/template/reconciliation tests; real account, Keyverse apply, and downstream ABAC/RBAC acceptance remain required | accepted-contract | | merge/SCIM PUT shared operation lock | concurrency/data-integrity decision; ADR-0006 | merge + full-replacement lock/concurrency tests | implemented-main | | SCIM PATCH active=false shared-lock parity | ADR-0006 boundary | current PATCH source has no shared-lock proof | gap-not-claimed | | intent before mutation, receipt after re-observation | desired-state/recovery decision | federation/directory/RP reconciliation tests | implemented-main | diff --git a/docs/TRD.md b/docs/TRD.md index 1ffc105..43fcba8 100644 --- a/docs/TRD.md +++ b/docs/TRD.md @@ -51,6 +51,12 @@ The PR #72 claim mapper profile is integrated in protected main. Downstream authorization acceptance remains deployment-specific and is not implied by Keycloak client reconciliation. +ADR-0009 defines a separate `lineageweave-web` account-derived profile: one +self-pinned audience, same-client role assignments, and scalar `org`/`workspace` +account attributes. It is an accepted contract on its implementation branch, +not protected-main or live-login evidence; controlled Keyverse and downstream +authorization acceptance remain required. + The per-application authorization matrix and remediation directions are governed by ADR-0008. Keyverse client reconciliation does not imply downstream authorization readiness. diff --git a/docs/adr/0008-keyverse-rp-authorization-boundary.md b/docs/adr/0008-keyverse-rp-authorization-boundary.md index 51a65b7..763d260 100644 --- a/docs/adr/0008-keyverse-rp-authorization-boundary.md +++ b/docs/adr/0008-keyverse-rp-authorization-boundary.md @@ -123,7 +123,10 @@ downstream application authorization: `role`, `org`, and `workspace` values may identify the reviewed deployment profile, but they must not be used as an unverified privilege escalation channel. Moving them to user/tenant-derived Keycloak roles or groups requires - a separate mapper and downstream authorization design with tests. + a separate mapper and downstream authorization design with tests. ADR-0009 + is the sole accepted exception: its `lineageweave-web` profile maps only + same-client roles and exact scalar `org`/`workspace` account attributes; it + does not authorize generic mapper expansion or downstream privilege bypass. 5. The account-unification operator token remains deployment-only and coarse-grained until per-operation RBAC/ABAC is implemented. No downstream application receives Keycloak Admin credentials to compensate for that gap. diff --git a/docs/adr/0009-lineageweave-account-derived-rp-claims.md b/docs/adr/0009-lineageweave-account-derived-rp-claims.md new file mode 100644 index 0000000..b40b298 --- /dev/null +++ b/docs/adr/0009-lineageweave-account-derived-rp-claims.md @@ -0,0 +1,99 @@ +# ADR-0009: Bind LineageWeave relying-party claims to Keyverse accounts + +**Status:** Accepted +**Date:** 2026-08-13 + +## Context + +LineageWeave requires real Keyverse accounts. Its company and PU dimensions are +authorization attributes, not substitute login identities. The existing +Keyverse relying-party mapper profile can emit only static routing claims, which +cannot prove that a current session belongs to the account represented by its +`sub` claim. + +Keycloak documents separate built-in mappers for a user's client roles and for +custom user attributes. A generic mapper editor would expose unnecessary +issuer-side authority, including cross-client roles, arbitrary user attributes, +groups, scripts, claim names, and token destinations. That conflicts with the +closed desired-state boundary and with the downstream ABAC-before-RBAC contract +in ADR-0008. + +## Decision + +Keyverse accepts one separately reviewed confidential relying-party profile for +`lineageweave-web`. The profile contains exactly these four ordered mappers: + +1. `keyverse-audience`: an audience mapper self-pinned to `lineageweave-web`. +2. `keyverse-account-role`: a client-role mapper pinned to the same client, + with no role prefix and a multivalued `role` claim. +3. `keyverse-account-org`: a scalar user-attribute mapper from `org` to `org`. +4. `keyverse-account-workspace`: a scalar user-attribute mapper from + `workspace` to `workspace`. + +All four mappers use the exact reviewed access-token, ID-token, +introspection-token, and UserInfo destinations. The three account-derived +claims are atomic: they must all be present, must not mix with hardcoded claims, +and cannot be extended by configuration. The desired-state representation has +no client-secret field; confidential-secret placement remains a separate +approved secret-management operation. + +The receiving application must validate issuer, signature/algorithm, expiry, +subject, and audience before reading these claims. It must bind `org` and +`workspace` to the requested resource before applying recognized client roles. +A green Keyverse preflight or apply receipt is not controlled login or +authorization evidence. + +```mermaid +flowchart LR + A["Verified Keyverse account"] --> B["Same-client role assignment"] + A --> C["org account attribute"] + A --> D["workspace account attribute"] + B --> E["Closed LineageWeave mapper profile"] + C --> E + D --> E + E --> F["Verified token claims"] + F --> G["Tenant and resource ABAC"] + G --> H["Bounded role RBAC"] +``` + +## Options considered + +1. Keep static `role`, `org`, and `workspace` claims. Rejected because they do + not bind the current authenticated account to company or PU attributes. +2. Permit generic Keycloak user/role/group mappers. Rejected because arbitrary + issuer-side mappings expand authorization authority and cannot be reviewed + from a stable desired-state contract. +3. Use the exact four-mapper account-derived profile. Accepted because it binds + the needed claims to one Keyverse account and one client while retaining + deterministic validation and reconciliation. + +## Consequences + +- Identity operators must provision a real Keyverse account with the two named + attributes and an allowed `lineageweave-web` client role before user routing. +- Account and role changes take effect through Keycloak session/token lifecycle; + operators must test downgrade and revocation behavior in controlled runtime + acceptance. +- The profile does not authorize a resource on its own. LineageWeave must retain + tenant/resource ABAC and only then apply its bounded role map. +- Any extra attribute, group, mapper type, audience, claim name, or token + destination requires a new ADR, RED regression, and downstream acceptance + evidence. + +## Acceptance evidence + +The implementation has local RED-to-GREEN validation, mapper-observation, and +secret-free-template tests. Before production use, record authenticated Keyverse +preflight and reconciliation receipts, private credential placement, a real +account authorization-code/PKCE exchange, token claim shape, cross-tenant +denial, role downgrade, logout, and rollback evidence. Until then the profile +is an accepted contract, not a deployed-login claim. + +## References + +Keycloak Project. (2026). *Protocol mappers*. Retrieved August 13, 2026, from +https://www.keycloak.org/admin-api/protocol-mappers + +Lodderstedt, T., Bradley, J., Labunets, A., & Fett, D. (2025). *Best current +practice for OAuth 2.0 security* (RFC 9700). Internet Engineering Task Force. +https://doi.org/10.17487/RFC9700 diff --git a/docs/doctoring/oidc-rp-claim-mapper-profile.md b/docs/doctoring/oidc-rp-claim-mapper-profile.md index fe5389e..82104df 100644 --- a/docs/doctoring/oidc-rp-claim-mapper-profile.md +++ b/docs/doctoring/oidc-rp-claim-mapper-profile.md @@ -60,6 +60,14 @@ orders known mapper identities canonically, and then performs semantic drift comparison. Unknown, malformed, or duplicate live mappers remain drift rather than being silently discarded. +ADR-0009 adds one separate, exact `lineageweave-web` profile. It permits a +client-role mapper whose configured client ID equals the registration client ID, +has no role prefix, and emits multivalued `role`; it also permits two scalar +user-attribute mappers from `org` to `org` and `workspace` to `workspace`. +Keycloak documents these mapper IDs and their configuration properties. Keyverse +intentionally rejects every other user attribute, role source, aggregation, +group, script, audience, claim name, and destination. + ## Stricter Keyverse product policy The product policy is intentionally narrower than the vendor representation: @@ -75,6 +83,8 @@ The product policy is intentionally narrower than the vendor representation: effect. 8. Desired state remains secret-free and write receipts are produced only after post-mutation re-observation. +9. The account-derived exception requires all three dynamic claims, forbids + static/dynamic mixing, and retains the same four-mapper maximum. The hardcoded claims are not, by themselves, proof of user entitlement. A consumer that uses them for authorization must still apply its independently @@ -93,6 +103,10 @@ The implementation is covered by production-shaped tests that exercise: - semantic drift for unknown, malformed, duplicate, or changed mappers; - the committed `deploy/templates/oidc-rp-naruon.json` artifact after placeholder substitution; +- the LineageWeave account-role, account-attribute, non-mixing, and + generated-ID/vendor-order reconciliation paths; +- the committed `deploy/templates/oidc-rp-lineageweave.json` artifact after + HTTPS placeholder substitution; - complete production statement and branch coverage in the repository CI gate. The template test was intentionally introduced before the template. Hosted CI @@ -112,6 +126,10 @@ RED receipt before the template was added. - Downstream Naruon token validation rejects invalid issuer, signature, algorithm, expiry, and audience values. - The deployed Keycloak version preserves the reviewed mapper semantics. +- A LineageWeave account has exactly one scalar `org` and `workspace` value and + a least-privilege set of client roles for `lineageweave-web`. +- LineageWeave validates a list-valued `role` claim and applies tenant/resource + ABAC before its product-role mapping. ## Limitations and follow-up @@ -123,6 +141,10 @@ change. Any new mapper type, claim name, token destination, resource audience, or native-client redirect profile requires explicit design and regression coverage rather than extension by configuration alone. +The account-derived profile also does not prove that a real Keyverse account +has been provisioned, its confidential credential has been placed, or its +LineageWeave login/tenant/role lifecycle has been accepted in production. + ## References Bertocci, V. (2021). *JSON Web Token (JWT) profile for OAuth 2.0 access tokens* @@ -138,5 +160,8 @@ Keycloak Project. (2026). *ClientRepresentation* (Keycloak Docs Distribution Keycloak Project. (2026). *ProtocolMapperRepresentation* (Keycloak Docs Distribution 26.x API). https://www.keycloak.org/docs-api/latest/javadocs/org/keycloak/representations/idm/ProtocolMapperRepresentation.html +Keycloak Project. (2026). *Protocol mappers*. Retrieved August 13, 2026, from +https://www.keycloak.org/admin-api/protocol-mappers + OpenID Foundation. (2023). *OpenID Connect Core 1.0 incorporating errata set 2*. https://openid.net/specs/openid-connect-core-1_0.html diff --git a/docs/doctoring/oidc-rp-client-desired-state.md b/docs/doctoring/oidc-rp-client-desired-state.md index ed39826..4d86904 100644 --- a/docs/doctoring/oidc-rp-client-desired-state.md +++ b/docs/doctoring/oidc-rp-client-desired-state.md @@ -100,6 +100,12 @@ client secret. Confidential-client credential provisioning remains a separate secret-management responsibility and must not be added to this lifecycle by loosening the model. +ADR-0009's `lineageweave-web` template follows the same boundary. Its dynamic +claims are mapper configuration, not embedded user data or credential material: +the role and two account attributes are resolved by Keycloak only after a real +account authenticates. A receipt still does not prove that account provisioning, +credential placement, or controlled login succeeded. + ## Locking and failure semantics A state lock protects KV access only. A process-local keyed lock serializes diff --git a/docs/operations/oidc-rp-reconciliation.md b/docs/operations/oidc-rp-reconciliation.md index 629f031..b77d5f3 100644 --- a/docs/operations/oidc-rp-reconciliation.md +++ b/docs/operations/oidc-rp-reconciliation.md @@ -9,12 +9,14 @@ authorization-code/JWT acceptance. ## Routine workflow -1. Render `deploy/templates/oidc-rp-client.json` for a generic RP or +1. Render `deploy/templates/oidc-rp-client.json` for a generic RP, `deploy/templates/oidc-rp-naruon.json` for the reviewed Naruon public-client - mapper profile into a private mode-0600 file. -2. Resolve all HTTPS and routing placeholders. Treat Naruon `role`, `org`, and - `workspace` values as visible product data, never credentials or personal - secrets. + profile, or `deploy/templates/oidc-rp-lineageweave.json` for the ADR-0009 + confidential account-derived profile into a private mode-0600 file. +2. Resolve only HTTPS and routing placeholders. Treat Naruon static values as + visible product data, never credentials or personal secrets. For + LineageWeave, provision the role and account attributes in Keyverse rather + than rendering them into the template. 3. Call `POST /clients/relying-parties:validate` and require HTTP 200 plus `ready_to_apply=true`. 4. Call `PUT /clients/relying-parties/{client_id}` with the same original file. @@ -46,6 +48,25 @@ configuration is issuer-side evidence only. The receiving Naruon boundary must independently validate the token and must not infer authorization merely from the presence of a hardcoded claim. +## LineageWeave account-claim contract + +The LineageWeave runtime artifact is a confidential `lineageweave-web` client +with exactly four canonical mappers: + +1. `keyverse-audience` — access-token audience pinned to `lineageweave-web`. +2. `keyverse-account-role` — an unprefixed, multivalued role mapper limited to + `lineageweave-web` client-role assignments. +3. `keyverse-account-org` — scalar `org` user attribute to `org` claim. +4. `keyverse-account-workspace` — scalar `workspace` user attribute to + `workspace` claim. + +Do not add a static claim, group, additional user attribute, role prefix, +aggregation setting, or client secret to this profile. Apply requires an actual +Keyverse account with the two attributes and an allowed client role. Controlled +acceptance must prove issuer/signature/expiry/audience validation, tenant and +resource ABAC denial, role downgrade, logout, and rollback. A compose-only IdP +or preflight receipt does not satisfy that evidence. + ## Example ```bash diff --git a/docs/rp-onboarding.md b/docs/rp-onboarding.md index 854f3ed..8c20a7f 100644 --- a/docs/rp-onboarding.md +++ b/docs/rp-onboarding.md @@ -17,6 +17,13 @@ For the reviewed Naruon browser-client path, use client (`publicClient=true`, `clientAuthenticatorType=none`) and contains the closed audience/session-claim mapper profile. +For the ADR-0009 LineageWeave path, use +`deploy/templates/oidc-rp-lineageweave.json`. It is a confidential +`lineageweave-web` client whose role, company, and PU claims are derived from +the authenticated Keyverse account. Its HTTPS endpoint placeholders are the +only values rendered into the client metadata; the role assignment and the two +account attributes are provisioned in Keyverse before controlled login. + Resolve every placeholder from deployment configuration or KV before preflight. For Naruon this includes exact HTTPS redirect, web-origin, and post-logout URIs plus the bounded `role`, `org`, and `workspace` routing values. Those claim @@ -133,10 +140,14 @@ When `protocolMappers` is present, the mapper profile is additionally closed: - exactly one `oidc-audience-mapper` is required and its `included.client.audience` must equal the validated `clientId`; - optional hardcoded claims are limited to `role`, `org`, and `workspace`; +- ADR-0009 additionally permits only the complete `lineageweave-web` + account-derived trio: same-client role mapping plus scalar `org` and + `workspace` user-attribute mappings; - mapper names, protocols, token destinations, nested fields, and list order are canonical and exact; -- script, user-attribute, group, regex, arbitrary-claim, unknown mapper, and - credential-bearing configuration is rejected; +- script, group, regex, arbitrary-claim, unknown mapper, and credential-bearing + configuration is rejected; user attributes are rejected except for the two + ADR-0009 mappings; - generated Keycloak mapper IDs and vendor return ordering are normalized only for observation; unknown, malformed, duplicate, or semantically changed live mapper state is reported as drift rather than silently accepted. @@ -198,6 +209,12 @@ Do not record bearer tokens, authorization codes, code verifiers, client-secret bytes, or private routing values beyond the minimum non-secret acceptance evidence required by the deployment record. +For LineageWeave, additionally prove with a real Keyverse account that the +verified `sub`, scalar `org`, scalar `workspace`, and list-valued same-client +`role` claims reach the application; invalid tenant, mismatched workspace, and +role-downgrade requests must deny before an RBAC allow. The Keyverse client +receipt is not a substitute for these downstream tests. + ## Checklist - [ ] placeholders resolved in a mode-0600 file diff --git a/docs/superpowers/specs/2026-08-13-keyverse-lineageweave-account-claim-profile.md b/docs/superpowers/specs/2026-08-13-keyverse-lineageweave-account-claim-profile.md new file mode 100644 index 0000000..387259a --- /dev/null +++ b/docs/superpowers/specs/2026-08-13-keyverse-lineageweave-account-claim-profile.md @@ -0,0 +1,45 @@ +# Keyverse LineageWeave Account-Derived Claim Profile + +**Status:** Approved bounded implementation under ADR-0009. + +## Purpose + +Provide LineageWeave with claims derived from the real Keyverse account that +authenticated, while keeping Keyverse's relying-party desired-state surface +closed and secret-free. + +## Contract + +- Client ID is fixed to `lineageweave-web`; it is confidential and uses + authorization code plus PKCE `S256`. +- The first mapper is the existing self-pinned audience mapper. +- `role` comes only from client roles assigned to that same client. It is a + multivalued string claim with no prefix. +- `org` and `workspace` come only from user attributes bearing those exact + names. They are scalar string claims. +- All three account-derived claims must appear together and cannot mix with + hardcoded claims. +- The profile rejects scripts, groups, regex, arbitrary attributes, arbitrary + roles, extra audiences, extra destinations, aggregation, secrets, and client + secret generation/retrieval. + +## Runtime prerequisites + +1. An identity operator creates or verifies the actual Keyverse account. +2. The operator assigns the account's `org` and `workspace` values and one or + more recognized `lineageweave-web` client roles. +3. The private rendered template passes Keyverse preflight, is reconciled by + Keyverse, and receives an exact observable receipt. +4. The confidential client credential is placed through the approved + secret-management channel. +5. LineageWeave proves issuer/signature/expiry/audience validation, tenant and + resource denial, role downgrade, logout, and rollback using that real + account. + +## Non-goals + +- Generic Keycloak mapper administration. +- A claim-based bypass of LineageWeave resource ABAC. +- Static company or PU routing values. +- An assertion that a local or compose-only identity provider is Keyverse + production evidence. diff --git a/services/account_unification/app/relying_party.py b/services/account_unification/app/relying_party.py index 1f83ef3..9f66c53 100644 --- a/services/account_unification/app/relying_party.py +++ b/services/account_unification/app/relying_party.py @@ -81,12 +81,44 @@ "introspection.token.claim", } ) +_ACCOUNT_ROLE_CONFIG_FIELDS = frozenset( + { + "usermodel.clientRoleMapping.clientId", + "usermodel.clientRoleMapping.rolePrefix", + "multivalued", + "claim.name", + "jsonType.label", + "access.token.claim", + "id.token.claim", + "userinfo.token.claim", + "introspection.token.claim", + } +) +_ACCOUNT_ROLE_EMPTY_CONFIG_FIELDS = frozenset( + {"usermodel.clientRoleMapping.rolePrefix"} +) +_ACCOUNT_ATTRIBUTE_CONFIG_FIELDS = frozenset( + { + "user.attribute", + "claim.name", + "jsonType.label", + "multivalued", + "access.token.claim", + "id.token.claim", + "userinfo.token.claim", + "introspection.token.claim", + } +) _REQUIRED_SCOPES = frozenset({"basic", "profile", "email"}) _CLAIM_ORDER = ("role", "org", "workspace") _CLAIM_RANK = {claim_name: index + 1 for index, claim_name in enumerate(_CLAIM_ORDER)} +_ACCOUNT_CLAIMS = frozenset(_CLAIM_ORDER) +_ACCOUNT_ATTRIBUTE_CLAIMS = frozenset({"org", "workspace"}) _AUDIENCE_MAPPER_NAME = "keyverse-audience" _AUDIENCE_MAPPER_TYPE = "oidc-audience-mapper" _CLAIM_MAPPER_TYPE = "oidc-hardcoded-claim-mapper" +_ACCOUNT_ROLE_MAPPER_TYPE = "oidc-usermodel-client-role-mapper" +_ACCOUNT_ATTRIBUTE_MAPPER_TYPE = "oidc-usermodel-attribute-mapper" class RelyingPartyProtocolMapper(BaseModel): @@ -384,13 +416,16 @@ def _validate_scopes(scopes: list[str]) -> None: def _require_exact_config( mapper: RelyingPartyProtocolMapper, expected_fields: frozenset[str], + *, + allow_empty_fields: frozenset[str] = frozenset(), ) -> None: """Require one mapper configuration to have an exact closed key set.""" fields = set(mapper.config) if fields != expected_fields: _client_error("protocolMappers.config", "must use the exact closed field set") for key, value in mapper.config.items(): - _require_clean_text(value, f"protocolMappers.config.{key}", maximum=128) + if value or key not in allow_empty_fields: + _require_clean_text(value, f"protocolMappers.config.{key}", maximum=128) def _validate_audience_mapper( @@ -465,6 +500,78 @@ def _validate_hardcoded_claim_mapper( return _CLAIM_RANK[claim_name], claim_name +def _validate_account_role_mapper( + mapper: RelyingPartyProtocolMapper, + client_id: str, +) -> tuple[int, str]: + """Validate the single account-derived client-role claim mapper.""" + if mapper.name != "keyverse-account-role": + _client_error("protocolMappers.name", "must be keyverse-account-role") + _require_exact_config( + mapper, + _ACCOUNT_ROLE_CONFIG_FIELDS, + allow_empty_fields=_ACCOUNT_ROLE_EMPTY_CONFIG_FIELDS, + ) + if mapper.config["usermodel.clientRoleMapping.clientId"] != client_id: + _client_error( + "protocolMappers.config.usermodel.clientRoleMapping.clientId", + "must exactly match clientId", + ) + expected_values = { + "usermodel.clientRoleMapping.rolePrefix": "", + "multivalued": "true", + "claim.name": "role", + "jsonType.label": "String", + "access.token.claim": "true", + "id.token.claim": "true", + "userinfo.token.claim": "false", + "introspection.token.claim": "true", + } + if any(mapper.config[key] != value for key, value in expected_values.items()): + _client_error( + "protocolMappers.config", + "must use the closed account-role claim destinations", + ) + return _CLAIM_RANK["role"], "role" + + +def _validate_account_attribute_mapper( + mapper: RelyingPartyProtocolMapper, +) -> tuple[int, str]: + """Validate one scalar account-derived organization or workspace mapper.""" + _require_exact_config(mapper, _ACCOUNT_ATTRIBUTE_CONFIG_FIELDS) + claim_name = mapper.config["claim.name"] + if claim_name not in _ACCOUNT_ATTRIBUTE_CLAIMS: + _client_error( + "protocolMappers.config.claim.name", + "must be org or workspace", + ) + if mapper.name != f"keyverse-account-{claim_name}": + _client_error( + "protocolMappers.name", + "must be canonical for the claim name", + ) + if mapper.config["user.attribute"] != claim_name: + _client_error( + "protocolMappers.config.user.attribute", + "must exactly match claim.name", + ) + expected_values = { + "jsonType.label": "String", + "multivalued": "false", + "access.token.claim": "true", + "id.token.claim": "true", + "userinfo.token.claim": "false", + "introspection.token.claim": "true", + } + if any(mapper.config[key] != value for key, value in expected_values.items()): + _client_error( + "protocolMappers.config", + "must use the closed account-attribute claim destinations", + ) + return _CLAIM_RANK[claim_name], claim_name + + def _validate_protocol_mappers(registration: RelyingPartyRegistration) -> None: """Validate the optional closed audience and session-claim mapper profile.""" mappers = registration.protocol_mappers @@ -475,7 +582,8 @@ def _validate_protocol_mappers(registration: RelyingPartyRegistration) -> None: ranks: list[int] = [] audience_count = 0 - claim_names: set[str] = set() + hardcoded_claim_names: set[str] = set() + account_claim_names: set[str] = set() for mapper in mappers: _require_clean_text( mapper.name, @@ -491,15 +599,40 @@ def _validate_protocol_mappers(registration: RelyingPartyRegistration) -> None: ranks.append(_validate_audience_mapper(mapper, registration.client_id)) elif mapper.protocol_mapper == _CLAIM_MAPPER_TYPE: rank, claim_name = _validate_hardcoded_claim_mapper(mapper) - if claim_name in claim_names: + if claim_name in hardcoded_claim_names: _client_error("protocolMappers", "must not duplicate claim names") - claim_names.add(claim_name) + hardcoded_claim_names.add(claim_name) + ranks.append(rank) + elif mapper.protocol_mapper == _ACCOUNT_ROLE_MAPPER_TYPE: + rank, claim_name = _validate_account_role_mapper( + mapper, + registration.client_id, + ) + if claim_name in account_claim_names: + _client_error("protocolMappers", "must not duplicate claim names") + account_claim_names.add(claim_name) + ranks.append(rank) + elif mapper.protocol_mapper == _ACCOUNT_ATTRIBUTE_MAPPER_TYPE: + rank, claim_name = _validate_account_attribute_mapper(mapper) + if claim_name in account_claim_names: + _client_error("protocolMappers", "must not duplicate claim names") + account_claim_names.add(claim_name) ranks.append(rank) else: _client_error("protocolMappers.protocolMapper", "is not supported") if audience_count != 1: _client_error("protocolMappers", "must contain exactly one audience mapper") + if hardcoded_claim_names and account_claim_names: + _client_error( + "protocolMappers", + "must not mix hardcoded and account-derived claims", + ) + if account_claim_names and account_claim_names != _ACCOUNT_CLAIMS: + _client_error( + "protocolMappers", + "must contain role, org, and workspace account claims", + ) if ranks != sorted(ranks) or len(set(ranks)) != len(ranks): _client_error("protocolMappers", "must use canonical mapper order") diff --git a/services/account_unification/app/relying_party_state.py b/services/account_unification/app/relying_party_state.py index 4d52ebd..1e0f871 100644 --- a/services/account_unification/app/relying_party_state.py +++ b/services/account_unification/app/relying_party_state.py @@ -466,7 +466,11 @@ def _observed_mapper_rank(mapper: dict) -> int | None: mapper_type = mapper.get("protocolMapper") if mapper_type == "oidc-audience-mapper": return 0 - if mapper_type != "oidc-hardcoded-claim-mapper": + if mapper_type not in { + "oidc-hardcoded-claim-mapper", + "oidc-usermodel-client-role-mapper", + "oidc-usermodel-attribute-mapper", + }: return None config = mapper["config"] claim_name = config.get("claim.name") diff --git a/services/account_unification/tests/test_relying_party_claim_mappers.py b/services/account_unification/tests/test_relying_party_claim_mappers.py index 168aa29..32943d9 100644 --- a/services/account_unification/tests/test_relying_party_claim_mappers.py +++ b/services/account_unification/tests/test_relying_party_claim_mappers.py @@ -13,11 +13,12 @@ _parse_registration, validate_relying_party_registration, ) +from app.relying_party_state import _normalized_observed_mappers from .test_relying_party_preflight import _confidential_web_client -def _audience_mapper() -> dict[str, object]: +def _audience_mapper(client_id: str = "naruon-web") -> dict[str, object]: """Return the canonical access-token audience mapper.""" return { "name": "keyverse-audience", @@ -25,7 +26,7 @@ def _audience_mapper() -> dict[str, object]: "protocolMapper": "oidc-audience-mapper", "consentRequired": False, "config": { - "included.client.audience": "naruon-web", + "included.client.audience": client_id, "access.token.claim": "true", "id.token.claim": "false", "introspection.token.claim": "true", @@ -52,6 +53,72 @@ def _claim_mapper(claim_name: str, claim_value: str) -> dict[str, object]: } +def _account_role_mapper(client_id: str) -> dict[str, object]: + """Return the closed client-role mapper for a verified account role.""" + return { + "name": "keyverse-account-role", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-client-role-mapper", + "consentRequired": False, + "config": { + "usermodel.clientRoleMapping.clientId": client_id, + "usermodel.clientRoleMapping.rolePrefix": "", + "multivalued": "true", + "claim.name": "role", + "jsonType.label": "String", + "access.token.claim": "true", + "id.token.claim": "true", + "userinfo.token.claim": "false", + "introspection.token.claim": "true", + }, + } + + +def _account_attribute_mapper(claim_name: str) -> dict[str, object]: + """Return one scalar account-attribute mapper for a tenant claim.""" + return { + "name": f"keyverse-account-{claim_name}", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "consentRequired": False, + "config": { + "user.attribute": claim_name, + "claim.name": claim_name, + "jsonType.label": "String", + "multivalued": "false", + "access.token.claim": "true", + "id.token.claim": "true", + "userinfo.token.claim": "false", + "introspection.token.claim": "true", + }, + } + + +def _lineageweave_registration_with_account_claims() -> dict[str, object]: + """Return a confidential RP using verified account-derived claim sources.""" + client_id = "lineageweave-web" + payload = deepcopy(_confidential_web_client()) + payload.update( + { + "clientId": client_id, + "name": client_id, + "redirectUris": ["https://lineageweave.example/auth/callback"], + "webOrigins": ["https://lineageweave.example"], + "attributes": { + **payload["attributes"], + "post.logout.redirect.uris": "https://lineageweave.example/logout", + }, + "protocolMappers": [ + _audience_mapper(client_id), + _account_role_mapper(client_id), + _account_attribute_mapper("org"), + _account_attribute_mapper("workspace"), + ], + } + ) + return payload + + def _naruon_registration_with_mappers() -> dict[str, object]: """Return a production-shaped Naruon client with its closed claim profile.""" payload = deepcopy(_confidential_web_client()) @@ -137,6 +204,157 @@ def test_audience_only_mapper_profile_is_accepted() -> None: assert len(result.registration.protocol_mappers) == 1 +def test_account_derived_claim_mapper_profile_is_accepted() -> None: + """Per-account role and tenant attributes may replace static RP claims.""" + payload = _lineageweave_registration_with_account_claims() + + result = validate_relying_party_registration(_parse_registration(payload)) + + assert result.ready_to_apply is True + mappers = payload["protocolMappers"] + assert isinstance(mappers, list) + assert [mapper["protocolMapper"] for mapper in mappers] == [ + "oidc-audience-mapper", + "oidc-usermodel-client-role-mapper", + "oidc-usermodel-attribute-mapper", + "oidc-usermodel-attribute-mapper", + ] + assert all("claim.value" not in mapper["config"] for mapper in mappers[1:]) + + +def test_account_derived_claim_mapper_observation_is_reconciled() -> None: + """Keycloak mapper IDs and order do not create dynamic-claim drift.""" + payload = _lineageweave_registration_with_account_claims() + desired_mappers = payload["protocolMappers"] + assert isinstance(desired_mappers, list) + observed_mappers = deepcopy(desired_mappers) + for index, mapper in enumerate(observed_mappers): + mapper["id"] = f"mapper-{index}" + observed_mappers.reverse() + + normalized = _normalized_observed_mappers( + observed_mappers, + _parse_registration(payload), + ) + + assert normalized == desired_mappers + + +@pytest.mark.parametrize( + ("mutate", "field"), + [ + (lambda mapper: mapper.update(name="account-role"), "protocolMappers.name"), + ( + lambda mapper: mapper["config"].update( + {"usermodel.clientRoleMapping.clientId": "other-web"} + ), + "protocolMappers.config.usermodel.clientRoleMapping.clientId", + ), + ( + lambda mapper: mapper["config"].update( + {"usermodel.clientRoleMapping.rolePrefix": "unexpected"} + ), + "protocolMappers.config", + ), + ( + lambda mapper: mapper["config"].update({"multivalued": "false"}), + "protocolMappers.config", + ), + ], +) +def test_account_role_mapper_policy_rejects_unsafe_values(mutate, field: str) -> None: + """The account role source is pinned to the relying-party client.""" + payload = _lineageweave_registration_with_account_claims() + mappers = payload["protocolMappers"] + assert isinstance(mappers, list) + mapper = mappers[1] + assert isinstance(mapper, dict) + mutate(mapper) + + _assert_policy_error(payload, field) + + +@pytest.mark.parametrize( + ("mutate", "field"), + [ + ( + lambda mapper: mapper["config"].update({"claim.name": "role"}), + "protocolMappers.config.claim.name", + ), + ( + lambda mapper: mapper.update(name="keyverse-account-other"), + "protocolMappers.name", + ), + ( + lambda mapper: mapper["config"].update({"user.attribute": "other"}), + "protocolMappers.config.user.attribute", + ), + ( + lambda mapper: mapper["config"].update({"multivalued": "true"}), + "protocolMappers.config", + ), + ], +) +def test_account_attribute_mapper_policy_rejects_unsafe_values( + mutate, + field: str, +) -> None: + """Only scalar organization and workspace account attributes may flow.""" + payload = _lineageweave_registration_with_account_claims() + mappers = payload["protocolMappers"] + assert isinstance(mappers, list) + mapper = mappers[2] + assert isinstance(mapper, dict) + mutate(mapper) + + _assert_policy_error(payload, field) + + +def test_account_claim_profile_requires_every_dynamic_claim() -> None: + """A partial dynamic profile cannot silently fall back to static routing.""" + payload = _lineageweave_registration_with_account_claims() + mappers = payload["protocolMappers"] + assert isinstance(mappers, list) + payload["protocolMappers"] = mappers[:-1] + + _assert_policy_error(payload, "protocolMappers") + + +def test_account_claim_profile_rejects_duplicate_dynamic_claim() -> None: + """One account attribute may map to only one canonical token claim.""" + payload = _lineageweave_registration_with_account_claims() + mappers = payload["protocolMappers"] + assert isinstance(mappers, list) + payload["protocolMappers"] = [mappers[0], mappers[1], mappers[2], deepcopy(mappers[2])] + + _assert_policy_error(payload, "protocolMappers") + + +def test_account_claim_profile_rejects_duplicate_account_role() -> None: + """A role source may not be duplicated under the same token claim.""" + payload = _lineageweave_registration_with_account_claims() + mappers = payload["protocolMappers"] + assert isinstance(mappers, list) + payload["protocolMappers"] = [mappers[0], mappers[1], deepcopy(mappers[1]), mappers[3]] + + _assert_policy_error(payload, "protocolMappers") + + +def test_account_claim_profile_rejects_static_claim_mixing() -> None: + """A client cannot combine per-account and hardcoded authorization claims.""" + payload = _lineageweave_registration_with_account_claims() + mappers = payload["protocolMappers"] + assert isinstance(mappers, list) + payload["protocolMappers"] = [ + mappers[0], + mappers[1], + _claim_mapper("org", "org-cwl"), + mappers[3], + ] + + _assert_policy_error(payload, "protocolMappers") + + @pytest.mark.parametrize( ("mapper_value", "detail"), [ diff --git a/services/account_unification/tests/test_relying_party_template.py b/services/account_unification/tests/test_relying_party_template.py index 7f4ed68..cc5c673 100644 --- a/services/account_unification/tests/test_relying_party_template.py +++ b/services/account_unification/tests/test_relying_party_template.py @@ -10,6 +10,7 @@ _TEMPLATE_ROOT = Path(__file__).resolve().parents[3] / "deploy" / "templates" _TEMPLATE_PATH = _TEMPLATE_ROOT / "oidc-rp-client.json" _NARUON_TEMPLATE_PATH = _TEMPLATE_ROOT / "oidc-rp-naruon.json" +_LINEAGEWEAVE_TEMPLATE_PATH = _TEMPLATE_ROOT / "oidc-rp-lineageweave.json" def _render_template() -> dict[str, object]: @@ -46,6 +47,21 @@ def _render_naruon_template() -> dict[str, object]: return payload +def _render_lineageweave_template() -> dict[str, object]: + """Render the committed account-derived client profile without a shell tool.""" + rendered = _LINEAGEWEAVE_TEMPLATE_PATH.read_text(encoding="utf-8") + replacements = { + "{{lineageweave_redirect_uri}}": "https://lineageweave.example/auth/callback", + "{{lineageweave_web_origin}}": "https://lineageweave.example", + "{{lineageweave_post_logout_uri}}": "https://lineageweave.example/logout", + } + for marker, value in replacements.items(): + rendered = rendered.replace(marker, value) + payload = json.loads(rendered) + assert isinstance(payload, dict) + return payload + + def test_oidc_rp_template_is_closed_secret_free_and_preflight_ready() -> None: """The rendered template passes the same production preflight as operators.""" payload = _render_template() @@ -82,3 +98,26 @@ def test_naruon_runtime_template_has_the_closed_mapper_profile() -> None: ] audience = mappers[0] assert audience["config"]["included.client.audience"] == "naruon-web" + + +def test_lineageweave_runtime_template_uses_account_derived_claims() -> None: + """The shipped LineageWeave profile is confidential and secret-free.""" + payload = _render_lineageweave_template() + + result = validate_relying_party_registration(_parse_registration(payload)) + + assert result.ready_to_apply is True + assert payload["clientId"] == "lineageweave-web" + assert payload["publicClient"] is False + assert payload["clientAuthenticatorType"] == "client-secret" + assert "secret" not in {str(key).lower() for key in payload} + assert "clientSecret" not in payload + mappers = payload["protocolMappers"] + assert isinstance(mappers, list) + assert [mapper["name"] for mapper in mappers] == [ + "keyverse-audience", + "keyverse-account-role", + "keyverse-account-org", + "keyverse-account-workspace", + ] + assert all("claim.value" not in mapper["config"] for mapper in mappers[1:]) From 694f406356ac86adc4a0210889477e73777efbab Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Thu, 13 Aug 2026 18:49:51 +0900 Subject: [PATCH 02/70] Harden account-derived mapper reconciliation --- CHANGELOG.md | 4 ++++ README.md | 5 +++-- deploy/templates/README.md | 6 +++--- docs/rp-onboarding.md | 9 ++++---- .../account_unification/app/relying_party.py | 5 +++++ .../app/relying_party_state.py | 2 ++ .../tests/test_relying_party_claim_mappers.py | 21 +++++++++++++++++++ ...est_relying_party_mapper_reconciliation.py | 12 +++++++++++ 8 files changed, 55 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f7d0f6..d42b384 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -59,6 +59,10 @@ Keep a Changelog, and releases use semantic versioning. ### Changed +- Account-derived OIDC claim mappers are now limited to the ADR-0009 + `lineageweave-web` profile, and a non-string observed mapper type is treated + as reconciliation drift rather than causing an exception. Operator guides now + consistently name issued `org` (company) and `workspace` (PU) claims. - Relying-party deployment controllers now send validated, secret-free metadata to Keyverse desired-state PUT instead of applying client representations directly to Keycloak; confidential credential placement remains a separate diff --git a/README.md b/README.md index 45a0100..91e9e40 100644 --- a/README.md +++ b/README.md @@ -96,8 +96,9 @@ See [`docs/federation-onboarding.md`](docs/federation-onboarding.md), ### Onboard a relying party See [`docs/rp-onboarding.md`](docs/rp-onboarding.md). -The ADR-0009 LineageWeave profile uses real account-derived role, company, and -PU claims; it is not enabled until private Keyverse apply and controlled +The ADR-0009 LineageWeave profile uses real account-derived `role`, `org` +(company), and `workspace` (PU) claims; it is not enabled until private Keyverse +apply and controlled downstream authorization evidence are recorded. ## Account unification & merge diff --git a/deploy/templates/README.md b/deploy/templates/README.md index 69302d6..1d9ab06 100644 --- a/deploy/templates/README.md +++ b/deploy/templates/README.md @@ -178,9 +178,9 @@ the downstream boundary validates token signature, issuer, expiry, the reviewed `oidc-rp-lineageweave.json` is the ADR-0009 confidential `lineageweave-web` artifact. It renders only the exact HTTPS redirect, origin, and post-logout URI. The fixed mapper order projects a self-pinned audience, client roles from -`lineageweave-web`, and the exact `org` and `workspace` Keyverse account -attributes. The template never contains a role value, company/PU value, or -client secret. +`lineageweave-web`, and the exact `org` (company) and `workspace` (PU) Keyverse +account attributes. The template never contains a role value, `org`/`workspace` +attribute value, or client secret. Before apply, provision a real account with both attributes and a recognized client role through the approved Keyverse identity lifecycle. Preflight and diff --git a/docs/rp-onboarding.md b/docs/rp-onboarding.md index 8c20a7f..310b9d8 100644 --- a/docs/rp-onboarding.md +++ b/docs/rp-onboarding.md @@ -19,10 +19,11 @@ closed audience/session-claim mapper profile. For the ADR-0009 LineageWeave path, use `deploy/templates/oidc-rp-lineageweave.json`. It is a confidential -`lineageweave-web` client whose role, company, and PU claims are derived from -the authenticated Keyverse account. Its HTTPS endpoint placeholders are the -only values rendered into the client metadata; the role assignment and the two -account attributes are provisioned in Keyverse before controlled login. +`lineageweave-web` client whose issued `role`, `org` (company), and `workspace` +(PU) claims are derived from the authenticated Keyverse account. Its HTTPS +endpoint placeholders are the only values rendered into the client metadata; +the same-client role assignment and the `org` and `workspace` account +attributes are provisioned in Keyverse before controlled login. Resolve every placeholder from deployment configuration or KV before preflight. For Naruon this includes exact HTTPS redirect, web-origin, and post-logout URIs diff --git a/services/account_unification/app/relying_party.py b/services/account_unification/app/relying_party.py index 9f66c53..b9300bc 100644 --- a/services/account_unification/app/relying_party.py +++ b/services/account_unification/app/relying_party.py @@ -628,6 +628,11 @@ def _validate_protocol_mappers(registration: RelyingPartyRegistration) -> None: "protocolMappers", "must not mix hardcoded and account-derived claims", ) + if account_claim_names and registration.client_id != "lineageweave-web": + _client_error( + "protocolMappers", + "account-derived claims are only supported for lineageweave-web", + ) if account_claim_names and account_claim_names != _ACCOUNT_CLAIMS: _client_error( "protocolMappers", diff --git a/services/account_unification/app/relying_party_state.py b/services/account_unification/app/relying_party_state.py index 1e0f871..5597395 100644 --- a/services/account_unification/app/relying_party_state.py +++ b/services/account_unification/app/relying_party_state.py @@ -464,6 +464,8 @@ def _client_uuid(client: dict) -> str: def _observed_mapper_rank(mapper: dict) -> int | None: """Return the canonical rank for one structurally valid live mapper.""" mapper_type = mapper.get("protocolMapper") + if not isinstance(mapper_type, str): + return None if mapper_type == "oidc-audience-mapper": return 0 if mapper_type not in { diff --git a/services/account_unification/tests/test_relying_party_claim_mappers.py b/services/account_unification/tests/test_relying_party_claim_mappers.py index 32943d9..8108b15 100644 --- a/services/account_unification/tests/test_relying_party_claim_mappers.py +++ b/services/account_unification/tests/test_relying_party_claim_mappers.py @@ -355,6 +355,27 @@ def test_account_claim_profile_rejects_static_claim_mixing() -> None: _assert_policy_error(payload, "protocolMappers") +def test_account_claim_profile_rejects_other_client() -> None: + """Only the reviewed LineageWeave client may use account-derived claims.""" + payload = _lineageweave_registration_with_account_claims() + payload["clientId"] = "other-web" + payload["name"] = "other-web" + mappers = payload["protocolMappers"] + assert isinstance(mappers, list) + audience = mappers[0] + role = mappers[1] + assert isinstance(audience, dict) + assert isinstance(role, dict) + audience_config = audience["config"] + role_config = role["config"] + assert isinstance(audience_config, dict) + assert isinstance(role_config, dict) + audience_config["included.client.audience"] = "other-web" + role_config["usermodel.clientRoleMapping.clientId"] = "other-web" + + _assert_policy_error(payload, "protocolMappers") + + @pytest.mark.parametrize( ("mapper_value", "detail"), [ diff --git a/services/account_unification/tests/test_relying_party_mapper_reconciliation.py b/services/account_unification/tests/test_relying_party_mapper_reconciliation.py index 4db2709..291b24e 100644 --- a/services/account_unification/tests/test_relying_party_mapper_reconciliation.py +++ b/services/account_unification/tests/test_relying_party_mapper_reconciliation.py @@ -127,6 +127,16 @@ def _set_unsupported_mapper_type(client: dict) -> None: ) +def _set_sequence_mapper_type(client: dict) -> None: + """Make a live mapper type unhashable and therefore invalid.""" + _live_mappers_from_client(client)[0]["protocolMapper"] = [] + + +def _set_mapping_mapper_type(client: dict) -> None: + """Make a live mapper type an invalid object rather than a string.""" + _live_mappers_from_client(client)[0]["protocolMapper"] = {} + + def _duplicate_mapper_identity(client: dict) -> None: """Make two live mappers claim the same canonical identity.""" mappers = _live_mappers_from_client(client) @@ -161,6 +171,8 @@ def _live_mappers_from_client(client: dict) -> list[dict]: _add_non_string_config_key, _add_non_string_config_value, _set_unsupported_mapper_type, + _set_sequence_mapper_type, + _set_mapping_mapper_type, _duplicate_mapper_identity, _set_policy_invalid_audience_name, ], From eb7271b47273947ee23c796cb5204efe67b38526 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 14 Aug 2026 00:02:01 +0900 Subject: [PATCH 03/70] Fix Keycloak realm import and account profile bootstrap --- .github/workflows/ci.yml | 2 +- .../workflows/hourly-product-development.yml | 2 +- CHANGELOG.md | 3 + CLAUDE.md | 2 +- Makefile | 2 +- README.md | 2 +- deploy/keycloak/Dockerfile | 6 + deploy/keycloak/README.md | 2 +- .../{realm-cwl.json => cwl-realm.json} | 0 deploy/keycloak/kcadm-bootstrap.sh | 2 +- .../keycloak/lineageweave-user-profile.json | 110 ++++++++++++++++++ .../reconcile-lineageweave-user-profile.sh | 45 +++++++ docker-compose.yml | 27 ++++- docs/TRACEABILITY.md | 3 +- docs/adr/0001-keycloak-hub.md | 14 ++- ...-lineageweave-account-derived-rp-claims.md | 29 ++++- docs/adr/README.md | 1 + docs/operations/hourly-product-development.md | 2 +- docs/passwordless-policy.md | 2 +- .../2026-08-03-keyverse-product-hardening.md | 2 +- .../2026-08-03-keyverse-review-remediation.md | 2 +- ...08-05-keyverse-ldap-directory-preflight.md | 2 +- ...26-08-07-keyverse-oidc-rp-claim-profile.md | 2 +- helm/cwl-idp/templates/keycloak.yaml | 4 + helm/cwl-idp/values.yaml | 3 +- scripts/validate_realm.py | 46 +++++++- .../tests/test_deployment_contracts.py | 28 +++++ .../tests/test_hourly_product_guard.py | 2 +- .../tests/test_realm_policy.py | 64 +++++++++- tests/test_documentation_contract.py | 1 + 30 files changed, 383 insertions(+), 29 deletions(-) create mode 100644 deploy/keycloak/Dockerfile rename deploy/keycloak/{realm-cwl.json => cwl-realm.json} (100%) create mode 100644 deploy/keycloak/lineageweave-user-profile.json create mode 100644 deploy/keycloak/reconcile-lineageweave-user-profile.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2a1eca6..96f6d41 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -53,7 +53,7 @@ jobs: with: python-version: "3.12" - name: Validate Keycloak realm config-as-code - run: python scripts/validate_realm.py deploy/keycloak/realm-cwl.json + run: python scripts/validate_realm.py deploy/keycloak/cwl-realm.json - name: Validate deployment template JSON run: | python - <<'PY' diff --git a/.github/workflows/hourly-product-development.yml b/.github/workflows/hourly-product-development.yml index 4351d54..7ff0e2f 100644 --- a/.github/workflows/hourly-product-development.yml +++ b/.github/workflows/hourly-product-development.yml @@ -741,7 +741,7 @@ jobs: uv run coverage report --show-missing --fail-under=100 uv build --out-dir dist ) - python scripts/validate_realm.py deploy/keycloak/realm-cwl.json + python scripts/validate_realm.py deploy/keycloak/cwl-realm.json docker compose -f docker-compose.yml config >/dev/null while IFS= read -r -d '' template; do python -m json.tool "$template" >/dev/null diff --git a/CHANGELOG.md b/CHANGELOG.md index d42b384..3b77608 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -97,6 +97,9 @@ Keep a Changelog, and releases use semantic versioning. ### Fixed +- Packaged the portable Keycloak realm under the required `cwl-realm.json` + directory-import name in Compose and mapped it in Helm, with a deployment + contract that prevents a healthy-but-empty identity realm. - Prevented relying-party inventory from silently accepting a KV key/body identity mismatch, rejected unsafe live or `Location`-derived client UUIDs, and aligned exact client discovery with Keycloak's documented diff --git a/CLAUDE.md b/CLAUDE.md index 31aff44..90e0db4 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -28,7 +28,7 @@ make ready # poll readiness (deploy/scripts/healthz.sh) make install # install the admin service development environment make test # run account-unification unit tests make lint # run Ruff + interrogate docstring coverage -make validate-realm # validate deploy/keycloak/realm-cwl.json +make validate-realm # validate deploy/keycloak/cwl-realm.json make seed-bootstrap # create a local SQLite KV bootstrap store ``` diff --git a/Makefile b/Makefile index 79dec87..a73f111 100644 --- a/Makefile +++ b/Makefile @@ -24,7 +24,7 @@ seed-bootstrap: ## Create a local sqlite KV bootstrap store for dev python $(SERVICE_DIR)/tools/seed_config_store.py validate-realm: ## Validate the Keycloak realm config-as-code - python scripts/validate_realm.py deploy/keycloak/realm-cwl.json + python scripts/validate_realm.py deploy/keycloak/cwl-realm.json install: ## Install the admin service with dev extras cd $(SERVICE_DIR) && python -m pip install -e '.[dev]' diff --git a/README.md b/README.md index 91e9e40..11c81f9 100644 --- a/README.md +++ b/README.md @@ -67,7 +67,7 @@ docker compose up -d # or: podman compose up -d - Admin service health: `http://localhost:8099/healthz` The stack imports the **passwordless-first** realm at first start -(`deploy/keycloak/realm-cwl.json`): a `browser-passwordless` flow with a +(`deploy/keycloak/cwl-realm.json`): a `browser-passwordless` flow with a WebAuthn passwordless authenticator and **no password authenticator**, plus `registrationAllowed:false` / `resetPasswordAllowed:false`. diff --git a/deploy/keycloak/Dockerfile b/deploy/keycloak/Dockerfile new file mode 100644 index 0000000..01c286c --- /dev/null +++ b/deploy/keycloak/Dockerfile @@ -0,0 +1,6 @@ +FROM quay.io/keycloak/keycloak:26.3.2@sha256:98fab020a3a490aba0978f237e2a06cd0ea42bf149c6cf10f11c0aaf27728ff2 + +# Keycloak directory import recognizes -realm.json at container start. +COPY cwl-realm.json /opt/keycloak/data/import/cwl-realm.json +COPY lineageweave-user-profile.json /opt/keycloak/lineageweave-user-profile.json +COPY --chmod=755 reconcile-lineageweave-user-profile.sh /opt/keycloak/reconcile-lineageweave-user-profile.sh diff --git a/deploy/keycloak/README.md b/deploy/keycloak/README.md index feaf209..aa67021 100644 --- a/deploy/keycloak/README.md +++ b/deploy/keycloak/README.md @@ -6,7 +6,7 @@ providers are converged afterwards from the KV/DB source of truth. | File | Responsibility | | --- | --- | -| `realm-cwl.json` | Portable passwordless realm, shared client scopes, RP template, concrete `naruon-web` PKCE client, and account-unification service client | +| `cwl-realm.json` | Portable passwordless realm, shared client scopes, RP template, concrete `naruon-web` PKCE client, and account-unification service client | | `kcadm-bootstrap.sh` | Idempotently inject the service-client secret, grant least-privilege realm-management roles, and reconcile the role mapper | | `../templates/` | Reference payloads for runtime federation and additional relying-party registrations | diff --git a/deploy/keycloak/realm-cwl.json b/deploy/keycloak/cwl-realm.json similarity index 100% rename from deploy/keycloak/realm-cwl.json rename to deploy/keycloak/cwl-realm.json diff --git a/deploy/keycloak/kcadm-bootstrap.sh b/deploy/keycloak/kcadm-bootstrap.sh index 347eb1e..fb00a7b 100755 --- a/deploy/keycloak/kcadm-bootstrap.sh +++ b/deploy/keycloak/kcadm-bootstrap.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash # cwl-idp — Keycloak post-import bootstrap (config-as-code, secrets from KV). # -# The realm SHAPE lives in realm-cwl.json and is imported at container start. +# The realm SHAPE lives in cwl-realm.json and is imported at container start. # This script patches the pieces that must NOT be committed (secrets, env URLs) # by reading them from the KV store and applying them with Keycloak's admin CLI # (`kcadm.sh`, shipped in the Keycloak image, Apache-2.0). Run it after the realm diff --git a/deploy/keycloak/lineageweave-user-profile.json b/deploy/keycloak/lineageweave-user-profile.json new file mode 100644 index 0000000..74f539a --- /dev/null +++ b/deploy/keycloak/lineageweave-user-profile.json @@ -0,0 +1,110 @@ +{ + "attributes": [ + { + "name": "username", + "displayName": "${username}", + "validations": { + "length": { + "min": 3, + "max": 255 + }, + "username-prohibited-characters": {}, + "up-username-not-idn-homograph": {} + }, + "permissions": { + "view": ["admin", "user"], + "edit": ["admin", "user"] + }, + "multivalued": false + }, + { + "name": "email", + "displayName": "${email}", + "validations": { + "email": {}, + "length": { + "max": 255 + } + }, + "required": { + "roles": ["user"] + }, + "permissions": { + "view": ["admin", "user"], + "edit": ["admin", "user"] + }, + "multivalued": false + }, + { + "name": "firstName", + "displayName": "${firstName}", + "validations": { + "length": { + "max": 255 + }, + "person-name-prohibited-characters": {} + }, + "required": { + "roles": ["user"] + }, + "permissions": { + "view": ["admin", "user"], + "edit": ["admin", "user"] + }, + "multivalued": false + }, + { + "name": "lastName", + "displayName": "${lastName}", + "validations": { + "length": { + "max": 255 + }, + "person-name-prohibited-characters": {} + }, + "required": { + "roles": ["user"] + }, + "permissions": { + "view": ["admin", "user"], + "edit": ["admin", "user"] + }, + "multivalued": false + }, + { + "name": "org", + "displayName": "Organization", + "validations": { + "length": { + "max": "64" + } + }, + "permissions": { + "view": ["admin"], + "edit": ["admin"] + }, + "multivalued": false + }, + { + "name": "workspace", + "displayName": "Workspace", + "validations": { + "length": { + "max": "64" + } + }, + "permissions": { + "view": ["admin"], + "edit": ["admin"] + }, + "multivalued": false + } + ], + "groups": [ + { + "name": "user-metadata", + "displayHeader": "User metadata", + "displayDescription": "Attributes, which refer to user metadata" + } + ] +} diff --git a/deploy/keycloak/reconcile-lineageweave-user-profile.sh b/deploy/keycloak/reconcile-lineageweave-user-profile.sh new file mode 100644 index 0000000..bc18a6f --- /dev/null +++ b/deploy/keycloak/reconcile-lineageweave-user-profile.sh @@ -0,0 +1,45 @@ +#!/usr/bin/env bash +# Reconcile the closed LineageWeave account-attribute profile after realm import. +set -euo pipefail +umask 077 + +REALM="${KC_REALM:-cwl}" +KC_SERVER="${KC_SERVER:-http://idp_engine:8080}" +ADMIN_USER="${KC_BOOTSTRAP_ADMIN_USERNAME:?bootstrap admin username is required}" +ADMIN_PASS="${KC_BOOTSTRAP_ADMIN_PASSWORD:?bootstrap admin password is required}" +KCADM_HOME="$(mktemp -d)" +cleanup() { + rm -rf "${KCADM_HOME}" + unset ADMIN_PASS KC_CLI_PASSWORD KC_BOOTSTRAP_ADMIN_PASSWORD +} +trap cleanup EXIT +kcadm() { + HOME="${KCADM_HOME}" /opt/keycloak/bin/kcadm.sh "$@" +} + +for attempt in $(seq 1 30); do + if KC_CLI_PASSWORD="${ADMIN_PASS}" kcadm config credentials \ + --server "${KC_SERVER}" --realm master --user "${ADMIN_USER}"; then + break + fi + if [[ "${attempt}" -eq 30 ]]; then + echo "profile bootstrap failed: Keycloak admin login did not become ready" >&2 + exit 1 + fi + sleep 1 +done +unset ADMIN_PASS KC_BOOTSTRAP_ADMIN_PASSWORD + +kcadm update "realms/${REALM}/users/profile" \ + -f /opt/keycloak/lineageweave-user-profile.json +profile="$(kcadm get "realms/${REALM}/users/profile")" +for attribute in org workspace; do + printf '%s' "${profile}" \ + | grep -Eq '"name"[[:space:]]*:[[:space:]]*"'"${attribute}"'"' +done +# Keycloak 26.3.2 represents the closed unmanaged-attribute policy as null, +# which is omitted from the Admin API JSON; DISABLED is not an accepted enum. +if printf '%s' "${profile}" | grep -Eq '"unmanagedAttributePolicy"'; then + echo "profile bootstrap failed: unmanaged attributes must stay disabled" >&2 + exit 1 +fi diff --git a/docker-compose.yml b/docker-compose.yml index dfcbe84..afe107f 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -44,10 +44,14 @@ services: # --------------------------------------------------------------------- # # Keycloak — the IdP engine. The passwordless-first realm (WebAuthn # passwordless flow, passwords disabled) is imported as-code at start from - # deploy/keycloak/realm-cwl.json via --import-realm. + # deploy/keycloak/cwl-realm.json. Keycloak requires the target name + # -realm.json, so the pinned runtime image packages that exact file. # --------------------------------------------------------------------- # idp_engine: - image: quay.io/keycloak/keycloak:26.3.2@sha256:98fab020a3a490aba0978f237e2a06cd0ea42bf149c6cf10f11c0aaf27728ff2 + build: + context: ./deploy/keycloak + dockerfile: Dockerfile + image: cwl-idp/keycloak:local container_name: cwl_idp_engine restart: unless-stopped command: > @@ -67,8 +71,6 @@ services: KC_HOSTNAME_STRICT: "false" KC_PROXY_HEADERS: xforwarded KC_CACHE: ${IDP_CACHE_MODE:-local} - volumes: - - ./deploy/keycloak/realm-cwl.json:/opt/keycloak/data/import/realm-cwl.json:ro ports: - "${IDP_EXTERNAL_PORT:-8080}:8080" depends_on: @@ -89,6 +91,23 @@ services: - idp_internal_network - idp_edge_network + # The realm representation cannot carry declarative user-profile settings. + # Reconcile the closed LineageWeave attributes only after cwl is imported. + idp_profile_bootstrap: + image: cwl-idp/keycloak:local + restart: "no" + entrypoint: ["/opt/keycloak/reconcile-lineageweave-user-profile.sh"] + environment: + KC_SERVER: http://idp_engine:8080 + KC_REALM: cwl + KC_BOOTSTRAP_ADMIN_USERNAME: ${IDP_BOOTSTRAP_ADMIN_USERNAME:-idp-admin} + KC_BOOTSTRAP_ADMIN_PASSWORD: ${IDP_BOOTSTRAP_ADMIN_PASSWORD} + depends_on: + idp_engine: + condition: service_healthy + networks: + - idp_internal_network + # --------------------------------------------------------------------- # # account-unification admin service (this repo). Fills the gap Keycloak # does not cover natively: MERGE two pre-existing accounts into one, and a diff --git a/docs/TRACEABILITY.md b/docs/TRACEABILITY.md index 44ac724..ec8c4d2 100644 --- a/docs/TRACEABILITY.md +++ b/docs/TRACEABILITY.md @@ -6,6 +6,7 @@ | Requirement / decision | Standards / authoritative basis | Source/evidence boundary | Maturity | |---|---|---|---| | passwordless local accounts | WebAuthn/FIDO2 + Keycloak supported flow; research/standards records | realm validator + deployment tests | implemented-main | +| Keycloak portable realm import | Keycloak 26 directory import naming contract | Compose/Helm filename mapping contract plus realm-discovery acceptance | implemented-main | | exact subject then verified-email match | OIDC federation / NIST federation guidance; merge documentation | account-unification matching/merge tests | implemented-main | | unverified email never auto-links | security/product invariant | merge/federation tests | implemented-main | | SCIM inbound lifecycle | RFC 7643/7644; protocol documentation | SCIM service/lifecycle tests | implemented-main | @@ -13,7 +14,7 @@ | LDAPS directory profile | LDAP RFC 4511–4515 + Keycloak component docs | directory preflight/reconciliation tests | implemented-main | | secret-free RP desired state | OAuth/OIDC/PKCE/Keycloak client docs | RP preflight/reconciliation/integrity tests | implemented-main | | RP audience/role/org/workspace mapper profile | OIDC/JWT audience + Keycloak mapper docs | PR #72 protected-main source/tests; downstream RP acceptance remains required | implemented-main | -| LineageWeave account-derived RP claims | ADR-0009; Keycloak Protocol Mappers | closed branch profile/template/reconciliation tests; real account, Keyverse apply, and downstream ABAC/RBAC acceptance remain required | accepted-contract | +| LineageWeave account-derived RP claims | ADR-0009; Keycloak Protocol Mappers and post-import declarative user profile | scalar, admin-managed account-attribute policy plus Compose profile reconciliation/template tests; real account, Keyverse apply, and downstream ABAC/RBAC acceptance remain required | accepted-contract | | merge/SCIM PUT shared operation lock | concurrency/data-integrity decision; ADR-0006 | merge + full-replacement lock/concurrency tests | implemented-main | | SCIM PATCH active=false shared-lock parity | ADR-0006 boundary | current PATCH source has no shared-lock proof | gap-not-claimed | | intent before mutation, receipt after re-observation | desired-state/recovery decision | federation/directory/RP reconciliation tests | implemented-main | diff --git a/docs/adr/0001-keycloak-hub.md b/docs/adr/0001-keycloak-hub.md index 1dd0af9..4eef5cc 100644 --- a/docs/adr/0001-keycloak-hub.md +++ b/docs/adr/0001-keycloak-hub.md @@ -3,4 +3,16 @@ **Status:** Accepted **Date:** 2026-08-09 -Keyverse uses Keycloak as the standards-based identity engine and adds CWL-owned control services around it. Employer/customer ADFS, LDAP/AD, external OIDC, and HR/IGA are federation/provisioning sources rather than peer hubs. CWL relying parties trust the Keyverse/Keycloak boundary instead of administering those external systems directly. Customer-specific federation remains deployment data, not portable realm code. \ No newline at end of file +Keyverse uses Keycloak as the standards-based identity engine and adds CWL-owned control services around it. Employer/customer ADFS, LDAP/AD, external OIDC, and HR/IGA are federation/provisioning sources rather than peer hubs. CWL relying parties trust the Keyverse/Keycloak boundary instead of administering those external systems directly. Customer-specific federation remains deployment data, not portable realm code. + +## Compose and Helm realm-import invariant + +Keycloak directory import discovers a realm only when its target is named +`-realm.json`. The portable file is therefore `cwl-realm.json`. Compose +packages that file in a derivative of the pinned Keycloak image instead of +bind-mounting a leaf below `/opt/keycloak/data`; Docker Desktop can present such +a leaf mount as a directory and make the import fail. Helm maps its ConfigMap +key to the same filename. A container health check alone is insufficient: it can +be healthy while the intended realm was never imported. Deployment acceptance +therefore verifies the realm discovery endpoint, and a static deployment contract +locks the filename mapping in both packaging paths. diff --git a/docs/adr/0009-lineageweave-account-derived-rp-claims.md b/docs/adr/0009-lineageweave-account-derived-rp-claims.md index b40b298..c279496 100644 --- a/docs/adr/0009-lineageweave-account-derived-rp-claims.md +++ b/docs/adr/0009-lineageweave-account-derived-rp-claims.md @@ -37,6 +37,19 @@ and cannot be extended by configuration. The desired-state representation has no client-secret field; confidential-secret placement remains a separate approved secret-management operation. +The Keyverse post-import declarative user profile declares `org` and +`workspace` as product authorization attributes, alongside the Keycloak +built-in account attributes required because its Admin API replaces the whole +profile rather than patching it. Both product attributes are scalar, maximum +64 characters, and visible/editable only to administrators. In the pinned +Keycloak 26.3.2 runtime, the closed unmanaged-attribute policy is represented +by an omitted/null value; its enum does not accept the documented `DISABLED` +string, and its implementation denies unmanaged attributes when that value is +null. Keycloak's realm-import representation does not accept this profile, so +a one-shot Compose bootstrap reconciles it only after the realm is healthy. +This keeps the issuer from silently accepting arbitrary account metadata while +preserving operators' ability to assign the two reviewed ABAC dimensions. + The receiving application must validate issuer, signature/algorithm, expiry, subject, and audience before reading these claims. It must bind `org` and `workspace` to the requested resource before applying recognized client roles. @@ -70,7 +83,8 @@ flowchart LR ## Consequences - Identity operators must provision a real Keyverse account with the two named - attributes and an allowed `lineageweave-web` client role before user routing. + administrator-managed attributes and an allowed `lineageweave-web` client + role before user routing. - Account and role changes take effect through Keycloak session/token lifecycle; operators must test downgrade and revocation behavior in controlled runtime acceptance. @@ -83,11 +97,14 @@ flowchart LR ## Acceptance evidence The implementation has local RED-to-GREEN validation, mapper-observation, and -secret-free-template tests. Before production use, record authenticated Keyverse -preflight and reconciliation receipts, private credential placement, a real -account authorization-code/PKCE exchange, token claim shape, cross-tenant -denial, role downgrade, logout, and rollback evidence. Until then the profile -is an accepted contract, not a deployed-login claim. +secret-free-template tests. It also has a live Keycloak 26.3.2 API acceptance: +the full profile PUT returns success, returns both reviewed attributes, and +omits `unmanagedAttributePolicy` after reconciliation. Before production use, +record authenticated Keyverse preflight and reconciliation receipts, private +credential placement, a real account authorization-code/PKCE exchange, token +claim shape, cross-tenant denial, role downgrade, logout, and rollback +evidence. Until then the profile is an accepted contract, not a deployed-login +claim. ## References diff --git a/docs/adr/README.md b/docs/adr/README.md index e53fc6d..66f733d 100644 --- a/docs/adr/README.md +++ b/docs/adr/README.md @@ -12,6 +12,7 @@ | [0006](0006-user-operation-lock.md) | Merge and SCIM full replacement share one user-operation lock boundary | Accepted | | [0007](0007-automation-authority.md) | Autonomous development remains separate from review/merge/release authority | Accepted | | [0008](0008-keyverse-rp-authorization-boundary.md) | Every non-fork RP explicitly validates Keyverse identity and manages ABAC/RBAC at its own boundary | Accepted | +| [0009](0009-lineageweave-account-derived-rp-claims.md) | Bind LineageWeave claims to explicit, administrator-managed Keyverse account attributes | Accepted | ## ADR triggers diff --git a/docs/operations/hourly-product-development.md b/docs/operations/hourly-product-development.md index abb366a..e46bd11 100644 --- a/docs/operations/hourly-product-development.md +++ b/docs/operations/hourly-product-development.md @@ -182,7 +182,7 @@ uv run coverage run --branch --source=app -m pytest -q uv run coverage report --show-missing --fail-under=100 uv build --out-dir dist cd ../.. -python scripts/validate_realm.py deploy/keycloak/realm-cwl.json +python scripts/validate_realm.py deploy/keycloak/cwl-realm.json docker compose -f docker-compose.yml config python -m json.tool deploy/templates/.json git diff --check diff --git a/docs/passwordless-policy.md b/docs/passwordless-policy.md index e33c2c3..4dbdea1 100644 --- a/docs/passwordless-policy.md +++ b/docs/passwordless-policy.md @@ -9,7 +9,7 @@ password to phish, reuse, reset, or leak. ## How it is enforced as code -`deploy/keycloak/realm-cwl.json` fixes the following invariants: +`deploy/keycloak/cwl-realm.json` fixes the following invariants: | Setting | Value | Effect | | --- | --- | --- | diff --git a/docs/superpowers/plans/2026-08-03-keyverse-product-hardening.md b/docs/superpowers/plans/2026-08-03-keyverse-product-hardening.md index 7d458cd..5f9c5e3 100644 --- a/docs/superpowers/plans/2026-08-03-keyverse-product-hardening.md +++ b/docs/superpowers/plans/2026-08-03-keyverse-product-hardening.md @@ -141,7 +141,7 @@ Interrogate, Keycloak Admin REST API, Docker Compose, Helm. ### Task 7: Enforce Keycloak realm policy **Files:** -- Modify: `deploy/keycloak/realm-cwl.json` +- Modify: `deploy/keycloak/cwl-realm.json` - Modify: `scripts/validate_realm.py` - Test: `services/account_unification/tests/test_realm_policy.py` diff --git a/docs/superpowers/plans/2026-08-03-keyverse-review-remediation.md b/docs/superpowers/plans/2026-08-03-keyverse-review-remediation.md index a4a2093..654c71a 100644 --- a/docs/superpowers/plans/2026-08-03-keyverse-review-remediation.md +++ b/docs/superpowers/plans/2026-08-03-keyverse-review-remediation.md @@ -31,7 +31,7 @@ REST API, pytest, Ruff, Interrogate, Helm, Docker Compose. ### Task 1: Passwordless registration enrollment **Files:** -- Modify: `deploy/keycloak/realm-cwl.json` +- Modify: `deploy/keycloak/cwl-realm.json` - Modify: `scripts/validate_realm.py` - Modify: `services/account_unification/app/registration.py` - Modify: `services/account_unification/app/product_keycloak_client.py` diff --git a/docs/superpowers/plans/2026-08-05-keyverse-ldap-directory-preflight.md b/docs/superpowers/plans/2026-08-05-keyverse-ldap-directory-preflight.md index de2ee77..9d7cc2f 100644 --- a/docs/superpowers/plans/2026-08-05-keyverse-ldap-directory-preflight.md +++ b/docs/superpowers/plans/2026-08-05-keyverse-ldap-directory-preflight.md @@ -84,7 +84,7 @@ Naruon deployment controllers. - [ ] `uv run coverage report --show-missing --fail-under=100` - [ ] `python -m compileall -q app tests tools` - [ ] package build and installed-wheel smoke test -- [ ] `python scripts/validate_realm.py deploy/keycloak/realm-cwl.json` +- [ ] `python scripts/validate_realm.py deploy/keycloak/cwl-realm.json` - [ ] `docker compose -f docker-compose.yml config` - [ ] validate every deployment JSON template - [ ] `git diff --check` diff --git a/docs/superpowers/plans/2026-08-07-keyverse-oidc-rp-claim-profile.md b/docs/superpowers/plans/2026-08-07-keyverse-oidc-rp-claim-profile.md index 9cdb3e1..6f87218 100644 --- a/docs/superpowers/plans/2026-08-07-keyverse-oidc-rp-claim-profile.md +++ b/docs/superpowers/plans/2026-08-07-keyverse-oidc-rp-claim-profile.md @@ -355,7 +355,7 @@ uv run coverage run --branch --source=app -m pytest -q uv run coverage report --show-missing --fail-under=100 uv build --out-dir dist cd ../.. -python scripts/validate_realm.py deploy/keycloak/realm-cwl.json +python scripts/validate_realm.py deploy/keycloak/cwl-realm.json docker compose -f docker-compose.yml config python - <<'PY' import json diff --git a/helm/cwl-idp/templates/keycloak.yaml b/helm/cwl-idp/templates/keycloak.yaml index 9b4ee2f..d769ddd 100644 --- a/helm/cwl-idp/templates/keycloak.yaml +++ b/helm/cwl-idp/templates/keycloak.yaml @@ -117,6 +117,10 @@ spec: - name: realm-import configMap: name: {{ .Values.keycloak.realmImport.configMapName }} + items: + # Keycloak directory import accepts -realm.json only. + - key: {{ .Values.keycloak.realmImport.fileName }} + path: cwl-realm.json --- apiVersion: v1 kind: Service diff --git a/helm/cwl-idp/values.yaml b/helm/cwl-idp/values.yaml index c5bf393..2a48c43 100644 --- a/helm/cwl-idp/values.yaml +++ b/helm/cwl-idp/values.yaml @@ -50,7 +50,8 @@ keycloak: existingSecret: cwl-idp-keycloak realmImport: configMapName: cwl-idp-realm - fileName: realm-cwl.json + # Source ConfigMap key; the chart mounts it as cwl-realm.json for Keycloak. + fileName: cwl-realm.json resources: requests: cpu: 500m diff --git a/scripts/validate_realm.py b/scripts/validate_realm.py index db6e6c5..c423c35 100644 --- a/scripts/validate_realm.py +++ b/scripts/validate_realm.py @@ -12,6 +12,7 @@ * Keycloak 26 import compatibility excludes ``$`` annotation keys; * the ``basic`` scope provides ``sub`` and is a realm default; * ``naruon-web`` is a bounded-token public PKCE client with required claims. +* the post-import product authorization profile is explicit and admin-only. Usage: python scripts/validate_realm.py [path-to-realm.json] Exit 0 = valid, 1 = invalid (prints the failing checks). @@ -31,6 +32,8 @@ PASSKEY_AUTHENTICATOR = f"webauthn-authenticator-{_CREDENTIAL_FACTOR}less" SECRET_PLACEHOLDER = "__set_from_kv__" MAX_PUBLIC_TOKEN_LIFESPAN = 900 +USER_PROFILE_FILENAME = "lineageweave-user-profile.json" +BUILTIN_USER_PROFILE_ATTRIBUTES = {"username", "email", "firstName", "lastName"} def _executions(realm: dict, alias: str) -> list[dict]: @@ -220,6 +223,40 @@ def validate(realm: dict) -> list[str]: return errors +def validate_user_profile(profile: dict) -> list[str]: + """Return violations for closed, administrator-managed product attributes.""" + errors: list[str] = [] + # Keycloak 26.3.2 has no DISABLED enum member: a missing/null policy is its + # fail-closed representation. Sending the documented string makes the API + # reject the complete profile payload. + if profile.get("unmanagedAttributePolicy") is not None: + errors.append( + "user profile must omit unmanagedAttributePolicy so Keycloak 26 " + "disables unmanaged attributes" + ) + attributes = { + item.get("name"): item + for item in profile.get("attributes", []) + if isinstance(item, dict) + } + if not BUILTIN_USER_PROFILE_ATTRIBUTES <= attributes.keys(): + errors.append( + "user profile must retain Keycloak built-in account attributes when " + "the Admin API replaces the complete profile" + ) + for name in ("org", "workspace"): + attribute = attributes.get(name) + if not isinstance(attribute, dict): + errors.append(f"user profile must define '{name}'") + elif attribute.get("multivalued") is not False: + errors.append(f"user profile '{name}' must be scalar") + elif attribute.get("permissions") != {"view": ["admin"], "edit": ["admin"]}: + errors.append(f"user profile '{name}' must be admin-managed") + elif attribute.get("validations", {}).get("length", {}).get("max") != "64": + errors.append(f"user profile '{name}' must have a maximum length of 64") + return errors + + def _dollar_keys(node: object, prefix: str = "") -> list[str]: """Collect every ``$``-prefixed object key with its JSON path.""" found: list[str] = [] @@ -240,7 +277,7 @@ def main(argv: list[str]) -> int: path = ( Path(argv[1]) if len(argv) > 1 - else Path("deploy/keycloak/realm-cwl.json") + else Path("deploy/keycloak/cwl-realm.json") ) try: realm = json.loads(path.read_text(encoding="utf-8")) @@ -249,6 +286,13 @@ def main(argv: list[str]) -> int: return 1 errors = validate(realm) + profile_path = path.with_name(USER_PROFILE_FILENAME) + try: + profile = json.loads(profile_path.read_text(encoding="utf-8")) + except (OSError, json.JSONDecodeError) as exc: + print(f"INVALID: cannot parse {profile_path}: {exc}", file=sys.stderr) + return 1 + errors.extend(validate_user_profile(profile)) if errors: print(f"INVALID: {path}", file=sys.stderr) for error in errors: diff --git a/services/account_unification/tests/test_deployment_contracts.py b/services/account_unification/tests/test_deployment_contracts.py index b346d29..3e43adc 100644 --- a/services/account_unification/tests/test_deployment_contracts.py +++ b/services/account_unification/tests/test_deployment_contracts.py @@ -45,6 +45,34 @@ def test_compose_persists_account_unification_state() -> None: assert "account_unification_data" in compose["volumes"] +def test_keycloak_import_packages_realm_and_profile_contracts() -> None: + """Keep Compose and Helm compatible with Keycloak's separate profile API.""" + root = _repository_root() + compose = yaml.safe_load((root / "docker-compose.yml").read_text(encoding="utf-8")) + engine = compose["services"]["idp_engine"] + assert engine["build"] == {"context": "./deploy/keycloak", "dockerfile": "Dockerfile"} + assert engine["image"] == "cwl-idp/keycloak:local" + dockerfile = (root / "deploy" / "keycloak" / "Dockerfile").read_text(encoding="utf-8") + assert "FROM quay.io/keycloak/keycloak:26.3.2@sha256:" in dockerfile + assert "COPY cwl-realm.json /opt/keycloak/data/import/cwl-realm.json" in dockerfile + assert "COPY lineageweave-user-profile.json" in dockerfile + assert "COPY --chmod=755 reconcile-lineageweave-user-profile.sh" in dockerfile + bootstrap_script = ( + root / "deploy" / "keycloak" / "reconcile-lineageweave-user-profile.sh" + ).read_text(encoding="utf-8") + assert "/opt/keycloak/bin/kcadm.sh" in bootstrap_script + profile = compose["services"]["idp_profile_bootstrap"] + assert profile["depends_on"]["idp_engine"]["condition"] == "service_healthy" + assert profile["entrypoint"] == ["/opt/keycloak/reconcile-lineageweave-user-profile.sh"] + + keycloak = ( + root / "helm" / "cwl-idp" / "templates" / "keycloak.yaml" + ).read_text(encoding="utf-8") + assert _helm_values()["keycloak"]["realmImport"]["fileName"] == "cwl-realm.json" + assert "key: {{ .Values.keycloak.realmImport.fileName }}" in keycloak + assert "path: cwl-realm.json" in keycloak + + def test_helm_can_fail_closed_on_missing_account_image_digest() -> None: """Production values can require an immutable account-service image.""" image = _helm_values()["accountUnification"]["image"] diff --git a/services/account_unification/tests/test_hourly_product_guard.py b/services/account_unification/tests/test_hourly_product_guard.py index 8467fbb..00910b5 100644 --- a/services/account_unification/tests/test_hourly_product_guard.py +++ b/services/account_unification/tests/test_hourly_product_guard.py @@ -46,7 +46,7 @@ def test_guard_allows_product_files_and_rejects_control_plane_files() -> None: "services/account_unification/uv.lock", "docker-compose.yml", "helm/cwl-idp/values.yaml", - "deploy/keycloak/realm-cwl.json", + "deploy/keycloak/cwl-realm.json", "../outside.txt", ): assert not guard._path_allowed(forbidden_path) diff --git a/services/account_unification/tests/test_realm_policy.py b/services/account_unification/tests/test_realm_policy.py index 83d03b2..822e5af 100644 --- a/services/account_unification/tests/test_realm_policy.py +++ b/services/account_unification/tests/test_realm_policy.py @@ -7,6 +7,8 @@ from pathlib import Path from types import ModuleType +import pytest + def _repository_root() -> Path: """Return the repository root from the service test package.""" @@ -28,10 +30,18 @@ def _validator_module() -> ModuleType: def _realm() -> dict: """Load the committed Keycloak realm representation.""" - realm_path = _repository_root() / "deploy" / "keycloak" / "realm-cwl.json" + realm_path = _repository_root() / "deploy" / "keycloak" / "cwl-realm.json" return json.loads(realm_path.read_text(encoding="utf-8")) +def _user_profile() -> dict: + """Load the closed post-import product account-attribute profile.""" + profile_path = ( + _repository_root() / "deploy" / "keycloak" / "lineageweave-user-profile.json" + ) + return json.loads(profile_path.read_text(encoding="utf-8")) + + def _client(realm: dict, client_id: str) -> dict: """Return one client representation by client ID.""" return next( @@ -45,6 +55,7 @@ def test_committed_realm_passes_passwordless_policy() -> None: """The checked-in realm satisfies every fail-closed policy invariant.""" validator = _validator_module() assert validator.validate(_realm()) == [] + assert validator.validate_user_profile(_user_profile()) == [] def test_bound_browser_flow_rejects_password_authenticator() -> None: @@ -81,6 +92,57 @@ def test_public_client_token_lifespan_is_bounded() -> None: assert any("access.token.lifespan" in error for error in errors) +@pytest.mark.parametrize( + ("field", "value", "expected"), + [ + ("multivalued", True, "must be scalar"), + ("permissions", {"view": ["admin"], "edit": ["admin", "user"]}, "admin-managed"), + ("validations", {"length": {"max": "65"}}, "maximum length of 64"), + ], +) +def test_product_account_attributes_are_constrained( + field: str, value: object, expected: str +) -> None: + """Authorization attributes stay scalar, bounded, and administrator-managed.""" + validator = _validator_module() + profile = deepcopy(_user_profile()) + attribute = next(item for item in profile["attributes"] if item["name"] == "org") + attribute[field] = value + + errors = validator.validate_user_profile(profile) + + assert any(expected in error for error in errors) + + +def test_product_account_attributes_cannot_be_omitted() -> None: + """Every issued product claim has an explicit Keycloak account source.""" + validator = _validator_module() + profile = deepcopy(_user_profile()) + profile["attributes"] = [] + + errors = validator.validate_user_profile(profile) + + assert any("must define 'org'" in error for error in errors) + assert any("must define 'workspace'" in error for error in errors) + + +def test_keycloak_26_profile_uses_the_closed_policy_representation() -> None: + """The Admin API rejects a string DISABLED; null is Keycloak 26's closed mode.""" + validator = _validator_module() + profile = deepcopy(_user_profile()) + + assert "unmanagedAttributePolicy" not in profile + assert {"username", "email", "firstName", "lastName"} <= { + item["name"] for item in profile["attributes"] + } + + profile["unmanagedAttributePolicy"] = "ENABLED" + + errors = validator.validate_user_profile(profile) + + assert any("must omit unmanagedAttributePolicy" in error for error in errors) + + def test_reusable_client_template_does_not_name_naruon_host() -> None: """The generic RP template stays portable across ecosystem products.""" template = _client(_realm(), "ecosystem-rp-template") diff --git a/tests/test_documentation_contract.py b/tests/test_documentation_contract.py index 47ef4cd..21abf99 100644 --- a/tests/test_documentation_contract.py +++ b/tests/test_documentation_contract.py @@ -32,6 +32,7 @@ "0006-user-operation-lock.md", "0007-automation-authority.md", "0008-keyverse-rp-authorization-boundary.md", + "0009-lineageweave-account-derived-rp-claims.md", ) From 6e96ff0e604e5c7d38b30db7d99a6508943cc01a Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 14 Aug 2026 01:35:08 +0900 Subject: [PATCH 04/70] Run Keycloak image as non-root --- deploy/keycloak/Dockerfile | 1 + docs/adr/0001-keycloak-hub.md | 9 +++++++++ .../tests/test_deployment_contracts.py | 1 + 3 files changed, 11 insertions(+) diff --git a/deploy/keycloak/Dockerfile b/deploy/keycloak/Dockerfile index 01c286c..b2c1523 100644 --- a/deploy/keycloak/Dockerfile +++ b/deploy/keycloak/Dockerfile @@ -4,3 +4,4 @@ FROM quay.io/keycloak/keycloak:26.3.2@sha256:98fab020a3a490aba0978f237e2a06cd0ea COPY cwl-realm.json /opt/keycloak/data/import/cwl-realm.json COPY lineageweave-user-profile.json /opt/keycloak/lineageweave-user-profile.json COPY --chmod=755 reconcile-lineageweave-user-profile.sh /opt/keycloak/reconcile-lineageweave-user-profile.sh +USER 1000 diff --git a/docs/adr/0001-keycloak-hub.md b/docs/adr/0001-keycloak-hub.md index 4eef5cc..d4ebfb5 100644 --- a/docs/adr/0001-keycloak-hub.md +++ b/docs/adr/0001-keycloak-hub.md @@ -16,3 +16,12 @@ key to the same filename. A container health check alone is insufficient: it can be healthy while the intended realm was never imported. Deployment acceptance therefore verifies the realm discovery endpoint, and a static deployment contract locks the filename mapping in both packaging paths. + +## Keycloak runtime-user invariant + +The derivative image must explicitly run as the non-root UID supplied by the +pinned Keycloak base image. Build-time file copies remain readable and +executable by that runtime user, while the Keycloak server and the post-import +profile reconciliation script do not receive root authority. The deployment +contract locks `USER 1000`, and acceptance also inspects a locally built image +before it can satisfy the image-security gate. diff --git a/services/account_unification/tests/test_deployment_contracts.py b/services/account_unification/tests/test_deployment_contracts.py index 3e43adc..16a50e0 100644 --- a/services/account_unification/tests/test_deployment_contracts.py +++ b/services/account_unification/tests/test_deployment_contracts.py @@ -57,6 +57,7 @@ def test_keycloak_import_packages_realm_and_profile_contracts() -> None: assert "COPY cwl-realm.json /opt/keycloak/data/import/cwl-realm.json" in dockerfile assert "COPY lineageweave-user-profile.json" in dockerfile assert "COPY --chmod=755 reconcile-lineageweave-user-profile.sh" in dockerfile + assert "\nUSER 1000\n" in dockerfile bootstrap_script = ( root / "deploy" / "keycloak" / "reconcile-lineageweave-user-profile.sh" ).read_text(encoding="utf-8") From cf4dbb9d708a8807dcbdebdbd415aaa545fc956b Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 14 Aug 2026 02:25:03 +0900 Subject: [PATCH 05/70] Harden LineageWeave account claim deployment --- .github/workflows/ci.yml | 3 + .../workflows/hourly-product-development.yml | 9 +- CHANGELOG.md | 3 + README.md | 5 + deploy/keycloak/README.md | 39 +++ .../keycloak/lineageweave-user-profile.json | 6 + docker-compose.yml | 2 + docs/TRACEABILITY.md | 4 +- ...-lineageweave-account-derived-rp-claims.md | 36 ++- .../doctoring/oidc-rp-claim-mapper-profile.md | 14 + scripts/validate_realm.py | 24 +- .../tests/test_deployment_contracts.py | 5 + .../tests/test_realm_policy.py | 57 +++- .../tests/test_validate_realm.py | 282 ++++++++++++++++++ 14 files changed, 463 insertions(+), 26 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 96f6d41..7a05705 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -42,6 +42,9 @@ jobs: run: | uv run coverage run --branch --source=app -m pytest -q uv run coverage report --show-missing --fail-under=100 + uv run coverage erase + uv run coverage run --branch -m pytest -q tests/test_validate_realm.py + uv run coverage report --include='*/scripts/validate_realm.py' --show-missing --fail-under=100 - name: Build distribution run: uv build --out-dir dist diff --git a/.github/workflows/hourly-product-development.yml b/.github/workflows/hourly-product-development.yml index 7ff0e2f..e5c9257 100644 --- a/.github/workflows/hourly-product-development.yml +++ b/.github/workflows/hourly-product-development.yml @@ -498,9 +498,9 @@ jobs: install -d -m 0750 "$agent_workspace" "$agent_home" "$agent_home/tmp" git archive HEAD | tar -x -C "$agent_workspace" - cat >"${agent_workspace}/opencode.json" <<'CONFIG' + cat >"${agent_workspace}/opencode.json" </dev/null 2>&1 || true successful_workspace="$agent_workspace" @@ -739,6 +739,9 @@ jobs: uv run coverage erase uv run coverage run --branch --source=app -m pytest -q uv run coverage report --show-missing --fail-under=100 + uv run coverage erase + uv run coverage run --branch -m pytest -q tests/test_validate_realm.py + uv run coverage report --include='*/scripts/validate_realm.py' --show-missing --fail-under=100 uv build --out-dir dist ) python scripts/validate_realm.py deploy/keycloak/cwl-realm.json diff --git a/CHANGELOG.md b/CHANGELOG.md index 3b77608..0c40e76 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -59,6 +59,9 @@ Keep a Changelog, and releases use semantic versioning. ### Changed +- The Helm realm-import operator runbook now migrates the legacy + `realm-cwl.json` ConfigMap key to `cwl-realm.json` before rollout, preserving + a rollback copy and requiring post-rollout realm discovery verification. - Account-derived OIDC claim mappers are now limited to the ADR-0009 `lineageweave-web` profile, and a non-string observed mapper type is treated as reconciliation drift rather than causing an exception. Operator guides now diff --git a/README.md b/README.md index 11c81f9..1bcb284 100644 --- a/README.md +++ b/README.md @@ -71,6 +71,11 @@ The stack imports the **passwordless-first** realm at first start WebAuthn passwordless authenticator and **no password authenticator**, plus `registrationAllowed:false` / `resetPasswordAllowed:false`. +For Helm installations created with the former `realm-cwl.json` ConfigMap key, +perform the zero-gap key migration in +[`deploy/keycloak/README.md`](deploy/keycloak/README.md#helm-configmap-key-migration) +before upgrading the chart. + ### Register external federation The portable realm contains no employer ADFS, LDAP/AD source, or other diff --git a/deploy/keycloak/README.md b/deploy/keycloak/README.md index aa67021..3b5bee9 100644 --- a/deploy/keycloak/README.md +++ b/deploy/keycloak/README.md @@ -58,6 +58,45 @@ URLs or invalid placeholder LDAP distinguished names. than 900 seconds; - committed client secrets are placeholders only. +## Helm ConfigMap key migration + +Older Helm installations used the ConfigMap data key `realm-cwl.json`. The +current chart requires the source key `cwl-realm.json` and mounts it at the +Keycloak-required target filename of the same name. Add the new key **before** +upgrading the StatefulSet so an existing Pod never references a missing +ConfigMap item. + +```bash +NAMESPACE=identity +RELEASE=cwl-idp +CONFIG_MAP=cwl-idp-realm + +# Keep a rollback copy of the dedicated realm-import ConfigMap. +kubectl -n "$NAMESPACE" get configmap "$CONFIG_MAP" -o yaml \ + > "${CONFIG_MAP}.before-cwl-realm.yaml" + +# Server-side apply adds the new data key without deleting the legacy key first. +kubectl -n "$NAMESPACE" create configmap "$CONFIG_MAP" \ + --from-file=cwl-realm.json=deploy/keycloak/cwl-realm.json \ + --dry-run=client -o yaml \ + | kubectl -n "$NAMESPACE" apply --server-side \ + --field-manager=cwl-idp-realm-migration -f - + +helm upgrade "$RELEASE" helm/cwl-idp -n "$NAMESPACE" \ + --set keycloak.realmImport.configMapName="$CONFIG_MAP" \ + --set keycloak.realmImport.fileName=cwl-realm.json +kubectl -n "$NAMESPACE" rollout status statefulset/"${RELEASE}-keycloak" + +# Only after the new StatefulSet is healthy may the obsolete source key go. +kubectl -n "$NAMESPACE" patch configmap "$CONFIG_MAP" --type=json \ + --patch='[{"op":"remove","path":"/data/realm-cwl.json"}]' +``` + +This ConfigMap is dedicated to realm import. If a deployment added unrelated +keys, preserve or relocate them under its own ownership before the migration. +Verify the `cwl` realm discovery endpoint after rollout; container health alone +does not prove import succeeded. + ## RP clients `ecosystem-rp-template` is a confidential PKCE S256 blueprint. It uses the diff --git a/deploy/keycloak/lineageweave-user-profile.json b/deploy/keycloak/lineageweave-user-profile.json index 74f539a..f2b5bc0 100644 --- a/deploy/keycloak/lineageweave-user-profile.json +++ b/deploy/keycloak/lineageweave-user-profile.json @@ -79,6 +79,9 @@ "max": "64" } }, + "required": { + "roles": ["admin"] + }, "permissions": { "view": ["admin"], "edit": ["admin"] @@ -93,6 +96,9 @@ "max": "64" } }, + "required": { + "roles": ["admin"] + }, "permissions": { "view": ["admin"], "edit": ["admin"] diff --git a/docker-compose.yml b/docker-compose.yml index afe107f..5d2a6bc 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -134,6 +134,8 @@ services: depends_on: idp_engine: condition: service_healthy + idp_profile_bootstrap: + condition: service_completed_successfully healthcheck: test: ["CMD", "python", "-m", "app.healthcheck"] interval: 15s diff --git a/docs/TRACEABILITY.md b/docs/TRACEABILITY.md index ec8c4d2..b06bb7b 100644 --- a/docs/TRACEABILITY.md +++ b/docs/TRACEABILITY.md @@ -1,7 +1,7 @@ # Keyverse Requirements and Evidence Traceability **Status:** Accepted cross-cutting baseline -**Last reviewed:** 2026-08-13 +**Last reviewed:** 2026-08-14 | Requirement / decision | Standards / authoritative basis | Source/evidence boundary | Maturity | |---|---|---|---| @@ -14,7 +14,7 @@ | LDAPS directory profile | LDAP RFC 4511–4515 + Keycloak component docs | directory preflight/reconciliation tests | implemented-main | | secret-free RP desired state | OAuth/OIDC/PKCE/Keycloak client docs | RP preflight/reconciliation/integrity tests | implemented-main | | RP audience/role/org/workspace mapper profile | OIDC/JWT audience + Keycloak mapper docs | PR #72 protected-main source/tests; downstream RP acceptance remains required | implemented-main | -| LineageWeave account-derived RP claims | ADR-0009; Keycloak Protocol Mappers and post-import declarative user profile | scalar, admin-managed account-attribute policy plus Compose profile reconciliation/template tests; real account, Keyverse apply, and downstream ABAC/RBAC acceptance remain required | accepted-contract | +| LineageWeave account-derived RP claims | ADR-0009; Keycloak Protocol Mappers and post-import declarative user profile | scalar, administrator-required account attributes; exact validator statement/branch coverage; Compose profile reconciliation/template tests; real account, Keyverse apply, and downstream ABAC/RBAC acceptance remain required | accepted-contract | | merge/SCIM PUT shared operation lock | concurrency/data-integrity decision; ADR-0006 | merge + full-replacement lock/concurrency tests | implemented-main | | SCIM PATCH active=false shared-lock parity | ADR-0006 boundary | current PATCH source has no shared-lock proof | gap-not-claimed | | intent before mutation, receipt after re-observation | desired-state/recovery decision | federation/directory/RP reconciliation tests | implemented-main | diff --git a/docs/adr/0009-lineageweave-account-derived-rp-claims.md b/docs/adr/0009-lineageweave-account-derived-rp-claims.md index c279496..2f19e35 100644 --- a/docs/adr/0009-lineageweave-account-derived-rp-claims.md +++ b/docs/adr/0009-lineageweave-account-derived-rp-claims.md @@ -41,20 +41,24 @@ The Keyverse post-import declarative user profile declares `org` and `workspace` as product authorization attributes, alongside the Keycloak built-in account attributes required because its Admin API replaces the whole profile rather than patching it. Both product attributes are scalar, maximum -64 characters, and visible/editable only to administrators. In the pinned -Keycloak 26.3.2 runtime, the closed unmanaged-attribute policy is represented -by an omitted/null value; its enum does not accept the documented `DISABLED` -string, and its implementation denies unmanaged attributes when that value is -null. Keycloak's realm-import representation does not accept this profile, so -a one-shot Compose bootstrap reconciles it only after the realm is healthy. -This keeps the issuer from silently accepting arbitrary account metadata while -preserving operators' ability to assign the two reviewed ABAC dimensions. +64 characters, visible/editable only to administrators, and required with +`{"roles":["admin"]}`. The administrative requiredness is deliberate: an +end user cannot repair an attribute that the same policy makes +administrator-managed. In the pinned Keycloak 26.3.2 runtime, the closed +unmanaged-attribute policy is represented by an omitted/null value; its enum +does not accept the documented `DISABLED` string, and its implementation denies +unmanaged attributes when that value is null. Keycloak's realm-import +representation does not accept this profile, so a one-shot Compose bootstrap +reconciles it only after the realm is healthy. This keeps the issuer from +silently accepting arbitrary account metadata while preserving operators' +ability to assign the two reviewed ABAC dimensions. The receiving application must validate issuer, signature/algorithm, expiry, -subject, and audience before reading these claims. It must bind `org` and -`workspace` to the requested resource before applying recognized client roles. -A green Keyverse preflight or apply receipt is not controlled login or -authorization evidence. +subject, and audience before reading these claims. It must reject a missing, +empty, or non-scalar `org` or `workspace` claim before any tenant/resource ABAC +or recognized-role RBAC decision, then bind both values to the requested +resource. A green Keyverse preflight or apply receipt is not controlled login +or authorization evidence. ```mermaid flowchart LR @@ -83,8 +87,9 @@ flowchart LR ## Consequences - Identity operators must provision a real Keyverse account with the two named - administrator-managed attributes and an allowed `lineageweave-web` client - role before user routing. + administrator-required attributes and an allowed `lineageweave-web` client + role before user routing; a missing attribute is a failed provisioning state, + not a downstream authorization default. - Account and role changes take effect through Keycloak session/token lifecycle; operators must test downgrade and revocation behavior in controlled runtime acceptance. @@ -111,6 +116,9 @@ claim. Keycloak Project. (2026). *Protocol mappers*. Retrieved August 13, 2026, from https://www.keycloak.org/admin-api/protocol-mappers +Keycloak Project. (2026). *Server Administration Guide* (User profile). +Retrieved August 14, 2026, from https://www.keycloak.org/docs/latest/server_admin/ + Lodderstedt, T., Bradley, J., Labunets, A., & Fett, D. (2025). *Best current practice for OAuth 2.0 security* (RFC 9700). Internet Engineering Task Force. https://doi.org/10.17487/RFC9700 diff --git a/docs/doctoring/oidc-rp-claim-mapper-profile.md b/docs/doctoring/oidc-rp-claim-mapper-profile.md index 82104df..189fa62 100644 --- a/docs/doctoring/oidc-rp-claim-mapper-profile.md +++ b/docs/doctoring/oidc-rp-claim-mapper-profile.md @@ -68,6 +68,17 @@ Keycloak documents these mapper IDs and their configuration properties. Keyverse intentionally rejects every other user attribute, role source, aggregation, group, script, audience, claim name, and destination. +### Account-profile requiredness + +Keycloak's declarative user profile permits a required role of `admin` or +`user`. The LineageWeave `org` and `workspace` attributes use +`{"roles":["admin"]}` because the same profile makes those fields viewable and +editable only in administrator context. A user-context requirement would direct +an end user to repair attributes they cannot edit. The receiving application is +independent of this provisioning workflow: after normal token verification, it +rejects an absent, empty, or non-scalar account dimension before tenant/resource +ABAC and bounded RBAC run. + ## Stricter Keyverse product policy The product policy is intentionally narrower than the vendor representation: @@ -163,5 +174,8 @@ Distribution 26.x API). https://www.keycloak.org/docs-api/latest/javadocs/org/ke Keycloak Project. (2026). *Protocol mappers*. Retrieved August 13, 2026, from https://www.keycloak.org/admin-api/protocol-mappers +Keycloak Project. (2026). *Server Administration Guide* (User profile). +Retrieved August 14, 2026, from https://www.keycloak.org/docs/latest/server_admin/ + OpenID Foundation. (2023). *OpenID Connect Core 1.0 incorporating errata set 2*. https://openid.net/specs/openid-connect-core-1_0.html diff --git a/scripts/validate_realm.py b/scripts/validate_realm.py index c423c35..e4d36ba 100644 --- a/scripts/validate_realm.py +++ b/scripts/validate_realm.py @@ -248,11 +248,17 @@ def validate_user_profile(profile: dict) -> list[str]: attribute = attributes.get(name) if not isinstance(attribute, dict): errors.append(f"user profile must define '{name}'") - elif attribute.get("multivalued") is not False: + continue + if attribute.get("multivalued") is not False: errors.append(f"user profile '{name}' must be scalar") - elif attribute.get("permissions") != {"view": ["admin"], "edit": ["admin"]}: + if attribute.get("permissions") != {"view": ["admin"], "edit": ["admin"]}: errors.append(f"user profile '{name}' must be admin-managed") - elif attribute.get("validations", {}).get("length", {}).get("max") != "64": + if attribute.get("required") != {"roles": ["admin"]}: + errors.append(f"user profile '{name}' must require administrators") + validations = attribute.get("validations") + length = validations.get("length") if isinstance(validations, dict) else None + maximum = length.get("max") if isinstance(length, dict) else None + if not (maximum == "64" or (type(maximum) is int and maximum == 64)): errors.append(f"user profile '{name}' must have a maximum length of 64") return errors @@ -273,7 +279,13 @@ def _dollar_keys(node: object, prefix: str = "") -> list[str]: def main(argv: list[str]) -> int: - """Run realm validation as a command-line check.""" + """Run realm validation with an optional explicit user-profile artifact.""" + if len(argv) > 3: + print( + "USAGE: validate_realm.py [realm_path] [user_profile_path]", + file=sys.stderr, + ) + return 1 path = ( Path(argv[1]) if len(argv) > 1 @@ -286,7 +298,9 @@ def main(argv: list[str]) -> int: return 1 errors = validate(realm) - profile_path = path.with_name(USER_PROFILE_FILENAME) + profile_path = ( + Path(argv[2]) if len(argv) > 2 else path.with_name(USER_PROFILE_FILENAME) + ) try: profile = json.loads(profile_path.read_text(encoding="utf-8")) except (OSError, json.JSONDecodeError) as exc: diff --git a/services/account_unification/tests/test_deployment_contracts.py b/services/account_unification/tests/test_deployment_contracts.py index 16a50e0..2aa82a4 100644 --- a/services/account_unification/tests/test_deployment_contracts.py +++ b/services/account_unification/tests/test_deployment_contracts.py @@ -65,6 +65,11 @@ def test_keycloak_import_packages_realm_and_profile_contracts() -> None: profile = compose["services"]["idp_profile_bootstrap"] assert profile["depends_on"]["idp_engine"]["condition"] == "service_healthy" assert profile["entrypoint"] == ["/opt/keycloak/reconcile-lineageweave-user-profile.sh"] + service = compose["services"]["account_unification_service"] + assert ( + service["depends_on"]["idp_profile_bootstrap"]["condition"] + == "service_completed_successfully" + ) keycloak = ( root / "helm" / "cwl-idp" / "templates" / "keycloak.yaml" diff --git a/services/account_unification/tests/test_realm_policy.py b/services/account_unification/tests/test_realm_policy.py index 822e5af..bb44d99 100644 --- a/services/account_unification/tests/test_realm_policy.py +++ b/services/account_unification/tests/test_realm_policy.py @@ -100,13 +100,16 @@ def test_public_client_token_lifespan_is_bounded() -> None: ("validations", {"length": {"max": "65"}}, "maximum length of 64"), ], ) +@pytest.mark.parametrize("attribute_name", ("org", "workspace")) def test_product_account_attributes_are_constrained( - field: str, value: object, expected: str + attribute_name: str, field: str, value: object, expected: str ) -> None: """Authorization attributes stay scalar, bounded, and administrator-managed.""" validator = _validator_module() profile = deepcopy(_user_profile()) - attribute = next(item for item in profile["attributes"] if item["name"] == "org") + attribute = next( + item for item in profile["attributes"] if item["name"] == attribute_name + ) attribute[field] = value errors = validator.validate_user_profile(profile) @@ -114,6 +117,56 @@ def test_product_account_attributes_are_constrained( assert any(expected in error for error in errors) +@pytest.mark.parametrize("attribute_name", ("org", "workspace")) +@pytest.mark.parametrize( + "required", + ({}, {"roles": ["user"]}, {"roles": ["admin", "user"]}), +) +def test_product_account_attributes_require_administrator_assignment( + attribute_name: str, required: dict[str, object] +) -> None: + """Product ABAC attributes cannot be omitted in administrator-managed updates.""" + validator = _validator_module() + profile = deepcopy(_user_profile()) + attribute = next( + item for item in profile["attributes"] if item["name"] == attribute_name + ) + attribute["required"] = required + + errors = validator.validate_user_profile(profile) + + assert any("must require administrators" in error for error in errors) + + +def test_product_account_attribute_policy_reports_every_independent_violation() -> None: + """One malformed attribute shows every repair an operator must make.""" + validator = _validator_module() + profile = deepcopy(_user_profile()) + attribute = next(item for item in profile["attributes"] if item["name"] == "org") + attribute["multivalued"] = True + attribute["permissions"] = {"view": ["admin"], "edit": ["admin", "user"]} + attribute["required"] = {"roles": ["user"]} + attribute["validations"] = {"length": {"max": 65}} + + errors = validator.validate_user_profile(profile) + + assert any("must be scalar" in error for error in errors) + assert any("must be admin-managed" in error for error in errors) + assert any("must require administrators" in error for error in errors) + assert any("maximum length of 64" in error for error in errors) + + +def test_product_account_attribute_policy_accepts_keycloak_numeric_length_limit() -> None: + """Keycloak's documented numeric JSON length maximum remains valid.""" + validator = _validator_module() + profile = deepcopy(_user_profile()) + for attribute in profile["attributes"]: + if attribute["name"] in {"org", "workspace"}: + attribute["validations"]["length"]["max"] = 64 + + assert validator.validate_user_profile(profile) == [] + + def test_product_account_attributes_cannot_be_omitted() -> None: """Every issued product claim has an explicit Keycloak account source.""" validator = _validator_module() diff --git a/services/account_unification/tests/test_validate_realm.py b/services/account_unification/tests/test_validate_realm.py index e833950..032b94e 100644 --- a/services/account_unification/tests/test_validate_realm.py +++ b/services/account_unification/tests/test_validate_realm.py @@ -2,13 +2,23 @@ from __future__ import annotations import importlib.util +import json +import runpy +import sys from pathlib import Path +import pytest + def _script_path() -> Path: return Path(__file__).resolve().parents[3] / "scripts" / "validate_realm.py" +def _repository_root() -> Path: + """Return the repository root from the account-unification tests.""" + return _script_path().parents[1] + + def _load_validate_realm(): script_path = _script_path() spec = importlib.util.spec_from_file_location("validate_realm", script_path) @@ -19,6 +29,21 @@ def _load_validate_realm(): return module +def _write_committed_policy_artifacts(realm_path: Path, profile_path: Path) -> None: + """Copy the reviewed realm and user profile into isolated CLI inputs.""" + root = _repository_root() + realm_path.write_text( + (root / "deploy" / "keycloak" / "cwl-realm.json").read_text(encoding="utf-8"), + encoding="utf-8", + ) + profile_path.write_text( + (root / "deploy" / "keycloak" / "lineageweave-user-profile.json").read_text( + encoding="utf-8" + ), + encoding="utf-8", + ) + + def test_realm_validation_errors_do_not_echo_sensitive_authenticator_terms(): validator = _load_validate_realm() realm = { @@ -69,3 +94,260 @@ def test_keycloak_authenticator_ids_are_preserved_without_log_taint_literals(): assert '"webauthn-authenticator-passwordless"' not in source assert '"auth-password-form"' not in source assert '"auth-username-password-form"' not in source + + +def test_validator_helpers_cover_missing_flows_cycles_and_token_inputs() -> None: + """Nested export flows and malformed lifespan values stay fail-closed.""" + validator = _load_validate_realm() + realm = { + "authenticationFlows": [ + { + "alias": "outer", + "authenticationExecutions": [ + {"authenticator": "first-factor"}, + {"flowAlias": "inner"}, + ], + }, + { + "alias": "inner", + "authenticationExecutions": [ + {"authenticator": "second-factor"}, + {"flowAlias": "outer"}, + ], + }, + ] + } + + assert validator._executions(realm, "missing") == [] + assert validator._all_authenticators(realm, "outer") == { + "first-factor", + "second-factor", + } + assert validator._public_token_lifespan({"attributes": {}}) is None + assert validator._public_token_lifespan( + {"attributes": {"access.token.lifespan": []}} + ) == -1 + assert validator._public_token_lifespan( + {"attributes": {"access.token.lifespan": "10.5"}} + ) == -1 + assert validator._public_token_lifespan( + {"attributes": {"access.token.lifespan": " 10 "}} + ) == 10 + + +def test_realm_validator_reports_independent_security_drift() -> None: + """A production-like export reports every independently dangerous drift.""" + validator = _load_validate_realm() + realm = json.loads( + (_repository_root() / "deploy/keycloak/cwl-realm.json").read_text( + encoding="utf-8" + ) + ) + clients = {client["clientId"]: client for client in realm["clients"]} + template = clients["ecosystem-rp-template"] + service_client = clients["account-unification-svc"] + naruon = clients["naruon-web"] + basic = next(scope for scope in realm["clientScopes"] if scope["name"] == "basic") + + realm["realm"] = "other" + realm["enabled"] = False + realm["registrationAllowed"] = True + realm["verifyEmail"] = True + realm.pop("smtpServer", None) + realm["$schema"] = "not-importable" + template["implicitFlowEnabled"] = True + template["attributes"]["pkce.code.challenge.method"] = "plain" + service_client["serviceAccountsEnabled"] = False + service_client["secret"] = "committed-secret" + basic["protocolMappers"] = [] + realm["defaultDefaultClientScopes"] = [ + scope for scope in realm["defaultDefaultClientScopes"] if scope != "basic" + ] + naruon["publicClient"] = False + naruon["implicitFlowEnabled"] = True + naruon["attributes"]["pkce.code.challenge.method"] = "plain" + naruon["attributes"]["access.token.lifespan"] = "901" + naruon["protocolMappers"] = [ + mapper + for mapper in naruon["protocolMappers"] + if mapper.get("protocolMapper") != "oidc-audience-mapper" + and mapper.get("config", {}).get("claim.name") != "workspace" + ] + naruon["defaultClientScopes"] = [ + scope for scope in naruon["defaultClientScopes"] if scope != "basic" + ] + + errors = set(validator.validate(realm)) + + assert { + "realm name must be 'cwl'", + "realm must be enabled", + "IdP-hosted registration must remain disabled; use the headless registration API", + "verifyEmail requires a realm smtpServer; configure SMTP or disable verifyEmail", + "RP template must not enable the implicit flow (OAuth 2.1)", + "RP template must require PKCE S256", + "account-unification-svc must enable service accounts", + "client 'account-unification-svc' commits a non-placeholder secret", + "'$'-annotation key '$schema' breaks Keycloak 26 realm import", + "client scope 'basic' must include the oidc-sub-mapper", + "'basic' must be a realm default client scope", + "naruon-web must be a public (PKCE) client", + "naruon-web must not enable the implicit flow", + "naruon-web must require PKCE S256", + "naruon-web access.token.lifespan must be an integer at or below 900 seconds", + "naruon-web must include an audience mapper", + "naruon-web must carry the hardcoded 'workspace' claim naruon's session contract requires", + "naruon-web must assign the 'basic' default scope", + } <= errors + + +def test_realm_validator_reports_missing_flow_and_required_clients() -> None: + """A malformed export cannot hide missing execution or relying-party policy.""" + validator = _load_validate_realm() + source = (_repository_root() / "deploy/keycloak/cwl-realm.json").read_text( + encoding="utf-8" + ) + + no_browser = json.loads(source) + no_browser.pop("browserFlow") + assert "browserFlow must be set" in validator.validate(no_browser) + + empty_browser = json.loads(source) + empty_browser["browserFlow"] = "empty-browser" + empty_browser["authenticationFlows"].append( + {"alias": "empty-browser", "authenticationExecutions": []} + ) + assert "browserFlow 'empty-browser' has no executions defined" in validator.validate( + empty_browser + ) + + required_clients_missing = json.loads(source) + required_clients_missing["clients"] = [ + client + for client in required_clients_missing["clients"] + if client["clientId"] + not in {"ecosystem-rp-template", "account-unification-svc"} + ] + errors = set(validator.validate(required_clients_missing)) + assert "OIDC RP client template 'ecosystem-rp-template' is missing" in errors + assert "service-account client 'account-unification-svc' is missing" in errors + + +def test_user_profile_validator_reports_all_administrator_attribute_drift() -> None: + """Closed account claims stay scalar, admin-controlled, and required.""" + validator = _load_validate_realm() + profile = json.loads( + ( + _repository_root() / "deploy/keycloak/lineageweave-user-profile.json" + ).read_text(encoding="utf-8") + ) + profile["unmanagedAttributePolicy"] = "ENABLED" + profile["attributes"] = [ + attribute + for attribute in profile["attributes"] + if attribute["name"] not in {"email", "workspace"} + ] + org = next(attribute for attribute in profile["attributes"] if attribute["name"] == "org") + org["multivalued"] = True + org["permissions"] = {"view": ["admin"]} + org["required"] = {} + org["validations"] = {} + + errors = set(validator.validate_user_profile(profile)) + + assert { + "user profile must omit unmanagedAttributePolicy so Keycloak 26 disables unmanaged attributes", + "user profile must retain Keycloak built-in account attributes when the Admin API replaces the complete profile", + "user profile 'org' must be scalar", + "user profile 'org' must be admin-managed", + "user profile 'org' must require administrators", + "user profile 'org' must have a maximum length of 64", + "user profile must define 'workspace'", + } <= errors + + +def test_main_accepts_an_explicit_profile_outside_the_realm_directory( + tmp_path: Path, capsys: pytest.CaptureFixture[str] +) -> None: + """Arbitrary realm validation can name its reviewed sibling-independent profile.""" + validator = _load_validate_realm() + realm_path = tmp_path / "exported-realm.json" + profile_path = tmp_path / "reviewed-profile.json" + _write_committed_policy_artifacts(realm_path, profile_path) + + result = validator.main(["validate_realm.py", str(realm_path), str(profile_path)]) + + assert result == 0 + assert f"OK: {realm_path}" in capsys.readouterr().out + + +def test_main_names_an_explicit_invalid_profile_in_its_error( + tmp_path: Path, capsys: pytest.CaptureFixture[str] +) -> None: + """A malformed supplied profile cannot be hidden by an implicit sibling lookup.""" + validator = _load_validate_realm() + realm_path = tmp_path / "exported-realm.json" + profile_path = tmp_path / "reviewed-profile.json" + _write_committed_policy_artifacts(realm_path, profile_path) + profile_path.write_text("{", encoding="utf-8") + + result = validator.main(["validate_realm.py", str(realm_path), str(profile_path)]) + + assert result == 1 + stderr = capsys.readouterr().err + assert str(profile_path) in stderr + assert "cannot parse" in stderr + + +def test_main_rejects_ambiguous_extra_path_arguments( + tmp_path: Path, capsys: pytest.CaptureFixture[str] +) -> None: + """The validator never silently ignores a second profile-like argument.""" + validator = _load_validate_realm() + realm_path = tmp_path / "cwl-realm.json" + profile_path = tmp_path / "lineageweave-user-profile.json" + _write_committed_policy_artifacts(realm_path, profile_path) + + result = validator.main( + ["validate_realm.py", str(realm_path), str(profile_path), "unexpected.json"] + ) + + assert result == 1 + assert "USAGE" in capsys.readouterr().err + + +def test_main_reports_realm_parse_and_profile_policy_errors( + tmp_path: Path, capsys: pytest.CaptureFixture[str] +) -> None: + """CLI users receive a bounded failure for unreadable and invalid artifacts.""" + validator = _load_validate_realm() + malformed_realm = tmp_path / "malformed-realm.json" + malformed_realm.write_text("{", encoding="utf-8") + + assert validator.main(["validate_realm.py", str(malformed_realm)]) == 1 + assert f"cannot parse {malformed_realm}" in capsys.readouterr().err + + realm_path = tmp_path / "cwl-realm.json" + profile_path = tmp_path / "lineageweave-user-profile.json" + _write_committed_policy_artifacts(realm_path, profile_path) + profile_path.write_text("{}", encoding="utf-8") + + assert validator.main(["validate_realm.py", str(realm_path)]) == 1 + stderr = capsys.readouterr().err + assert f"INVALID: {realm_path}" in stderr + assert "user profile must define 'org'" in stderr + + +def test_script_entrypoint_honors_the_explicit_profile_contract( + tmp_path: Path, monkeypatch: pytest.MonkeyPatch +) -> None: + """The executable entrypoint preserves the tested main-function behavior.""" + realm_path = tmp_path / "exported-realm.json" + profile_path = tmp_path / "reviewed-profile.json" + _write_committed_policy_artifacts(realm_path, profile_path) + monkeypatch.setattr(sys, "argv", [str(_script_path()), str(realm_path), str(profile_path)]) + + with pytest.raises(SystemExit) as raised: + runpy.run_path(str(_script_path()), run_name="__main__") + + assert raised.value.code == 0 From 4ea8fbc42a7f38330a947a72b519568027cb06b1 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 14 Aug 2026 19:02:26 +0900 Subject: [PATCH 06/70] build: refresh account-unification lockfile --- services/account_unification/uv.lock | 200 +++++++++++++++------------ 1 file changed, 115 insertions(+), 85 deletions(-) diff --git a/services/account_unification/uv.lock b/services/account_unification/uv.lock index 1ed80ca..bf57988 100644 --- a/services/account_unification/uv.lock +++ b/services/account_unification/uv.lock @@ -172,86 +172,116 @@ wheels = [ [[package]] name = "coverage" -version = "7.15.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/76/d0/55fe630f4cf94e3fcba868240fad8c8cdd1f764e2a932f8926347e6ec4cd/coverage-7.15.2.tar.gz", hash = "sha256:3df60dc267f0a2ca23cb7a9ab1109c62b9335ffbf519fcfe167157c28c09b81d", size = 927741, upload-time = "2026-07-15T18:56:19.558Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/7d/3a/54536704f507d4573bf9161c4d0dd3dd59b6d85e48c664e901b6844d8e33/coverage-7.15.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2f1ec6f304b156669cfde653b4e9a953f5de87e247ea02ac599bce0ab2744036", size = 221414, upload-time = "2026-07-15T18:53:51.941Z" }, - { url = "https://files.pythonhosted.org/packages/b6/d9/8ba925d29743e3577b21e4d8c11a702b76bc93c41e7fdfd1177af63d4b8d/coverage-7.15.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4d3361879d736f469f45723c11ea1a5bbdaf1f6928f0e632c940378b5aa9b660", size = 221913, upload-time = "2026-07-15T18:53:53.682Z" }, - { url = "https://files.pythonhosted.org/packages/09/54/a855f3aa0187f2b431ade4e4791b77b56282cfb5d201c83ec26a31b5b36a/coverage-7.15.2-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:c6a98d698f9e2c8008d0370ec7fc452ebfcc530002ae2d0061170d768b992589", size = 252332, upload-time = "2026-07-15T18:53:55.467Z" }, - { url = "https://files.pythonhosted.org/packages/8e/d3/13ac97b4370640ba3452fc8559b06cc2f479ce3ba4a0b632a73e44c38a7d/coverage-7.15.2-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:d50dd325e18ec25bfcc10cd7f99b04df1ab9ec76b0918c260e60817ad0643dee", size = 254243, upload-time = "2026-07-15T18:53:57.055Z" }, - { url = "https://files.pythonhosted.org/packages/88/83/5eca144942d8d0659d3f55176517f4a59cdc65eefd17146a0770935a3ebd/coverage-7.15.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:67d7602480a47bdf5b675635403625553ebaa70d5a62a657c035149fd401cea0", size = 256352, upload-time = "2026-07-15T18:53:58.83Z" }, - { url = "https://files.pythonhosted.org/packages/4e/ba/d3db2e01a50fc88cdb4c0f19542bcf6f61489e34dc9aa3538413e2459a38/coverage-7.15.2-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:cee0f89f4767a6057c8fbf168f8135f18be651300496086bd873e3189fed0487", size = 258313, upload-time = "2026-07-15T18:54:00.497Z" }, - { url = "https://files.pythonhosted.org/packages/78/b3/aba83416e9177df28e5186d856c19158c59fc0e7e814aaa61a4a2354ad1b/coverage-7.15.2-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a29ec5305a7335aacee2d799e3422e91e1c8a12474986e2b3b07e315c91be82f", size = 252449, upload-time = "2026-07-15T18:54:02.456Z" }, - { url = "https://files.pythonhosted.org/packages/6a/a5/4b00ecac0194431ab451b0f6710f8e2517d04cef60f821b14dec4637d575/coverage-7.15.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:48ccc6395958eda89093ecdc35644c86f23a8b23a7f4d44958812b721aad67c1", size = 254043, upload-time = "2026-07-15T18:54:04.072Z" }, - { url = "https://files.pythonhosted.org/packages/75/b6/cfa209b4313ee7f1b34da47efcd789ea51c024ad35af390e00f5a3c10a2e/coverage-7.15.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:81f382c5a94b434ec1f6da607edb904c76d7212e618cd4d1bc9f97bed4120ef5", size = 252107, upload-time = "2026-07-15T18:54:06.745Z" }, - { url = "https://files.pythonhosted.org/packages/36/67/e8cac5a6954038c98d7fe7eb9802afe7ab3ecb637bb7cc00e69b4148b56d/coverage-7.15.2-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:bbc808daf4f5cd567af8075ecc72d21c6dfef9a254709a621a84c217c935ebc0", size = 255873, upload-time = "2026-07-15T18:54:08.48Z" }, - { url = "https://files.pythonhosted.org/packages/2c/92/395cca9f330a86c3fe3471d73e2c102116c4c58fdc619dbbc125c6e93a54/coverage-7.15.2-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:a4c46b247b5d4b78f613bd89fea926d32b25c6cc61a50bd1e99ba310348f3dad", size = 251826, upload-time = "2026-07-15T18:54:10.083Z" }, - { url = "https://files.pythonhosted.org/packages/51/60/3e91b20295439652424f426b7086ec5bf4fbe3f604c73eda22b986c4fd6b/coverage-7.15.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:094dd37f3ef7b2da8b068b583d1f4c40f91c65197e16c52a71962d5d537fc5db", size = 252735, upload-time = "2026-07-15T18:54:11.878Z" }, - { url = "https://files.pythonhosted.org/packages/a5/eb/8c07839005e5e3c6b3877d3a6e2a80ce766589f31dd2b6882b78d59a7b8c/coverage-7.15.2-cp311-cp311-win32.whl", hash = "sha256:a63b9e190711134d581c4d703df5df09851b1acf99792c7aacbbe9f41f0283c9", size = 223500, upload-time = "2026-07-15T18:54:13.525Z" }, - { url = "https://files.pythonhosted.org/packages/2e/98/59d83c257cd59f0fbaf9d9ddb26b744a576760dfd1ae16e516408894a02b/coverage-7.15.2-cp311-cp311-win_amd64.whl", hash = "sha256:8bb9f4b4279187560796a4cdaca3b0a93dd97e48ee667df005f4ed9a97403688", size = 223973, upload-time = "2026-07-15T18:54:15.163Z" }, - { url = "https://files.pythonhosted.org/packages/ea/09/2d285c8bef5c4f695d120c1c96dc11715638aa8e134069f210bb6a62a9fe/coverage-7.15.2-cp311-cp311-win_arm64.whl", hash = "sha256:8c726b232659cbd2ae57ade46509eb068c9bd7a06df9fcbff6fe484870006934", size = 223519, upload-time = "2026-07-15T18:54:16.803Z" }, - { url = "https://files.pythonhosted.org/packages/6a/50/eb5bf42e531611a9f8d272556b1ed4de503f84a91413584094487cf69f8f/coverage-7.15.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:1adac78e5abc7c5438f7a209c9ca69d06542f0bf481d728b6989ea80b813fdf9", size = 221587, upload-time = "2026-07-15T18:54:18.439Z" }, - { url = "https://files.pythonhosted.org/packages/06/d1/da99af464c335d4e023a6efcd7ec30f63b88a43c93745154ab74ffb31cea/coverage-7.15.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b868acc62aa5de3be7a9d05c2333bf8359ca987e43f9cb30ff8fbda6a024ab73", size = 221943, upload-time = "2026-07-15T18:54:20.062Z" }, - { url = "https://files.pythonhosted.org/packages/5b/8a/13c42723d61ca447eafa18732e8141dd6a63f2732e1c7e1502c182dd88d7/coverage-7.15.2-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:6f6966fc30e6f06ca8f98fb0ce51eda6b111b3ee8d066a8b1ec9e77fa06ab55d", size = 253450, upload-time = "2026-07-15T18:54:21.765Z" }, - { url = "https://files.pythonhosted.org/packages/d7/29/99021303f98fbdcb63504b4d07bea4cc025b9b2dd907c4f07c85d50a0dab/coverage-7.15.2-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:68af907f595ab01a78f794932ff3bdf929c316d3000810d38dbc247129e26f8b", size = 256187, upload-time = "2026-07-15T18:54:23.4Z" }, - { url = "https://files.pythonhosted.org/packages/f9/a8/fd503715ed6ca9c5d742923aa5209257340b367a867b2ced0c7d4ba8a0b9/coverage-7.15.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:afa29e2eff3d5729267e2cb2fd4ce9d61c952932fb2694e34ccb5d9540c6a296", size = 257301, upload-time = "2026-07-15T18:54:25.183Z" }, - { url = "https://files.pythonhosted.org/packages/da/40/3f4b8fb409810036ebc2857d36adc0498c6e957b5df0290c5036b2e143f1/coverage-7.15.2-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:bbf44513ceb1589e31948e20eafbde9deaface90e1a1afa5f5f77b4423d17ce6", size = 259562, upload-time = "2026-07-15T18:54:27.204Z" }, - { url = "https://files.pythonhosted.org/packages/0b/8a/9bdffbef47db77cce3d6b02a28f7e919b19f0106c4b080c2c2246040f885/coverage-7.15.2-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:9deddf09eecb717b7f980414b43d90a5b22ff3967d2949ab29cb0aa83d9e9098", size = 253841, upload-time = "2026-07-15T18:54:29.134Z" }, - { url = "https://files.pythonhosted.org/packages/1b/1e/9031efde019d31a06646261fce6dfc5c3c74e951e27a71e5c9a424563178/coverage-7.15.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ae901f7e55ba405c84ee1cab3d3e962e4e871e4a2bcb9c90911adbd69b42ac5a", size = 255221, upload-time = "2026-07-15T18:54:31.142Z" }, - { url = "https://files.pythonhosted.org/packages/56/db/787acde872389fc84a9ef9d8cd1ccc658e391ab4cb5b28092a714426a394/coverage-7.15.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:a0f47002c6eeb7c280228467a4cb0cc15ca2103a8421b986b2d3ec04a0f9bd8b", size = 253366, upload-time = "2026-07-15T18:54:32.886Z" }, - { url = "https://files.pythonhosted.org/packages/2f/9b/6f57bc4b93c842eef1695f8cdaf2318e35e7ba54f5ba80d84be213ab7858/coverage-7.15.2-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:1cd7a5beb7af3e864a13b1f0fb26efd3695da43ef0daf71e586adfffaf34d5b2", size = 257434, upload-time = "2026-07-15T18:54:34.7Z" }, - { url = "https://files.pythonhosted.org/packages/88/26/b3186a21b2acc83e451118978905c81c7072c3333707804db09a78c096a2/coverage-7.15.2-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:97a5c5457a9fb1d6c4e06cfb5dc835871fbfb6a6a51addc9e925bdeff5ef7440", size = 252935, upload-time = "2026-07-15T18:54:36.548Z" }, - { url = "https://files.pythonhosted.org/packages/20/c2/c9f3376b2e717ea69ed7a6e9a5fcab968fb0b290db6cf4bd9a1fc7541b75/coverage-7.15.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0901cfe6c13bcd2302da4f83e884555d2a22bda6e4c476f09ef204ba20ca536e", size = 254807, upload-time = "2026-07-15T18:54:38.296Z" }, - { url = "https://files.pythonhosted.org/packages/f0/e1/dfc15401f4a8aaeb486e1ba3e9e3c40522a6e38bd0ecf0b3f29cb8082957/coverage-7.15.2-cp312-cp312-win32.whl", hash = "sha256:b171bdd71cb7ff792bf32e376173b0ace7e7963e7e57c58dfc42063a6a7174cd", size = 223641, upload-time = "2026-07-15T18:54:40.103Z" }, - { url = "https://files.pythonhosted.org/packages/91/40/81b6d809d320cd366ec5bdf8176575e897dcb8efe7fb4b489ef9e93e4d13/coverage-7.15.2-cp312-cp312-win_amd64.whl", hash = "sha256:582edc45c2040543fef83341be23c43024a3ab3ae0c2d8bc498a06282905ad40", size = 224172, upload-time = "2026-07-15T18:54:41.882Z" }, - { url = "https://files.pythonhosted.org/packages/ef/28/9f14ec438149f7de557f45518f09b4a7917b795cc37083aa7db482693f8c/coverage-7.15.2-cp312-cp312-win_arm64.whl", hash = "sha256:a638db90c61cd219aeee65e83a24fdaa57269a741ae0cf773309208ac862cee3", size = 223556, upload-time = "2026-07-15T18:54:43.674Z" }, - { url = "https://files.pythonhosted.org/packages/fc/d5/f8c838e6b7282976f7c918884b792df7a0c42c5bba5d99c60ad2d221d56d/coverage-7.15.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1121caa19159a38b5463eaae4b1e1fde81e525b15ecc5e000cd5b1a108f743a8", size = 221606, upload-time = "2026-07-15T18:54:45.448Z" }, - { url = "https://files.pythonhosted.org/packages/bf/37/97c926376364f66298cc44893b89cdf17b8bc406376497c4061ae4b8a8ff/coverage-7.15.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a300c6934e0989c327b9e8a1e110329da4641149f872bbe9f70168be66da76c1", size = 221982, upload-time = "2026-07-15T18:54:47.341Z" }, - { url = "https://files.pythonhosted.org/packages/b7/30/a36050a6e83c2135ee0776f452ca3948224befc6d7f26acecc082d0c106a/coverage-7.15.2-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:2617f8799d268fabdeef42a7e89ac3a23e1deee9025427db2df970f99a89a578", size = 252972, upload-time = "2026-07-15T18:54:49.2Z" }, - { url = "https://files.pythonhosted.org/packages/31/d3/06b5f1daf95f0f15ab05bd75f26ba5f3c8b33d0bb72f3aaa3cf41d1bad3a/coverage-7.15.2-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:7dc2950a2992cd676d35c20ae63522836deeb034f08874699d14068710af3dc1", size = 255569, upload-time = "2026-07-15T18:54:51.098Z" }, - { url = "https://files.pythonhosted.org/packages/81/1c/9afb3f8de2b8d36960391c48559a2e3ff96594b58099f115921549ea8d0d/coverage-7.15.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9e36686f7a442185db2400b3df171aac520869faf9deb59df687d28659eda2a6", size = 256806, upload-time = "2026-07-15T18:54:53.145Z" }, - { url = "https://files.pythonhosted.org/packages/64/d8/b989f96061a5e32d82fddd1b1b9ff48a7c8f8ae7606f0e80fd9de54b1e33/coverage-7.15.2-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7d29ca7bd67af6e12e74632d65f026eabc1364da5c254494cd914446a28a3ef7", size = 258936, upload-time = "2026-07-15T18:54:55.015Z" }, - { url = "https://files.pythonhosted.org/packages/b8/fa/f99771f5110457c7b511c1935ca49ddf288218eaa84322e028b9334146ae/coverage-7.15.2-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:db9c8438057e5b0f6a22a0af99c0c1d26b57fbbdbd1be5861ddb8f897fcc3a2d", size = 253178, upload-time = "2026-07-15T18:54:57.527Z" }, - { url = "https://files.pythonhosted.org/packages/f6/96/c098a6044d119c751ceede7be91035fa8310170ec24a6523aff72f0a5793/coverage-7.15.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:63022c4c8dec1d0342f05c3ede99842fe3d007689acc45e86f123a1746e4a026", size = 254934, upload-time = "2026-07-15T18:54:59.41Z" }, - { url = "https://files.pythonhosted.org/packages/b2/a2/1457b3a7a50c8d77500103b97a046db863e2f59a1cf6d2f814595f349885/coverage-7.15.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:6c0be82b4d4aa5b2704e08518e2252f3e3d110164bcca826816801052e48a7aa", size = 252898, upload-time = "2026-07-15T18:55:01.338Z" }, - { url = "https://files.pythonhosted.org/packages/6c/0e/76958874c471ecfcdde0d2b2747bb2c61bdbf34a40636f4ce9db9923e643/coverage-7.15.2-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4510fb9cdf6bb02dfa6af0be4a534b8102d086e22e4a33f8836df663da3d660d", size = 257056, upload-time = "2026-07-15T18:55:03.243Z" }, - { url = "https://files.pythonhosted.org/packages/7c/7c/3d7c4e3bf58baa40327dc7edc2272b17cf02299366d52763db1b0ca1556a/coverage-7.15.2-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:42ec3d989421b174a2ab607c1539f24127ad362757b7f1c0c0d7a2993f7eb37b", size = 252718, upload-time = "2026-07-15T18:55:05.029Z" }, - { url = "https://files.pythonhosted.org/packages/c8/b8/1cecffed9ce14fb25be9ba42d37b6bb61485c9a3ddd43cd3dde36b6087d8/coverage-7.15.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e8f91bce78e32343af184c3b7fa28fcf5a9e2641f4b6623d392038f804939188", size = 254490, upload-time = "2026-07-15T18:55:06.889Z" }, - { url = "https://files.pythonhosted.org/packages/6c/2c/42984561bc7f4c045dca67516a0c50ee5ef8d84352dbeb5559dc86c4823e/coverage-7.15.2-cp313-cp313-win32.whl", hash = "sha256:434e68d531858205895eb0d74b73d20b84260de426387d53c422a5acda2cf050", size = 223647, upload-time = "2026-07-15T18:55:08.941Z" }, - { url = "https://files.pythonhosted.org/packages/41/9f/39c7c9245efc583beddf89a87683574e663ed93637f3afb6cd7b88405676/coverage-7.15.2-cp313-cp313-win_amd64.whl", hash = "sha256:26c3b04a6377fd7c09800921fa934e3a17c0020439cd59df73e73ae1d4b6a78c", size = 224190, upload-time = "2026-07-15T18:55:10.789Z" }, - { url = "https://files.pythonhosted.org/packages/c7/de/3a2883cf8a213659280ef4b403059e17a9acaeb7fc7fd4105e1226ff2e6d/coverage-7.15.2-cp313-cp313-win_arm64.whl", hash = "sha256:3ed010aa1b69cda8e827aabfca9866216c980e2dca82ab9a78c5f83689964c8b", size = 223583, upload-time = "2026-07-15T18:55:12.678Z" }, - { url = "https://files.pythonhosted.org/packages/81/5f/aed265fd7a3551a394f36dfe41868aee709b7f95db4052205b4ad1563ac3/coverage-7.15.2-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:40f633c5c5fc783732f6312280122e859538fa24461235597c13d803ea9a108a", size = 221650, upload-time = "2026-07-15T18:55:14.527Z" }, - { url = "https://files.pythonhosted.org/packages/6b/2c/222ba12a545189017120f8eddfc1a0bd4616b47d5d4a8d99421edb2fe4c6/coverage-7.15.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:075560438765b7a2ef43bf7aa7758661b53d889df47f062a31bda6c1ade553a2", size = 221988, upload-time = "2026-07-15T18:55:16.674Z" }, - { url = "https://files.pythonhosted.org/packages/aa/38/304b5877ab46e6c290b4292cfcf3fe28245f0e5597cad7f6acc91fc7e0a4/coverage-7.15.2-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:25fd15dd40a0a2c51a500d664ca29053c09c3259d998407bf982b6e114696138", size = 253029, upload-time = "2026-07-15T18:55:18.856Z" }, - { url = "https://files.pythonhosted.org/packages/6c/58/821b533b8db9e44cf1d8a97bd525149ced40dde1d0093da02cb78e715244/coverage-7.15.2-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b9a6367e4aff723e8ee8190836836124284e8fcd4265e307c844010cfa074f3f", size = 255536, upload-time = "2026-07-15T18:55:21.027Z" }, - { url = "https://files.pythonhosted.org/packages/f1/f2/7aa06604c389d32ea7f0a6a988359a7eafc3cd3f8e7bc2e88cd2fdf0b877/coverage-7.15.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9854ca62c152874b2060772503535be2e8f53f70b8aaa7686b094888d872f984", size = 256881, upload-time = "2026-07-15T18:55:23.125Z" }, - { url = "https://files.pythonhosted.org/packages/a2/4f/1ef342339c7916d0096bc5888cc0f653882cc7bc8f897d5cb89143287c9b/coverage-7.15.2-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:913b6c56e110da40e035bbd168353bf7aaa2544a5eaccea5d98a4629aac156c7", size = 259196, upload-time = "2026-07-15T18:55:25.099Z" }, - { url = "https://files.pythonhosted.org/packages/fe/f4/7ed055d7a9c5ec13b161773a115a5ccc6b0081d568c31fad830806306cc7/coverage-7.15.2-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:aaccad4129d735a8a4d526f26929894c9a4e8ef7034566f210b176749d6906e3", size = 253036, upload-time = "2026-07-15T18:55:27.018Z" }, - { url = "https://files.pythonhosted.org/packages/14/79/ea82cca18c242a3a38b6c017da39726aa62dcb64aa635abf79b92009975c/coverage-7.15.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:a164b50081fc7357331c4024ef4d17b78ba325f8380d05f5a69599a7e05257ee", size = 254887, upload-time = "2026-07-15T18:55:29.084Z" }, - { url = "https://files.pythonhosted.org/packages/a4/ba/a136db3c0d9562b00e10b72540dbf3a33cd3bc5b95060c9308e247494623/coverage-7.15.2-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:bfd341ccf78128e72c094bc70cc25b3ef309c33c7c2c66ba3ed4309549e02de1", size = 252852, upload-time = "2026-07-15T18:55:31.184Z" }, - { url = "https://files.pythonhosted.org/packages/17/17/ea334246b16b7d059953fad6fdefa11e33c68efbd3fe37b1098120a1fac2/coverage-7.15.2-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:1473b3ba8e7ee0f076117b1a72c23f579a2b9e2bb742f48a8d86ea27ca93f91a", size = 257128, upload-time = "2026-07-15T18:55:33.163Z" }, - { url = "https://files.pythonhosted.org/packages/ed/c3/074fb66d46d607855f710876b117cbda562c5ab08363528e78820449f937/coverage-7.15.2-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:17c432b5f73ad52ef46fb06019f6fa7c66ce381961cf0f7dfd1d3a4bd3a98145", size = 252668, upload-time = "2026-07-15T18:55:35.063Z" }, - { url = "https://files.pythonhosted.org/packages/e1/c1/f620850ada9b36435921c9a3a8057013422b1d964eb4bf37fe138724d192/coverage-7.15.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:77f0ef5011df53a4bd1b35211ab122287f8d9b8d7aa1c4553e5c2deb24b1d446", size = 254325, upload-time = "2026-07-15T18:55:37.125Z" }, - { url = "https://files.pythonhosted.org/packages/cc/31/a729ca3689404493af82ef8e6ff70bd88bdda8da89aeef6ca9b387aeb2b4/coverage-7.15.2-cp314-cp314-win32.whl", hash = "sha256:f653e5d7248c1191ec988a85c72edeab46c3ff44f90639a4ed4874ec0be90243", size = 223844, upload-time = "2026-07-15T18:55:39.078Z" }, - { url = "https://files.pythonhosted.org/packages/c6/83/5d809dc808fb1698c671f3e372259bb9158e64b7ea526fc6ab7de64de9fe/coverage-7.15.2-cp314-cp314-win_amd64.whl", hash = "sha256:9911f31aad8906abe337c271343485cf20df5e70df5d2f57f9f136e7b55f26bc", size = 224331, upload-time = "2026-07-15T18:55:41.346Z" }, - { url = "https://files.pythonhosted.org/packages/16/4e/35e488548e952795829e129995c4174df33bf432b591d1aa42c8d9e4e7ad/coverage-7.15.2-cp314-cp314-win_arm64.whl", hash = "sha256:e38def96ad59853824c97953fdcd2c320a84ba3ce99b417db78af8bb6c3db635", size = 223760, upload-time = "2026-07-15T18:55:43.518Z" }, - { url = "https://files.pythonhosted.org/packages/ed/49/dd2c86cd6374038f6e415fb5bfb86db5218553209c081384a020369dee79/coverage-7.15.2-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:835ec4e20b45f0a7f63ed78f94065aca00de033403df8377bfe8b9c6abc0a7be", size = 222384, upload-time = "2026-07-15T18:55:45.569Z" }, - { url = "https://files.pythonhosted.org/packages/d3/74/173ff17a1c0808e5a438f549f6f145d5ac7528f2791310b63523e3200ac7/coverage-7.15.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7466cc7ab6dc0db871d264bf99e8779f0917ee63d40730af0552f71535a6e072", size = 222647, upload-time = "2026-07-15T18:55:47.544Z" }, - { url = "https://files.pythonhosted.org/packages/84/f8/b8cba872162356fb44ac79c10309d987206a4461e32072fc29228dad7331/coverage-7.15.2-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:e370c12133095ff18432de8c044962be85a5a96d90c6fcbce8e17e76236d2328", size = 264013, upload-time = "2026-07-15T18:55:49.768Z" }, - { url = "https://files.pythonhosted.org/packages/ee/67/a807a7586d0b8cae485308ddd55756f0806c92f8e0b411bacbf23c48edf3/coverage-7.15.2-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:fe41909c9515c3bfdb5f02c4d1f857dba322d9a9a1178069b91eea77889df63a", size = 266135, upload-time = "2026-07-15T18:55:51.941Z" }, - { url = "https://files.pythonhosted.org/packages/ce/67/cd78771dc985f7e4ebdcc82b1a96d9a932af9e806f01f2f91a89f4c72e80/coverage-7.15.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6aa28cfb6488e5453b5b762d65f73aa586380f6693a04d58078ce228a29b06c0", size = 268555, upload-time = "2026-07-15T18:55:54.065Z" }, - { url = "https://files.pythonhosted.org/packages/18/3e/10134cf81275188c58568f324fc74aedff32c63ca4d5bbc513a91944a6f0/coverage-7.15.2-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:bcc0aae933921d03096f53b0b03eeb702129fd406dee59f08d2efacc68681fa5", size = 269674, upload-time = "2026-07-15T18:55:56.066Z" }, - { url = "https://files.pythonhosted.org/packages/75/4a/771b77de446cba985dc414bbc5844bd21604da05dbc044286df8318a48a7/coverage-7.15.2-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:7c63387e21ab21f512c69c9756a8c7dadd322c7275edb064064433c9a09c3743", size = 263101, upload-time = "2026-07-15T18:55:58.107Z" }, - { url = "https://files.pythonhosted.org/packages/5f/b5/70a7011da15f4071943361183aefa27847f3e3aec4fd335f1cb3d3a622b1/coverage-7.15.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:0e55510bc98ae943cece9e667a6c0fe94c6a92913720dea34243657a17993d0c", size = 266007, upload-time = "2026-07-15T18:56:00.468Z" }, - { url = "https://files.pythonhosted.org/packages/b4/0d/f9547e804ce7ad49646ffeffac26699510efbe6c0f751b66fdc960c4e825/coverage-7.15.2-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:2ff08701be2d1556fc78b326c80a3e8042da09352ecb3819105f8e386c8a3071", size = 263611, upload-time = "2026-07-15T18:56:02.615Z" }, - { url = "https://files.pythonhosted.org/packages/ac/59/f576a396659c0efd351f5c1544f67c3560e89c7761cabf7f65e412beeda5/coverage-7.15.2-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:38c9518b7103826c403a461544e3c2e77151e8676d06eaed85911a97e962584a", size = 267344, upload-time = "2026-07-15T18:56:04.622Z" }, - { url = "https://files.pythonhosted.org/packages/7c/5d/c2e4fce3579c0cb635024293f1a32bbe26df101b3e3a69f22243d1352b6c/coverage-7.15.2-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:dee88b1ed88587abd8c0269a1fc1f4cc77f7750d1dfde2869e2a123af420e67d", size = 262456, upload-time = "2026-07-15T18:56:06.641Z" }, - { url = "https://files.pythonhosted.org/packages/bb/dd/956287d69436b66094bc4b57ac2da71e43bfd2a5524e958900b9f582fcf8/coverage-7.15.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:2fbeeeecea279727f8ac16c8e1133ddfeee793e985c86ae343d6a5ce744eef8c", size = 264771, upload-time = "2026-07-15T18:56:08.795Z" }, - { url = "https://files.pythonhosted.org/packages/2c/5a/6f979530c2734c575de77cf58f5f28d51f7123a94b5030fd9156fe5f363c/coverage-7.15.2-cp314-cp314t-win32.whl", hash = "sha256:cb0fddaa6884be6aae36ced9544b5e90f7d5f03845a2853bf47a14953a4e8688", size = 224151, upload-time = "2026-07-15T18:56:10.856Z" }, - { url = "https://files.pythonhosted.org/packages/54/7e/27f6b2a74d484742f4017553e710b01e396b23d809df3e95ca0bb9a2824b/coverage-7.15.2-cp314-cp314t-win_amd64.whl", hash = "sha256:77f091ea3a9cc611cd29f433565476bc1936c084ac8eee00ea0e7e70c27e4199", size = 224981, upload-time = "2026-07-15T18:56:12.928Z" }, - { url = "https://files.pythonhosted.org/packages/b1/48/284863423aa474240f6842bd00d680da22f4e6ea2e466618ef7c9c9e69a9/coverage-7.15.2-cp314-cp314t-win_arm64.whl", hash = "sha256:6fc448c377d6eeb00a47c673494bd9bae29280ca53987e1869e67ebedfe20658", size = 224294, upload-time = "2026-07-15T18:56:15.156Z" }, - { url = "https://files.pythonhosted.org/packages/ec/82/32e3bd191d498e64f6f911ad55d14006a0861e54869d2d32452326399e65/coverage-7.15.2-py3-none-any.whl", hash = "sha256:eb6bcae8d1a9d305351ecb108232441d11c5cfe9de840a04388ba5d2db8d735c", size = 213375, upload-time = "2026-07-15T18:56:17.305Z" }, +version = "7.15.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/be/c3/4f2195f512fb172aa425a8803a874b2baa9ba7f80ff7b6080998761fc701/coverage-7.15.4.tar.gz", hash = "sha256:0548198fff07ccf4faf469520bce1c2eceb1ce3e62891921138dec10907f9d00", size = 936952, upload-time = "2026-08-06T13:50:24.442Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2a/66/edcec7d7a0b524aa8923e22925fde6fe50ce005a113dca13ae1581455c4c/coverage-7.15.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bbac5abad70df71019988f83f26ac7092ff2642975def4429e98dc7585ef3490", size = 222367, upload-time = "2026-08-06T13:47:15.578Z" }, + { url = "https://files.pythonhosted.org/packages/e6/c6/ab8de429e2e8548faf58ec7e1674a4ce00414b4113942d3fe87109cf0f68/coverage-7.15.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:357a173465c7ce028d07a95cc2b63b5bf59f50ecdd5ad75c5cbb78ada984048e", size = 222874, upload-time = "2026-08-06T13:47:16.961Z" }, + { url = "https://files.pythonhosted.org/packages/be/c4/3b7b49587e8a6b9af79b3eb468d443d6042b6d65b47aa26586846a0d6566/coverage-7.15.4-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:21b803935e2efc3acebe9697197a294fccf5dc4e5382bd6369542ff7a7d2a1d7", size = 253287, upload-time = "2026-08-06T13:47:18.291Z" }, + { url = "https://files.pythonhosted.org/packages/fb/65/ec03b743a2a229c72cc1eff3e57be9d3564e9c6b4d5aba2d70744a3fc0d8/coverage-7.15.4-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:7a2b580774a4786c1053157c0165e04476e03ff293993d7c148eee784a94bae6", size = 255199, upload-time = "2026-08-06T13:47:19.765Z" }, + { url = "https://files.pythonhosted.org/packages/41/4b/5163729e4b6582d61975cfd3ccab45b4ec53e21cf156d9941cb025188468/coverage-7.15.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a9464451c4efffe8d47ace5a540b10b0dc10e879066290f8600872b7f54a419d", size = 257308, upload-time = "2026-08-06T13:47:21.206Z" }, + { url = "https://files.pythonhosted.org/packages/86/08/2167a0f08fb87d702fa423a48578a32865464b7c9e1db3911ad7812ab414/coverage-7.15.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:de602f34123c2f4af1c1869c6dbbbd60da6d5983bf01937367295d135cccbfce", size = 259268, upload-time = "2026-08-06T13:47:22.503Z" }, + { url = "https://files.pythonhosted.org/packages/1e/e5/68eebae3053dbd48508edea559c21b23fbdf3460784f91370c83a86a6acd/coverage-7.15.4-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:6879ded16a27f3eeca19b900c147e81616e7054db451471a611b2755ee5249f7", size = 253392, upload-time = "2026-08-06T13:47:23.88Z" }, + { url = "https://files.pythonhosted.org/packages/1a/46/fd4ced40a2b691c774e515c9b69500bfa64c7960b67fcee4b2f6fad97fc3/coverage-7.15.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:986be58c3ab54aae8d3496a6225eea74f760fdbe739b38bd442c7e8d133aa53b", size = 255001, upload-time = "2026-08-06T13:47:25.469Z" }, + { url = "https://files.pythonhosted.org/packages/53/25/ae2e5fa710bb6957a9aadeb9e3598d3b3e4af6587ce857ad42e8639a3f30/coverage-7.15.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:c6103639613fe6c1e989082948419bc77a2d26b6c825c99d7fad25f7d3d87afc", size = 253061, upload-time = "2026-08-06T13:47:26.845Z" }, + { url = "https://files.pythonhosted.org/packages/d7/31/67ddc0365db2c6e93ac8580bc4bbc50f65273262f973f63ebcdbc15c0495/coverage-7.15.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:d3af93dddb5659276c63bc16ac6466ac2033a70ca816097bbc06345b8ccdf571", size = 256831, upload-time = "2026-08-06T13:47:28.217Z" }, + { url = "https://files.pythonhosted.org/packages/f6/78/82b8fd18f57fb13f12d98fe874995bb2c4f9f17be8aff762c426323fdb96/coverage-7.15.4-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:b10075e5421d04265766a6d1dac809bbeb8a946fbb23c8f82c227409b2190719", size = 252781, upload-time = "2026-08-06T13:47:29.712Z" }, + { url = "https://files.pythonhosted.org/packages/0a/eb/6c74ef4dd12b252e573c49bdef9e2ac265bf3dbb79b8d7feb3266e084e9e/coverage-7.15.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a67a9f78b2942d87ba8ce3059c642164d2aedd65337377fb52fe9803656bc5c7", size = 253692, upload-time = "2026-08-06T13:47:31.192Z" }, + { url = "https://files.pythonhosted.org/packages/5a/66/eb9aed1c3fd2d36ee00eb173f434b14fa607fc056739c9a89ff4244010ea/coverage-7.15.4-cp311-cp311-win32.whl", hash = "sha256:69484d1aca26e322e1c3ce03f09341e84524ababad2d7202161738d83cc9f82e", size = 224461, upload-time = "2026-08-06T13:47:32.572Z" }, + { url = "https://files.pythonhosted.org/packages/e2/6d/81fa4161dfb3ed9d74e40d58647eff83a56b7612e78352581280fce2f477/coverage-7.15.4-cp311-cp311-win_amd64.whl", hash = "sha256:63fd6fcd1dd6e158f7eb78606e72933b3f6d01e7b747f99c6c12d764307a0fdc", size = 224937, upload-time = "2026-08-06T13:47:34.205Z" }, + { url = "https://files.pythonhosted.org/packages/5b/c1/d8dacf683c6cad3cf85ce68fd3774a6774ec402128822fdfaed920f11e6a/coverage-7.15.4-cp311-cp311-win_arm64.whl", hash = "sha256:ea82116c9893fa89e929b7f197ee5a1950a76e91cc5c85ba503fc02379d04890", size = 224479, upload-time = "2026-08-06T13:47:36.118Z" }, + { url = "https://files.pythonhosted.org/packages/1d/48/bc8d4ba7b37551a767bd863f15b3f80182b271c2f55975356f5f7dbe94c2/coverage-7.15.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d4fedd1f7f428f9fe83b1ead5e7cc87a43427be31aadafbac3ac0636dc7abb22", size = 222543, upload-time = "2026-08-06T13:47:37.562Z" }, + { url = "https://files.pythonhosted.org/packages/20/dd/88d6f83f1fffc974a3691a34a97951c5b12df7512a6782c5963883cbc058/coverage-7.15.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:37e2f0cdf58e2e1fed4e4d5a8f8786ae2f7eb80b478016876667dc4a01d60a97", size = 222905, upload-time = "2026-08-06T13:47:38.927Z" }, + { url = "https://files.pythonhosted.org/packages/bd/5c/54ee0d4748585bb0acab9891cd8d92f2d3593165b4e59fc9de113bfb3140/coverage-7.15.4-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:fb55d0e70bb15f2e81477613627286581414693d74ac7963c93a790dd453ca9d", size = 254407, upload-time = "2026-08-06T13:47:40.488Z" }, + { url = "https://files.pythonhosted.org/packages/8c/3f/f0642a372f494bd0d7dad3b497083b910194a5f1c88be2c94fef707c3b59/coverage-7.15.4-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:899b9da30f3c6c336566e3707495bb23e8302d39d862f01fa78c48b99b9437e2", size = 257145, upload-time = "2026-08-06T13:47:41.931Z" }, + { url = "https://files.pythonhosted.org/packages/71/17/8b46d0ed68251016002ec972c8fc0119961a765d0984cafb8bf317c43758/coverage-7.15.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d15715e8c46552827e5e4f30a35575a2dbcad14454cf3284c54483946bd16931", size = 258257, upload-time = "2026-08-06T13:47:43.527Z" }, + { url = "https://files.pythonhosted.org/packages/30/b8/8498a0e72d0adbe15477dd07463d2b3bb2c9f6a4815e8589e50939e2c3ae/coverage-7.15.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:002a438859f7b430bc99afeaf01a6d187dad1d0dc907b64cdeffc632a5db8fd8", size = 260517, upload-time = "2026-08-06T13:47:45.121Z" }, + { url = "https://files.pythonhosted.org/packages/41/e1/7dce19c3bdb1e3dd63e769508216500edad81bd5f69a26d724e32aceaf78/coverage-7.15.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e4193a04b518f7968f3099755f5509ee7cccc6dc2b92a6b14841934d22e222c9", size = 254785, upload-time = "2026-08-06T13:47:46.541Z" }, + { url = "https://files.pythonhosted.org/packages/dd/b1/e1494703c675a2561723cd9b89f45c9168782c31280c611b1f767851e57c/coverage-7.15.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e98dcc55d572b38e69d117da7e8e8efb8500f1f5eaf81ecd460a63220790b839", size = 256176, upload-time = "2026-08-06T13:47:48.155Z" }, + { url = "https://files.pythonhosted.org/packages/73/76/a5629d270fb638a43a4b10466f51e2f49d532c1aa4da2913cbbb150bbe0a/coverage-7.15.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:af6c538498ce66c10d3fd541c2a8d5b03da5850355add34e6cba564210cb9e72", size = 254321, upload-time = "2026-08-06T13:47:49.757Z" }, + { url = "https://files.pythonhosted.org/packages/ff/4f/9c44447218435d5766b911534f9d798144a5560f85e9a54ebe5f3f5d19f9/coverage-7.15.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:1d10025d96ea89fc2f73714dbc4cbd433fe012c1ac9e23f895d7728b238b6e52", size = 258390, upload-time = "2026-08-06T13:47:51.248Z" }, + { url = "https://files.pythonhosted.org/packages/de/36/c1e127616fb3fa18a9ff71e76c417f2fd7424332a4870015ac224ef4c039/coverage-7.15.4-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:d802e1947603162ded419bff83ac7489820355d2b856dfb09206574e3a37ac0c", size = 253894, upload-time = "2026-08-06T13:47:52.816Z" }, + { url = "https://files.pythonhosted.org/packages/e9/b9/fdb92c8ae7a8bb9b850cc253b7b3b9c8526f68130002048b5671cd510d09/coverage-7.15.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c2de40895718f91951b86712b4c5b694acaf9a0a49be13874896f599a1eed3f4", size = 255763, upload-time = "2026-08-06T13:47:54.296Z" }, + { url = "https://files.pythonhosted.org/packages/6f/c0/a7d51b2587c7bdb76e71b0896d2565bf7d60436b5122fc83e511adb1f7cd/coverage-7.15.4-cp312-cp312-win32.whl", hash = "sha256:5c3431b2161279b7db5c2a1aa58ae02e5cb8c3c42d93a5094be3f5537bd5b11b", size = 224597, upload-time = "2026-08-06T13:47:56.074Z" }, + { url = "https://files.pythonhosted.org/packages/49/b9/5c5f80cc55f5acaaca6dee677626bfcec8c87204a7809b438b08e84f4571/coverage-7.15.4-cp312-cp312-win_amd64.whl", hash = "sha256:6befeab5fb2b51c958ca4ac6c5d141a1e8240f4f76e46350f1911963deda49cd", size = 225135, upload-time = "2026-08-06T13:47:57.52Z" }, + { url = "https://files.pythonhosted.org/packages/47/e4/2a4561f89ff6bf7c925c287d0f2cce8bdf139c3a33735c87e3203401cf94/coverage-7.15.4-cp312-cp312-win_arm64.whl", hash = "sha256:67bc345491ab55b837277d76f5775d057e8c7f1ac44d890d8c2c82adde258c6f", size = 224515, upload-time = "2026-08-06T13:47:58.977Z" }, + { url = "https://files.pythonhosted.org/packages/f1/84/651a9310859673aaa3b3203f1aa1641ca60fcf2494683e1c9474c7172780/coverage-7.15.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c705b28feb2775dc82a25f1d473a370bc37ff93f5177f4e29ce2425f560f6921", size = 222565, upload-time = "2026-08-06T13:48:00.796Z" }, + { url = "https://files.pythonhosted.org/packages/82/f9/4dcf700137e8af550670f4d74d1b63828ce93e1e2b05e5f10710eb2ea987/coverage-7.15.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3ff205ab5e3ecc670f6a4dd19d9cbf12ede53dd41cfc1e15716ec961ea6d314e", size = 222936, upload-time = "2026-08-06T13:48:02.391Z" }, + { url = "https://files.pythonhosted.org/packages/07/4a/612ff1e780b3fbfd637486f542f84adc5503873d8b5d279dec1ffeef9414/coverage-7.15.4-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:5172326e861a38b48b48befca15e0f477a26b283337a33a739c8fed229934e36", size = 253926, upload-time = "2026-08-06T13:48:04.382Z" }, + { url = "https://files.pythonhosted.org/packages/b0/04/d1cff1c2ead4708a6a79c01d3736b6a25bd38a36678398f72a8dd33dfad9/coverage-7.15.4-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:12b59c90084e3234fb11184886bf4a40f4f16a8c8f867be2e087b81f8e8868d4", size = 256523, upload-time = "2026-08-06T13:48:05.996Z" }, + { url = "https://files.pythonhosted.org/packages/b9/80/d34e13fb4b293cbdb9665838cf5522077b8ad14ef947550631a4bced36a5/coverage-7.15.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:349062d66f00b40fa2c1c222438bad25fabf755631b5d82937fe985c8008615c", size = 257759, upload-time = "2026-08-06T13:48:08.036Z" }, + { url = "https://files.pythonhosted.org/packages/0f/e7/2c5fe7636fdb0732fe0f09f308a5b066864078b7fc61f6678e8478554f2e/coverage-7.15.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4256ced708e598e05209bc1a8ab4074e04a51dba4c62fb45926a229af675ace7", size = 259890, upload-time = "2026-08-06T13:48:09.834Z" }, + { url = "https://files.pythonhosted.org/packages/92/28/9689f0858dfff59c2ea688938ab9fa2925631235df67126a42b6c5c70ae1/coverage-7.15.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d80f974b20782d9612c8b4c9beeca867074c7cf4079d1419843fa25a26428b25", size = 254121, upload-time = "2026-08-06T13:48:11.459Z" }, + { url = "https://files.pythonhosted.org/packages/f9/e2/785077c230c157243eb5aa9a26c3be260ecd02001bead54a3cada3df8e03/coverage-7.15.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:2e179f19bfe1d31f8eeeaa12990194d761c4f62f0759661000bca6cd8729f40b", size = 255891, upload-time = "2026-08-06T13:48:13.209Z" }, + { url = "https://files.pythonhosted.org/packages/d4/90/e20371b17b40f912f21305c2db2f30efa3de306f7320fc916804872c85a4/coverage-7.15.4-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8bc16bb47b7679670eceff71d78bfb7d6e5b143f6c2cd117487ec7c75e0d4b78", size = 253859, upload-time = "2026-08-06T13:48:14.736Z" }, + { url = "https://files.pythonhosted.org/packages/05/49/25371987ee459a5f67c0427fb75c74f9358e65f2c71fe75bf41c1b6c5fcb/coverage-7.15.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:1cd685005cd2c4200adfc14cf39a603b9320efab3f18a8f7f156d20c9cc3345f", size = 258011, upload-time = "2026-08-06T13:48:16.464Z" }, + { url = "https://files.pythonhosted.org/packages/30/6e/32e67467f6154bf4f1c4f63b05acc5097cba4237d45bbeeea446b52e8ac1/coverage-7.15.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:337399ad2c93b3acd2a937627dae8b3e86b66707cd3d3e856347999aadf1ef8d", size = 253676, upload-time = "2026-08-06T13:48:18.493Z" }, + { url = "https://files.pythonhosted.org/packages/03/c1/8b24192e89286399765155251f99ee9f070a9d637109018ac23d99b99f6f/coverage-7.15.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:96e257121228ec5cd2bb919276e94ac11074471bc37d68dbae0e8308cce15fff", size = 255453, upload-time = "2026-08-06T13:48:20.057Z" }, + { url = "https://files.pythonhosted.org/packages/16/6f/8b41ebdf67c87854e17c035336a90f1cfbad0c14c2a584301be6ff148718/coverage-7.15.4-cp313-cp313-win32.whl", hash = "sha256:c65a9e0dfc6143491879da4e13b5e30f8be192055de508d737fb14601edbd22c", size = 224605, upload-time = "2026-08-06T13:48:21.655Z" }, + { url = "https://files.pythonhosted.org/packages/e0/e2/2946c7f0b42b152ecb21ff1bdad72e3d301e790c0c487e4a86e8c9f69347/coverage-7.15.4-cp313-cp313-win_amd64.whl", hash = "sha256:2ff8f5e9b8f7a94f0c11c45631eee103dbcb7d63274edd12c56efe1be690b3b4", size = 225148, upload-time = "2026-08-06T13:48:23.376Z" }, + { url = "https://files.pythonhosted.org/packages/9e/83/3f4a69957f48ae7a0aba76c34743f88963d607b19e03f3f8e66f91cae0f9/coverage-7.15.4-cp313-cp313-win_arm64.whl", hash = "sha256:6e0a8a5083b096487d6cfced94cdd514d8f5db6f113610fb36c0620edb1028cf", size = 224536, upload-time = "2026-08-06T13:48:25.117Z" }, + { url = "https://files.pythonhosted.org/packages/ea/ac/748cf29eeb2d6be34a3176ce26a4f49e38085ee08e8935f05f6f26ed7e0f/coverage-7.15.4-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:770e9325ab5ea6d56f77e59b29ecfe0ac20b57a82a601876f90494a4dda0386f", size = 222608, upload-time = "2026-08-06T13:48:26.806Z" }, + { url = "https://files.pythonhosted.org/packages/0b/02/1abbf5c984677b0aa439cdacaccbf38d248939d8ef8fe1cc7a50d73edb77/coverage-7.15.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:d12b33a3a50a1676b7784dc8d00a0c6d66a9f2add4b85a041c19b6a7e53ef23c", size = 222940, upload-time = "2026-08-06T13:48:28.432Z" }, + { url = "https://files.pythonhosted.org/packages/eb/e1/ff8f9f53d9fcf586125b55d0b1f04ec1c14955fee41e83d5814bee141bb5/coverage-7.15.4-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:5669c8378ebde86f5def7a25d29586631b58acc27ffde04399f678f3dfc6e082", size = 253985, upload-time = "2026-08-06T13:48:29.995Z" }, + { url = "https://files.pythonhosted.org/packages/a1/26/595759762e514e81be1d7d01ed03444303bcd152226a6529998d253f9201/coverage-7.15.4-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:ff97a14362eef486483ed44042ca2027ea257df6ff768e62358ee0c9776925ac", size = 256492, upload-time = "2026-08-06T13:48:31.634Z" }, + { url = "https://files.pythonhosted.org/packages/24/68/b79aabac54d482be23b5fcdd4f4662bff24a78edc4ee29201726929936d5/coverage-7.15.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5a325e815318638aed1655d9c06e6d7c2d3d46c09231ce988070428a8762d734", size = 257837, upload-time = "2026-08-06T13:48:33.186Z" }, + { url = "https://files.pythonhosted.org/packages/09/0f/bf7f297885a5bf6fd71e5782404e0ff059ca09e8711ceb3a08544abde45a/coverage-7.15.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:474223409d88eb20d2d6a0d37ea60e8647a65a90cc008dc1f0410af5f64f1e0d", size = 260152, upload-time = "2026-08-06T13:48:34.75Z" }, + { url = "https://files.pythonhosted.org/packages/fd/f1/296744e854ff8368542343457414380465e9ceefb9192342feb9d3bc461d/coverage-7.15.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:7f2f62ae3cd189dd2e13aece758c57b3eecbd27be070dbd4cbd10936049e5dbf", size = 253978, upload-time = "2026-08-06T13:48:36.434Z" }, + { url = "https://files.pythonhosted.org/packages/55/b0/bbdb2e9057493e66220a2e149ca2d301ba0e3a58a83bd6b90de9826d16f3/coverage-7.15.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:39ece820e29e0a2ba34b3ecb3be83c27e997eed8926f2ba6fe7ce7a0bda5843b", size = 255846, upload-time = "2026-08-06T13:48:38.317Z" }, + { url = "https://files.pythonhosted.org/packages/96/e4/38015b2b6d21258713bd17e76b59d033b191efb5703589cffd037dfbca20/coverage-7.15.4-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:f21b56dcace11dfe013014201f577dcd592b2a9b72182d930361b47cf6f73f25", size = 253808, upload-time = "2026-08-06T13:48:39.993Z" }, + { url = "https://files.pythonhosted.org/packages/0b/64/0d515c1e60ee6fbfd1a0e79c07cd87d388a233b7adc37758735677203808/coverage-7.15.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:93a3a0b662abcc10c73a47cbc72cd60f63618d6989fb2d1286e50eacd974f303", size = 258081, upload-time = "2026-08-06T13:48:41.971Z" }, + { url = "https://files.pythonhosted.org/packages/91/71/04d9e7a3642146c6351338aef4ef85ab11dbbb54744c13245caba1aad1c0/coverage-7.15.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:141fae2cabf5569b782c10afc4c850ce10f618c13f8db54765cba99cc839da1f", size = 253624, upload-time = "2026-08-06T13:48:43.731Z" }, + { url = "https://files.pythonhosted.org/packages/b4/a7/6c28b74c81ebff66987b0e2522ba5cffa3e90b0c33cb6a2eb264d4ee8cf1/coverage-7.15.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:81294c7e6ab30c5f74c0353b11b2fd6320e72d9bee6ac73b357caa8b916323a5", size = 255280, upload-time = "2026-08-06T13:48:45.58Z" }, + { url = "https://files.pythonhosted.org/packages/52/af/bc19996a7014b98d7bbb0f0939453c67074af65784a3aa16a789a07381fa/coverage-7.15.4-cp314-cp314-win32.whl", hash = "sha256:7bbd7d6418e0dab31a206af5203bd43ae36edb8e7fba1940b055d3e9249290d7", size = 224768, upload-time = "2026-08-06T13:48:47.525Z" }, + { url = "https://files.pythonhosted.org/packages/ee/90/219484e476d6e101ba0a444852579e05f5b75c37c611a42ed1190f73ef62/coverage-7.15.4-cp314-cp314-win_amd64.whl", hash = "sha256:f0204ed122758782970526057093f448051a39db9d810d4e344bb87a3546f425", size = 225259, upload-time = "2026-08-06T13:48:49.513Z" }, + { url = "https://files.pythonhosted.org/packages/b7/66/fa77daf4e383e5f776dac62c2409b6af81910ae6fe326bd5170dba74cc63/coverage-7.15.4-cp314-cp314-win_arm64.whl", hash = "sha256:9e71e7bc71c686a123347ae47a0de33a175e797a85bb57b791492adf4eec8ed8", size = 224684, upload-time = "2026-08-06T13:48:51.235Z" }, + { url = "https://files.pythonhosted.org/packages/58/5b/f03bf0ce362bbf3f785fa5219620d00778d4ac6fc9e407734828e9c672f6/coverage-7.15.4-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:7c922735321eef3f87c280a3d39afff6b646723a2880b862cda4ac7a093b8aa8", size = 223338, upload-time = "2026-08-06T13:48:52.896Z" }, + { url = "https://files.pythonhosted.org/packages/0f/76/e77d0ae22501831cc9f92193e8a957a5caa1dd177f90a6d1d9b106242d92/coverage-7.15.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f41c17c4668a655ce96d090d8d5ffdc24ef64b5a02f9753884d08483e8a4a41a", size = 223609, upload-time = "2026-08-06T13:48:54.688Z" }, + { url = "https://files.pythonhosted.org/packages/82/1a/b1f089da8d38ac612fa2dd6dc7f4a1a7657d12f3e261d2996edd3a838d0b/coverage-7.15.4-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:46822e9b6ff1c6a72b518c162c44a8f45a61a1d609c51084bf5b16c023c5037b", size = 264970, upload-time = "2026-08-06T13:48:56.403Z" }, + { url = "https://files.pythonhosted.org/packages/bf/31/e66d98d6e9c7fcc88470f1e234eaf6b1950dc0dfbf797f7282c1c861da24/coverage-7.15.4-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:3d6f4955b73b5445271379a59e3792b0d978f42d4a01e0cf7a67d9c33a3bb0a5", size = 267088, upload-time = "2026-08-06T13:48:58.41Z" }, + { url = "https://files.pythonhosted.org/packages/59/a1/ae94eb2c541add426378408379f233591e069040b1e2cdb33df9498a0682/coverage-7.15.4-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3fc9e047706fb4a9abb54f719d3aa643e80e5bb3818182c40aee01ac0f0247ba", size = 269508, upload-time = "2026-08-06T13:49:00.42Z" }, + { url = "https://files.pythonhosted.org/packages/9c/c7/88a10694a1c6a213569766aba9f25847b28155d4ac731b13226db216356d/coverage-7.15.4-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:05e491d4f3165d62d4f5c8fd48dfeabf2ae8f42cbbd484319af33ea851b78982", size = 270629, upload-time = "2026-08-06T13:49:02.234Z" }, + { url = "https://files.pythonhosted.org/packages/b3/34/d8b8232e5e55169933b59aabcef2fedfa4b9d8897361bb80fcbda146505f/coverage-7.15.4-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:226c66e80ec0598d3b9b4874123df167ccca342aca8714f77cac6829688ee09c", size = 264043, upload-time = "2026-08-06T13:49:04.102Z" }, + { url = "https://files.pythonhosted.org/packages/7e/35/58b009dbf8c471c7224716478b9fed4a7e1af15320e1ed41660978504663/coverage-7.15.4-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:ac41cc14bebda0dbfb0628036b7f75706935c95bcc07fefe9a0f93614aa60a57", size = 266963, upload-time = "2026-08-06T13:49:05.821Z" }, + { url = "https://files.pythonhosted.org/packages/62/aa/57fbda1b42c892968273c56b6ee9dc0f1310850859230a507bc7873b1f65/coverage-7.15.4-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:8af623e5cd92080acddd02b38f2f406a2c3a0893c38950b211890361448fbf26", size = 264569, upload-time = "2026-08-06T13:49:07.706Z" }, + { url = "https://files.pythonhosted.org/packages/98/8a/360e6e7f24d477b7e889703af0afa878d15b6d4d8d2a822b2835c169a879/coverage-7.15.4-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:07545711d4f0f32852a18f18ad11f76f0109909d09e78b9008b4cfc67e829429", size = 268299, upload-time = "2026-08-06T13:49:09.587Z" }, + { url = "https://files.pythonhosted.org/packages/4e/89/6f701261aee21b6b5fa8f7872229406dc917e125069448292223bf213606/coverage-7.15.4-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:a0865421cfdc53654b342d515e5a233187590882d20b95752150e53f65460017", size = 263413, upload-time = "2026-08-06T13:49:11.604Z" }, + { url = "https://files.pythonhosted.org/packages/3f/0f/6f04036edc260ed425af83e834f627fad48941ce97b50bfe6edd8b6fa623/coverage-7.15.4-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:460115e32ee40566476db5048f9bec1e842c127ad8e6f8be745aad3ac9cbc839", size = 265725, upload-time = "2026-08-06T13:49:13.38Z" }, + { url = "https://files.pythonhosted.org/packages/c4/ce/d19b5d4d5c49a7bfb925fd74310fee7d28bc99520ac3367ccbc54e662518/coverage-7.15.4-cp314-cp314t-win32.whl", hash = "sha256:cbde877ef9dd7baf272b9bfef2b8a25edd45d9170fc326951dd20eb480335e85", size = 225079, upload-time = "2026-08-06T13:49:15.265Z" }, + { url = "https://files.pythonhosted.org/packages/26/bb/7aa1b3b173faee0679037ca950bbbe1247273656697994d8d13f80f8d4b4/coverage-7.15.4-cp314-cp314t-win_amd64.whl", hash = "sha256:3da9e92d1c551fd7563833e9ade686efb0c4b7363ab7681a94283958c950bf5e", size = 225911, upload-time = "2026-08-06T13:49:17.279Z" }, + { url = "https://files.pythonhosted.org/packages/81/1c/4ea9e47426d80038d9222db3c4534cb6021a74b237d3ff97ffd33b6600dd/coverage-7.15.4-cp314-cp314t-win_arm64.whl", hash = "sha256:3a54f5a0d85050c73a38f6793090ee83974531e67fe5e57a1da9bee11398aa5e", size = 225219, upload-time = "2026-08-06T13:49:19.293Z" }, + { url = "https://files.pythonhosted.org/packages/2b/c4/dc5d2ac8f9142e7ec7de66e7bf0591db29d78955a040bd915870d9c0e657/coverage-7.15.4-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:2c9872e4d9dc5d3cf616bf4b382f5a00359305a5be666a3dd0b5cdb4e49597f9", size = 222604, upload-time = "2026-08-06T13:49:21.279Z" }, + { url = "https://files.pythonhosted.org/packages/70/39/33e63df81fe2ee100897451841c821467635923e58e37c6bd4b46dd8106c/coverage-7.15.4-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:e101dbb4b9b72f0cddd8cdc8c9c5b47f456766f5e0ac82dbfb75e5c55409b78a", size = 222944, upload-time = "2026-08-06T13:49:23.187Z" }, + { url = "https://files.pythonhosted.org/packages/99/1f/ef3ffb5557febc75a0d97aa459d0266d7d741110265121cc6d8539343d44/coverage-7.15.4-cp315-cp315-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:7d1abebdb047729e852b9c77a00497dfbeb11eb3a117e037d7dbc3ac8e5f5c54", size = 254050, upload-time = "2026-08-06T13:49:25.008Z" }, + { url = "https://files.pythonhosted.org/packages/6f/f5/1f0f6f77698c3601ca0ae7431e34b24c62ca2f06fecb23b73ed1f651d2be/coverage-7.15.4-cp315-cp315-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:d28a4a899354d0ea6214cc59b4fa19eefbce1b9ff1688ab579acf49e894bd3fb", size = 256967, upload-time = "2026-08-06T13:49:26.896Z" }, + { url = "https://files.pythonhosted.org/packages/03/7a/2ed9bed79925f4367c83c77f66a89e5ca7229c288d2d19ad5f36d1ca0070/coverage-7.15.4-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ffb3c2aacea411cc7e1d27712490c11108e2de1d39019ae32915493a59a8b9ed", size = 258587, upload-time = "2026-08-06T13:49:28.692Z" }, + { url = "https://files.pythonhosted.org/packages/45/8c/fa34044f71b7cc4ecb6da9c2408770959b0591fa9b5fb6fb6bca38f94298/coverage-7.15.4-cp315-cp315-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a9447978a92f405d301123cfd39ff49895490efb769a758fe2734c7f631bf8ce", size = 260785, upload-time = "2026-08-06T13:49:30.472Z" }, + { url = "https://files.pythonhosted.org/packages/4f/54/d5727ce36b4524a7394ab9f5f1df378e1f23affcdab01037dc8655185cc7/coverage-7.15.4-cp315-cp315-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:050467a7983b8e2fe7dd41a78bb30c3e7f8c0b8cafda14b1c46f8b5e3cf2dd3c", size = 254545, upload-time = "2026-08-06T13:49:32.271Z" }, + { url = "https://files.pythonhosted.org/packages/dc/e6/6e3783e576719590194bdffb6dd6d85490801785b7c331e35a245d8cb8b5/coverage-7.15.4-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:d003b7a5708ddad5c206c79607a6b92abb6fc13c57d99d8a4468cc03a2941ced", size = 256682, upload-time = "2026-08-06T13:49:34.089Z" }, + { url = "https://files.pythonhosted.org/packages/dc/f2/bacdbde18b69ed2de424fcf64d9fb0a4913753d4f0eca8bae9daad69f4bd/coverage-7.15.4-cp315-cp315-musllinux_1_2_i686.whl", hash = "sha256:c38efe30fd74e5c19e9433f11fb1f5dc9c6522770971b7c6145bbaa413dc8800", size = 254560, upload-time = "2026-08-06T13:49:36.052Z" }, + { url = "https://files.pythonhosted.org/packages/6c/a3/1fb927196e3477c1b48831169ab58ba08f451ba87ae311ff1de68b26a616/coverage-7.15.4-cp315-cp315-musllinux_1_2_ppc64le.whl", hash = "sha256:1f4f826d70f772ab8b0c052329580d7fe8b8abd191e4ce0c8f81aec6614665d3", size = 258792, upload-time = "2026-08-06T13:49:38.01Z" }, + { url = "https://files.pythonhosted.org/packages/41/58/30d4c149c69053de0edfe325614c1d28d508f62b1783e0e4a234d2e49136/coverage-7.15.4-cp315-cp315-musllinux_1_2_riscv64.whl", hash = "sha256:4a4bf917c9953f57c957be31c1cd504e3bd2f34d4a352b9d391a3025336f6768", size = 253968, upload-time = "2026-08-06T13:49:39.934Z" }, + { url = "https://files.pythonhosted.org/packages/89/e4/77f639371b918aad30dda4051f95404b43578f7f2e2f87ba73e02ed1ff37/coverage-7.15.4-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:1c9bf40ebef178a45192c75c4964760bb261b0e6ad725da5fc4c93f674f19753", size = 255893, upload-time = "2026-08-06T13:49:41.825Z" }, + { url = "https://files.pythonhosted.org/packages/5c/62/13be29b3ddab35f14c87967a4820a05106d2a3eccb4fa4ff550bf30b75e0/coverage-7.15.4-cp315-cp315-win32.whl", hash = "sha256:43619d04c3671792d2c4706ae8bf45e265dc87bbd4078189ef8b847ea1e74be2", size = 224768, upload-time = "2026-08-06T13:49:44.08Z" }, + { url = "https://files.pythonhosted.org/packages/a1/70/af0c6be0f964af6954f6b74bc109b0dbca02824696d2520fb17fe1ab06e3/coverage-7.15.4-cp315-cp315-win_amd64.whl", hash = "sha256:be619439dbcd31a2eab10b32de9fff62c26ed4bab69dc32b8363fdaaa0882809", size = 225242, upload-time = "2026-08-06T13:49:45.899Z" }, + { url = "https://files.pythonhosted.org/packages/4f/2d/f3bd3aab899fc9efc18b53133ee68f5f98574ef480649b23e12962226387/coverage-7.15.4-cp315-cp315-win_arm64.whl", hash = "sha256:def597967dafc2e8d97c9097ea453c464e0bb8ed38f193a43070f10dc623bb6d", size = 224674, upload-time = "2026-08-06T13:49:48.322Z" }, + { url = "https://files.pythonhosted.org/packages/f5/ca/f69251cd63eabc6438321aea22148754cce758a26bde07dd490e3fe7cfc5/coverage-7.15.4-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:c7dbc748ac8a1e3e59a2b28bea47675e6e778081dbbf081bde0d75def2fcbe1d", size = 223333, upload-time = "2026-08-06T13:49:50.293Z" }, + { url = "https://files.pythonhosted.org/packages/a7/a7/037b53b2885b0d8447064432491a4d5a1014cd9f97a594d53acd0c04541a/coverage-7.15.4-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:2413074a5ecbb61a01a7888fc72db0ca324d13588c5b38bc0dd8564cdcdfea26", size = 223630, upload-time = "2026-08-06T13:49:52.637Z" }, + { url = "https://files.pythonhosted.org/packages/80/4f/152b8a4779ae90da11bb24f7467df8a59f0be48a5c52acb856325ca48289/coverage-7.15.4-cp315-cp315t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:4e6f6f632b7b2f714bf7a1346e8f97b650ee71f3c298aaad42a2ab60f0f07645", size = 264489, upload-time = "2026-08-06T13:49:54.52Z" }, + { url = "https://files.pythonhosted.org/packages/10/2d/84b4b9e0e1dd6528a51920ff7031f35b789382e467a28ec6a5a578cb8812/coverage-7.15.4-cp315-cp315t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:8df457da2249d3c75ca2e5e835d59c725abfe92d27fdff6cd99eed85b51d5e9a", size = 267567, upload-time = "2026-08-06T13:49:56.721Z" }, + { url = "https://files.pythonhosted.org/packages/53/fc/ba01cc25299f9f8a2c8b02d3b28c53f3543d9fbfbe4e74fa2760b48f163e/coverage-7.15.4-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:050f66a08805acb5b8a23c6d4a517b1ecf82c08e81ed0e4bd727df065e5c6624", size = 270123, upload-time = "2026-08-06T13:49:58.736Z" }, + { url = "https://files.pythonhosted.org/packages/cf/d0/db2647cbf40b14f8c308f94ff7bf89c06d564e59f396906edf50086ec788/coverage-7.15.4-cp315-cp315t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1587fb771d1ccceef708fdde1e5af8c7ed24b486b61d13a321acb7d8145390aa", size = 271107, upload-time = "2026-08-06T13:50:00.811Z" }, + { url = "https://files.pythonhosted.org/packages/70/ff/4d2d17924552c458bb4f77dd631f0e3bc92fbbdf2d2d916cd4b33bbfd5b1/coverage-7.15.4-cp315-cp315t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:8b4f1c3a69ca580f3fbd6b2046915f536d7f586874f25c1bb23add2a3c88d50f", size = 264955, upload-time = "2026-08-06T13:50:03.023Z" }, + { url = "https://files.pythonhosted.org/packages/ee/de/dc010c7a3691f396d93bbc26bfcafa1c2a3a351cd520470f15faf5795bd5/coverage-7.15.4-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:ffb58d7eff5b7f6ecc6fa21d6288ab7f968a212cb67d682c269c09b9eba3b66f", size = 267949, upload-time = "2026-08-06T13:50:05.557Z" }, + { url = "https://files.pythonhosted.org/packages/78/ea/dc96a11375e83c045c2f7c61fb6918277cfe9401db7c0f7b1d111a84b2e5/coverage-7.15.4-cp315-cp315t-musllinux_1_2_i686.whl", hash = "sha256:d9df165544774574ee004b953023d1bebada1894a80b1052a43d798b0f676e67", size = 264421, upload-time = "2026-08-06T13:50:07.612Z" }, + { url = "https://files.pythonhosted.org/packages/c8/86/b77131a0f9503ce461cd577076147d7a9040f0c5dda772686f729e2cc9cb/coverage-7.15.4-cp315-cp315t-musllinux_1_2_ppc64le.whl", hash = "sha256:f9de0a24a4079b53e523b5c5e2c5945ec251ab486652659955187cf255a259bc", size = 269121, upload-time = "2026-08-06T13:50:09.58Z" }, + { url = "https://files.pythonhosted.org/packages/24/24/944bc35007862955e7ebf05754e645419dcf5d7526c52735cfa2715e8ebf/coverage-7.15.4-cp315-cp315t-musllinux_1_2_riscv64.whl", hash = "sha256:150089274bdc9f940628552cb92844e0223c987f1902ab8efe9f45a2ec758d88", size = 264565, upload-time = "2026-08-06T13:50:11.722Z" }, + { url = "https://files.pythonhosted.org/packages/c7/cc/a3bb9f93e7e740659163e2ea584f8196ddcd2c456a5dbe15f6c50105fec1/coverage-7.15.4-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:a58a94fed5da6997d258e8f7668c1e195fbd04a691d781b7558f1e468f9e68bc", size = 266522, upload-time = "2026-08-06T13:50:13.786Z" }, + { url = "https://files.pythonhosted.org/packages/49/dd/e0e40f3560d878d888c580698ff5ad1179f5e1c3ac949684ef66b41a3817/coverage-7.15.4-cp315-cp315t-win32.whl", hash = "sha256:ebd5a6d8466ff30836572f3ba2cae8a5e8f85029b1c6d5e2ed338dc472a5166a", size = 225068, upload-time = "2026-08-06T13:50:15.825Z" }, + { url = "https://files.pythonhosted.org/packages/c6/7e/37732ea80eebc30e976e4cdab15c190bc42d96959a42e38ddf6f8c60468f/coverage-7.15.4-cp315-cp315t-win_amd64.whl", hash = "sha256:288bde2a2d7ab6b6c2d7252fcde8b524387f2d970bdba9658fc6f8bbcaef0f9b", size = 225895, upload-time = "2026-08-06T13:50:17.928Z" }, + { url = "https://files.pythonhosted.org/packages/c6/08/1e00f7923eaaba45fb3d51dd794125fc766304b1df264f3a9c6557bfb30e/coverage-7.15.4-cp315-cp315t-win_arm64.whl", hash = "sha256:68be5e1de60ff13c9095bbec0e5a7fa45b33b101752215b91345ea1f61c4a278", size = 225213, upload-time = "2026-08-06T13:50:19.981Z" }, + { url = "https://files.pythonhosted.org/packages/b4/d9/e70c286c979378f061d8266e279b686ab0b0b688e1fe0af864684f23a77d/coverage-7.15.4-py3-none-any.whl", hash = "sha256:964730a1e9de9c0cf11be6a1a3c79ce419c34882842abd256086ba4698705e84", size = 214332, upload-time = "2026-08-06T13:50:22.192Z" }, ] [[package]] @@ -335,7 +365,7 @@ dev = [ [package.metadata] requires-dist = [ - { name = "coverage", marker = "extra == 'dev'", specifier = "==7.15.2" }, + { name = "coverage", marker = "extra == 'dev'", specifier = "==7.15.4" }, { name = "cryptography", specifier = "==50.0.0" }, { name = "fastapi", specifier = "==0.141.1" }, { name = "httpx", specifier = "==0.28.1" }, @@ -345,7 +375,7 @@ requires-dist = [ { name = "pytest", marker = "extra == 'dev'", specifier = "==9.1.1" }, { name = "pyyaml", specifier = "==6.0.3" }, { name = "ruff", marker = "extra == 'dev'", specifier = "==0.16.1" }, - { name = "setuptools", marker = "extra == 'dev'", specifier = "==83.0.0" }, + { name = "setuptools", marker = "extra == 'dev'", specifier = "==84.0.0" }, { name = "uvicorn", specifier = "==0.52.1" }, ] provides-extras = ["dev"] @@ -726,11 +756,11 @@ wheels = [ [[package]] name = "setuptools" -version = "83.0.0" +version = "84.0.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/34/26/f5d29e25ffdb535afef2d35cdb55b325298f96debd670da4c325e08d70f4/setuptools-83.0.0.tar.gz", hash = "sha256:025bccbbf0fa05b6192bc64ae1e7b16e001fd6d6d4d5de03c97b1c1ade523bef", size = 1154254, upload-time = "2026-07-04T15:31:22.699Z" } +sdist = { url = "https://files.pythonhosted.org/packages/6d/44/f5da03a8ef95d369145c5bb53050e7877c9f3d312e128605fd9504829143/setuptools-84.0.0.tar.gz", hash = "sha256:f4695c21257f0d9b537ec2692c941d02ee143b7cc1276941349a546573b2ef73", size = 1168449, upload-time = "2026-08-08T18:27:58.365Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/5d/40/e1e72872c6354b306daef1703549e8e83b4d43cfea356311bf722a043752/setuptools-83.0.0-py3-none-any.whl", hash = "sha256:29b23c360f22f414dc7336bb39178cc7bcbf6021ed2733cde173f09dba19abb3", size = 1008090, upload-time = "2026-07-04T15:31:20.885Z" }, + { url = "https://files.pythonhosted.org/packages/95/9c/c510029fc6ef33a6275cd2c5d3cecd6613dfd6aa401d57c54f1c18852ccf/setuptools-84.0.0-py3-none-any.whl", hash = "sha256:51a52592b3b99e102b609654876bd65f19f999935166d1352678931132b0c670", size = 818216, upload-time = "2026-08-08T18:27:56.719Z" }, ] [[package]] From 43e76072992d1490ebf8d84a62701d83fb096952 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 14 Aug 2026 19:30:37 +0900 Subject: [PATCH 07/70] docs: separate downstream RP evidence --- docs/doctoring/oidc-rp-claim-mapper-profile.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/docs/doctoring/oidc-rp-claim-mapper-profile.md b/docs/doctoring/oidc-rp-claim-mapper-profile.md index 189fa62..9627b70 100644 --- a/docs/doctoring/oidc-rp-claim-mapper-profile.md +++ b/docs/doctoring/oidc-rp-claim-mapper-profile.md @@ -74,10 +74,9 @@ Keycloak's declarative user profile permits a required role of `admin` or `user`. The LineageWeave `org` and `workspace` attributes use `{"roles":["admin"]}` because the same profile makes those fields viewable and editable only in administrator context. A user-context requirement would direct -an end user to repair attributes they cannot edit. The receiving application is -independent of this provisioning workflow: after normal token verification, it -rejects an absent, empty, or non-scalar account dimension before tenant/resource -ABAC and bounded RBAC run. +an end user to repair attributes they cannot edit. This Keyverse policy proves +only the issuer-side provisioning constraint; receiving-application claim +validation is a separate operational-acceptance requirement. ## Stricter Keyverse product policy @@ -139,8 +138,11 @@ RED receipt before the template was added. - The deployed Keycloak version preserves the reviewed mapper semantics. - A LineageWeave account has exactly one scalar `org` and `workspace` value and a least-privilege set of client roles for `lineageweave-web`. -- LineageWeave validates a list-valued `role` claim and applies tenant/resource - ABAC before its product-role mapping. +- After normal token verification, LineageWeave must reject an absent, empty, + or non-scalar `org` or `workspace` claim before tenant/resource ABAC and its + bounded product-role mapping. This downstream behavior requires its own + implementation and runtime acceptance evidence; it is not established by + Keyverse mapper validation or reconciliation alone. ## Limitations and follow-up From eed91c9a62d46d03d98f4aa984796c4f11f758aa Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Thu, 20 Aug 2026 18:53:45 +0900 Subject: [PATCH 08/70] docs: record product technical gap baseline --- CHANGELOG.md | 3 + docs/TRACEABILITY.md | 3 +- .../product-technical-gap-baseline.md | 62 +++++ docs/product-technical-gap-baseline.md | 242 ++++++++++++++++++ 4 files changed, 309 insertions(+), 1 deletion(-) create mode 100644 docs/doctoring/product-technical-gap-baseline.md create mode 100644 docs/product-technical-gap-baseline.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c40e76..e824e86 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ Keep a Changelog, and releases use semantic versioning. ### Added +- A dated product and technical gap baseline that records the live PR/Issue + queue, exact-head Check evidence, buyer-visible authorization and runtime + acceptance gaps, and the protected hourly loop. - ADR-0008 and the non-fork RP authorization matrix, requiring explicit Keyverse token validation, tenant/resource ABAC, bounded RBAC, and cross-tenant acceptance evidence per application. diff --git a/docs/TRACEABILITY.md b/docs/TRACEABILITY.md index b06bb7b..164798d 100644 --- a/docs/TRACEABILITY.md +++ b/docs/TRACEABILITY.md @@ -1,7 +1,7 @@ # Keyverse Requirements and Evidence Traceability **Status:** Accepted cross-cutting baseline -**Last reviewed:** 2026-08-14 +**Last reviewed:** 2026-08-20 | Requirement / decision | Standards / authoritative basis | Source/evidence boundary | Maturity | |---|---|---|---| @@ -29,6 +29,7 @@ | contextual-orchestrator Keyverse identity and tenant boundary | ADR-0008; deployment-owned OIDC validation plus downstream scope RBAC and org/workspace ABAC | PR #109 `32ba3a9` adds the injected verifier seam; stacked PR #110 `8607eba` requires `VerifiedIdentity`, rejects boolean-only authorization, binds workflow/evaluation/batch resources to secret-free tenant context, and denies cross-tenant or ownerless reads; main remains unchanged until both protected PRs merge | active-PR | | sidecar anonymous-access boundary | ADR-0008; private service-boundary and least-privilege policy | newsdom-api protected `develop` `3d0426b` (PR #595) fail-closed token gate, startup credential registry, explicit anonymous opt-in, review-fixed authenticated examples/healthcheck/401 contract, and pypdf Trivy remediation; Keyverse-aware gateway evidence remains required for exposure | implemented-main | | 100% production statement/branch/docstring | CWL quality contract | CI/pytest/interrogate | implemented-main | +| product and technical gap baseline | PRD/TRD/ADR-0008/operability and current GitHub evidence | [`docs/product-technical-gap-baseline.md`](product-technical-gap-baseline.md) plus [`docs/doctoring/product-technical-gap-baseline.md`](doctoring/product-technical-gap-baseline.md) | active-PR | ## Research, standards, and operations records diff --git a/docs/doctoring/product-technical-gap-baseline.md b/docs/doctoring/product-technical-gap-baseline.md new file mode 100644 index 0000000..0c6759f --- /dev/null +++ b/docs/doctoring/product-technical-gap-baseline.md @@ -0,0 +1,62 @@ +# Product-technical gap baseline doctoring record + +**Date:** 2026-08-20 +**Scope:** Keyverse product, trust-boundary, PR queue, and release evidence + +## Interpretation + +The baseline classifies facts by evidence boundary. Repository source/tests can +prove deterministic validation and reconciliation behavior. They cannot prove a +live issuer, browser login, token signature acceptance, downstream tenant +authorization, or release provenance without an approved runtime lane. This +record therefore treats missing runtime evidence as `gap-not-claimed`, not as a +failed implementation and not as success. + +The current mapper policy remains closed. `role`, `org`, and `workspace` are +issuer-side product claims; a relying party must define and verify its own +tenant/resource/purpose semantics before RBAC. Adding a generic tenant claim +would be a new authorization profile and requires a separate ADR, red tests, +consumer evidence, and traceability update. + +## Standards interpretation + +- OpenID Connect Core requires exact issuer matching, client audience + validation, signature validation, and expiration processing during ID Token + validation. These are consumer acceptance requirements, not evidence supplied + by an issuer-side mapper configuration. +- RFC 8725 requires applications to validate issuer ownership, issuer/subject + validity, and audience association, and to reject invalid tokens. This + supports keeping tenant and resource authorization after cryptographic token + validation. +- RFC 9700 is the current OAuth 2.0 Security BCP used here. It supports exact + redirect matching and authorization-code + PKCE protection, with `S256` as + the interoperable code-challenge method for this profile. +- Keycloak's current administration guide documents protocol mappers as the + mechanism that projects roles and user/session data into tokens. That vendor + behavior does not establish that a receiving application enforces ABAC/RBAC. + +## APA 7th references + +OpenID Foundation. (2014). *OpenID Connect Core 1.0*. +https://openid.net/specs/openid-connect-core-1_0-18.html + +Keycloak. (2026). *Server administration guide*. +https://www.keycloak.org/docs/latest/server_admin/ + +Lodderstedt, T., Bradley, J., Labunets, A., & Fett, D. (2025). *Best current +practice for OAuth 2.0 security* (RFC 9700). Internet Engineering Task Force. +https://www.rfc-editor.org/rfc/rfc9700.html + +Sheffer, Y., Hardt, D., & Jones, M. (2020). *JSON Web Token best current +practices* (RFC 8725). Internet Engineering Task Force. +https://www.rfc-editor.org/rfc/rfc8725.html + +## Evidence sources + +- `docs/PRD.md`, `docs/TRD.md`, `ARCHITECTURE.md`, `docs/OPERABILITY.md`, + `docs/THREAT_MODEL.md`, `docs/TEST_STRATEGY.md`, and `docs/TRACEABILITY.md`. +- ADR-0008 and ADR-0009 plus their related specification, plan, operations, + and doctoring records. +- Exact-head GitHub PR, review, issue, check-run, ruleset, and scheduled-run + queries performed on 2026-08-20. No credential, private payload, or PII is + recorded here. diff --git a/docs/product-technical-gap-baseline.md b/docs/product-technical-gap-baseline.md new file mode 100644 index 0000000..405818c --- /dev/null +++ b/docs/product-technical-gap-baseline.md @@ -0,0 +1,242 @@ +# Keyverse product and technical gap baseline + +**Evidence snapshot:** 2026-08-20 (Asia/Seoul) +**Repository:** `ContextualWisdomLab/keyverse` +**Protected-main head observed:** `ce207dfd42975db61c82a5963e206fc1db14ac2b` +**Status:** live inventory and gap register; not a release acceptance record + +This document turns the accepted PRD, TRD, architecture, ADRs, doctoring +records, and current GitHub state into an executable buyer-facing backlog. +It separates implementation on protected `main`, active PR work, accepted +contracts, and evidence that is still absent. A green unit or preflight check +does not promote a lower-level result into login, token, authorization, or +release acceptance. + +## Product contract + +Keyverse is a standalone and embeddable identity control plane for CWL, Naruon, +and sibling products. Its durable boundary owns passwordless-first Keycloak +policy, federation and directory preflight/reconciliation, account +unification, SCIM lifecycle, relying-party desired state, audit, and safe +deployment operations. Downstream applications still own token verification, +tenant/resource/purpose ABAC, and bounded RBAC. + +The trust order is: + +```text +portable realm policy + -> authenticated side-effect-free preflight + -> secret-free desired state + -> exact remote reconciliation + -> post-mutation observation and receipt + -> controlled protocol acceptance + -> downstream authorization acceptance +``` + +The final two stages are intentionally separate from Keycloak mapper +configuration. A relying-party registration or mapper receipt is never proof +that a receiving application validates issuer, signature, expiry, audience, +tenant, or resource ownership. + +## Evidence classification + +| Classification | Meaning in this baseline | +|---|---| +| `implemented-main` | Source and tests are on the observed protected-main head. | +| `active-PR` | Work exists in an open PR and is not part of protected-main evidence. | +| `accepted-contract` | An ADR/specification defines the policy, but runtime or buyer acceptance may still be absent. | +| `gap-not-claimed` | The repository deliberately makes no success claim until stronger evidence exists. | + +## Current capability map + +| Capability | Current state | Evidence boundary | +|---|---|---| +| Passwordless local identity | `implemented-main` | Portable realm validation requires WebAuthn passwordless flow and rejects a password authenticator. | +| Federation and LDAP preflight | `implemented-main` | Closed validators are side-effect-free; apply and external bind/discovery remain separate. | +| Account linking, merge, and SCIM full replacement | `implemented-main` | Verified identity evidence, tombstones, audit, and shared merge/`PUT` lock are covered. SCIM `PATCH active=false` is intentionally narrower. | +| Secret-free RP desired state | `implemented-main` | Exact client identity, duplicate fail-closed behavior, re-observation, receipt, and remote-first delete are implemented. | +| Closed RP mapper profile | `implemented-main` / `accepted-contract` | Canonical `role`, `org`, `workspace` policy is protected; ADR-0009 remains a separate `lineageweave-web` profile. | +| Downstream RP authorization | `gap-not-claimed` | Each consumer must independently prove issuer/JWKS/signature/expiry/audience, tenant/resource ABAC, and RBAC. | +| Real Keyverse login and token acceptance | `gap-not-claimed` | Local tests do not establish a live issuer, controlled account, browser flow, or consumer token acceptance. | +| Standalone Compose and Helm module boundaries | `implemented-main` | Repository contracts and validators exist; release-grade deployment/rollback evidence is still required. | +| Hourly product and PR loop | `active-PR` / `implemented-main` | Workflows and fail-closed guards exist; every scheduled run must be checked against exact external evidence. | +| Release artifact acceptance | `gap-not-claimed` | Version, immutable image digest, SBOM/provenance, rollback, and exact-main acceptance remain release gates. | + +## Live PR inventory + +The following is the current open-PR inventory. `Checks` means the exact head +rollup observed on 2026-08-20; it is not inherited from a predecessor commit. + +| PR | Scope | Exact-head Checks | Review state | Next safe action | +|---:|---|---|---|---| +| [#112](https://github.com/ContextualWisdomLab/keyverse/pull/112) | Resync account-unification lockfile | PASS | review required | Obtain independent review, then let protected automation re-check and merge. | +| [#111](https://github.com/ContextualWisdomLab/keyverse/pull/111) | CodeQL init 4.37.7 | FAIL: account tests, CodeQL, Strix | review required | Keep coupled with #110; revalidate after lockfile and action-version coupling is resolved. | +| [#110](https://github.com/ContextualWisdomLab/keyverse/pull/110) | CodeQL analyze 4.37.7 | FAIL: account tests, CodeQL | review required | Treat as the companion of #111; do not merge the action pair independently. | +| [#109](https://github.com/ContextualWisdomLab/keyverse/pull/109) | `typing-inspection` update | FAIL: account tests | review required | Re-check after #112; the observed failure is the stale locked dependency graph. | +| [#108](https://github.com/ContextualWisdomLab/keyverse/pull/108) | Ruff update | FAIL: account tests | review required | Re-check after #112; do not rerun unchanged checks. | +| [#107](https://github.com/ContextualWisdomLab/keyverse/pull/107) | Uvicorn update | FAIL: account tests | review required | Re-check after #112; do not rerun unchanged checks. | +| [#106](https://github.com/ContextualWisdomLab/keyverse/pull/106) | `setup-uv` update | FAIL: account tests | review required | Re-check after #112; do not rerun unchanged checks. | +| [#105](https://github.com/ContextualWisdomLab/keyverse/pull/105) | `harden-runner` update | FAIL: account tests | changes requested | Fix the locked dependency gate first, then obtain a new exact-head review. | +| [#104](https://github.com/ContextualWisdomLab/keyverse/pull/104) | ADR and buyer README expansion | FAIL: account tests | draft | Keep draft until scope and exact-main evidence are ready. | +| [#103](https://github.com/ContextualWisdomLab/keyverse/pull/103) | Hierarchical authorization, login helper, PATs | FAIL: Strix | changes requested | Inspect the unavailable Strix evidence and security findings before any merge claim. | +| [#101](https://github.com/ContextualWisdomLab/keyverse/pull/101) | Atomic coupled Python dependency updates | PASS | changes requested | Obtain fresh independent review; this is the policy companion to the lockfile gap. | +| [#100](https://github.com/ContextualWisdomLab/keyverse/pull/100) | `lineageweave-web` account-derived claims | PASS | changes requested | Existing actionable comments are addressed on head `43e76072992d1490ebf8d84a62701d83fb096952`; obtain independent review, without self-approval. | +| [#83](https://github.com/ContextualWisdomLab/keyverse/pull/83) | Remove runtime application RPs from portable realm | PASS | changes requested | Reconfirm current-head approval and latest-pusher rule before protected merge. | + +### Check failure root causes observed + +- The representative account-test failure on Dependabot PRs stopped at + `uv sync --locked`: the checked-in lockfile needed updating. This is a + dependency-graph consistency failure, not evidence that the product tests + failed after installation. +- PRs #110 and #111 update the two coupled CodeQL actions separately. The + #111 run loaded configuration for 4.37.7 while running 4.37.6. They must be + evaluated as one compatible pair, with fresh exact-head Checks after the + lockfile queue is clear. +- The historical #103 Strix run is not currently retrievable through the + Actions API. That is missing evidence, not a pass and not permission to + bypass the security gate. + +## Open Issue inventory + +| Issue | Product signal | Classification | Required outcome | +|---:|---|---|---| +| [#102](https://github.com/ContextualWisdomLab/keyverse/issues/102) | Hierarchical authorization plane, login helper, PATs | `active-PR` | Security-review the proposed authority model and prove fail-closed token/tenant/resource behavior. | +| [#99](https://github.com/ContextualWisdomLab/keyverse/issues/99) | Orphaned federation and product-loop workflow identities | `gap-not-claimed` | Disable only through the owning protected workflow/organization path and record live identity evidence. | +| [#71](https://github.com/ContextualWisdomLab/keyverse/issues/71) | Remove runtime application RPs from portable import | `active-PR` | Merge #83 only after current-head protected evidence. | +| [#2](https://github.com/ContextualWisdomLab/keyverse/issues/2) | Central IdP plus external-IdP federation | `accepted-contract` | Use the existing closed preflight/apply boundary and add approved-environment acceptance. | + +## Gap register and buyer-visible order + +### G0 — Protected queue convergence + +**State:** `active-PR` +**Buyer impact:** A buyer cannot rely on a controlled identity product if the +repository cannot distinguish a reviewed, current, passing artifact from a +stale or coupled dependency proposal. + +**Required loop:** inventory PRs; inspect review threads; fix the root cause; +verify the exact head; require independent approval; let the protected steward +arm normal auto-merge; verify merge SHA; then re-list. Never self-approve, +force-push, admin-merge, or treat queued/retrievable-missing Checks as green. + +### G1 — Coupled dependency and workflow updates + +**State:** `active-PR` +**Root cause:** the current queue contains a lockfile consistency fix and two +CodeQL action updates that are safe only as a coupled set. + +**Acceptance:** #112 passes the full current Checks and receives independent +approval; #101/#110/#111 are then re-evaluated on current bases; `uv sync +--locked` succeeds; both CodeQL actions resolve the same compatible version; +Strix and security checks are completed; no stale predecessor evidence is +counted. + +### G2 — Stable downstream tenant semantics + +**State:** `gap-not-claimed` with `active-PR` evidence in #100 and #103 +**Root cause:** Keyverse emits a deliberately closed `role`, `org`, and +`workspace` profile, but a consumer must not guess that either account +dimension is an application-specific `tenant_id`. + +**Acceptance:** publish one explicit consumer contract per RP: claim name, +cardinality, lifecycle, audience, membership ambiguity behavior, and the +negative vector in which a valid token for tenant B cannot authorize tenant A. +Until a consumer proves that contract, it remains deployment-restricted. +Adding a generic tenant mapper to Keyverse is not an acceptable shortcut; it +would expand the closed mapper policy without a separately reviewed profile. + +### G3 — Controlled real login and authorization acceptance + +**State:** `gap-not-claimed` +**Buyer impact:** Static realm/template validation is not a buyer-observable +login or authorization guarantee. + +**Acceptance:** in an approved environment, record redacted evidence for +discovery/issuer, JWKS signature and algorithm, authorization-code + PKCE +`S256`, passwordless browser login, token `iss`/`sub`/`aud`/time claims, +controlled logout, tenant/resource ABAC, role/scope RBAC, cross-tenant denial, +and verifier-unavailable fail-closed behavior. Keep secrets and PII out of +repository artifacts. An unavailable issuer must remain `unavailable`, never +be converted into a synthetic success. + +### G4 — SCIM deactivation concurrency boundary + +**State:** `accepted-contract` with an explicit protected-main limitation +**Root cause:** `PATCH active=false` is not covered by the shared cross-process +lock used by merge and full-replacement `PUT`. + +**Acceptance:** add a real concurrent deactivation/merge regression, join the +same lock only if the implementation preserves tombstone and survivor +invariants, and update PRD/TRD/ERD/Threat/Test/Operability/doctoring together. + +### G5 — Physical database and hot-partition evidence + +**State:** `gap-not-claimed` +**Root cause:** the ERD defines logical tenant-qualified uniqueness and +two-word-or-longer snake_case names, but a production claim needs migration, +index, partition-key, skew, and recovery evidence from the owning database. + +**Acceptance:** run PostgreSQL migration/rollback tests with tenant-scoped +composite constraints, measure skew under concentrated tenants, document the +chosen partition/index strategy, and prove backup/restore. Do not add a +partitioning abstraction before measured pressure requires it. + +### G6 — Release and module acceptance + +**State:** `gap-not-claimed` +**Acceptance:** on exact protected `main`, complete regression and controlled +deployment acceptance; publish immutable image digest, SBOM, provenance, +rollback/restore evidence, version consistency, and CHANGELOG entry. A green +feature PR is not a release. + +### G7 — Ecosystem consumer readiness + +**State:** `accepted-contract` / `gap-not-claimed` +**Root cause:** Keyverse exposes stable HTTP/protocol boundaries, but a module +boundary is only buyer-ready when each owned consumer proves its own +authorization and operational acceptance. + +**Acceptance order:** Keyverse issuer and RP contract first; then the highest +leverage owned consumer with a falsifiable browser/API acceptance lane; then +federation/SCIM connectors. Preserve import/REST boundaries and do not copy +private Keycloak internals into sibling repositories. + +## Hourly loop contract + +The repository currently schedules: + +- **Hourly PR steward:** UTC minute `17`, inventory and advance only trusted + same-repository PRs with exact-head independent approval and required Checks. +- **Hourly product development:** UTC minute `41`, after the steward's evidence + settles; create at most one bounded draft product-gap PR only when the open + PR queue is empty and protected-main evidence is healthy. + +The current live run inventory showed a successful product-development run at +the protected-main head and a queued PR-steward run. Queued or delayed runs are +not blockers for independent documentation, review analysis, standards work, +or test design, but they are not evidence of a merge or release. + +## Standards interpretation and design tooling boundary + +The baseline follows OpenID Connect's exact issuer/audience/time/signature +validation boundary, JWT Best Current Practices' issuer/subject/audience +validation, and OAuth Security BCP's authorization-code + PKCE and exact +redirect guidance. Keycloak protocol mappers are treated as claim projection +configuration, not as downstream authorization proof. + +This change adds no UI or frontend behavior, so no Figma file or Storybook +inventory is required for this baseline. If a future buyer gap changes a web +surface, the owning ADR must record the Figma File ID, design tokens, reusable +components, Storybook inventory, and interaction/accessibility acceptance +before implementation is claimed. + +## References + +- OpenID Foundation. (2014). *OpenID Connect Core 1.0*. https://openid.net/specs/openid-connect-core-1_0-18.html +- Keycloak. (2026). *Server administration guide*. https://www.keycloak.org/docs/latest/server_admin/ +- Lodderstedt, T., Bradley, J., Labunets, A., & Fett, D. (2025). *Best current practice for OAuth 2.0 security* (RFC 9700). Internet Engineering Task Force. https://www.rfc-editor.org/rfc/rfc9700.html +- Sheffer, Y., Hardt, D., & Jones, M. (2020). *JSON Web Token best current practices* (RFC 8725). Internet Engineering Task Force. https://www.rfc-editor.org/rfc/rfc8725.html + +Interpretations and repository evidence are maintained separately in +[`docs/doctoring/product-technical-gap-baseline.md`](doctoring/product-technical-gap-baseline.md). From eafa344780d0fd355a6546d302a10ff04d8ffbb1 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Thu, 20 Aug 2026 18:57:29 +0900 Subject: [PATCH 09/70] docs: refresh exact head gap evidence --- docs/doctoring/product-technical-gap-baseline.md | 5 +++-- docs/product-technical-gap-baseline.md | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/doctoring/product-technical-gap-baseline.md b/docs/doctoring/product-technical-gap-baseline.md index 0c6759f..6b65a2a 100644 --- a/docs/doctoring/product-technical-gap-baseline.md +++ b/docs/doctoring/product-technical-gap-baseline.md @@ -58,5 +58,6 @@ https://www.rfc-editor.org/rfc/rfc8725.html - ADR-0008 and ADR-0009 plus their related specification, plan, operations, and doctoring records. - Exact-head GitHub PR, review, issue, check-run, ruleset, and scheduled-run - queries performed on 2026-08-20. No credential, private payload, or PII is - recorded here. + queries performed on 2026-08-20. The follow-up #100 head after this baseline + commit is recorded as pending until its new Checks complete. No credential, + private payload, or PII is recorded here. diff --git a/docs/product-technical-gap-baseline.md b/docs/product-technical-gap-baseline.md index 405818c..46ccd21 100644 --- a/docs/product-technical-gap-baseline.md +++ b/docs/product-technical-gap-baseline.md @@ -66,6 +66,7 @@ tenant, or resource ownership. The following is the current open-PR inventory. `Checks` means the exact head rollup observed on 2026-08-20; it is not inherited from a predecessor commit. +The #100 row was refreshed after this baseline commit requeued its checks. | PR | Scope | Exact-head Checks | Review state | Next safe action | |---:|---|---|---|---| @@ -80,7 +81,7 @@ rollup observed on 2026-08-20; it is not inherited from a predecessor commit. | [#104](https://github.com/ContextualWisdomLab/keyverse/pull/104) | ADR and buyer README expansion | FAIL: account tests | draft | Keep draft until scope and exact-main evidence are ready. | | [#103](https://github.com/ContextualWisdomLab/keyverse/pull/103) | Hierarchical authorization, login helper, PATs | FAIL: Strix | changes requested | Inspect the unavailable Strix evidence and security findings before any merge claim. | | [#101](https://github.com/ContextualWisdomLab/keyverse/pull/101) | Atomic coupled Python dependency updates | PASS | changes requested | Obtain fresh independent review; this is the policy companion to the lockfile gap. | -| [#100](https://github.com/ContextualWisdomLab/keyverse/pull/100) | `lineageweave-web` account-derived claims | PASS | changes requested | Existing actionable comments are addressed on head `43e76072992d1490ebf8d84a62701d83fb096952`; obtain independent review, without self-approval. | +| [#100](https://github.com/ContextualWisdomLab/keyverse/pull/100) | `lineageweave-web` account-derived claims | PENDING on exact head `eed91c9a62d46d03d98f4aa984796c4f11f758aa` | changes requested; fresh review requested | Do not transfer the predecessor PASS; wait for exact-head Checks and independent review, without self-approval. | | [#83](https://github.com/ContextualWisdomLab/keyverse/pull/83) | Remove runtime application RPs from portable realm | PASS | changes requested | Reconfirm current-head approval and latest-pusher rule before protected merge. | ### Check failure root causes observed From f9d0159751bee21ee4f4f6dbc27c5719b95d5087 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Thu, 20 Aug 2026 19:17:47 +0900 Subject: [PATCH 10/70] docs: define lineageweave tenant mapping --- CHANGELOG.md | 4 ++++ ...-lineageweave-account-derived-rp-claims.md | 23 ++++++++++++++++++ .../product-technical-gap-baseline.md | 9 +++++++ docs/operations/oidc-rp-reconciliation.md | 17 +++++++++++++ docs/product-technical-gap-baseline.md | 14 +++++++---- tests/test_documentation_contract.py | 24 +++++++++++++++++++ 6 files changed, 86 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e824e86..8532636 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,10 @@ Keep a Changelog, and releases use semantic versioning. same-client roles plus exact scalar `org` and `workspace` account attributes, with no static/dynamic mixing, a secret-free deployment template, and reconciliation regression coverage. +- A normative LineageWeave tenant mapping: `org` is the opaque external tenant + key, `workspace` is its child namespace, ambiguous or multi-membership + resolution fails closed, and lifecycle changes require a new token or + session renewal; no generic `tenant` mapper was introduced. - Durable, secret-free OIDC relying-party desired-state CRUD and reconciliation with exact `clientId` matching, duplicate fail-closed behavior, post-mutation re-observation, canonical apply receipts, realm-rebuild recovery, per-client diff --git a/docs/adr/0009-lineageweave-account-derived-rp-claims.md b/docs/adr/0009-lineageweave-account-derived-rp-claims.md index 2f19e35..0076e0e 100644 --- a/docs/adr/0009-lineageweave-account-derived-rp-claims.md +++ b/docs/adr/0009-lineageweave-account-derived-rp-claims.md @@ -60,6 +60,29 @@ or recognized-role RBAC decision, then bind both values to the requested resource. A green Keyverse preflight or apply receipt is not controlled login or authorization evidence. +### Normative tenant mapping + +For this profile, `org` is the opaque external tenant key. It has exactly one +trimmed scalar value per token and is mapped by the receiving application to +exactly one local tenant record through a verified configuration or membership +lookup; it is never inferred from client ID, subject, email, or role. +`workspace` is a child namespace under `org`, also with exactly one trimmed +scalar value per token. It is not a replacement tenant key: a consumer must +prove that the workspace belongs to the resolved organization before resource +lookup. + +The profile does not represent multiple memberships. Multiple memberships are +not represented by comma-separated values, arrays, or delimiter conventions. +If membership resolution is ambiguous, missing, or maps either claim to more +than one local record, the consumer must deny before ABAC or RBAC. Operators +must issue a new token or session renewal after an organization, workspace, or +membership change; existing tokens remain bounded by their configured expiry +and must never be reinterpreted as a new tenant binding. + +This is a normative mapping from the existing `org` and `workspace` claims, +not a new `tenant` mapper. A future multi-membership or scalar-tenant profile +requires a separate ADR, RED regression, and downstream acceptance evidence. + ```mermaid flowchart LR A["Verified Keyverse account"] --> B["Same-client role assignment"] diff --git a/docs/doctoring/product-technical-gap-baseline.md b/docs/doctoring/product-technical-gap-baseline.md index 6b65a2a..26ec996 100644 --- a/docs/doctoring/product-technical-gap-baseline.md +++ b/docs/doctoring/product-technical-gap-baseline.md @@ -18,6 +18,15 @@ tenant/resource/purpose semantics before RBAC. Adding a generic tenant claim would be a new authorization profile and requires a separate ADR, red tests, consumer evidence, and traceability update. +The follow-up LineageWeave contract makes the existing mapping explicit without +expanding that profile: `org` is one opaque external tenant key, `workspace` is +one child namespace under that organization, multiple memberships have no +comma-separated or array encoding, and ambiguous membership resolution denies +before ABAC/RBAC. A changed membership requires a new token or session renewal. +This closes the contract ambiguity only; real login, token validation, local +tenant binding, cross-tenant denial, and resource authorization remain runtime +evidence gaps. + ## Standards interpretation - OpenID Connect Core requires exact issuer matching, client audience diff --git a/docs/operations/oidc-rp-reconciliation.md b/docs/operations/oidc-rp-reconciliation.md index b77d5f3..f4f28ae 100644 --- a/docs/operations/oidc-rp-reconciliation.md +++ b/docs/operations/oidc-rp-reconciliation.md @@ -67,6 +67,23 @@ acceptance must prove issuer/signature/expiry/audience validation, tenant and resource ABAC denial, role downgrade, logout, and rollback. A compose-only IdP or preflight receipt does not satisfy that evidence. +### Normative tenant mapping for LineageWeave + +For the `lineageweave-web` profile, `org` is the opaque external tenant key +and must resolve to exactly one local tenant record. `workspace` is a child +namespace under `org` and must resolve to a workspace belonging to that tenant. +Both claims are one trimmed scalar value per token; neither may be inferred +from client ID, subject, email, or role. Multiple memberships are not +represented by comma-separated values, arrays, or delimiter conventions. + +Before resource access, reject missing, malformed, unmapped, or ambiguous +tenant/workspace resolution. If membership resolution is ambiguous, do not +continue to role or scope checks. Operators must issue a new token or session +renewal after organization, workspace, or membership changes; an existing +token is bounded by its expiry and must not be silently rebound to another +tenant. This mapping deliberately uses the existing `org` and `workspace` +claims and does not add a generic `tenant` mapper. + ## Example ```bash diff --git a/docs/product-technical-gap-baseline.md b/docs/product-technical-gap-baseline.md index 46ccd21..c0f87bd 100644 --- a/docs/product-technical-gap-baseline.md +++ b/docs/product-technical-gap-baseline.md @@ -135,15 +135,19 @@ counted. ### G2 — Stable downstream tenant semantics -**State:** `gap-not-claimed` with `active-PR` evidence in #100 and #103 +**State:** `active-PR` contract clarification; runtime remains `gap-not-claimed` **Root cause:** Keyverse emits a deliberately closed `role`, `org`, and `workspace` profile, but a consumer must not guess that either account dimension is an application-specific `tenant_id`. -**Acceptance:** publish one explicit consumer contract per RP: claim name, -cardinality, lifecycle, audience, membership ambiguity behavior, and the -negative vector in which a valid token for tenant B cannot authorize tenant A. -Until a consumer proves that contract, it remains deployment-restricted. +**Contract clarification:** for `lineageweave-web`, `org` is the one opaque +external tenant key and `workspace` is one child namespace under that `org`. +Multiple memberships have no comma-separated or array encoding; missing, +unmapped, or ambiguous membership resolution denies before ABAC/RBAC. A +membership change requires a new token or session renewal. The full consumer +acceptance still requires the negative vector in which a valid token for tenant +B cannot authorize tenant A, plus resource authorization evidence. +Until a consumer proves that runtime contract, it remains deployment-restricted. Adding a generic tenant mapper to Keyverse is not an acceptable shortcut; it would expand the closed mapper policy without a separately reviewed profile. diff --git a/tests/test_documentation_contract.py b/tests/test_documentation_contract.py index 21abf99..fc9100e 100644 --- a/tests/test_documentation_contract.py +++ b/tests/test_documentation_contract.py @@ -99,3 +99,27 @@ def test_adr_index_contains_governing_identity_decisions() -> None: adr_path = ROOT / "docs" / "adr" / adr assert adr_path.is_file(), f"ADR file is missing: {adr}" assert f"]({adr})" in index, f"ADR index does not link {adr}" + + +def test_lineageweave_tenant_contract_is_explicit() -> None: + """Keep the account-derived tenant mapping deterministic for consumers.""" + + adr = _read("docs/adr/0009-lineageweave-account-derived-rp-claims.md") + operations = _read("docs/operations/oidc-rp-reconciliation.md") + adr_contract = " ".join(adr.lower().split()) + operations_contract = " ".join(operations.lower().split()) + required_markers = ( + "`org` is the opaque external tenant key", + "`workspace` is a child namespace under `org`", + "multiple memberships are not represented by comma-separated values", + "membership resolution is ambiguous", + "new token or session renewal", + ) + for marker in required_markers: + assert marker in adr_contract, ( + f"ADR-0009 is missing tenant contract marker: {marker}" + ) + assert marker in operations_contract, ( + "OIDC reconciliation operations are missing tenant contract marker: " + f"{marker}" + ) From 65c629032c20639009b781f25bf6bd3cc20193d2 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Thu, 20 Aug 2026 19:51:04 +0900 Subject: [PATCH 11/70] docs: refresh exact-head PR inventory --- CHANGELOG.md | 3 +++ docs/doctoring/product-technical-gap-baseline.md | 8 +++++--- docs/product-technical-gap-baseline.md | 6 ++++-- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8532636..8ada8eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -66,6 +66,9 @@ Keep a Changelog, and releases use semantic versioning. ### Changed +- Refreshed the product and technical gap baseline with the current exact-head + PR inventory, including the lockfile repair review gate and the requeued + `lineageweave-web` Checks; predecessor evidence remains non-transferable. - The Helm realm-import operator runbook now migrates the legacy `realm-cwl.json` ConfigMap key to `cwl-realm.json` before rollout, preserving a rollback copy and requiring post-rollout realm discovery verification. diff --git a/docs/doctoring/product-technical-gap-baseline.md b/docs/doctoring/product-technical-gap-baseline.md index 26ec996..76258f1 100644 --- a/docs/doctoring/product-technical-gap-baseline.md +++ b/docs/doctoring/product-technical-gap-baseline.md @@ -67,6 +67,8 @@ https://www.rfc-editor.org/rfc/rfc8725.html - ADR-0008 and ADR-0009 plus their related specification, plan, operations, and doctoring records. - Exact-head GitHub PR, review, issue, check-run, ruleset, and scheduled-run - queries performed on 2026-08-20. The follow-up #100 head after this baseline - commit is recorded as pending until its new Checks complete. No credential, - private payload, or PII is recorded here. + queries performed on 2026-08-20. PR #112's lockfile head has terminal-success + Checks but still requires independent review; PR #100's current head + `f9d0159751bee21ee4f4f6dbc27c5719b95d5087` has newly queued Checks and is + recorded as pending until those Checks and a fresh review complete. No + credential, private payload, or PII is recorded here. diff --git a/docs/product-technical-gap-baseline.md b/docs/product-technical-gap-baseline.md index c0f87bd..d6c0bc7 100644 --- a/docs/product-technical-gap-baseline.md +++ b/docs/product-technical-gap-baseline.md @@ -66,7 +66,9 @@ tenant, or resource ownership. The following is the current open-PR inventory. `Checks` means the exact head rollup observed on 2026-08-20; it is not inherited from a predecessor commit. -The #100 row was refreshed after this baseline commit requeued its checks. +The #100 row was refreshed after the documentation commits advanced its head; +its exact-head Checks are currently queued and must not inherit predecessor +evidence. | PR | Scope | Exact-head Checks | Review state | Next safe action | |---:|---|---|---|---| @@ -81,7 +83,7 @@ The #100 row was refreshed after this baseline commit requeued its checks. | [#104](https://github.com/ContextualWisdomLab/keyverse/pull/104) | ADR and buyer README expansion | FAIL: account tests | draft | Keep draft until scope and exact-main evidence are ready. | | [#103](https://github.com/ContextualWisdomLab/keyverse/pull/103) | Hierarchical authorization, login helper, PATs | FAIL: Strix | changes requested | Inspect the unavailable Strix evidence and security findings before any merge claim. | | [#101](https://github.com/ContextualWisdomLab/keyverse/pull/101) | Atomic coupled Python dependency updates | PASS | changes requested | Obtain fresh independent review; this is the policy companion to the lockfile gap. | -| [#100](https://github.com/ContextualWisdomLab/keyverse/pull/100) | `lineageweave-web` account-derived claims | PENDING on exact head `eed91c9a62d46d03d98f4aa984796c4f11f758aa` | changes requested; fresh review requested | Do not transfer the predecessor PASS; wait for exact-head Checks and independent review, without self-approval. | +| [#100](https://github.com/ContextualWisdomLab/keyverse/pull/100) | `lineageweave-web` account-derived claims | PENDING on exact head `f9d0159751bee21ee4f4f6dbc27c5719b95d5087` | changes requested; fresh review requested | Do not transfer the predecessor PASS; wait for exact-head Checks and independent review, without self-approval. | | [#83](https://github.com/ContextualWisdomLab/keyverse/pull/83) | Remove runtime application RPs from portable realm | PASS | changes requested | Reconfirm current-head approval and latest-pusher rule before protected merge. | ### Check failure root causes observed From 826e774d4465728ea6588158cabeffa99cbc8f6e Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Thu, 20 Aug 2026 19:52:00 +0900 Subject: [PATCH 12/70] docs: keep live PR evidence non-self-referential --- docs/doctoring/product-technical-gap-baseline.md | 8 ++++---- docs/product-technical-gap-baseline.md | 9 +++++---- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/docs/doctoring/product-technical-gap-baseline.md b/docs/doctoring/product-technical-gap-baseline.md index 76258f1..e0cc1e9 100644 --- a/docs/doctoring/product-technical-gap-baseline.md +++ b/docs/doctoring/product-technical-gap-baseline.md @@ -68,7 +68,7 @@ https://www.rfc-editor.org/rfc/rfc8725.html and doctoring records. - Exact-head GitHub PR, review, issue, check-run, ruleset, and scheduled-run queries performed on 2026-08-20. PR #112's lockfile head has terminal-success - Checks but still requires independent review; PR #100's current head - `f9d0159751bee21ee4f4f6dbc27c5719b95d5087` has newly queued Checks and is - recorded as pending until those Checks and a fresh review complete. No - credential, private payload, or PII is recorded here. + Checks but still requires independent review. PR #100's live current head is + recorded as pending until its Checks and a fresh review complete; this record + travels in that PR, so the live PR record is authoritative for its changing + exact hash. No credential, private payload, or PII is recorded here. diff --git a/docs/product-technical-gap-baseline.md b/docs/product-technical-gap-baseline.md index d6c0bc7..3d91513 100644 --- a/docs/product-technical-gap-baseline.md +++ b/docs/product-technical-gap-baseline.md @@ -66,9 +66,10 @@ tenant, or resource ownership. The following is the current open-PR inventory. `Checks` means the exact head rollup observed on 2026-08-20; it is not inherited from a predecessor commit. -The #100 row was refreshed after the documentation commits advanced its head; -its exact-head Checks are currently queued and must not inherit predecessor -evidence. +The #100 row is intentionally expressed as the current PR head rather than a +literal hash: this baseline travels on PR #100, so every documentation commit +advances that head. The live PR record is authoritative for the exact hash and +Checks; predecessor evidence remains non-transferable. | PR | Scope | Exact-head Checks | Review state | Next safe action | |---:|---|---|---|---| @@ -83,7 +84,7 @@ evidence. | [#104](https://github.com/ContextualWisdomLab/keyverse/pull/104) | ADR and buyer README expansion | FAIL: account tests | draft | Keep draft until scope and exact-main evidence are ready. | | [#103](https://github.com/ContextualWisdomLab/keyverse/pull/103) | Hierarchical authorization, login helper, PATs | FAIL: Strix | changes requested | Inspect the unavailable Strix evidence and security findings before any merge claim. | | [#101](https://github.com/ContextualWisdomLab/keyverse/pull/101) | Atomic coupled Python dependency updates | PASS | changes requested | Obtain fresh independent review; this is the policy companion to the lockfile gap. | -| [#100](https://github.com/ContextualWisdomLab/keyverse/pull/100) | `lineageweave-web` account-derived claims | PENDING on exact head `f9d0159751bee21ee4f4f6dbc27c5719b95d5087` | changes requested; fresh review requested | Do not transfer the predecessor PASS; wait for exact-head Checks and independent review, without self-approval. | +| [#100](https://github.com/ContextualWisdomLab/keyverse/pull/100) | `lineageweave-web` account-derived claims | PENDING on current PR head (exact live record) | changes requested; fresh review requested | Do not transfer the predecessor PASS; verify the live exact-head Checks and independent review, without self-approval. | | [#83](https://github.com/ContextualWisdomLab/keyverse/pull/83) | Remove runtime application RPs from portable realm | PASS | changes requested | Reconfirm current-head approval and latest-pusher rule before protected merge. | ### Check failure root causes observed From fb5e875350111f190ad41eb2f69493485216a6af Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Thu, 20 Aug 2026 20:11:34 +0900 Subject: [PATCH 13/70] docs: track current SCIM lock PR evidence --- CHANGELOG.md | 3 +++ .../doctoring/product-technical-gap-baseline.md | 14 +++++++++----- docs/product-technical-gap-baseline.md | 17 ++++++++++------- 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8ada8eb..8af0168 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -69,6 +69,9 @@ Keep a Changelog, and releases use semantic versioning. - Refreshed the product and technical gap baseline with the current exact-head PR inventory, including the lockfile repair review gate and the requeued `lineageweave-web` Checks; predecessor evidence remains non-transferable. +- Added the active PR #113 SCIM deactivation-lock state and the current PR #103 + Strix/IDOR evidence to the gap baseline; neither is represented as protected + main until exact-head review and merge evidence exists. - The Helm realm-import operator runbook now migrates the legacy `realm-cwl.json` ConfigMap key to `cwl-realm.json` before rollout, preserving a rollback copy and requiring post-rollout realm discovery verification. diff --git a/docs/doctoring/product-technical-gap-baseline.md b/docs/doctoring/product-technical-gap-baseline.md index e0cc1e9..d900610 100644 --- a/docs/doctoring/product-technical-gap-baseline.md +++ b/docs/doctoring/product-technical-gap-baseline.md @@ -67,8 +67,12 @@ https://www.rfc-editor.org/rfc/rfc8725.html - ADR-0008 and ADR-0009 plus their related specification, plan, operations, and doctoring records. - Exact-head GitHub PR, review, issue, check-run, ruleset, and scheduled-run - queries performed on 2026-08-20. PR #112's lockfile head has terminal-success - Checks but still requires independent review. PR #100's live current head is - recorded as pending until its Checks and a fresh review complete; this record - travels in that PR, so the live PR record is authoritative for its changing - exact hash. No credential, private payload, or PII is recorded here. + queries performed on 2026-08-20. PR #113's SCIM lock head `8f18d57` has + hosted Checks queued and requires independent review; its local RED-to-GREEN + evidence is not protected-main evidence. PR #112's lockfile head has + terminal-success Checks but still requires independent review. PR #103 has a + terminal Strix failure with a MEDIUM IDOR report whose operator-admin trust + boundary still requires independent validation. PR #100's live current head + is recorded as pending until its Checks and a fresh review complete; this + record travels in that PR, so the live PR record is authoritative for its + changing exact hash. No credential, private payload, or PII is recorded here. diff --git a/docs/product-technical-gap-baseline.md b/docs/product-technical-gap-baseline.md index 3d91513..d6dbf1f 100644 --- a/docs/product-technical-gap-baseline.md +++ b/docs/product-technical-gap-baseline.md @@ -73,6 +73,7 @@ Checks; predecessor evidence remains non-transferable. | PR | Scope | Exact-head Checks | Review state | Next safe action | |---:|---|---|---|---| +| [#113](https://github.com/ContextualWisdomLab/keyverse/pull/113) | SCIM `PATCH active=false` shared operation lock | PENDING: hosted Checks queued | review required | Obtain independent review and terminal exact-head Checks, then let protected automation merge; do not treat local GREEN as protected-main evidence. | | [#112](https://github.com/ContextualWisdomLab/keyverse/pull/112) | Resync account-unification lockfile | PASS | review required | Obtain independent review, then let protected automation re-check and merge. | | [#111](https://github.com/ContextualWisdomLab/keyverse/pull/111) | CodeQL init 4.37.7 | FAIL: account tests, CodeQL, Strix | review required | Keep coupled with #110; revalidate after lockfile and action-version coupling is resolved. | | [#110](https://github.com/ContextualWisdomLab/keyverse/pull/110) | CodeQL analyze 4.37.7 | FAIL: account tests, CodeQL | review required | Treat as the companion of #111; do not merge the action pair independently. | @@ -82,7 +83,7 @@ Checks; predecessor evidence remains non-transferable. | [#106](https://github.com/ContextualWisdomLab/keyverse/pull/106) | `setup-uv` update | FAIL: account tests | review required | Re-check after #112; do not rerun unchanged checks. | | [#105](https://github.com/ContextualWisdomLab/keyverse/pull/105) | `harden-runner` update | FAIL: account tests | changes requested | Fix the locked dependency gate first, then obtain a new exact-head review. | | [#104](https://github.com/ContextualWisdomLab/keyverse/pull/104) | ADR and buyer README expansion | FAIL: account tests | draft | Keep draft until scope and exact-main evidence are ready. | -| [#103](https://github.com/ContextualWisdomLab/keyverse/pull/103) | Hierarchical authorization, login helper, PATs | FAIL: Strix | changes requested | Inspect the unavailable Strix evidence and security findings before any merge claim. | +| [#103](https://github.com/ContextualWisdomLab/keyverse/pull/103) | Hierarchical authorization, login helper, PATs | FAIL: Strix, MEDIUM IDOR report | changes requested | Validate the report against the operator-admin trust boundary, retain fail-closed treatment, and obtain a fresh exact-head review/check run before any merge claim. | | [#101](https://github.com/ContextualWisdomLab/keyverse/pull/101) | Atomic coupled Python dependency updates | PASS | changes requested | Obtain fresh independent review; this is the policy companion to the lockfile gap. | | [#100](https://github.com/ContextualWisdomLab/keyverse/pull/100) | `lineageweave-web` account-derived claims | PENDING on current PR head (exact live record) | changes requested; fresh review requested | Do not transfer the predecessor PASS; verify the live exact-head Checks and independent review, without self-approval. | | [#83](https://github.com/ContextualWisdomLab/keyverse/pull/83) | Remove runtime application RPs from portable realm | PASS | changes requested | Reconfirm current-head approval and latest-pusher rule before protected merge. | @@ -170,13 +171,15 @@ be converted into a synthetic success. ### G4 — SCIM deactivation concurrency boundary -**State:** `accepted-contract` with an explicit protected-main limitation -**Root cause:** `PATCH active=false` is not covered by the shared cross-process -lock used by merge and full-replacement `PUT`. +**State:** `active-PR` with an explicit protected-main limitation +**Root cause:** protected `main` did not cover `PATCH active=false` with the +shared cross-process lock used by merge and full-replacement `PUT`. -**Acceptance:** add a real concurrent deactivation/merge regression, join the -same lock only if the implementation preserves tombstone and survivor -invariants, and update PRD/TRD/ERD/Threat/Test/Operability/doctoring together. +**Acceptance:** PR #113 adds the shared lock, SCIM-shaped 503 lock-timeout +mapping, a real concurrent deactivation/merge regression, and reconciled +PRD/TRD/UML/Threat/Test/Operability/doctoring records. The protected-main gap +closes only after exact-head hosted Checks, independent review, protected merge, +and a refreshed baseline prove the change on main. ### G5 — Physical database and hot-partition evidence From b52e0c0c0657e44132a7e11a5a9f51a6e471455a Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Thu, 20 Aug 2026 20:14:53 +0900 Subject: [PATCH 14/70] docs: refresh SCIM PR head evidence --- docs/doctoring/product-technical-gap-baseline.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/doctoring/product-technical-gap-baseline.md b/docs/doctoring/product-technical-gap-baseline.md index d900610..e26c7e8 100644 --- a/docs/doctoring/product-technical-gap-baseline.md +++ b/docs/doctoring/product-technical-gap-baseline.md @@ -67,7 +67,7 @@ https://www.rfc-editor.org/rfc/rfc8725.html - ADR-0008 and ADR-0009 plus their related specification, plan, operations, and doctoring records. - Exact-head GitHub PR, review, issue, check-run, ruleset, and scheduled-run - queries performed on 2026-08-20. PR #113's SCIM lock head `8f18d57` has + queries performed on 2026-08-20. PR #113's SCIM lock head `c697816` has hosted Checks queued and requires independent review; its local RED-to-GREEN evidence is not protected-main evidence. PR #112's lockfile head has terminal-success Checks but still requires independent review. PR #103 has a From cf34b819aa2a8a775fddab449453d418731c07b9 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Thu, 20 Aug 2026 20:23:11 +0900 Subject: [PATCH 15/70] docs: refresh SCIM PR head evidence --- docs/doctoring/product-technical-gap-baseline.md | 7 ++++--- docs/product-technical-gap-baseline.md | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/docs/doctoring/product-technical-gap-baseline.md b/docs/doctoring/product-technical-gap-baseline.md index e26c7e8..3ac311e 100644 --- a/docs/doctoring/product-technical-gap-baseline.md +++ b/docs/doctoring/product-technical-gap-baseline.md @@ -67,9 +67,10 @@ https://www.rfc-editor.org/rfc/rfc8725.html - ADR-0008 and ADR-0009 plus their related specification, plan, operations, and doctoring records. - Exact-head GitHub PR, review, issue, check-run, ruleset, and scheduled-run - queries performed on 2026-08-20. PR #113's SCIM lock head `c697816` has - hosted Checks queued and requires independent review; its local RED-to-GREEN - evidence is not protected-main evidence. PR #112's lockfile head has + queries performed on 2026-08-20. PR #113's SCIM lock head `d68159e` + (`d68159e5c0c7be84a1a9b0fbfe8b7b632e4a74d2`) has hosted Checks queued and + requires independent review; its local RED-to-GREEN and root-level SCIM + error-wire evidence are not protected-main evidence. PR #112's lockfile head has terminal-success Checks but still requires independent review. PR #103 has a terminal Strix failure with a MEDIUM IDOR report whose operator-admin trust boundary still requires independent validation. PR #100's live current head diff --git a/docs/product-technical-gap-baseline.md b/docs/product-technical-gap-baseline.md index d6dbf1f..f1fb1be 100644 --- a/docs/product-technical-gap-baseline.md +++ b/docs/product-technical-gap-baseline.md @@ -175,8 +175,8 @@ be converted into a synthetic success. **Root cause:** protected `main` did not cover `PATCH active=false` with the shared cross-process lock used by merge and full-replacement `PUT`. -**Acceptance:** PR #113 adds the shared lock, SCIM-shaped 503 lock-timeout -mapping, a real concurrent deactivation/merge regression, and reconciled +**Acceptance:** PR #113 adds the shared lock, root-level SCIM `503` +lock-timeout mapping, a real concurrent deactivation/merge regression, and reconciled PRD/TRD/UML/Threat/Test/Operability/doctoring records. The protected-main gap closes only after exact-head hosted Checks, independent review, protected merge, and a refreshed baseline prove the change on main. From 815332d45d7f0f54970e3ed5545e96e655eff8b7 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Thu, 20 Aug 2026 20:23:52 +0900 Subject: [PATCH 16/70] docs: correct SCIM PR head hash --- docs/doctoring/product-technical-gap-baseline.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/doctoring/product-technical-gap-baseline.md b/docs/doctoring/product-technical-gap-baseline.md index 3ac311e..2f39099 100644 --- a/docs/doctoring/product-technical-gap-baseline.md +++ b/docs/doctoring/product-technical-gap-baseline.md @@ -68,7 +68,7 @@ https://www.rfc-editor.org/rfc/rfc8725.html and doctoring records. - Exact-head GitHub PR, review, issue, check-run, ruleset, and scheduled-run queries performed on 2026-08-20. PR #113's SCIM lock head `d68159e` - (`d68159e5c0c7be84a1a9b0fbfe8b7b632e4a74d2`) has hosted Checks queued and + (`d68159e4b69765b81d4508600a802d2cea175265`) has hosted Checks queued and requires independent review; its local RED-to-GREEN and root-level SCIM error-wire evidence are not protected-main evidence. PR #112's lockfile head has terminal-success Checks but still requires independent review. PR #103 has a From 271541ff783523ee0aff4e7dff9f46465774a8d6 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Thu, 20 Aug 2026 20:31:21 +0900 Subject: [PATCH 17/70] docs: record exact Strix failure evidence --- CHANGELOG.md | 3 +++ docs/doctoring/product-technical-gap-baseline.md | 7 ++++--- docs/product-technical-gap-baseline.md | 13 +++++++++---- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8af0168..46e4033 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -72,6 +72,9 @@ Keep a Changelog, and releases use semantic versioning. - Added the active PR #113 SCIM deactivation-lock state and the current PR #103 Strix/IDOR evidence to the gap baseline; neither is represented as protected main until exact-head review and merge evidence exists. +- Refreshed the PR #103 Strix evidence with its exact failed run/job and kept + the contradictory operator-admin IDOR interpretation fail-closed pending + independent security validation. - The Helm realm-import operator runbook now migrates the legacy `realm-cwl.json` ConfigMap key to `cwl-realm.json` before rollout, preserving a rollback copy and requiring post-rollout realm discovery verification. diff --git a/docs/doctoring/product-technical-gap-baseline.md b/docs/doctoring/product-technical-gap-baseline.md index 2f39099..c0cd858 100644 --- a/docs/doctoring/product-technical-gap-baseline.md +++ b/docs/doctoring/product-technical-gap-baseline.md @@ -71,9 +71,10 @@ https://www.rfc-editor.org/rfc/rfc8725.html (`d68159e4b69765b81d4508600a802d2cea175265`) has hosted Checks queued and requires independent review; its local RED-to-GREEN and root-level SCIM error-wire evidence are not protected-main evidence. PR #112's lockfile head has - terminal-success Checks but still requires independent review. PR #103 has a - terminal Strix failure with a MEDIUM IDOR report whose operator-admin trust - boundary still requires independent validation. PR #100's live current head + terminal-success Checks but still requires independent review. PR #103's + terminal Strix run 32092025335 / job 95576032571 emitted a MEDIUM IDOR report + with contradictory model text; its operator-admin trust boundary still + requires independent validation. PR #100's live current head is recorded as pending until its Checks and a fresh review complete; this record travels in that PR, so the live PR record is authoritative for its changing exact hash. No credential, private payload, or PII is recorded here. diff --git a/docs/product-technical-gap-baseline.md b/docs/product-technical-gap-baseline.md index f1fb1be..af3b45c 100644 --- a/docs/product-technical-gap-baseline.md +++ b/docs/product-technical-gap-baseline.md @@ -83,7 +83,7 @@ Checks; predecessor evidence remains non-transferable. | [#106](https://github.com/ContextualWisdomLab/keyverse/pull/106) | `setup-uv` update | FAIL: account tests | review required | Re-check after #112; do not rerun unchanged checks. | | [#105](https://github.com/ContextualWisdomLab/keyverse/pull/105) | `harden-runner` update | FAIL: account tests | changes requested | Fix the locked dependency gate first, then obtain a new exact-head review. | | [#104](https://github.com/ContextualWisdomLab/keyverse/pull/104) | ADR and buyer README expansion | FAIL: account tests | draft | Keep draft until scope and exact-main evidence are ready. | -| [#103](https://github.com/ContextualWisdomLab/keyverse/pull/103) | Hierarchical authorization, login helper, PATs | FAIL: Strix, MEDIUM IDOR report | changes requested | Validate the report against the operator-admin trust boundary, retain fail-closed treatment, and obtain a fresh exact-head review/check run before any merge claim. | +| [#103](https://github.com/ContextualWisdomLab/keyverse/pull/103) | Hierarchical authorization, login helper, PATs | FAIL: Strix run 32092025335 / job 95576032571, MEDIUM IDOR report | changes requested | Independently validate the report against the operator-admin trust boundary; retain fail-closed treatment and obtain a fresh exact-head review/check run before any merge claim. | | [#101](https://github.com/ContextualWisdomLab/keyverse/pull/101) | Atomic coupled Python dependency updates | PASS | changes requested | Obtain fresh independent review; this is the policy companion to the lockfile gap. | | [#100](https://github.com/ContextualWisdomLab/keyverse/pull/100) | `lineageweave-web` account-derived claims | PENDING on current PR head (exact live record) | changes requested; fresh review requested | Do not transfer the predecessor PASS; verify the live exact-head Checks and independent review, without self-approval. | | [#83](https://github.com/ContextualWisdomLab/keyverse/pull/83) | Remove runtime application RPs from portable realm | PASS | changes requested | Reconfirm current-head approval and latest-pusher rule before protected merge. | @@ -98,9 +98,14 @@ Checks; predecessor evidence remains non-transferable. #111 run loaded configuration for 4.37.7 while running 4.37.6. They must be evaluated as one compatible pair, with fresh exact-head Checks after the lockfile queue is clear. -- The historical #103 Strix run is not currently retrievable through the - Actions API. That is missing evidence, not a pass and not permission to - bypass the security gate. +- PR #103 Strix run 32092025335 / job 95576032571 failed closed after emitting + a MEDIUM IDOR report that requests binding grant-management + actor_identity_id values to the authenticated principal. The same model + report also says the issue was already resolved, so the evidence is + contradictory. The routes are currently operator-admin gated and the + operator token does not expose distinct end-user principals; independent + security validation must resolve that trust-boundary interpretation. Until + then the failure remains blocking and is not converted into a pass. ## Open Issue inventory From 1acf3a572f046432603bd68d17f924eb66090229 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Thu, 20 Aug 2026 20:46:41 +0900 Subject: [PATCH 18/70] test(clients): cover malformed observed mapper drift --- .../tests/test_relying_party_claim_mappers.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/services/account_unification/tests/test_relying_party_claim_mappers.py b/services/account_unification/tests/test_relying_party_claim_mappers.py index 8108b15..8f2b605 100644 --- a/services/account_unification/tests/test_relying_party_claim_mappers.py +++ b/services/account_unification/tests/test_relying_party_claim_mappers.py @@ -240,6 +240,21 @@ def test_account_derived_claim_mapper_observation_is_reconciled() -> None: assert normalized == desired_mappers +@pytest.mark.parametrize("protocol_mapper", ([], {})) +def test_observed_non_string_mapper_type_is_drift(protocol_mapper: object) -> None: + """Malformed vendor mapper types fail closed instead of raising unexpectedly.""" + payload = _lineageweave_registration_with_account_claims() + registration = _parse_registration(payload) + desired_mappers = payload["protocolMappers"] + assert isinstance(desired_mappers, list) + observed_mappers = deepcopy(desired_mappers) + first_mapper = observed_mappers[0] + assert isinstance(first_mapper, dict) + first_mapper["protocolMapper"] = protocol_mapper + + assert _normalized_observed_mappers(observed_mappers, registration) is None + + @pytest.mark.parametrize( ("mutate", "field"), [ From 506c7a1a471d1452e76ef336918787b3d38dfbc4 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Thu, 20 Aug 2026 20:57:32 +0900 Subject: [PATCH 19/70] docs: record workflow registry lifecycle evidence --- docs/doctoring/product-technical-gap-baseline.md | 8 +++++++- docs/product-technical-gap-baseline.md | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/docs/doctoring/product-technical-gap-baseline.md b/docs/doctoring/product-technical-gap-baseline.md index c0cd858..5dd8560 100644 --- a/docs/doctoring/product-technical-gap-baseline.md +++ b/docs/doctoring/product-technical-gap-baseline.md @@ -77,4 +77,10 @@ https://www.rfc-editor.org/rfc/rfc8725.html requires independent validation. PR #100's live current head is recorded as pending until its Checks and a fresh review complete; this record travels in that PR, so the live PR record is authoritative for its - changing exact hash. No credential, private payload, or PII is recorded here. + changing exact hash. A complete read-only Keyverse Actions registry/tree + reconciliation at protected `main` `ce207dfd` found 43 active identities: + four repository workflow paths present in the exact tree, 37 active + repository paths absent from it, and two `dynamic/*` GitHub-owned paths. + No workflow state was mutated; the evidence is recorded on Keyverse issue + #99 and central issue #945 for the owning lifecycle operator. No credential, + private payload, or PII is recorded here. diff --git a/docs/product-technical-gap-baseline.md b/docs/product-technical-gap-baseline.md index af3b45c..0adef79 100644 --- a/docs/product-technical-gap-baseline.md +++ b/docs/product-technical-gap-baseline.md @@ -112,7 +112,7 @@ Checks; predecessor evidence remains non-transferable. | Issue | Product signal | Classification | Required outcome | |---:|---|---|---| | [#102](https://github.com/ContextualWisdomLab/keyverse/issues/102) | Hierarchical authorization plane, login helper, PATs | `active-PR` | Security-review the proposed authority model and prove fail-closed token/tenant/resource behavior. | -| [#99](https://github.com/ContextualWisdomLab/keyverse/issues/99) | Orphaned federation and product-loop workflow identities | `gap-not-claimed` | Disable only through the owning protected workflow/organization path and record live identity evidence. | +| [#99](https://github.com/ContextualWisdomLab/keyverse/issues/99) | Orphaned federation and product-loop workflow identities | `gap-not-claimed` | Live evidence at protected `main` `ce207dfd` found 43 active registry identities: 4 present repository paths, 37 missing repository paths, and 2 GitHub-owned dynamic paths. Disable only through the owning protected workflow/organization path and revalidate by workflow ID immediately before mutation. | | [#71](https://github.com/ContextualWisdomLab/keyverse/issues/71) | Remove runtime application RPs from portable import | `active-PR` | Merge #83 only after current-head protected evidence. | | [#2](https://github.com/ContextualWisdomLab/keyverse/issues/2) | Central IdP plus external-IdP federation | `accepted-contract` | Use the existing closed preflight/apply boundary and add approved-environment acceptance. | From f785db2fc3cb742fb6cc0ded233b13599b9de01d Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Thu, 20 Aug 2026 21:00:00 +0900 Subject: [PATCH 20/70] docs: record workflow inventory pagination evidence --- docs/doctoring/product-technical-gap-baseline.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/doctoring/product-technical-gap-baseline.md b/docs/doctoring/product-technical-gap-baseline.md index 5dd8560..086e402 100644 --- a/docs/doctoring/product-technical-gap-baseline.md +++ b/docs/doctoring/product-technical-gap-baseline.md @@ -80,7 +80,8 @@ https://www.rfc-editor.org/rfc/rfc8725.html changing exact hash. A complete read-only Keyverse Actions registry/tree reconciliation at protected `main` `ce207dfd` found 43 active identities: four repository workflow paths present in the exact tree, 37 active - repository paths absent from it, and two `dynamic/*` GitHub-owned paths. - No workflow state was mutated; the evidence is recorded on Keyverse issue - #99 and central issue #945 for the owning lifecycle operator. No credential, - private payload, or PII is recorded here. + repository paths absent from it, and two `dynamic/*` GitHub-owned paths. The + workflow registry used one API page and the recursive protected-tree response + was not truncated. No workflow state was mutated; the evidence is recorded + on Keyverse issue #99 and central issue #945 for the owning lifecycle + operator. No credential, private payload, or PII is recorded here. From d548df1326af3c031be582b297c238cf600c9b40 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Thu, 20 Aug 2026 21:20:07 +0900 Subject: [PATCH 21/70] docs: record uv lock failure evidence --- docs/doctoring/product-technical-gap-baseline.md | 11 +++++++++-- docs/product-technical-gap-baseline.md | 6 +++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/docs/doctoring/product-technical-gap-baseline.md b/docs/doctoring/product-technical-gap-baseline.md index 086e402..cac8f92 100644 --- a/docs/doctoring/product-technical-gap-baseline.md +++ b/docs/doctoring/product-technical-gap-baseline.md @@ -70,8 +70,15 @@ https://www.rfc-editor.org/rfc/rfc8725.html queries performed on 2026-08-20. PR #113's SCIM lock head `d68159e` (`d68159e4b69765b81d4508600a802d2cea175265`) has hosted Checks queued and requires independent review; its local RED-to-GREEN and root-level SCIM - error-wire evidence are not protected-main evidence. PR #112's lockfile head has - terminal-success Checks but still requires independent review. PR #103's + error-wire evidence are not protected-main evidence. PR #112's lockfile head + `f02acf93367a40dbfb23a73985017dca8d42ff39` has terminal-success Checks but + still requires independent review. PR #105's exact head + `72de5499d6e97ae7f7bd804ab78b3e1644dd5a4f` has a failed + `account-unification-tests` Check: `uv 0.12.5` reproduces + `uv sync --locked` refusing the stale `coverage==7.15.2` and + `setuptools==83.0.0` lock entries while the current `pyproject.toml` requires + `7.15.4` and `84.0.0`; #112 is the existing prerequisite lock refresh. + PR #103's terminal Strix run 32092025335 / job 95576032571 emitted a MEDIUM IDOR report with contradictory model text; its operator-admin trust boundary still requires independent validation. PR #100's live current head diff --git a/docs/product-technical-gap-baseline.md b/docs/product-technical-gap-baseline.md index 0adef79..01cf2f6 100644 --- a/docs/product-technical-gap-baseline.md +++ b/docs/product-technical-gap-baseline.md @@ -93,7 +93,11 @@ Checks; predecessor evidence remains non-transferable. - The representative account-test failure on Dependabot PRs stopped at `uv sync --locked`: the checked-in lockfile needed updating. This is a dependency-graph consistency failure, not evidence that the product tests - failed after installation. + failed after installation. On PR #105 exact head + `72de5499d6e97ae7f7bd804ab78b3e1644dd5a4f`, `uv 0.12.5` reproduced the + mismatch between required `coverage==7.15.4` / `setuptools==84.0.0` and + locked `7.15.2` / `83.0.0`; PR #112 is the existing lock-refresh + prerequisite, so #105 must be rechecked after #112's protected merge. - PRs #110 and #111 update the two coupled CodeQL actions separately. The #111 run loaded configuration for 4.37.7 while running 4.37.6. They must be evaluated as one compatible pair, with fresh exact-head Checks after the From 1bd15d08927a6130d4d0eb1365ff8a7118cf9822 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Thu, 20 Aug 2026 21:42:50 +0900 Subject: [PATCH 22/70] docs: refresh SCIM PR baseline evidence --- docs/doctoring/product-technical-gap-baseline.md | 10 ++++++---- docs/product-technical-gap-baseline.md | 5 +++-- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/docs/doctoring/product-technical-gap-baseline.md b/docs/doctoring/product-technical-gap-baseline.md index cac8f92..f8d15be 100644 --- a/docs/doctoring/product-technical-gap-baseline.md +++ b/docs/doctoring/product-technical-gap-baseline.md @@ -67,10 +67,12 @@ https://www.rfc-editor.org/rfc/rfc8725.html - ADR-0008 and ADR-0009 plus their related specification, plan, operations, and doctoring records. - Exact-head GitHub PR, review, issue, check-run, ruleset, and scheduled-run - queries performed on 2026-08-20. PR #113's SCIM lock head `d68159e` - (`d68159e4b69765b81d4508600a802d2cea175265`) has hosted Checks queued and - requires independent review; its local RED-to-GREEN and root-level SCIM - error-wire evidence are not protected-main evidence. PR #112's lockfile head + queries performed on 2026-08-20. PR #113's current SCIM lock head + `9e82f163c1a33c290ca04f4e8de1c2f9e9b65e68` includes a normal merge of + prerequisite PR #112 and a spawned-process SQLite lock regression; its hosted + Checks are queued and it requires independent review. Its local RED-to-GREEN, + root-level SCIM error-wire, and cross-process sidecar evidence are not + protected-main evidence. PR #112's lockfile head `f02acf93367a40dbfb23a73985017dca8d42ff39` has terminal-success Checks but still requires independent review. PR #105's exact head `72de5499d6e97ae7f7bd804ab78b3e1644dd5a4f` has a failed diff --git a/docs/product-technical-gap-baseline.md b/docs/product-technical-gap-baseline.md index 01cf2f6..1ecf0c3 100644 --- a/docs/product-technical-gap-baseline.md +++ b/docs/product-technical-gap-baseline.md @@ -73,7 +73,7 @@ Checks; predecessor evidence remains non-transferable. | PR | Scope | Exact-head Checks | Review state | Next safe action | |---:|---|---|---|---| -| [#113](https://github.com/ContextualWisdomLab/keyverse/pull/113) | SCIM `PATCH active=false` shared operation lock | PENDING: hosted Checks queued | review required | Obtain independent review and terminal exact-head Checks, then let protected automation merge; do not treat local GREEN as protected-main evidence. | +| [#113](https://github.com/ContextualWisdomLab/keyverse/pull/113) | SCIM `PATCH active=false` shared operation lock, stacked on #112 lockfile refresh | PENDING: hosted Checks queued on `9e82f163c1a33c290ca04f4e8de1c2f9e9b65e68` | review required | Obtain independent review and terminal exact-head Checks, then let protected automation merge; do not treat local GREEN as protected-main evidence. | | [#112](https://github.com/ContextualWisdomLab/keyverse/pull/112) | Resync account-unification lockfile | PASS | review required | Obtain independent review, then let protected automation re-check and merge. | | [#111](https://github.com/ContextualWisdomLab/keyverse/pull/111) | CodeQL init 4.37.7 | FAIL: account tests, CodeQL, Strix | review required | Keep coupled with #110; revalidate after lockfile and action-version coupling is resolved. | | [#110](https://github.com/ContextualWisdomLab/keyverse/pull/110) | CodeQL analyze 4.37.7 | FAIL: account tests, CodeQL | review required | Treat as the companion of #111; do not merge the action pair independently. | @@ -185,7 +185,8 @@ be converted into a synthetic success. shared cross-process lock used by merge and full-replacement `PUT`. **Acceptance:** PR #113 adds the shared lock, root-level SCIM `503` -lock-timeout mapping, a real concurrent deactivation/merge regression, and reconciled +lock-timeout mapping, real concurrent deactivation/merge and cross-process +sidecar-lock regressions, and reconciled PRD/TRD/UML/Threat/Test/Operability/doctoring records. The protected-main gap closes only after exact-head hosted Checks, independent review, protected merge, and a refreshed baseline prove the change on main. From 9b0069e485d985ce01912f192866e4df218fe337 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Thu, 20 Aug 2026 21:48:58 +0900 Subject: [PATCH 23/70] docs: record current SCIM review head --- docs/doctoring/product-technical-gap-baseline.md | 2 +- docs/product-technical-gap-baseline.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/doctoring/product-technical-gap-baseline.md b/docs/doctoring/product-technical-gap-baseline.md index f8d15be..430a686 100644 --- a/docs/doctoring/product-technical-gap-baseline.md +++ b/docs/doctoring/product-technical-gap-baseline.md @@ -68,7 +68,7 @@ https://www.rfc-editor.org/rfc/rfc8725.html and doctoring records. - Exact-head GitHub PR, review, issue, check-run, ruleset, and scheduled-run queries performed on 2026-08-20. PR #113's current SCIM lock head - `9e82f163c1a33c290ca04f4e8de1c2f9e9b65e68` includes a normal merge of + `c2c03a5dba46b207b02d296c26d8bb1dbf215092` includes a normal merge of prerequisite PR #112 and a spawned-process SQLite lock regression; its hosted Checks are queued and it requires independent review. Its local RED-to-GREEN, root-level SCIM error-wire, and cross-process sidecar evidence are not diff --git a/docs/product-technical-gap-baseline.md b/docs/product-technical-gap-baseline.md index 1ecf0c3..baf073d 100644 --- a/docs/product-technical-gap-baseline.md +++ b/docs/product-technical-gap-baseline.md @@ -73,7 +73,7 @@ Checks; predecessor evidence remains non-transferable. | PR | Scope | Exact-head Checks | Review state | Next safe action | |---:|---|---|---|---| -| [#113](https://github.com/ContextualWisdomLab/keyverse/pull/113) | SCIM `PATCH active=false` shared operation lock, stacked on #112 lockfile refresh | PENDING: hosted Checks queued on `9e82f163c1a33c290ca04f4e8de1c2f9e9b65e68` | review required | Obtain independent review and terminal exact-head Checks, then let protected automation merge; do not treat local GREEN as protected-main evidence. | +| [#113](https://github.com/ContextualWisdomLab/keyverse/pull/113) | SCIM `PATCH active=false` shared operation lock, stacked on #112 lockfile refresh | PENDING: hosted Checks queued on `c2c03a5dba46b207b02d296c26d8bb1dbf215092` | review required | Obtain independent review and terminal exact-head Checks, then let protected automation merge; do not treat local GREEN as protected-main evidence. | | [#112](https://github.com/ContextualWisdomLab/keyverse/pull/112) | Resync account-unification lockfile | PASS | review required | Obtain independent review, then let protected automation re-check and merge. | | [#111](https://github.com/ContextualWisdomLab/keyverse/pull/111) | CodeQL init 4.37.7 | FAIL: account tests, CodeQL, Strix | review required | Keep coupled with #110; revalidate after lockfile and action-version coupling is resolved. | | [#110](https://github.com/ContextualWisdomLab/keyverse/pull/110) | CodeQL analyze 4.37.7 | FAIL: account tests, CodeQL | review required | Treat as the companion of #111; do not merge the action pair independently. | From c483bd53ea74aad5fcea7d3cec2f402e4d8f27c2 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 21 Aug 2026 07:05:49 +0900 Subject: [PATCH 24/70] docs: refresh live product gap baseline --- docs/product-technical-gap-baseline.md | 51 +++++++++++++++----------- 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/docs/product-technical-gap-baseline.md b/docs/product-technical-gap-baseline.md index baf073d..dbdbddf 100644 --- a/docs/product-technical-gap-baseline.md +++ b/docs/product-technical-gap-baseline.md @@ -1,6 +1,6 @@ # Keyverse product and technical gap baseline -**Evidence snapshot:** 2026-08-20 (Asia/Seoul) +**Evidence snapshot:** 2026-08-21 (Asia/Seoul) **Repository:** `ContextualWisdomLab/keyverse` **Protected-main head observed:** `ce207dfd42975db61c82a5963e206fc1db14ac2b` **Status:** live inventory and gap register; not a release acceptance record @@ -65,30 +65,37 @@ tenant, or resource ownership. ## Live PR inventory The following is the current open-PR inventory. `Checks` means the exact head -rollup observed on 2026-08-20; it is not inherited from a predecessor commit. -The #100 row is intentionally expressed as the current PR head rather than a -literal hash: this baseline travels on PR #100, so every documentation commit -advances that head. The live PR record is authoritative for the exact hash and -Checks; predecessor evidence remains non-transferable. +rollup observed on 2026-08-21; it is not inherited from a predecessor commit. +The baseline is being updated on PR #100, so this documentation commit advances +that head and requires a fresh hosted rollup. The live PR record is authoritative +for the exact hash and Checks; predecessor evidence remains non-transferable. + +At this snapshot, 14 PRs are open: four have 23 successful Checks with none +queued, ten have 14 Checks queued, and no PR has a terminal failure, error, +timeout, or cancellation. Queued Checks remain unverified rather than green. | PR | Scope | Exact-head Checks | Review state | Next safe action | |---:|---|---|---|---| -| [#113](https://github.com/ContextualWisdomLab/keyverse/pull/113) | SCIM `PATCH active=false` shared operation lock, stacked on #112 lockfile refresh | PENDING: hosted Checks queued on `c2c03a5dba46b207b02d296c26d8bb1dbf215092` | review required | Obtain independent review and terminal exact-head Checks, then let protected automation merge; do not treat local GREEN as protected-main evidence. | -| [#112](https://github.com/ContextualWisdomLab/keyverse/pull/112) | Resync account-unification lockfile | PASS | review required | Obtain independent review, then let protected automation re-check and merge. | -| [#111](https://github.com/ContextualWisdomLab/keyverse/pull/111) | CodeQL init 4.37.7 | FAIL: account tests, CodeQL, Strix | review required | Keep coupled with #110; revalidate after lockfile and action-version coupling is resolved. | -| [#110](https://github.com/ContextualWisdomLab/keyverse/pull/110) | CodeQL analyze 4.37.7 | FAIL: account tests, CodeQL | review required | Treat as the companion of #111; do not merge the action pair independently. | -| [#109](https://github.com/ContextualWisdomLab/keyverse/pull/109) | `typing-inspection` update | FAIL: account tests | review required | Re-check after #112; the observed failure is the stale locked dependency graph. | -| [#108](https://github.com/ContextualWisdomLab/keyverse/pull/108) | Ruff update | FAIL: account tests | review required | Re-check after #112; do not rerun unchanged checks. | -| [#107](https://github.com/ContextualWisdomLab/keyverse/pull/107) | Uvicorn update | FAIL: account tests | review required | Re-check after #112; do not rerun unchanged checks. | -| [#106](https://github.com/ContextualWisdomLab/keyverse/pull/106) | `setup-uv` update | FAIL: account tests | review required | Re-check after #112; do not rerun unchanged checks. | -| [#105](https://github.com/ContextualWisdomLab/keyverse/pull/105) | `harden-runner` update | FAIL: account tests | changes requested | Fix the locked dependency gate first, then obtain a new exact-head review. | -| [#104](https://github.com/ContextualWisdomLab/keyverse/pull/104) | ADR and buyer README expansion | FAIL: account tests | draft | Keep draft until scope and exact-main evidence are ready. | -| [#103](https://github.com/ContextualWisdomLab/keyverse/pull/103) | Hierarchical authorization, login helper, PATs | FAIL: Strix run 32092025335 / job 95576032571, MEDIUM IDOR report | changes requested | Independently validate the report against the operator-admin trust boundary; retain fail-closed treatment and obtain a fresh exact-head review/check run before any merge claim. | -| [#101](https://github.com/ContextualWisdomLab/keyverse/pull/101) | Atomic coupled Python dependency updates | PASS | changes requested | Obtain fresh independent review; this is the policy companion to the lockfile gap. | -| [#100](https://github.com/ContextualWisdomLab/keyverse/pull/100) | `lineageweave-web` account-derived claims | PENDING on current PR head (exact live record) | changes requested; fresh review requested | Do not transfer the predecessor PASS; verify the live exact-head Checks and independent review, without self-approval. | -| [#83](https://github.com/ContextualWisdomLab/keyverse/pull/83) | Remove runtime application RPs from portable realm | PASS | changes requested | Reconfirm current-head approval and latest-pusher rule before protected merge. | - -### Check failure root causes observed +| [#113](https://github.com/ContextualWisdomLab/keyverse/pull/113) | SCIM `PATCH active=false` shared operation lock, stacked on #112 lockfile refresh | PENDING: 14 Checks queued, 0 terminal failures on `50f19ec6338fb8eb959b8c797bdfa938e1071c87` | review required | Obtain independent review and terminal exact-head Checks, then let protected automation merge; do not treat local GREEN as protected-main evidence. | +| [#112](https://github.com/ContextualWisdomLab/keyverse/pull/112) | Resync account-unification lockfile | PASS: 23 Checks successful, 0 queued on `f02acf93367a40dbfb23a73985017dca8d42ff39` | review required | Obtain independent review, then let protected automation re-check and merge. | +| [#111](https://github.com/ContextualWisdomLab/keyverse/pull/111) | CodeQL init 4.37.7 | PENDING: 14 Checks queued, 0 terminal failures on `e1d0fee6ce29cb9ec75d9fbdb38cd15242bf4fdc` | review required | Keep coupled with #110; revalidate after lockfile and action-version coupling is resolved. | +| [#110](https://github.com/ContextualWisdomLab/keyverse/pull/110) | CodeQL analyze 4.37.7 | PENDING: 14 Checks queued, 0 terminal failures on `07acd65145c9522a74858d1ff8761ea05a09e8f0` | review required | Treat as the companion of #111; do not merge the action pair independently. | +| [#109](https://github.com/ContextualWisdomLab/keyverse/pull/109) | `typing-inspection` update | PENDING: 14 Checks queued, 0 terminal failures on `28a4e05b23baa75d44b37589ba662a3c46c67129` | review required | Re-check after #112; do not treat queued Checks as a failure. | +| [#108](https://github.com/ContextualWisdomLab/keyverse/pull/108) | Ruff update | PENDING: 14 Checks queued, 0 terminal failures on `d9791bba5a2e277c2ae503504b871e8df0937439` | review required | Re-check after #112; do not rerun unchanged checks. | +| [#107](https://github.com/ContextualWisdomLab/keyverse/pull/107) | Uvicorn update | PENDING: 14 Checks queued, 0 terminal failures on `0240ef8df7269da8eddcfe17abd2383812768001` | review required | Re-check after #112; do not rerun unchanged checks. | +| [#106](https://github.com/ContextualWisdomLab/keyverse/pull/106) | `setup-uv` update | PENDING: 14 Checks queued, 0 terminal failures on `2f0e3fb19a63db7f51cdadfeae6155cd469a0c91` | review required | Re-check after #112; do not rerun unchanged checks. | +| [#105](https://github.com/ContextualWisdomLab/keyverse/pull/105) | `harden-runner` update | PENDING: 14 Checks queued, 0 terminal failures on `ef03c5a93c891980588b125f6c774fa84bf0feef` | changes requested | Keep the historical lockfile failure distinct from this current queued head; obtain a new exact-head review after the dependency gate settles. | +| [#104](https://github.com/ContextualWisdomLab/keyverse/pull/104) | ADR and buyer README expansion | PENDING: 14 Checks queued, 0 terminal failures on `01b6dc73f55680d6980e249bcf9dfd71945542f7` | draft | Keep draft until scope and exact-main evidence are ready. | +| [#103](https://github.com/ContextualWisdomLab/keyverse/pull/103) | Hierarchical authorization, login helper, PATs | PENDING: 14 Checks queued, 0 terminal failures on `157b76893b32cda66fc586aa67ae72a30ac6b0d6` | changes requested | Independently validate the historical Strix report against the operator-admin trust boundary; retain fail-closed treatment and obtain a fresh exact-head review/check run before any merge claim. | +| [#101](https://github.com/ContextualWisdomLab/keyverse/pull/101) | Atomic coupled Python dependency updates | PASS: 23 Checks successful, 0 queued on `50dd9c96cab5c230f775685e8baea939fba390dd` | changes requested | Obtain fresh independent review; this is the policy companion to the lockfile gap. | +| [#100](https://github.com/ContextualWisdomLab/keyverse/pull/100) | `lineageweave-web` account-derived claims plus this live baseline refresh | PENDING after this documentation commit; re-fetch the exact live head and hosted rollup | changes requested; fresh review requested | Do not transfer the predecessor PASS; verify the live exact-head Checks and independent review, without self-approval. | +| [#83](https://github.com/ContextualWisdomLab/keyverse/pull/83) | Remove runtime application RPs from portable realm | PASS: 23 Checks successful, 0 queued on `dd1ab7444a75342b42e3af013ccda6d1dbfb359d` | changes requested | Reconfirm current-head approval and latest-pusher rule before protected merge. | + +### Historical check failure root causes observed + +The current exact-head audit above found no terminal failures. The following +items explain earlier failures that still determine safe sequencing; they must +not be copied into the current Checks column as if they were live failures. - The representative account-test failure on Dependabot PRs stopped at `uv sync --locked`: the checked-in lockfile needed updating. This is a From 14193ad6f10e91be8a7ffaa67600086d00e728ed Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 21 Aug 2026 07:12:23 +0900 Subject: [PATCH 25/70] docs: refresh gap baseline doctoring --- .../product-technical-gap-baseline.md | 57 ++++++++++++------- 1 file changed, 36 insertions(+), 21 deletions(-) diff --git a/docs/doctoring/product-technical-gap-baseline.md b/docs/doctoring/product-technical-gap-baseline.md index 430a686..f0b0c97 100644 --- a/docs/doctoring/product-technical-gap-baseline.md +++ b/docs/doctoring/product-technical-gap-baseline.md @@ -1,6 +1,6 @@ # Product-technical gap baseline doctoring record -**Date:** 2026-08-20 +**Date:** 2026-08-21 **Scope:** Keyverse product, trust-boundary, PR queue, and release evidence ## Interpretation @@ -67,27 +67,42 @@ https://www.rfc-editor.org/rfc/rfc8725.html - ADR-0008 and ADR-0009 plus their related specification, plan, operations, and doctoring records. - Exact-head GitHub PR, review, issue, check-run, ruleset, and scheduled-run - queries performed on 2026-08-20. PR #113's current SCIM lock head - `c2c03a5dba46b207b02d296c26d8bb1dbf215092` includes a normal merge of - prerequisite PR #112 and a spawned-process SQLite lock regression; its hosted - Checks are queued and it requires independent review. Its local RED-to-GREEN, - root-level SCIM error-wire, and cross-process sidecar evidence are not - protected-main evidence. PR #112's lockfile head - `f02acf93367a40dbfb23a73985017dca8d42ff39` has terminal-success Checks but - still requires independent review. PR #105's exact head - `72de5499d6e97ae7f7bd804ab78b3e1644dd5a4f` has a failed - `account-unification-tests` Check: `uv 0.12.5` reproduces + queries performed on 2026-08-21. Fourteen Keyverse PRs are open: #112, #101, + and #83 each have 23 successful Checks with no queued run; the other eleven + currently have queued Checks, including #100 after this documentation + refresh. No current open PR has a terminal failure, error, timeout, or + cancellation, and no current open PR has a qualifying formal approval. + Queued Checks remain unverified. + PR #113's current SCIM lock head + `50f19ec6338fb8eb959b8c797bdfa938e1071c87` includes the normal prerequisite + lockfile history and a realistic SCIM PatchOp race plus spawned-process + SQLite lock regression; its hosted Checks are queued and it requires + independent review. Its local RED-to-GREEN, root-level SCIM error-wire, and + cross-process sidecar evidence are not protected-main evidence. PR #112's + lockfile head `f02acf93367a40dbfb23a73985017dca8d42ff39` has terminal-success + Checks but still requires independent review. + The historical PR #105 exact head + `72de5499d6e97ae7f7bd804ab78b3e1644dd5a4f` had a failed + `account-unification-tests` Check: `uv 0.12.5` reproduced `uv sync --locked` refusing the stale `coverage==7.15.2` and - `setuptools==83.0.0` lock entries while the current `pyproject.toml` requires - `7.15.4` and `84.0.0`; #112 is the existing prerequisite lock refresh. - PR #103's - terminal Strix run 32092025335 / job 95576032571 emitted a MEDIUM IDOR report - with contradictory model text; its operator-admin trust boundary still - requires independent validation. PR #100's live current head - is recorded as pending until its Checks and a fresh review complete; this - record travels in that PR, so the live PR record is authoritative for its - changing exact hash. A complete read-only Keyverse Actions registry/tree - reconciliation at protected `main` `ce207dfd` found 43 active identities: + `setuptools==83.0.0` lock entries while the current `pyproject.toml` required + `7.15.4` and `84.0.0`; the current #105 head is queued with no terminal + failure, and #112 remains the lock-refresh prerequisite. + PR #103's historical terminal Strix run 32092025335 / job 95576032571 + emitted a MEDIUM IDOR report with contradictory model text. Current head + `157b76893b32cda66fc586aa67ae72a30ac6b0d6` adds direct-mount operator-auth + regression evidence, but the operator-admin trust boundary still requires + independent validation. PR #100's pre-doctoring-refresh head was + `c483bd53ea74aad5fcea7d3cec2f402e4d8f27c2`; this documentation commit creates + a new pending successor, so its hosted Checks and review must be re-fetched. + Its prior review state is not approval. This record travels in that PR, so + the live PR record remains authoritative for its changing exact hash. + The active ruleset requires two approving reviews, resolved threads, and + latest-push approval, while its read-only audit exposes an + `OrganizationAdmin` always-bypass actor. The ordinary documentation push + emitted GitHub's server-side bypass warning; no explicit bypass option, + protected merge, or self-approval was used. A complete read-only Keyverse + Actions registry/tree reconciliation at protected `main` `ce207dfd` found 43 active identities: four repository workflow paths present in the exact tree, 37 active repository paths absent from it, and two `dynamic/*` GitHub-owned paths. The workflow registry used one API page and the recursive protected-tree response From 02baa312acf794c69150e124c37b0642270f5ee4 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 21 Aug 2026 07:16:25 +0900 Subject: [PATCH 26/70] docs: record live oidc acceptance boundary --- .../product-technical-gap-baseline.md | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/docs/doctoring/product-technical-gap-baseline.md b/docs/doctoring/product-technical-gap-baseline.md index f0b0c97..2307f1c 100644 --- a/docs/doctoring/product-technical-gap-baseline.md +++ b/docs/doctoring/product-technical-gap-baseline.md @@ -44,6 +44,39 @@ evidence gaps. mechanism that projects roles and user/session data into tokens. That vendor behavior does not establish that a receiving application enforces ABAC/RBAC. +## 2026-08-21 local runtime probe + +This is partial protocol-readiness evidence, not login or release acceptance. + +- Docker Engine 29.5.2 was available. The existing Compose runtime reported + `idp_database` healthy, `idp_engine` healthy, and the one-shot + `idp_profile_bootstrap` completed successfully. The account-unification + service was not running. +- `docker compose config --quiet` remained structurally valid but warned that + the deployment-only `IDP_DB_PASSWORD` and + `IDP_BOOTSTRAP_ADMIN_PASSWORD` values were unset. The ignored + `deploy/bootstrap/bootstrap.yaml` was absent; only the secret-free example + pointer exists. No secret or credential value was recorded. +- The live realm discovery endpoint returned HTTP 200 with issuer + `http://localhost:28080/realms/cwl`, authorization/token/JWKS endpoints, and + advertised `S256` among the realm-wide code-challenge methods. +- A real authorization request for the committed `naruon-web` client, its + committed `https://naruon.example/auth/callback` redirect, and a valid + `S256` challenge reached the Keycloak login page with HTTP 200. The earlier + intentionally invalid localhost redirect returned HTTP 400, confirming + redirect enforcement at the live client boundary. +- No account was created, no password or passkey credential was entered, no + authorization code was exchanged, and no token signature/issuer/audience/ + tenant/resource acceptance was claimed. Browser automation was unavailable + in this environment, so browser-clicked passwordless E2E remains absent. + +**Result:** the live issuer and authorization-start boundary are reachable, +but controlled passwordless login, token validation, downstream authorization, +and account-service runtime acceptance remain `gap-not-claimed`. The missing +bootstrap/config-store path is an actionable standalone-Compose deployment gap +that requires deployment-owned secret/config setup before a safe service start; +placeholder credentials must not be committed to close it. + ## APA 7th references OpenID Foundation. (2014). *OpenID Connect Core 1.0*. From 3777f54a824d3b2d3458b94f88e5627a7761a2c0 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 21 Aug 2026 07:29:13 +0900 Subject: [PATCH 27/70] test(realm): cover default validator artifacts --- .../tests/test_validate_realm.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/services/account_unification/tests/test_validate_realm.py b/services/account_unification/tests/test_validate_realm.py index 032b94e..718d462 100644 --- a/services/account_unification/tests/test_validate_realm.py +++ b/services/account_unification/tests/test_validate_realm.py @@ -281,6 +281,19 @@ def test_main_accepts_an_explicit_profile_outside_the_realm_directory( assert f"OK: {realm_path}" in capsys.readouterr().out +def test_main_uses_the_default_committed_realm_and_profile( + monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture[str] +) -> None: + """The CLI default paths validate the committed policy artifacts.""" + validator = _load_validate_realm() + monkeypatch.chdir(_repository_root()) + + result = validator.main(["validate_realm.py"]) + + assert result == 0 + assert "OK: deploy/keycloak/cwl-realm.json" in capsys.readouterr().out + + def test_main_names_an_explicit_invalid_profile_in_its_error( tmp_path: Path, capsys: pytest.CaptureFixture[str] ) -> None: From 193ea3acfbf9e55a27f2d879997a1e1590615624 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 21 Aug 2026 07:31:43 +0900 Subject: [PATCH 28/70] docs: refresh current PR gap evidence --- .../product-technical-gap-baseline.md | 18 ++++++++++++------ docs/product-technical-gap-baseline.md | 12 ++++++------ 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/docs/doctoring/product-technical-gap-baseline.md b/docs/doctoring/product-technical-gap-baseline.md index 2307f1c..a651763 100644 --- a/docs/doctoring/product-technical-gap-baseline.md +++ b/docs/doctoring/product-technical-gap-baseline.md @@ -102,8 +102,8 @@ https://www.rfc-editor.org/rfc/rfc8725.html - Exact-head GitHub PR, review, issue, check-run, ruleset, and scheduled-run queries performed on 2026-08-21. Fourteen Keyverse PRs are open: #112, #101, and #83 each have 23 successful Checks with no queued run; the other eleven - currently have queued Checks, including #100 after this documentation - refresh. No current open PR has a terminal failure, error, timeout, or + currently have queued Checks, including #100 after its default-path coverage + test fix and #104 after its intentional stacked-base rebase. No current open PR has a terminal failure, error, timeout, or cancellation, and no current open PR has a qualifying formal approval. Queued Checks remain unverified. PR #113's current SCIM lock head @@ -126,10 +126,16 @@ https://www.rfc-editor.org/rfc/rfc8725.html `157b76893b32cda66fc586aa67ae72a30ac6b0d6` adds direct-mount operator-auth regression evidence, but the operator-admin trust boundary still requires independent validation. PR #100's pre-doctoring-refresh head was - `c483bd53ea74aad5fcea7d3cec2f402e4d8f27c2`; this documentation commit creates - a new pending successor, so its hosted Checks and review must be re-fetched. - Its prior review state is not approval. This record travels in that PR, so - the live PR record remains authoritative for its changing exact hash. + `c483bd53ea74aad5fcea7d3cec2f402e4d8f27c2`; successor head + `3777f54a824d3b2d3458b94f88e5627a7761a2c0` adds a regression test that invokes + the validator's committed default realm/profile paths after an exact-head + Devin coverage finding. This evidence refresh creates another pending + successor, so its hosted Checks must be re-fetched; its prior review state is + not approval. PR #104 is ready for review at + `0353001438efb060b85373c121f4d54dfd48e8c8`, intentionally based on #112's + lockfile head with no net lockfile change; its stacked Checks remain queued. + This record travels in these PRs, so the live PR records remain authoritative + for their changing exact hashes. The active ruleset requires two approving reviews, resolved threads, and latest-push approval, while its read-only audit exposes an `OrganizationAdmin` always-bypass actor. The ordinary documentation push diff --git a/docs/product-technical-gap-baseline.md b/docs/product-technical-gap-baseline.md index dbdbddf..94696a5 100644 --- a/docs/product-technical-gap-baseline.md +++ b/docs/product-technical-gap-baseline.md @@ -66,12 +66,12 @@ tenant, or resource ownership. The following is the current open-PR inventory. `Checks` means the exact head rollup observed on 2026-08-21; it is not inherited from a predecessor commit. -The baseline is being updated on PR #100, so this documentation commit advances -that head and requires a fresh hosted rollup. The live PR record is authoritative +This record was refreshed after the PR #100 validator-coverage test fix and the +intentional stacked-base rebase of PR #104. The live PR record is authoritative for the exact hash and Checks; predecessor evidence remains non-transferable. -At this snapshot, 14 PRs are open: four have 23 successful Checks with none -queued, ten have 14 Checks queued, and no PR has a terminal failure, error, +At this snapshot, 14 PRs are open: three have 23 successful Checks with none +queued, eleven have queued Checks, and no PR has a terminal failure, error, timeout, or cancellation. Queued Checks remain unverified rather than green. | PR | Scope | Exact-head Checks | Review state | Next safe action | @@ -85,10 +85,10 @@ timeout, or cancellation. Queued Checks remain unverified rather than green. | [#107](https://github.com/ContextualWisdomLab/keyverse/pull/107) | Uvicorn update | PENDING: 14 Checks queued, 0 terminal failures on `0240ef8df7269da8eddcfe17abd2383812768001` | review required | Re-check after #112; do not rerun unchanged checks. | | [#106](https://github.com/ContextualWisdomLab/keyverse/pull/106) | `setup-uv` update | PENDING: 14 Checks queued, 0 terminal failures on `2f0e3fb19a63db7f51cdadfeae6155cd469a0c91` | review required | Re-check after #112; do not rerun unchanged checks. | | [#105](https://github.com/ContextualWisdomLab/keyverse/pull/105) | `harden-runner` update | PENDING: 14 Checks queued, 0 terminal failures on `ef03c5a93c891980588b125f6c774fa84bf0feef` | changes requested | Keep the historical lockfile failure distinct from this current queued head; obtain a new exact-head review after the dependency gate settles. | -| [#104](https://github.com/ContextualWisdomLab/keyverse/pull/104) | ADR and buyer README expansion | PENDING: 14 Checks queued, 0 terminal failures on `01b6dc73f55680d6980e249bcf9dfd71945542f7` | draft | Keep draft until scope and exact-main evidence are ready. | +| [#104](https://github.com/ContextualWisdomLab/keyverse/pull/104) | ADR and buyer README expansion, stacked on #112 | PENDING: 14 Checks queued, 0 terminal failures on `0353001438efb060b85373c121f4d54dfd48e8c8` | review required | Base is intentionally `fix/account-unification-lock-20260819`; the net diff has no lockfile change. Obtain independent review and terminal stacked-head Checks. | | [#103](https://github.com/ContextualWisdomLab/keyverse/pull/103) | Hierarchical authorization, login helper, PATs | PENDING: 14 Checks queued, 0 terminal failures on `157b76893b32cda66fc586aa67ae72a30ac6b0d6` | changes requested | Independently validate the historical Strix report against the operator-admin trust boundary; retain fail-closed treatment and obtain a fresh exact-head review/check run before any merge claim. | | [#101](https://github.com/ContextualWisdomLab/keyverse/pull/101) | Atomic coupled Python dependency updates | PASS: 23 Checks successful, 0 queued on `50dd9c96cab5c230f775685e8baea939fba390dd` | changes requested | Obtain fresh independent review; this is the policy companion to the lockfile gap. | -| [#100](https://github.com/ContextualWisdomLab/keyverse/pull/100) | `lineageweave-web` account-derived claims plus this live baseline refresh | PENDING after this documentation commit; re-fetch the exact live head and hosted rollup | changes requested; fresh review requested | Do not transfer the predecessor PASS; verify the live exact-head Checks and independent review, without self-approval. | +| [#100](https://github.com/ContextualWisdomLab/keyverse/pull/100) | `lineageweave-web` account-derived claims plus default validator-path coverage | PENDING after this evidence refresh; predecessor `3777f54a824d3b2d3458b94f88e5627a7761a2c0` had 14 Checks queued and 0 terminal failures | changes requested; fresh review requested | Devin's exact-head coverage finding is addressed by the default-artifact regression test; the live PR record must be re-fetched after this commit, without self-approval. | | [#83](https://github.com/ContextualWisdomLab/keyverse/pull/83) | Remove runtime application RPs from portable realm | PASS: 23 Checks successful, 0 queued on `dd1ab7444a75342b42e3af013ccda6d1dbfb359d` | changes requested | Reconfirm current-head approval and latest-pusher rule before protected merge. | ### Historical check failure root causes observed From 49d8899dca3eda31df76d5fc236f7f5fee5ed31e Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 21 Aug 2026 07:52:39 +0900 Subject: [PATCH 29/70] docs: record cross-repo cadence dependency --- docs/doctoring/product-technical-gap-baseline.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/docs/doctoring/product-technical-gap-baseline.md b/docs/doctoring/product-technical-gap-baseline.md index a651763..3ac49e9 100644 --- a/docs/doctoring/product-technical-gap-baseline.md +++ b/docs/doctoring/product-technical-gap-baseline.md @@ -77,6 +77,22 @@ bootstrap/config-store path is an actionable standalone-Compose deployment gap that requires deployment-owned secret/config setup before a safe service start; placeholder credentials must not be committed to close it. +## 2026-08-21 cross-repository cadence dependency + +- The related contextual-orchestrator hourly caller is open as PR #797 at exact + head `2693c01b79c564db041abc930f3365eddd74dfe3`. It invokes the central + review-repair scheduler for one exact-head dispatch per hourly tick and names + central `.github` PR #1170 as a prerequisite for the gateway route. +- Central `.github` PR #1170 is open at exact head + `4684f6e212ba40d12e5217f0f52ee1e90c796ed8` after the gateway fallback/privacy/ + reasoning fixes and the final docstring repair. Its new hosted rollup has 17 + queued checks, one success, and no terminal failure. Neither #1170 nor #797 + has qualifying formal approval or protected merge evidence. +- Keyverse's existing `Hourly product development` workflow remains active at + `41 * * * *`; its latest observed scheduled runs succeeded. No duplicate + scheduler was added. Activation of the related caller remains conditional on + independent approval and terminal exact-head evidence for both PRs. + ## APA 7th references OpenID Foundation. (2014). *OpenID Connect Core 1.0*. From 32b69cdcf2b3b2553163daa38d42ed2b20c467a4 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 21 Aug 2026 08:01:53 +0900 Subject: [PATCH 30/70] docs: refresh live check failure baseline --- .../product-technical-gap-baseline.md | 34 ++++++++------ docs/product-technical-gap-baseline.md | 46 ++++++++++++------- 2 files changed, 50 insertions(+), 30 deletions(-) diff --git a/docs/doctoring/product-technical-gap-baseline.md b/docs/doctoring/product-technical-gap-baseline.md index 3ac49e9..cf999ca 100644 --- a/docs/doctoring/product-technical-gap-baseline.md +++ b/docs/doctoring/product-technical-gap-baseline.md @@ -117,26 +117,32 @@ https://www.rfc-editor.org/rfc/rfc8725.html and doctoring records. - Exact-head GitHub PR, review, issue, check-run, ruleset, and scheduled-run queries performed on 2026-08-21. Fourteen Keyverse PRs are open: #112, #101, - and #83 each have 23 successful Checks with no queued run; the other eleven - currently have queued Checks, including #100 after its default-path coverage - test fix and #104 after its intentional stacked-base rebase. No current open PR has a terminal failure, error, timeout, or - cancellation, and no current open PR has a qualifying formal approval. + and #83 each have 22 successful Checks with no queued run; nine others have + queued Checks without a terminal failure, while #111 and #113 each have one + terminal failure. No current open PR has a qualifying formal approval. Queued Checks remain unverified. PR #113's current SCIM lock head `50f19ec6338fb8eb959b8c797bdfa938e1071c87` includes the normal prerequisite lockfile history and a realistic SCIM PatchOp race plus spawned-process - SQLite lock regression; its hosted Checks are queued and it requires - independent review. Its local RED-to-GREEN, root-level SCIM error-wire, and - cross-process sidecar evidence are not protected-main evidence. PR #112's - lockfile head `f02acf93367a40dbfb23a73985017dca8d42ff39` has terminal-success - Checks but still requires independent review. + SQLite lock regression; its hosted Checks have one terminal `strix` failure, + one queued run, and 18 successful runs. The failed Strix job could not pull + `ghcr.io/usestrix/strix-sandbox:1.3.0` because GHCR returned HTTP 500/EOF, + and it produced no structured vulnerability report, so the workflow failed + closed. Its local RED-to-GREEN, root-level SCIM error-wire, and cross-process + sidecar evidence are not protected-main evidence. PR #112's lockfile head + `f02acf93367a40dbfb23a73985017dca8d42ff39` has 22 terminal-success Checks + but still requires independent review. PR #111's current head + `e1d0fee6ce29cb9ec75d9fbdb38cd15242bf4fdc` has one terminal + `account-unification-tests` failure because `uv sync --locked` found a stale + `uv.lock` before tests began; it remains coupled to #112 and #110. The historical PR #105 exact head `72de5499d6e97ae7f7bd804ab78b3e1644dd5a4f` had a failed `account-unification-tests` Check: `uv 0.12.5` reproduced `uv sync --locked` refusing the stale `coverage==7.15.2` and `setuptools==83.0.0` lock entries while the current `pyproject.toml` required - `7.15.4` and `84.0.0`; the current #105 head is queued with no terminal - failure, and #112 remains the lock-refresh prerequisite. + `7.15.4` and `84.0.0`; the current #105 head has nine queued and nine + successful Checks with no terminal failure, and #112 remains the + lock-refresh prerequisite. PR #103's historical terminal Strix run 32092025335 / job 95576032571 emitted a MEDIUM IDOR report with contradictory model text. Current head `157b76893b32cda66fc586aa67ae72a30ac6b0d6` adds direct-mount operator-auth @@ -145,9 +151,9 @@ https://www.rfc-editor.org/rfc/rfc8725.html `c483bd53ea74aad5fcea7d3cec2f402e4d8f27c2`; successor head `3777f54a824d3b2d3458b94f88e5627a7761a2c0` adds a regression test that invokes the validator's committed default realm/profile paths after an exact-head - Devin coverage finding. This evidence refresh creates another pending - successor, so its hosted Checks must be re-fetched; its prior review state is - not approval. PR #104 is ready for review at + Devin coverage finding. The current documentation successor is + `49d8899dca3eda31df76d5fc236f7f5fee5ed31e`, with 14 queued Checks and no + terminal failure; its prior review state is not approval. PR #104 is ready for review at `0353001438efb060b85373c121f4d54dfd48e8c8`, intentionally based on #112's lockfile head with no net lockfile change; its stacked Checks remain queued. This record travels in these PRs, so the live PR records remain authoritative diff --git a/docs/product-technical-gap-baseline.md b/docs/product-technical-gap-baseline.md index 94696a5..14658a7 100644 --- a/docs/product-technical-gap-baseline.md +++ b/docs/product-technical-gap-baseline.md @@ -70,32 +70,46 @@ This record was refreshed after the PR #100 validator-coverage test fix and the intentional stacked-base rebase of PR #104. The live PR record is authoritative for the exact hash and Checks; predecessor evidence remains non-transferable. -At this snapshot, 14 PRs are open: three have 23 successful Checks with none -queued, eleven have queued Checks, and no PR has a terminal failure, error, -timeout, or cancellation. Queued Checks remain unverified rather than green. +At this snapshot, 14 PRs are open: three have 22 successful Checks with none +queued, nine have queued Checks without a terminal failure, and two have a +terminal failure in addition to queued or successful Checks. Queued Checks +remain unverified rather than green. | PR | Scope | Exact-head Checks | Review state | Next safe action | |---:|---|---|---|---| -| [#113](https://github.com/ContextualWisdomLab/keyverse/pull/113) | SCIM `PATCH active=false` shared operation lock, stacked on #112 lockfile refresh | PENDING: 14 Checks queued, 0 terminal failures on `50f19ec6338fb8eb959b8c797bdfa938e1071c87` | review required | Obtain independent review and terminal exact-head Checks, then let protected automation merge; do not treat local GREEN as protected-main evidence. | -| [#112](https://github.com/ContextualWisdomLab/keyverse/pull/112) | Resync account-unification lockfile | PASS: 23 Checks successful, 0 queued on `f02acf93367a40dbfb23a73985017dca8d42ff39` | review required | Obtain independent review, then let protected automation re-check and merge. | -| [#111](https://github.com/ContextualWisdomLab/keyverse/pull/111) | CodeQL init 4.37.7 | PENDING: 14 Checks queued, 0 terminal failures on `e1d0fee6ce29cb9ec75d9fbdb38cd15242bf4fdc` | review required | Keep coupled with #110; revalidate after lockfile and action-version coupling is resolved. | -| [#110](https://github.com/ContextualWisdomLab/keyverse/pull/110) | CodeQL analyze 4.37.7 | PENDING: 14 Checks queued, 0 terminal failures on `07acd65145c9522a74858d1ff8761ea05a09e8f0` | review required | Treat as the companion of #111; do not merge the action pair independently. | +| [#113](https://github.com/ContextualWisdomLab/keyverse/pull/113) | SCIM `PATCH active=false` shared operation lock, stacked on #112 lockfile refresh | FAIL: 1 terminal `strix` failure, 1 queued, 18 successful on `50f19ec6338fb8eb959b8c797bdfa938e1071c87` | review required | The failure was a transient GHCR Strix image pull EOF with no report; preserve fail-closed treatment and obtain a fresh exact-head run when the external image service is available. | +| [#112](https://github.com/ContextualWisdomLab/keyverse/pull/112) | Resync account-unification lockfile | PASS: 22 Checks successful, 0 queued on `f02acf93367a40dbfb23a73985017dca8d42ff39` | review required | Obtain independent review, then let protected automation re-check and merge. | +| [#111](https://github.com/ContextualWisdomLab/keyverse/pull/111) | CodeQL init 4.37.7 | FAIL: 1 terminal `account-unification-tests` failure, 3 queued, 16 successful on `e1d0fee6ce29cb9ec75d9fbdb38cd15242bf4fdc` | review required | Keep coupled with #110 and #112; the exact run stopped at stale `uv.lock`, so rebase or regenerate only after the lockfile prerequisite is protected-main. | +| [#110](https://github.com/ContextualWisdomLab/keyverse/pull/110) | CodeQL analyze 4.37.7 | PENDING: 5 Checks queued, 15 successful, 0 terminal failures on `07acd65145c9522a74858d1ff8761ea05a09e8f0` | review required | Treat as the companion of #111; do not merge the action pair independently. | | [#109](https://github.com/ContextualWisdomLab/keyverse/pull/109) | `typing-inspection` update | PENDING: 14 Checks queued, 0 terminal failures on `28a4e05b23baa75d44b37589ba662a3c46c67129` | review required | Re-check after #112; do not treat queued Checks as a failure. | -| [#108](https://github.com/ContextualWisdomLab/keyverse/pull/108) | Ruff update | PENDING: 14 Checks queued, 0 terminal failures on `d9791bba5a2e277c2ae503504b871e8df0937439` | review required | Re-check after #112; do not rerun unchanged checks. | +| [#108](https://github.com/ContextualWisdomLab/keyverse/pull/108) | Ruff update | PENDING: 7 Checks queued, 12 successful, 0 terminal failures on `d9791bba5a2e277c2ae503504b871e8df0937439` | review required | Re-check after #112; do not rerun unchanged checks. | | [#107](https://github.com/ContextualWisdomLab/keyverse/pull/107) | Uvicorn update | PENDING: 14 Checks queued, 0 terminal failures on `0240ef8df7269da8eddcfe17abd2383812768001` | review required | Re-check after #112; do not rerun unchanged checks. | -| [#106](https://github.com/ContextualWisdomLab/keyverse/pull/106) | `setup-uv` update | PENDING: 14 Checks queued, 0 terminal failures on `2f0e3fb19a63db7f51cdadfeae6155cd469a0c91` | review required | Re-check after #112; do not rerun unchanged checks. | -| [#105](https://github.com/ContextualWisdomLab/keyverse/pull/105) | `harden-runner` update | PENDING: 14 Checks queued, 0 terminal failures on `ef03c5a93c891980588b125f6c774fa84bf0feef` | changes requested | Keep the historical lockfile failure distinct from this current queued head; obtain a new exact-head review after the dependency gate settles. | +| [#106](https://github.com/ContextualWisdomLab/keyverse/pull/106) | `setup-uv` update | PENDING: 6 Checks queued, 14 successful, 0 terminal failures on `2f0e3fb19a63db7f51cdadfeae6155cd469a0c91` | review required | Re-check after #112; do not rerun unchanged checks. | +| [#105](https://github.com/ContextualWisdomLab/keyverse/pull/105) | `harden-runner` update | PENDING: 9 Checks queued, 9 successful, 0 terminal failures on `ef03c5a93c891980588b125f6c774fa84bf0feef` | changes requested | Keep the historical lockfile failure distinct from this current mixed head; obtain a new exact-head review after the dependency gate settles. | | [#104](https://github.com/ContextualWisdomLab/keyverse/pull/104) | ADR and buyer README expansion, stacked on #112 | PENDING: 14 Checks queued, 0 terminal failures on `0353001438efb060b85373c121f4d54dfd48e8c8` | review required | Base is intentionally `fix/account-unification-lock-20260819`; the net diff has no lockfile change. Obtain independent review and terminal stacked-head Checks. | | [#103](https://github.com/ContextualWisdomLab/keyverse/pull/103) | Hierarchical authorization, login helper, PATs | PENDING: 14 Checks queued, 0 terminal failures on `157b76893b32cda66fc586aa67ae72a30ac6b0d6` | changes requested | Independently validate the historical Strix report against the operator-admin trust boundary; retain fail-closed treatment and obtain a fresh exact-head review/check run before any merge claim. | -| [#101](https://github.com/ContextualWisdomLab/keyverse/pull/101) | Atomic coupled Python dependency updates | PASS: 23 Checks successful, 0 queued on `50dd9c96cab5c230f775685e8baea939fba390dd` | changes requested | Obtain fresh independent review; this is the policy companion to the lockfile gap. | -| [#100](https://github.com/ContextualWisdomLab/keyverse/pull/100) | `lineageweave-web` account-derived claims plus default validator-path coverage | PENDING after this evidence refresh; predecessor `3777f54a824d3b2d3458b94f88e5627a7761a2c0` had 14 Checks queued and 0 terminal failures | changes requested; fresh review requested | Devin's exact-head coverage finding is addressed by the default-artifact regression test; the live PR record must be re-fetched after this commit, without self-approval. | -| [#83](https://github.com/ContextualWisdomLab/keyverse/pull/83) | Remove runtime application RPs from portable realm | PASS: 23 Checks successful, 0 queued on `dd1ab7444a75342b42e3af013ccda6d1dbfb359d` | changes requested | Reconfirm current-head approval and latest-pusher rule before protected merge. | +| [#101](https://github.com/ContextualWisdomLab/keyverse/pull/101) | Atomic coupled Python dependency updates | PASS: 22 Checks successful, 0 queued on `50dd9c96cab5c230f775685e8baea939fba390dd` | changes requested | Obtain fresh independent review; this is the policy companion to the lockfile gap. | +| [#100](https://github.com/ContextualWisdomLab/keyverse/pull/100) | `lineageweave-web` account-derived claims plus default validator-path coverage | PENDING: 14 Checks queued, 0 terminal failures on `49d8899dca3eda31df76d5fc236f7f5fee5ed31e` | changes requested; fresh review requested | Devin's exact-head coverage finding is addressed by the default-artifact regression test; obtain current-head review without self-approval. | +| [#83](https://github.com/ContextualWisdomLab/keyverse/pull/83) | Remove runtime application RPs from portable realm | PASS: 22 Checks successful, 0 queued on `dd1ab7444a75342b42e3af013ccda6d1dbfb359d` | changes requested | Reconfirm current-head approval and latest-pusher rule before protected merge. | ### Historical check failure root causes observed -The current exact-head audit above found no terminal failures. The following -items explain earlier failures that still determine safe sequencing; they must -not be copied into the current Checks column as if they were live failures. +The current exact-head audit above found two terminal failures. The following +items explain the live failures and earlier failures that still determine safe +sequencing; they must not be copied to another PR as if they were transferable +evidence. + +- PR #113's exact-head `strix` failure was an external image-pull failure, not + a source finding: `ghcr.io/usestrix/strix-sandbox:1.3.0` returned HTTP 500 + with an EOF while downloading from GHCR, and no structured vulnerability + report was produced. The workflow correctly failed closed. A fresh run is + required after the external image service recovers; no code change can make + that exact failed run green. + +- PR #111's exact-head `account-unification-tests` failure stopped before tests + at `uv sync --locked`: the branch carries a stale `uv.lock`. PR #112 is the + existing lock-refresh prerequisite; rebase or regenerate #111 only after + the protected dependency sequence is resolved. - The representative account-test failure on Dependabot PRs stopped at `uv sync --locked`: the checked-in lockfile needed updating. This is a From fb7599482b775a3079bf6e6f0dc0f5845ae8bd28 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 21 Aug 2026 08:05:30 +0900 Subject: [PATCH 31/70] docs: record stacked lockfile rerun --- docs/doctoring/product-technical-gap-baseline.md | 13 ++++++++----- docs/product-technical-gap-baseline.md | 8 ++++---- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/docs/doctoring/product-technical-gap-baseline.md b/docs/doctoring/product-technical-gap-baseline.md index cf999ca..daf7acb 100644 --- a/docs/doctoring/product-technical-gap-baseline.md +++ b/docs/doctoring/product-technical-gap-baseline.md @@ -118,8 +118,9 @@ https://www.rfc-editor.org/rfc/rfc8725.html - Exact-head GitHub PR, review, issue, check-run, ruleset, and scheduled-run queries performed on 2026-08-21. Fourteen Keyverse PRs are open: #112, #101, and #83 each have 22 successful Checks with no queued run; nine others have - queued Checks without a terminal failure, while #111 and #113 each have one - terminal failure. No current open PR has a qualifying formal approval. + queued Checks without a terminal failure, #111 retains one old-base failure + while its stacked rerun is queued, and #113 has one current terminal failure. + No current open PR has a qualifying formal approval. Queued Checks remain unverified. PR #113's current SCIM lock head `50f19ec6338fb8eb959b8c797bdfa938e1071c87` includes the normal prerequisite @@ -132,9 +133,11 @@ https://www.rfc-editor.org/rfc/rfc8725.html sidecar evidence are not protected-main evidence. PR #112's lockfile head `f02acf93367a40dbfb23a73985017dca8d42ff39` has 22 terminal-success Checks but still requires independent review. PR #111's current head - `e1d0fee6ce29cb9ec75d9fbdb38cd15242bf4fdc` has one terminal - `account-unification-tests` failure because `uv sync --locked` found a stale - `uv.lock` before tests began; it remains coupled to #112 and #110. + `e1d0fee6ce29cb9ec75d9fbdb38cd15242bf4fdc` is now stacked on #112. Its + prior `account-unification-tests` failure occurred against the old `main` + base because `uv sync --locked` found a stale `uv.lock` before tests began; + that failed job was rerun against the lock-refresh base and remains queued. + It remains coupled to #112 and #110. The historical PR #105 exact head `72de5499d6e97ae7f7bd804ab78b3e1644dd5a4f` had a failed `account-unification-tests` Check: `uv 0.12.5` reproduced diff --git a/docs/product-technical-gap-baseline.md b/docs/product-technical-gap-baseline.md index 14658a7..fe4ae33 100644 --- a/docs/product-technical-gap-baseline.md +++ b/docs/product-technical-gap-baseline.md @@ -71,15 +71,15 @@ intentional stacked-base rebase of PR #104. The live PR record is authoritative for the exact hash and Checks; predecessor evidence remains non-transferable. At this snapshot, 14 PRs are open: three have 22 successful Checks with none -queued, nine have queued Checks without a terminal failure, and two have a -terminal failure in addition to queued or successful Checks. Queued Checks -remain unverified rather than green. +queued, nine have queued Checks without a terminal failure, #111 retains one +old-base failure while its stacked rerun is queued, and #113 has one current +terminal failure. Queued Checks remain unverified rather than green. | PR | Scope | Exact-head Checks | Review state | Next safe action | |---:|---|---|---|---| | [#113](https://github.com/ContextualWisdomLab/keyverse/pull/113) | SCIM `PATCH active=false` shared operation lock, stacked on #112 lockfile refresh | FAIL: 1 terminal `strix` failure, 1 queued, 18 successful on `50f19ec6338fb8eb959b8c797bdfa938e1071c87` | review required | The failure was a transient GHCR Strix image pull EOF with no report; preserve fail-closed treatment and obtain a fresh exact-head run when the external image service is available. | | [#112](https://github.com/ContextualWisdomLab/keyverse/pull/112) | Resync account-unification lockfile | PASS: 22 Checks successful, 0 queued on `f02acf93367a40dbfb23a73985017dca8d42ff39` | review required | Obtain independent review, then let protected automation re-check and merge. | -| [#111](https://github.com/ContextualWisdomLab/keyverse/pull/111) | CodeQL init 4.37.7 | FAIL: 1 terminal `account-unification-tests` failure, 3 queued, 16 successful on `e1d0fee6ce29cb9ec75d9fbdb38cd15242bf4fdc` | review required | Keep coupled with #110 and #112; the exact run stopped at stale `uv.lock`, so rebase or regenerate only after the lockfile prerequisite is protected-main. | +| [#111](https://github.com/ContextualWisdomLab/keyverse/pull/111) | CodeQL init 4.37.7 | PENDING: 1 queued rerun, 18 successful, plus the prior-base `account-unification-tests` failure on `e1d0fee6ce29cb9ec75d9fbdb38cd15242bf4fdc` | review required | Now stacked on #112; the failed job was rerun against the lock-refresh base, so wait for that exact-base result before review or merge decisions. | | [#110](https://github.com/ContextualWisdomLab/keyverse/pull/110) | CodeQL analyze 4.37.7 | PENDING: 5 Checks queued, 15 successful, 0 terminal failures on `07acd65145c9522a74858d1ff8761ea05a09e8f0` | review required | Treat as the companion of #111; do not merge the action pair independently. | | [#109](https://github.com/ContextualWisdomLab/keyverse/pull/109) | `typing-inspection` update | PENDING: 14 Checks queued, 0 terminal failures on `28a4e05b23baa75d44b37589ba662a3c46c67129` | review required | Re-check after #112; do not treat queued Checks as a failure. | | [#108](https://github.com/ContextualWisdomLab/keyverse/pull/108) | Ruff update | PENDING: 7 Checks queued, 12 successful, 0 terminal failures on `d9791bba5a2e277c2ae503504b871e8df0937439` | review required | Re-check after #112; do not rerun unchanged checks. | From 0cf06bf3d5fbbae50927c39afb93fc1bca4e9e33 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 21 Aug 2026 08:09:35 +0900 Subject: [PATCH 32/70] docs: record recovered lockfile checks --- docs/doctoring/product-technical-gap-baseline.md | 9 +++++---- docs/product-technical-gap-baseline.md | 9 +++++---- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/docs/doctoring/product-technical-gap-baseline.md b/docs/doctoring/product-technical-gap-baseline.md index daf7acb..5b15d50 100644 --- a/docs/doctoring/product-technical-gap-baseline.md +++ b/docs/doctoring/product-technical-gap-baseline.md @@ -118,8 +118,9 @@ https://www.rfc-editor.org/rfc/rfc8725.html - Exact-head GitHub PR, review, issue, check-run, ruleset, and scheduled-run queries performed on 2026-08-21. Fourteen Keyverse PRs are open: #112, #101, and #83 each have 22 successful Checks with no queued run; nine others have - queued Checks without a terminal failure, #111 retains one old-base failure - while its stacked rerun is queued, and #113 has one current terminal failure. + queued Checks without a terminal failure, #111 has 18 successful Checks and + two queued after its lock-refresh stack, and #113 has one current terminal + failure. No current open PR has a qualifying formal approval. Queued Checks remain unverified. PR #113's current SCIM lock head @@ -136,8 +137,8 @@ https://www.rfc-editor.org/rfc/rfc8725.html `e1d0fee6ce29cb9ec75d9fbdb38cd15242bf4fdc` is now stacked on #112. Its prior `account-unification-tests` failure occurred against the old `main` base because `uv sync --locked` found a stale `uv.lock` before tests began; - that failed job was rerun against the lock-refresh base and remains queued. - It remains coupled to #112 and #110. + the rerun against the lock-refresh base now has no terminal failure and two + queued Checks. It remains coupled to #112 and #110. The historical PR #105 exact head `72de5499d6e97ae7f7bd804ab78b3e1644dd5a4f` had a failed `account-unification-tests` Check: `uv 0.12.5` reproduced diff --git a/docs/product-technical-gap-baseline.md b/docs/product-technical-gap-baseline.md index fe4ae33..68544c8 100644 --- a/docs/product-technical-gap-baseline.md +++ b/docs/product-technical-gap-baseline.md @@ -71,15 +71,16 @@ intentional stacked-base rebase of PR #104. The live PR record is authoritative for the exact hash and Checks; predecessor evidence remains non-transferable. At this snapshot, 14 PRs are open: three have 22 successful Checks with none -queued, nine have queued Checks without a terminal failure, #111 retains one -old-base failure while its stacked rerun is queued, and #113 has one current -terminal failure. Queued Checks remain unverified rather than green. +queued, nine have queued Checks without a terminal failure, #111 has 18 +successful Checks with two queued after its lock-refresh stack, and #113 has +one current terminal failure. Queued Checks remain unverified rather than +green. | PR | Scope | Exact-head Checks | Review state | Next safe action | |---:|---|---|---|---| | [#113](https://github.com/ContextualWisdomLab/keyverse/pull/113) | SCIM `PATCH active=false` shared operation lock, stacked on #112 lockfile refresh | FAIL: 1 terminal `strix` failure, 1 queued, 18 successful on `50f19ec6338fb8eb959b8c797bdfa938e1071c87` | review required | The failure was a transient GHCR Strix image pull EOF with no report; preserve fail-closed treatment and obtain a fresh exact-head run when the external image service is available. | | [#112](https://github.com/ContextualWisdomLab/keyverse/pull/112) | Resync account-unification lockfile | PASS: 22 Checks successful, 0 queued on `f02acf93367a40dbfb23a73985017dca8d42ff39` | review required | Obtain independent review, then let protected automation re-check and merge. | -| [#111](https://github.com/ContextualWisdomLab/keyverse/pull/111) | CodeQL init 4.37.7 | PENDING: 1 queued rerun, 18 successful, plus the prior-base `account-unification-tests` failure on `e1d0fee6ce29cb9ec75d9fbdb38cd15242bf4fdc` | review required | Now stacked on #112; the failed job was rerun against the lock-refresh base, so wait for that exact-base result before review or merge decisions. | +| [#111](https://github.com/ContextualWisdomLab/keyverse/pull/111) | CodeQL init 4.37.7 | PENDING: 2 queued, 18 successful, 0 terminal failures on `e1d0fee6ce29cb9ec75d9fbdb38cd15242bf4fdc` | review required | Now stacked on #112; the stale-lock failure is cleared on the new base, so wait for the remaining exact-head Checks and independent review. | | [#110](https://github.com/ContextualWisdomLab/keyverse/pull/110) | CodeQL analyze 4.37.7 | PENDING: 5 Checks queued, 15 successful, 0 terminal failures on `07acd65145c9522a74858d1ff8761ea05a09e8f0` | review required | Treat as the companion of #111; do not merge the action pair independently. | | [#109](https://github.com/ContextualWisdomLab/keyverse/pull/109) | `typing-inspection` update | PENDING: 14 Checks queued, 0 terminal failures on `28a4e05b23baa75d44b37589ba662a3c46c67129` | review required | Re-check after #112; do not treat queued Checks as a failure. | | [#108](https://github.com/ContextualWisdomLab/keyverse/pull/108) | Ruff update | PENDING: 7 Checks queued, 12 successful, 0 terminal failures on `d9791bba5a2e277c2ae503504b871e8df0937439` | review required | Re-check after #112; do not rerun unchanged checks. | From 89a1415d5a6bdd95eb7dd2cc4842f05dbedcca67 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 21 Aug 2026 08:15:43 +0900 Subject: [PATCH 33/70] docs: bound storage evidence gap --- docs/doctoring/product-technical-gap-baseline.md | 11 +++++++++++ docs/product-technical-gap-baseline.md | 6 ++++++ 2 files changed, 17 insertions(+) diff --git a/docs/doctoring/product-technical-gap-baseline.md b/docs/doctoring/product-technical-gap-baseline.md index 5b15d50..dd7eb10 100644 --- a/docs/doctoring/product-technical-gap-baseline.md +++ b/docs/doctoring/product-technical-gap-baseline.md @@ -77,6 +77,17 @@ bootstrap/config-store path is an actionable standalone-Compose deployment gap that requires deployment-owned secret/config setup before a safe service start; placeholder credentials must not be committed to close it. +## 2026-08-21 storage evidence + +- The focused exact-tree run `uv run pytest -q + tests/test_storage_concurrency.py tests/test_lifecycle.py` passed 6 tests. + This is evidence for the SQLite sidecar's local lock contention and lifecycle + behavior only. +- No PostgreSQL migration/rollback, concentrated-tenant skew, partition-key, + backup/restore, or production recovery evidence was observed. G5 therefore + remains `gap-not-claimed`; the local SQLite result must not be promoted into a + production database acceptance claim. + ## 2026-08-21 cross-repository cadence dependency - The related contextual-orchestrator hourly caller is open as PR #797 at exact diff --git a/docs/product-technical-gap-baseline.md b/docs/product-technical-gap-baseline.md index 68544c8..4e46ffc 100644 --- a/docs/product-technical-gap-baseline.md +++ b/docs/product-technical-gap-baseline.md @@ -220,6 +220,12 @@ and a refreshed baseline prove the change on main. two-word-or-longer snake_case names, but a production claim needs migration, index, partition-key, skew, and recovery evidence from the owning database. +**Current repository evidence:** the focused local SQLite storage/lifecycle +regression run (`tests/test_storage_concurrency.py` and +`tests/test_lifecycle.py`) passed 6 tests on this tree. It proves only the +sidecar's local locking and lifecycle behavior; it is not PostgreSQL migration, +partition-skew, backup, restore, or production recovery evidence. + **Acceptance:** run PostgreSQL migration/rollback tests with tenant-scoped composite constraints, measure skew under concentrated tenants, document the chosen partition/index strategy, and prove backup/restore. Do not add a From 2b8c59fd29acf9464044734100c520ad591a6a75 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 21 Aug 2026 08:18:40 +0900 Subject: [PATCH 34/70] docs: reconcile ecosystem dependency evidence --- docs/doctoring/product-technical-gap-baseline.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/docs/doctoring/product-technical-gap-baseline.md b/docs/doctoring/product-technical-gap-baseline.md index dd7eb10..5699ac6 100644 --- a/docs/doctoring/product-technical-gap-baseline.md +++ b/docs/doctoring/product-technical-gap-baseline.md @@ -91,14 +91,16 @@ placeholder credentials must not be committed to close it. ## 2026-08-21 cross-repository cadence dependency - The related contextual-orchestrator hourly caller is open as PR #797 at exact - head `2693c01b79c564db041abc930f3365eddd74dfe3`. It invokes the central - review-repair scheduler for one exact-head dispatch per hourly tick and names - central `.github` PR #1170 as a prerequisite for the gateway route. + head `5dccb65fdd6088deb7c014f819340cceeb89c313`. It invokes the central + review-repair scheduler for one exact-head dispatch at minute 07 of each hour + and names central `.github` PR #1170 as the gateway prerequisite. Its current + exact-head rollup has 15 queued Checks, 0 terminal failures, and 0 successes. - Central `.github` PR #1170 is open at exact head `4684f6e212ba40d12e5217f0f52ee1e90c796ed8` after the gateway fallback/privacy/ - reasoning fixes and the final docstring repair. Its new hosted rollup has 17 - queued checks, one success, and no terminal failure. Neither #1170 nor #797 - has qualifying formal approval or protected merge evidence. + reasoning fixes and the final docstring repair. Its current hosted rollup has + 16 queued Checks, 2 successes, and no terminal failure. The superseded + central PR #1183 is closed without merge and is not a prerequisite. Neither + #1170 nor #797 has qualifying formal approval or protected merge evidence. - Keyverse's existing `Hourly product development` workflow remains active at `41 * * * *`; its latest observed scheduled runs succeeded. No duplicate scheduler was added. Activation of the related caller remains conditional on From a9978261d19e096de5c2ce76d2188ecc8f7bec80 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 21 Aug 2026 08:19:55 +0900 Subject: [PATCH 35/70] docs: update current documentation head --- docs/doctoring/product-technical-gap-baseline.md | 2 +- docs/product-technical-gap-baseline.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/doctoring/product-technical-gap-baseline.md b/docs/doctoring/product-technical-gap-baseline.md index 5699ac6..ec80b86 100644 --- a/docs/doctoring/product-technical-gap-baseline.md +++ b/docs/doctoring/product-technical-gap-baseline.md @@ -169,7 +169,7 @@ https://www.rfc-editor.org/rfc/rfc8725.html `3777f54a824d3b2d3458b94f88e5627a7761a2c0` adds a regression test that invokes the validator's committed default realm/profile paths after an exact-head Devin coverage finding. The current documentation successor is - `49d8899dca3eda31df76d5fc236f7f5fee5ed31e`, with 14 queued Checks and no + `2b8c59fd29acf9464044734100c520ad591a6a75`, with 14 queued Checks and no terminal failure; its prior review state is not approval. PR #104 is ready for review at `0353001438efb060b85373c121f4d54dfd48e8c8`, intentionally based on #112's lockfile head with no net lockfile change; its stacked Checks remain queued. diff --git a/docs/product-technical-gap-baseline.md b/docs/product-technical-gap-baseline.md index 4e46ffc..0daa9df 100644 --- a/docs/product-technical-gap-baseline.md +++ b/docs/product-technical-gap-baseline.md @@ -90,7 +90,7 @@ green. | [#104](https://github.com/ContextualWisdomLab/keyverse/pull/104) | ADR and buyer README expansion, stacked on #112 | PENDING: 14 Checks queued, 0 terminal failures on `0353001438efb060b85373c121f4d54dfd48e8c8` | review required | Base is intentionally `fix/account-unification-lock-20260819`; the net diff has no lockfile change. Obtain independent review and terminal stacked-head Checks. | | [#103](https://github.com/ContextualWisdomLab/keyverse/pull/103) | Hierarchical authorization, login helper, PATs | PENDING: 14 Checks queued, 0 terminal failures on `157b76893b32cda66fc586aa67ae72a30ac6b0d6` | changes requested | Independently validate the historical Strix report against the operator-admin trust boundary; retain fail-closed treatment and obtain a fresh exact-head review/check run before any merge claim. | | [#101](https://github.com/ContextualWisdomLab/keyverse/pull/101) | Atomic coupled Python dependency updates | PASS: 22 Checks successful, 0 queued on `50dd9c96cab5c230f775685e8baea939fba390dd` | changes requested | Obtain fresh independent review; this is the policy companion to the lockfile gap. | -| [#100](https://github.com/ContextualWisdomLab/keyverse/pull/100) | `lineageweave-web` account-derived claims plus default validator-path coverage | PENDING: 14 Checks queued, 0 terminal failures on `49d8899dca3eda31df76d5fc236f7f5fee5ed31e` | changes requested; fresh review requested | Devin's exact-head coverage finding is addressed by the default-artifact regression test; obtain current-head review without self-approval. | +| [#100](https://github.com/ContextualWisdomLab/keyverse/pull/100) | `lineageweave-web` account-derived claims plus default validator-path coverage | PENDING: 14 Checks queued, 0 terminal failures on `2b8c59fd29acf9464044734100c520ad591a6a75` | changes requested; fresh review requested | Devin's exact-head coverage finding is addressed by the default-artifact regression test; obtain current-head review without self-approval. | | [#83](https://github.com/ContextualWisdomLab/keyverse/pull/83) | Remove runtime application RPs from portable realm | PASS: 22 Checks successful, 0 queued on `dd1ab7444a75342b42e3af013ccda6d1dbfb359d` | changes requested | Reconfirm current-head approval and latest-pusher rule before protected merge. | ### Historical check failure root causes observed From 8a5ba11322bebc09bde8ea57e9fb06d35ad0d614 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 21 Aug 2026 08:24:13 +0900 Subject: [PATCH 36/70] docs: record exact local CI evidence --- docs/doctoring/product-technical-gap-baseline.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/docs/doctoring/product-technical-gap-baseline.md b/docs/doctoring/product-technical-gap-baseline.md index ec80b86..cecc2b7 100644 --- a/docs/doctoring/product-technical-gap-baseline.md +++ b/docs/doctoring/product-technical-gap-baseline.md @@ -88,6 +88,18 @@ placeholder credentials must not be committed to close it. remains `gap-not-claimed`; the local SQLite result must not be promoted into a production database acceptance claim. +## 2026-08-21 exact local CI contract verification + +- The repository CI-scoped command passed the full test suite with 2,786 + application statements and 770 branches at 100% coverage, with no missing + statements or branches. +- The committed validator-path command passed with 181 statements and 114 + branches at 100% coverage. Interrogate, Ruff, compileall, and diff checks + also passed on the same local tree. +- These results are exact local evidence for the current PR head only. Hosted + GitHub Checks, independent approval, latest-pusher compliance, and protected + merge evidence remain separate gates. + ## 2026-08-21 cross-repository cadence dependency - The related contextual-orchestrator hourly caller is open as PR #797 at exact From 0d4d1b98dfc8b722b5502dba942b322a1657902e Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 21 Aug 2026 08:25:11 +0900 Subject: [PATCH 37/70] docs: pin latest baseline head --- docs/doctoring/product-technical-gap-baseline.md | 2 +- docs/product-technical-gap-baseline.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/doctoring/product-technical-gap-baseline.md b/docs/doctoring/product-technical-gap-baseline.md index cecc2b7..09059db 100644 --- a/docs/doctoring/product-technical-gap-baseline.md +++ b/docs/doctoring/product-technical-gap-baseline.md @@ -181,7 +181,7 @@ https://www.rfc-editor.org/rfc/rfc8725.html `3777f54a824d3b2d3458b94f88e5627a7761a2c0` adds a regression test that invokes the validator's committed default realm/profile paths after an exact-head Devin coverage finding. The current documentation successor is - `2b8c59fd29acf9464044734100c520ad591a6a75`, with 14 queued Checks and no + `8a5ba11322bebc09bde8ea57e9fb06d35ad0d614`, with 14 queued Checks and no terminal failure; its prior review state is not approval. PR #104 is ready for review at `0353001438efb060b85373c121f4d54dfd48e8c8`, intentionally based on #112's lockfile head with no net lockfile change; its stacked Checks remain queued. diff --git a/docs/product-technical-gap-baseline.md b/docs/product-technical-gap-baseline.md index 0daa9df..1d7d480 100644 --- a/docs/product-technical-gap-baseline.md +++ b/docs/product-technical-gap-baseline.md @@ -90,7 +90,7 @@ green. | [#104](https://github.com/ContextualWisdomLab/keyverse/pull/104) | ADR and buyer README expansion, stacked on #112 | PENDING: 14 Checks queued, 0 terminal failures on `0353001438efb060b85373c121f4d54dfd48e8c8` | review required | Base is intentionally `fix/account-unification-lock-20260819`; the net diff has no lockfile change. Obtain independent review and terminal stacked-head Checks. | | [#103](https://github.com/ContextualWisdomLab/keyverse/pull/103) | Hierarchical authorization, login helper, PATs | PENDING: 14 Checks queued, 0 terminal failures on `157b76893b32cda66fc586aa67ae72a30ac6b0d6` | changes requested | Independently validate the historical Strix report against the operator-admin trust boundary; retain fail-closed treatment and obtain a fresh exact-head review/check run before any merge claim. | | [#101](https://github.com/ContextualWisdomLab/keyverse/pull/101) | Atomic coupled Python dependency updates | PASS: 22 Checks successful, 0 queued on `50dd9c96cab5c230f775685e8baea939fba390dd` | changes requested | Obtain fresh independent review; this is the policy companion to the lockfile gap. | -| [#100](https://github.com/ContextualWisdomLab/keyverse/pull/100) | `lineageweave-web` account-derived claims plus default validator-path coverage | PENDING: 14 Checks queued, 0 terminal failures on `2b8c59fd29acf9464044734100c520ad591a6a75` | changes requested; fresh review requested | Devin's exact-head coverage finding is addressed by the default-artifact regression test; obtain current-head review without self-approval. | +| [#100](https://github.com/ContextualWisdomLab/keyverse/pull/100) | `lineageweave-web` account-derived claims plus default validator-path coverage | PENDING: 14 Checks queued, 0 terminal failures on `8a5ba11322bebc09bde8ea57e9fb06d35ad0d614` | changes requested; fresh review requested | Devin's exact-head coverage finding is addressed by the default-artifact regression test; obtain current-head review without self-approval. | | [#83](https://github.com/ContextualWisdomLab/keyverse/pull/83) | Remove runtime application RPs from portable realm | PASS: 22 Checks successful, 0 queued on `dd1ab7444a75342b42e3af013ccda6d1dbfb359d` | changes requested | Reconfirm current-head approval and latest-pusher rule before protected merge. | ### Historical check failure root causes observed From 9f6e9b6b4ab9efdbb4e6c1e786c3fc12a702fca1 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 21 Aug 2026 08:32:40 +0900 Subject: [PATCH 38/70] docs: reconcile scheduler and check baseline --- .../product-technical-gap-baseline.md | 44 ++++++++++--------- docs/product-technical-gap-baseline.md | 12 ++--- 2 files changed, 30 insertions(+), 26 deletions(-) diff --git a/docs/doctoring/product-technical-gap-baseline.md b/docs/doctoring/product-technical-gap-baseline.md index 09059db..e6db154 100644 --- a/docs/doctoring/product-technical-gap-baseline.md +++ b/docs/doctoring/product-technical-gap-baseline.md @@ -102,21 +102,24 @@ placeholder credentials must not be committed to close it. ## 2026-08-21 cross-repository cadence dependency -- The related contextual-orchestrator hourly caller is open as PR #797 at exact - head `5dccb65fdd6088deb7c014f819340cceeb89c313`. It invokes the central - review-repair scheduler for one exact-head dispatch at minute 07 of each hour - and names central `.github` PR #1170 as the gateway prerequisite. Its current - exact-head rollup has 15 queued Checks, 0 terminal failures, and 0 successes. +- Contextual-orchestrator PR #797 is closed without merge and superseded. Its + minute-07 caller duplicated the canonical central caller now proposed in + `.github` PR #1178; it must not be reopened or merged while #1178 owns this + dispatch boundary. Central PR #1183 is also closed without merge. - Central `.github` PR #1170 is open at exact head `4684f6e212ba40d12e5217f0f52ee1e90c796ed8` after the gateway fallback/privacy/ reasoning fixes and the final docstring repair. Its current hosted rollup has - 16 queued Checks, 2 successes, and no terminal failure. The superseded - central PR #1183 is closed without merge and is not a prerequisite. Neither - #1170 nor #797 has qualifying formal approval or protected merge evidence. + 16 queued Checks, 2 successes, and no terminal failure. +- Central `.github` PR #1178 is the canonical contextual-orchestrator hourly + caller, open at exact head + `97b084ac28b5ccf6de7f68fd2e019d8da6f80143`. Its current rollup has 15 queued, + 1 in-progress, and 8 successful Checks; the one cancelled scheduler run is + historical and a newer exact-head scheduler run is queued. Neither #1170 nor + #1178 has qualifying formal approval or protected merge evidence. - Keyverse's existing `Hourly product development` workflow remains active at `41 * * * *`; its latest observed scheduled runs succeeded. No duplicate - scheduler was added. Activation of the related caller remains conditional on - independent approval and terminal exact-head evidence for both PRs. + scheduler was added. Activation of the central caller remains conditional on + independent approval and terminal exact-head evidence for #1170 and #1178. ## APA 7th references @@ -142,20 +145,21 @@ https://www.rfc-editor.org/rfc/rfc8725.html and doctoring records. - Exact-head GitHub PR, review, issue, check-run, ruleset, and scheduled-run queries performed on 2026-08-21. Fourteen Keyverse PRs are open: #112, #101, - and #83 each have 22 successful Checks with no queued run; nine others have - queued Checks without a terminal failure, #111 has 18 successful Checks and - two queued after its lock-refresh stack, and #113 has one current terminal - failure. + and #83 each have 22 successful Checks with no queued run; the other eleven + have queued Checks without a terminal failure. #111 and #113 each have 18 + successful Checks and two queued Checks after their lock-refresh/external + security reruns. No current open PR has a qualifying formal approval. Queued Checks remain unverified. PR #113's current SCIM lock head `50f19ec6338fb8eb959b8c797bdfa938e1071c87` includes the normal prerequisite lockfile history and a realistic SCIM PatchOp race plus spawned-process - SQLite lock regression; its hosted Checks have one terminal `strix` failure, - one queued run, and 18 successful runs. The failed Strix job could not pull - `ghcr.io/usestrix/strix-sandbox:1.3.0` because GHCR returned HTTP 500/EOF, - and it produced no structured vulnerability report, so the workflow failed - closed. Its local RED-to-GREEN, root-level SCIM error-wire, and cross-process + SQLite lock regression; its hosted Checks now have 18 successful runs and + two queued reruns with no terminal failure. The earlier Strix job could not + pull `ghcr.io/usestrix/strix-sandbox:1.3.0` because GHCR returned HTTP + 500/EOF, and it produced no structured vulnerability report, so that run + failed closed; the fresh exact-head rerun remains unverified while queued. + Its local RED-to-GREEN, root-level SCIM error-wire, and cross-process sidecar evidence are not protected-main evidence. PR #112's lockfile head `f02acf93367a40dbfb23a73985017dca8d42ff39` has 22 terminal-success Checks but still requires independent review. PR #111's current head @@ -181,7 +185,7 @@ https://www.rfc-editor.org/rfc/rfc8725.html `3777f54a824d3b2d3458b94f88e5627a7761a2c0` adds a regression test that invokes the validator's committed default realm/profile paths after an exact-head Devin coverage finding. The current documentation successor is - `8a5ba11322bebc09bde8ea57e9fb06d35ad0d614`, with 14 queued Checks and no + `0d4d1b98dfc8b722b5502dba942b322a1657902e`, with 14 queued Checks and no terminal failure; its prior review state is not approval. PR #104 is ready for review at `0353001438efb060b85373c121f4d54dfd48e8c8`, intentionally based on #112's lockfile head with no net lockfile change; its stacked Checks remain queued. diff --git a/docs/product-technical-gap-baseline.md b/docs/product-technical-gap-baseline.md index 1d7d480..29e2561 100644 --- a/docs/product-technical-gap-baseline.md +++ b/docs/product-technical-gap-baseline.md @@ -71,14 +71,14 @@ intentional stacked-base rebase of PR #104. The live PR record is authoritative for the exact hash and Checks; predecessor evidence remains non-transferable. At this snapshot, 14 PRs are open: three have 22 successful Checks with none -queued, nine have queued Checks without a terminal failure, #111 has 18 -successful Checks with two queued after its lock-refresh stack, and #113 has -one current terminal failure. Queued Checks remain unverified rather than -green. +queued, and the other eleven have queued Checks without a terminal failure. +#111 and #113 each have 18 successful Checks and two queued Checks after their +lock-refresh/external-security reruns. Queued Checks remain unverified rather +than green. | PR | Scope | Exact-head Checks | Review state | Next safe action | |---:|---|---|---|---| -| [#113](https://github.com/ContextualWisdomLab/keyverse/pull/113) | SCIM `PATCH active=false` shared operation lock, stacked on #112 lockfile refresh | FAIL: 1 terminal `strix` failure, 1 queued, 18 successful on `50f19ec6338fb8eb959b8c797bdfa938e1071c87` | review required | The failure was a transient GHCR Strix image pull EOF with no report; preserve fail-closed treatment and obtain a fresh exact-head run when the external image service is available. | +| [#113](https://github.com/ContextualWisdomLab/keyverse/pull/113) | SCIM `PATCH active=false` shared operation lock, stacked on #112 lockfile refresh | PENDING: 2 queued, 18 successful, 0 terminal failures on `50f19ec6338fb8eb959b8c797bdfa938e1071c87` | review required | The earlier GHCR Strix image-pull failure was rerun; wait for the fresh exact-head security result and independent review. | | [#112](https://github.com/ContextualWisdomLab/keyverse/pull/112) | Resync account-unification lockfile | PASS: 22 Checks successful, 0 queued on `f02acf93367a40dbfb23a73985017dca8d42ff39` | review required | Obtain independent review, then let protected automation re-check and merge. | | [#111](https://github.com/ContextualWisdomLab/keyverse/pull/111) | CodeQL init 4.37.7 | PENDING: 2 queued, 18 successful, 0 terminal failures on `e1d0fee6ce29cb9ec75d9fbdb38cd15242bf4fdc` | review required | Now stacked on #112; the stale-lock failure is cleared on the new base, so wait for the remaining exact-head Checks and independent review. | | [#110](https://github.com/ContextualWisdomLab/keyverse/pull/110) | CodeQL analyze 4.37.7 | PENDING: 5 Checks queued, 15 successful, 0 terminal failures on `07acd65145c9522a74858d1ff8761ea05a09e8f0` | review required | Treat as the companion of #111; do not merge the action pair independently. | @@ -90,7 +90,7 @@ green. | [#104](https://github.com/ContextualWisdomLab/keyverse/pull/104) | ADR and buyer README expansion, stacked on #112 | PENDING: 14 Checks queued, 0 terminal failures on `0353001438efb060b85373c121f4d54dfd48e8c8` | review required | Base is intentionally `fix/account-unification-lock-20260819`; the net diff has no lockfile change. Obtain independent review and terminal stacked-head Checks. | | [#103](https://github.com/ContextualWisdomLab/keyverse/pull/103) | Hierarchical authorization, login helper, PATs | PENDING: 14 Checks queued, 0 terminal failures on `157b76893b32cda66fc586aa67ae72a30ac6b0d6` | changes requested | Independently validate the historical Strix report against the operator-admin trust boundary; retain fail-closed treatment and obtain a fresh exact-head review/check run before any merge claim. | | [#101](https://github.com/ContextualWisdomLab/keyverse/pull/101) | Atomic coupled Python dependency updates | PASS: 22 Checks successful, 0 queued on `50dd9c96cab5c230f775685e8baea939fba390dd` | changes requested | Obtain fresh independent review; this is the policy companion to the lockfile gap. | -| [#100](https://github.com/ContextualWisdomLab/keyverse/pull/100) | `lineageweave-web` account-derived claims plus default validator-path coverage | PENDING: 14 Checks queued, 0 terminal failures on `8a5ba11322bebc09bde8ea57e9fb06d35ad0d614` | changes requested; fresh review requested | Devin's exact-head coverage finding is addressed by the default-artifact regression test; obtain current-head review without self-approval. | +| [#100](https://github.com/ContextualWisdomLab/keyverse/pull/100) | `lineageweave-web` account-derived claims plus default validator-path coverage | PENDING: 14 Checks queued, 0 terminal failures on `0d4d1b98dfc8b722b5502dba942b322a1657902e` | changes requested; fresh review requested | Devin's exact-head coverage finding is addressed by the default-artifact regression test; obtain current-head review without self-approval. | | [#83](https://github.com/ContextualWisdomLab/keyverse/pull/83) | Remove runtime application RPs from portable realm | PASS: 22 Checks successful, 0 queued on `dd1ab7444a75342b42e3af013ccda6d1dbfb359d` | changes requested | Reconfirm current-head approval and latest-pusher rule before protected merge. | ### Historical check failure root causes observed From 972ed50371bccee69a8ba0c5d0f8f0360317909a Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 21 Aug 2026 08:36:58 +0900 Subject: [PATCH 39/70] docs: record local PostgreSQL evidence --- docs/doctoring/product-technical-gap-baseline.md | 13 +++++++++++++ docs/product-technical-gap-baseline.md | 9 +++++++++ 2 files changed, 22 insertions(+) diff --git a/docs/doctoring/product-technical-gap-baseline.md b/docs/doctoring/product-technical-gap-baseline.md index e6db154..45662e1 100644 --- a/docs/doctoring/product-technical-gap-baseline.md +++ b/docs/doctoring/product-technical-gap-baseline.md @@ -88,6 +88,19 @@ placeholder credentials must not be committed to close it. remains `gap-not-claimed`; the local SQLite result must not be promoted into a production database acceptance claim. +## 2026-08-21 physical PostgreSQL probe + +- The running Compose `idp_database` container uses the pinned PostgreSQL 17 + image. A read-only catalog probe found 88 non-system tables, 3,981,312 + relation bytes, zero partitioned tables, and `pg_is_in_recovery=false`. + Observed settings were `max_connections=100`, `shared_buffers=163848kB`, + `work_mem=4096kB`, `wal_level=replica`, and `archive_mode=off`. +- This is local Keycloak system-of-record smoke evidence only. The + account-unification service uses its SQLite sidecar for local state, and + neither runtime path proves tenant-concentration behavior, application-owned + partitioning, backup/restore, failover, or production sizing. G5 therefore + remains `gap-not-claimed`. + ## 2026-08-21 exact local CI contract verification - The repository CI-scoped command passed the full test suite with 2,786 diff --git a/docs/product-technical-gap-baseline.md b/docs/product-technical-gap-baseline.md index 29e2561..8650b76 100644 --- a/docs/product-technical-gap-baseline.md +++ b/docs/product-technical-gap-baseline.md @@ -226,6 +226,15 @@ regression run (`tests/test_storage_concurrency.py` and sidecar's local locking and lifecycle behavior; it is not PostgreSQL migration, partition-skew, backup, restore, or production recovery evidence. +**Current local PostgreSQL probe (2026-08-21):** the running Compose +`idp_database` uses the pinned PostgreSQL 17 image and reports 88 non-system +tables, 3,981,312 relation bytes, zero partitioned tables, and +`pg_is_in_recovery=false`. Observed settings were `max_connections=100`, +`shared_buffers=163848kB`, `work_mem=4096kB`, `wal_level=replica`, and +`archive_mode=off`. This is a local Keycloak system-of-record smoke probe; it +does not prove tenant skew tolerance, application-owned partitioning, backup/ +restore, failover, or production sizing. + **Acceptance:** run PostgreSQL migration/rollback tests with tenant-scoped composite constraints, measure skew under concentrated tenants, document the chosen partition/index strategy, and prove backup/restore. Do not add a From 8e74c4ef6f011756dc85d77b5d3d374f94cc52c9 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 21 Aug 2026 08:40:55 +0900 Subject: [PATCH 40/70] docs: record stacked CodeQL checks --- docs/doctoring/product-technical-gap-baseline.md | 11 +++++++---- docs/product-technical-gap-baseline.md | 8 ++++---- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/docs/doctoring/product-technical-gap-baseline.md b/docs/doctoring/product-technical-gap-baseline.md index 45662e1..b7fa305 100644 --- a/docs/doctoring/product-technical-gap-baseline.md +++ b/docs/doctoring/product-technical-gap-baseline.md @@ -159,9 +159,9 @@ https://www.rfc-editor.org/rfc/rfc8725.html - Exact-head GitHub PR, review, issue, check-run, ruleset, and scheduled-run queries performed on 2026-08-21. Fourteen Keyverse PRs are open: #112, #101, and #83 each have 22 successful Checks with no queued run; the other eleven - have queued Checks without a terminal failure. #111 and #113 each have 18 - successful Checks and two queued Checks after their lock-refresh/external - security reruns. + have queued or in-progress Checks without a terminal failure. #110, #111, + and #113 each have 18 successful Checks and two queued Checks after their + lock-refresh/external-security reruns. No current open PR has a qualifying formal approval. Queued Checks remain unverified. PR #113's current SCIM lock head @@ -180,7 +180,10 @@ https://www.rfc-editor.org/rfc/rfc8725.html prior `account-unification-tests` failure occurred against the old `main` base because `uv sync --locked` found a stale `uv.lock` before tests began; the rerun against the lock-refresh base now has no terminal failure and two - queued Checks. It remains coupled to #112 and #110. + queued Checks. It remains coupled to #112 and #110. PR #110's current head + `07acd65145c9522a74858d1ff8761ea05a09e8f0` was likewise retargeted to #112 + after the same pre-test lock failure; its rerun now has 18 successful Checks + and two queued Checks with no terminal failure. The historical PR #105 exact head `72de5499d6e97ae7f7bd804ab78b3e1644dd5a4f` had a failed `account-unification-tests` Check: `uv 0.12.5` reproduced diff --git a/docs/product-technical-gap-baseline.md b/docs/product-technical-gap-baseline.md index 8650b76..c37b511 100644 --- a/docs/product-technical-gap-baseline.md +++ b/docs/product-technical-gap-baseline.md @@ -72,16 +72,16 @@ for the exact hash and Checks; predecessor evidence remains non-transferable. At this snapshot, 14 PRs are open: three have 22 successful Checks with none queued, and the other eleven have queued Checks without a terminal failure. -#111 and #113 each have 18 successful Checks and two queued Checks after their -lock-refresh/external-security reruns. Queued Checks remain unverified rather -than green. +#110, #111, and #113 each have 18 successful Checks and two queued Checks after +their lock-refresh/external-security reruns. Queued Checks remain unverified +rather than green. | PR | Scope | Exact-head Checks | Review state | Next safe action | |---:|---|---|---|---| | [#113](https://github.com/ContextualWisdomLab/keyverse/pull/113) | SCIM `PATCH active=false` shared operation lock, stacked on #112 lockfile refresh | PENDING: 2 queued, 18 successful, 0 terminal failures on `50f19ec6338fb8eb959b8c797bdfa938e1071c87` | review required | The earlier GHCR Strix image-pull failure was rerun; wait for the fresh exact-head security result and independent review. | | [#112](https://github.com/ContextualWisdomLab/keyverse/pull/112) | Resync account-unification lockfile | PASS: 22 Checks successful, 0 queued on `f02acf93367a40dbfb23a73985017dca8d42ff39` | review required | Obtain independent review, then let protected automation re-check and merge. | | [#111](https://github.com/ContextualWisdomLab/keyverse/pull/111) | CodeQL init 4.37.7 | PENDING: 2 queued, 18 successful, 0 terminal failures on `e1d0fee6ce29cb9ec75d9fbdb38cd15242bf4fdc` | review required | Now stacked on #112; the stale-lock failure is cleared on the new base, so wait for the remaining exact-head Checks and independent review. | -| [#110](https://github.com/ContextualWisdomLab/keyverse/pull/110) | CodeQL analyze 4.37.7 | PENDING: 5 Checks queued, 15 successful, 0 terminal failures on `07acd65145c9522a74858d1ff8761ea05a09e8f0` | review required | Treat as the companion of #111; do not merge the action pair independently. | +| [#110](https://github.com/ContextualWisdomLab/keyverse/pull/110) | CodeQL analyze 4.37.7, stacked on #112 lockfile refresh | PENDING: 2 queued, 18 successful, 0 terminal failures on `07acd65145c9522a74858d1ff8761ea05a09e8f0` | review required | Treat as the companion of #111 on the refreshed #112 base; wait for the remaining exact-head Checks and do not merge the action pair independently. | | [#109](https://github.com/ContextualWisdomLab/keyverse/pull/109) | `typing-inspection` update | PENDING: 14 Checks queued, 0 terminal failures on `28a4e05b23baa75d44b37589ba662a3c46c67129` | review required | Re-check after #112; do not treat queued Checks as a failure. | | [#108](https://github.com/ContextualWisdomLab/keyverse/pull/108) | Ruff update | PENDING: 7 Checks queued, 12 successful, 0 terminal failures on `d9791bba5a2e277c2ae503504b871e8df0937439` | review required | Re-check after #112; do not rerun unchanged checks. | | [#107](https://github.com/ContextualWisdomLab/keyverse/pull/107) | Uvicorn update | PENDING: 14 Checks queued, 0 terminal failures on `0240ef8df7269da8eddcfe17abd2383812768001` | review required | Re-check after #112; do not rerun unchanged checks. | From b35def43a9d8cb4973bea765533ec42634982d6d Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 21 Aug 2026 08:42:54 +0900 Subject: [PATCH 41/70] docs: record dependency stack state --- docs/doctoring/product-technical-gap-baseline.md | 9 ++++++--- docs/product-technical-gap-baseline.md | 10 +++++----- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/docs/doctoring/product-technical-gap-baseline.md b/docs/doctoring/product-technical-gap-baseline.md index b7fa305..9b45ea3 100644 --- a/docs/doctoring/product-technical-gap-baseline.md +++ b/docs/doctoring/product-technical-gap-baseline.md @@ -189,9 +189,12 @@ https://www.rfc-editor.org/rfc/rfc8725.html `account-unification-tests` Check: `uv 0.12.5` reproduced `uv sync --locked` refusing the stale `coverage==7.15.2` and `setuptools==83.0.0` lock entries while the current `pyproject.toml` required - `7.15.4` and `84.0.0`; the current #105 head has nine queued and nine - successful Checks with no terminal failure, and #112 remains the - lock-refresh prerequisite. + `7.15.4` and `84.0.0`; the current #105 head + `ef03c5a93c891980588b125f6c774fa84bf0feef` is now stacked on #112 and has + 19 successful Checks plus one queued Check with no terminal failure. The + current #106, #107, #108, and #109 heads are likewise stacked on #112, each + with 19 successful Checks plus one queued Check; their queued Checks remain + unverified and #112 remains the lock-refresh prerequisite. PR #103's historical terminal Strix run 32092025335 / job 95576032571 emitted a MEDIUM IDOR report with contradictory model text. Current head `157b76893b32cda66fc586aa67ae72a30ac6b0d6` adds direct-mount operator-auth diff --git a/docs/product-technical-gap-baseline.md b/docs/product-technical-gap-baseline.md index c37b511..48ff7b6 100644 --- a/docs/product-technical-gap-baseline.md +++ b/docs/product-technical-gap-baseline.md @@ -82,11 +82,11 @@ rather than green. | [#112](https://github.com/ContextualWisdomLab/keyverse/pull/112) | Resync account-unification lockfile | PASS: 22 Checks successful, 0 queued on `f02acf93367a40dbfb23a73985017dca8d42ff39` | review required | Obtain independent review, then let protected automation re-check and merge. | | [#111](https://github.com/ContextualWisdomLab/keyverse/pull/111) | CodeQL init 4.37.7 | PENDING: 2 queued, 18 successful, 0 terminal failures on `e1d0fee6ce29cb9ec75d9fbdb38cd15242bf4fdc` | review required | Now stacked on #112; the stale-lock failure is cleared on the new base, so wait for the remaining exact-head Checks and independent review. | | [#110](https://github.com/ContextualWisdomLab/keyverse/pull/110) | CodeQL analyze 4.37.7, stacked on #112 lockfile refresh | PENDING: 2 queued, 18 successful, 0 terminal failures on `07acd65145c9522a74858d1ff8761ea05a09e8f0` | review required | Treat as the companion of #111 on the refreshed #112 base; wait for the remaining exact-head Checks and do not merge the action pair independently. | -| [#109](https://github.com/ContextualWisdomLab/keyverse/pull/109) | `typing-inspection` update | PENDING: 14 Checks queued, 0 terminal failures on `28a4e05b23baa75d44b37589ba662a3c46c67129` | review required | Re-check after #112; do not treat queued Checks as a failure. | -| [#108](https://github.com/ContextualWisdomLab/keyverse/pull/108) | Ruff update | PENDING: 7 Checks queued, 12 successful, 0 terminal failures on `d9791bba5a2e277c2ae503504b871e8df0937439` | review required | Re-check after #112; do not rerun unchanged checks. | -| [#107](https://github.com/ContextualWisdomLab/keyverse/pull/107) | Uvicorn update | PENDING: 14 Checks queued, 0 terminal failures on `0240ef8df7269da8eddcfe17abd2383812768001` | review required | Re-check after #112; do not rerun unchanged checks. | -| [#106](https://github.com/ContextualWisdomLab/keyverse/pull/106) | `setup-uv` update | PENDING: 6 Checks queued, 14 successful, 0 terminal failures on `2f0e3fb19a63db7f51cdadfeae6155cd469a0c91` | review required | Re-check after #112; do not rerun unchanged checks. | -| [#105](https://github.com/ContextualWisdomLab/keyverse/pull/105) | `harden-runner` update | PENDING: 9 Checks queued, 9 successful, 0 terminal failures on `ef03c5a93c891980588b125f6c774fa84bf0feef` | changes requested | Keep the historical lockfile failure distinct from this current mixed head; obtain a new exact-head review after the dependency gate settles. | +| [#109](https://github.com/ContextualWisdomLab/keyverse/pull/109) | `typing-inspection` update, stacked on #112 lockfile refresh | PENDING: 1 queued, 19 successful, 0 terminal failures on `28a4e05b23baa75d44b37589ba662a3c46c67129` | review required | Obtain independent review on the refreshed #112 base; do not treat the queued Check as green. | +| [#108](https://github.com/ContextualWisdomLab/keyverse/pull/108) | Ruff update, stacked on #112 lockfile refresh | PENDING: 1 queued, 19 successful, 0 terminal failures on `d9791bba5a2e277c2ae503504b871e8df0937439` | review required | Obtain independent review on the refreshed #112 base; do not treat the queued Check as green. | +| [#107](https://github.com/ContextualWisdomLab/keyverse/pull/107) | Uvicorn update, stacked on #112 lockfile refresh | PENDING: 1 queued, 19 successful, 0 terminal failures on `0240ef8df7269da8eddcfe17abd2383812768001` | review required | Obtain independent review on the refreshed #112 base; do not treat the queued Check as green. | +| [#106](https://github.com/ContextualWisdomLab/keyverse/pull/106) | `setup-uv` update, stacked on #112 lockfile refresh | PENDING: 1 queued, 19 successful, 0 terminal failures on `2f0e3fb19a63db7f51cdadfeae6155cd469a0c91` | review required | Obtain independent review on the refreshed #112 base; do not treat the queued Check as green. | +| [#105](https://github.com/ContextualWisdomLab/keyverse/pull/105) | `harden-runner` update, stacked on #112 lockfile refresh | PENDING: 1 queued, 19 successful, 0 terminal failures on `ef03c5a93c891980588b125f6c774fa84bf0feef` | changes requested | Re-evaluate the prior requested changes against this refreshed #112 base and obtain current-head independent review. | | [#104](https://github.com/ContextualWisdomLab/keyverse/pull/104) | ADR and buyer README expansion, stacked on #112 | PENDING: 14 Checks queued, 0 terminal failures on `0353001438efb060b85373c121f4d54dfd48e8c8` | review required | Base is intentionally `fix/account-unification-lock-20260819`; the net diff has no lockfile change. Obtain independent review and terminal stacked-head Checks. | | [#103](https://github.com/ContextualWisdomLab/keyverse/pull/103) | Hierarchical authorization, login helper, PATs | PENDING: 14 Checks queued, 0 terminal failures on `157b76893b32cda66fc586aa67ae72a30ac6b0d6` | changes requested | Independently validate the historical Strix report against the operator-admin trust boundary; retain fail-closed treatment and obtain a fresh exact-head review/check run before any merge claim. | | [#101](https://github.com/ContextualWisdomLab/keyverse/pull/101) | Atomic coupled Python dependency updates | PASS: 22 Checks successful, 0 queued on `50dd9c96cab5c230f775685e8baea939fba390dd` | changes requested | Obtain fresh independent review; this is the policy companion to the lockfile gap. | From b0748bcb4ecb409e0cd77896a48e1c8b6708e690 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 21 Aug 2026 08:46:32 +0900 Subject: [PATCH 42/70] docs: refresh current authorization and cadence checks --- docs/doctoring/product-technical-gap-baseline.md | 15 +++++++++------ docs/product-technical-gap-baseline.md | 2 +- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/docs/doctoring/product-technical-gap-baseline.md b/docs/doctoring/product-technical-gap-baseline.md index 9b45ea3..f063d90 100644 --- a/docs/doctoring/product-technical-gap-baseline.md +++ b/docs/doctoring/product-technical-gap-baseline.md @@ -125,10 +125,11 @@ placeholder credentials must not be committed to close it. 16 queued Checks, 2 successes, and no terminal failure. - Central `.github` PR #1178 is the canonical contextual-orchestrator hourly caller, open at exact head - `97b084ac28b5ccf6de7f68fd2e019d8da6f80143`. Its current rollup has 15 queued, - 1 in-progress, and 8 successful Checks; the one cancelled scheduler run is - historical and a newer exact-head scheduler run is queued. Neither #1170 nor - #1178 has qualifying formal approval or protected merge evidence. + `97b084ac28b5ccf6de7f68fd2e019d8da6f80143`. Its current rollup has 18 + successful, 7 queued, 3 neutral, and 1 cancelled Check with no terminal + failure; the cancelled scheduler run remains historical and the queued + checks are unverified. Neither #1170 nor #1178 has qualifying formal approval + or protected merge evidence. - Keyverse's existing `Hourly product development` workflow remains active at `41 * * * *`; its latest observed scheduled runs succeeded. No duplicate scheduler was added. Activation of the central caller remains conditional on @@ -198,8 +199,10 @@ https://www.rfc-editor.org/rfc/rfc8725.html PR #103's historical terminal Strix run 32092025335 / job 95576032571 emitted a MEDIUM IDOR report with contradictory model text. Current head `157b76893b32cda66fc586aa67ae72a30ac6b0d6` adds direct-mount operator-auth - regression evidence, but the operator-admin trust boundary still requires - independent validation. PR #100's pre-doctoring-refresh head was + regression evidence and currently has 18 successful Checks, one in-progress + Strix Check, and one queued coverage Check with no terminal failure. The + operator-admin trust boundary still requires independent validation. PR + #100's pre-doctoring-refresh head was `c483bd53ea74aad5fcea7d3cec2f402e4d8f27c2`; successor head `3777f54a824d3b2d3458b94f88e5627a7761a2c0` adds a regression test that invokes the validator's committed default realm/profile paths after an exact-head diff --git a/docs/product-technical-gap-baseline.md b/docs/product-technical-gap-baseline.md index 48ff7b6..4ca1e6d 100644 --- a/docs/product-technical-gap-baseline.md +++ b/docs/product-technical-gap-baseline.md @@ -88,7 +88,7 @@ rather than green. | [#106](https://github.com/ContextualWisdomLab/keyverse/pull/106) | `setup-uv` update, stacked on #112 lockfile refresh | PENDING: 1 queued, 19 successful, 0 terminal failures on `2f0e3fb19a63db7f51cdadfeae6155cd469a0c91` | review required | Obtain independent review on the refreshed #112 base; do not treat the queued Check as green. | | [#105](https://github.com/ContextualWisdomLab/keyverse/pull/105) | `harden-runner` update, stacked on #112 lockfile refresh | PENDING: 1 queued, 19 successful, 0 terminal failures on `ef03c5a93c891980588b125f6c774fa84bf0feef` | changes requested | Re-evaluate the prior requested changes against this refreshed #112 base and obtain current-head independent review. | | [#104](https://github.com/ContextualWisdomLab/keyverse/pull/104) | ADR and buyer README expansion, stacked on #112 | PENDING: 14 Checks queued, 0 terminal failures on `0353001438efb060b85373c121f4d54dfd48e8c8` | review required | Base is intentionally `fix/account-unification-lock-20260819`; the net diff has no lockfile change. Obtain independent review and terminal stacked-head Checks. | -| [#103](https://github.com/ContextualWisdomLab/keyverse/pull/103) | Hierarchical authorization, login helper, PATs | PENDING: 14 Checks queued, 0 terminal failures on `157b76893b32cda66fc586aa67ae72a30ac6b0d6` | changes requested | Independently validate the historical Strix report against the operator-admin trust boundary; retain fail-closed treatment and obtain a fresh exact-head review/check run before any merge claim. | +| [#103](https://github.com/ContextualWisdomLab/keyverse/pull/103) | Hierarchical authorization, login helper, PATs | PENDING: 1 in-progress, 1 queued, 18 successful, 0 terminal failures on `157b76893b32cda66fc586aa67ae72a30ac6b0d6` | changes requested | Independently validate the historical Strix report against the operator-admin trust boundary; retain fail-closed treatment and obtain a fresh exact-head review/check run before any merge claim. | | [#101](https://github.com/ContextualWisdomLab/keyverse/pull/101) | Atomic coupled Python dependency updates | PASS: 22 Checks successful, 0 queued on `50dd9c96cab5c230f775685e8baea939fba390dd` | changes requested | Obtain fresh independent review; this is the policy companion to the lockfile gap. | | [#100](https://github.com/ContextualWisdomLab/keyverse/pull/100) | `lineageweave-web` account-derived claims plus default validator-path coverage | PENDING: 14 Checks queued, 0 terminal failures on `0d4d1b98dfc8b722b5502dba942b322a1657902e` | changes requested; fresh review requested | Devin's exact-head coverage finding is addressed by the default-artifact regression test; obtain current-head review without self-approval. | | [#83](https://github.com/ContextualWisdomLab/keyverse/pull/83) | Remove runtime application RPs from portable realm | PASS: 22 Checks successful, 0 queued on `dd1ab7444a75342b42e3af013ccda6d1dbfb359d` | changes requested | Reconfirm current-head approval and latest-pusher rule before protected merge. | From 1937a6f8bc1e28dd42181cbf691de0c061cf21ba Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 21 Aug 2026 08:50:46 +0900 Subject: [PATCH 43/70] docs: record rebased dependency heads --- docs/doctoring/product-technical-gap-baseline.md | 11 ++++++++--- docs/product-technical-gap-baseline.md | 4 ++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/docs/doctoring/product-technical-gap-baseline.md b/docs/doctoring/product-technical-gap-baseline.md index f063d90..0164fa7 100644 --- a/docs/doctoring/product-technical-gap-baseline.md +++ b/docs/doctoring/product-technical-gap-baseline.md @@ -193,9 +193,14 @@ https://www.rfc-editor.org/rfc/rfc8725.html `7.15.4` and `84.0.0`; the current #105 head `ef03c5a93c891980588b125f6c774fa84bf0feef` is now stacked on #112 and has 19 successful Checks plus one queued Check with no terminal failure. The - current #106, #107, #108, and #109 heads are likewise stacked on #112, each - with 19 successful Checks plus one queued Check; their queued Checks remain - unverified and #112 remains the lock-refresh prerequisite. + current #106 and #109 heads remain stacked on #112 with that same rollup. + PR #107 was rebased cleanly onto #112 at + `53842560d397aa20309a6b16aceb560540611686`, and PR #108 was rebased cleanly + onto #112 at `538cead991a7c1bed32f2dcb5413b5fc56f53e93`; each now has 14 + queued Checks and no terminal failure. Local `uv sync --locked --extra dev` + plus the full service pytest suite passed on both rebased trees. Their fresh + hosted Checks remain unverified and #112 remains the lock-refresh + prerequisite. PR #103's historical terminal Strix run 32092025335 / job 95576032571 emitted a MEDIUM IDOR report with contradictory model text. Current head `157b76893b32cda66fc586aa67ae72a30ac6b0d6` adds direct-mount operator-auth diff --git a/docs/product-technical-gap-baseline.md b/docs/product-technical-gap-baseline.md index 4ca1e6d..b5ce0e2 100644 --- a/docs/product-technical-gap-baseline.md +++ b/docs/product-technical-gap-baseline.md @@ -83,8 +83,8 @@ rather than green. | [#111](https://github.com/ContextualWisdomLab/keyverse/pull/111) | CodeQL init 4.37.7 | PENDING: 2 queued, 18 successful, 0 terminal failures on `e1d0fee6ce29cb9ec75d9fbdb38cd15242bf4fdc` | review required | Now stacked on #112; the stale-lock failure is cleared on the new base, so wait for the remaining exact-head Checks and independent review. | | [#110](https://github.com/ContextualWisdomLab/keyverse/pull/110) | CodeQL analyze 4.37.7, stacked on #112 lockfile refresh | PENDING: 2 queued, 18 successful, 0 terminal failures on `07acd65145c9522a74858d1ff8761ea05a09e8f0` | review required | Treat as the companion of #111 on the refreshed #112 base; wait for the remaining exact-head Checks and do not merge the action pair independently. | | [#109](https://github.com/ContextualWisdomLab/keyverse/pull/109) | `typing-inspection` update, stacked on #112 lockfile refresh | PENDING: 1 queued, 19 successful, 0 terminal failures on `28a4e05b23baa75d44b37589ba662a3c46c67129` | review required | Obtain independent review on the refreshed #112 base; do not treat the queued Check as green. | -| [#108](https://github.com/ContextualWisdomLab/keyverse/pull/108) | Ruff update, stacked on #112 lockfile refresh | PENDING: 1 queued, 19 successful, 0 terminal failures on `d9791bba5a2e277c2ae503504b871e8df0937439` | review required | Obtain independent review on the refreshed #112 base; do not treat the queued Check as green. | -| [#107](https://github.com/ContextualWisdomLab/keyverse/pull/107) | Uvicorn update, stacked on #112 lockfile refresh | PENDING: 1 queued, 19 successful, 0 terminal failures on `0240ef8df7269da8eddcfe17abd2383812768001` | review required | Obtain independent review on the refreshed #112 base; do not treat the queued Check as green. | +| [#108](https://github.com/ContextualWisdomLab/keyverse/pull/108) | Ruff update, stacked on #112 lockfile refresh | PENDING: 14 queued, 0 terminal failures on `538cead991a7c1bed32f2dcb5413b5fc56f53e93` | review required | The conflicting lockfile base was rebased cleanly onto #112; wait for the fresh exact-head Checks and independent review. | +| [#107](https://github.com/ContextualWisdomLab/keyverse/pull/107) | Uvicorn update, stacked on #112 lockfile refresh | PENDING: 14 queued, 0 terminal failures on `53842560d397aa20309a6b16aceb560540611686` | review required | The conflicting lockfile base was rebased cleanly onto #112; wait for the fresh exact-head Checks and independent review. | | [#106](https://github.com/ContextualWisdomLab/keyverse/pull/106) | `setup-uv` update, stacked on #112 lockfile refresh | PENDING: 1 queued, 19 successful, 0 terminal failures on `2f0e3fb19a63db7f51cdadfeae6155cd469a0c91` | review required | Obtain independent review on the refreshed #112 base; do not treat the queued Check as green. | | [#105](https://github.com/ContextualWisdomLab/keyverse/pull/105) | `harden-runner` update, stacked on #112 lockfile refresh | PENDING: 1 queued, 19 successful, 0 terminal failures on `ef03c5a93c891980588b125f6c774fa84bf0feef` | changes requested | Re-evaluate the prior requested changes against this refreshed #112 base and obtain current-head independent review. | | [#104](https://github.com/ContextualWisdomLab/keyverse/pull/104) | ADR and buyer README expansion, stacked on #112 | PENDING: 14 Checks queued, 0 terminal failures on `0353001438efb060b85373c121f4d54dfd48e8c8` | review required | Base is intentionally `fix/account-unification-lock-20260819`; the net diff has no lockfile change. Obtain independent review and terminal stacked-head Checks. | From 35a0bbd95d5bcb712ca39cbac8bd3cde80a49119 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 21 Aug 2026 09:00:26 +0900 Subject: [PATCH 44/70] docs: record encoded start-login remediation --- docs/doctoring/product-technical-gap-baseline.md | 13 ++++++++----- docs/product-technical-gap-baseline.md | 13 ++++++++++--- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/docs/doctoring/product-technical-gap-baseline.md b/docs/doctoring/product-technical-gap-baseline.md index 0164fa7..6093380 100644 --- a/docs/doctoring/product-technical-gap-baseline.md +++ b/docs/doctoring/product-technical-gap-baseline.md @@ -202,11 +202,14 @@ https://www.rfc-editor.org/rfc/rfc8725.html hosted Checks remain unverified and #112 remains the lock-refresh prerequisite. PR #103's historical terminal Strix run 32092025335 / job 95576032571 - emitted a MEDIUM IDOR report with contradictory model text. Current head - `157b76893b32cda66fc586aa67ae72a30ac6b0d6` adds direct-mount operator-auth - regression evidence and currently has 18 successful Checks, one in-progress - Strix Check, and one queued coverage Check with no terminal failure. The - operator-admin trust boundary still requires independent validation. PR + emitted a MEDIUM IDOR report with contradictory model text. Its next exact + head `d540515be66a6ca0aa538c61f977a57bf7a69fb8` adds a RED-to-GREEN + regression for percent-encoded discovery markers and normalizes + `public_issuer_url` before the no-fetch policy check. Local focused/full + tests, Ruff, Interrogate, and 100% statement/branch coverage pass; its 16 + hosted Checks remain pending, so hosted security and review success are not + claimed. The operator-admin trust boundary and the new URL-normalization + fix still require independent exact-head validation. PR #100's pre-doctoring-refresh head was `c483bd53ea74aad5fcea7d3cec2f402e4d8f27c2`; successor head `3777f54a824d3b2d3458b94f88e5627a7761a2c0` adds a regression test that invokes diff --git a/docs/product-technical-gap-baseline.md b/docs/product-technical-gap-baseline.md index b5ce0e2..e2ba59a 100644 --- a/docs/product-technical-gap-baseline.md +++ b/docs/product-technical-gap-baseline.md @@ -88,15 +88,15 @@ rather than green. | [#106](https://github.com/ContextualWisdomLab/keyverse/pull/106) | `setup-uv` update, stacked on #112 lockfile refresh | PENDING: 1 queued, 19 successful, 0 terminal failures on `2f0e3fb19a63db7f51cdadfeae6155cd469a0c91` | review required | Obtain independent review on the refreshed #112 base; do not treat the queued Check as green. | | [#105](https://github.com/ContextualWisdomLab/keyverse/pull/105) | `harden-runner` update, stacked on #112 lockfile refresh | PENDING: 1 queued, 19 successful, 0 terminal failures on `ef03c5a93c891980588b125f6c774fa84bf0feef` | changes requested | Re-evaluate the prior requested changes against this refreshed #112 base and obtain current-head independent review. | | [#104](https://github.com/ContextualWisdomLab/keyverse/pull/104) | ADR and buyer README expansion, stacked on #112 | PENDING: 14 Checks queued, 0 terminal failures on `0353001438efb060b85373c121f4d54dfd48e8c8` | review required | Base is intentionally `fix/account-unification-lock-20260819`; the net diff has no lockfile change. Obtain independent review and terminal stacked-head Checks. | -| [#103](https://github.com/ContextualWisdomLab/keyverse/pull/103) | Hierarchical authorization, login helper, PATs | PENDING: 1 in-progress, 1 queued, 18 successful, 0 terminal failures on `157b76893b32cda66fc586aa67ae72a30ac6b0d6` | changes requested | Independently validate the historical Strix report against the operator-admin trust boundary; retain fail-closed treatment and obtain a fresh exact-head review/check run before any merge claim. | +| [#103](https://github.com/ContextualWisdomLab/keyverse/pull/103) | Hierarchical authorization, login helper, PATs | PENDING: 16 pending, 0 terminal failures on `d540515be66a6ca0aa538c61f977a57bf7a69fb8` | changes requested | Fresh head adds RED-to-GREEN rejection for percent-encoded discovery markers; wait for exact-head Strix, full Checks, and independent review before any merge claim. | | [#101](https://github.com/ContextualWisdomLab/keyverse/pull/101) | Atomic coupled Python dependency updates | PASS: 22 Checks successful, 0 queued on `50dd9c96cab5c230f775685e8baea939fba390dd` | changes requested | Obtain fresh independent review; this is the policy companion to the lockfile gap. | | [#100](https://github.com/ContextualWisdomLab/keyverse/pull/100) | `lineageweave-web` account-derived claims plus default validator-path coverage | PENDING: 14 Checks queued, 0 terminal failures on `0d4d1b98dfc8b722b5502dba942b322a1657902e` | changes requested; fresh review requested | Devin's exact-head coverage finding is addressed by the default-artifact regression test; obtain current-head review without self-approval. | | [#83](https://github.com/ContextualWisdomLab/keyverse/pull/83) | Remove runtime application RPs from portable realm | PASS: 22 Checks successful, 0 queued on `dd1ab7444a75342b42e3af013ccda6d1dbfb359d` | changes requested | Reconfirm current-head approval and latest-pusher rule before protected merge. | ### Historical check failure root causes observed -The current exact-head audit above found two terminal failures. The following -items explain the live failures and earlier failures that still determine safe +The evidence set contains two relevant terminal failures from earlier exact +heads. The following items explain those failures and earlier failures that still determine safe sequencing; they must not be copied to another PR as if they were transferable evidence. @@ -132,6 +132,13 @@ evidence. operator token does not expose distinct end-user principals; independent security validation must resolve that trust-boundary interpretation. Until then the failure remains blocking and is not converted into a pass. +- PR #103's next exact head `d540515be66a6ca0aa538c61f977a57bf7a69fb8` adds + a RED-to-GREEN regression for percent-encoded `.well-known`, `metadataUrl`, + and `discoveryEndpoint` markers. The implementation normalizes + `public_issuer_url` with the standard-library URL decoder before the existing + no-fetch policy check. Local focused/full tests, Ruff, Interrogate, and + 100% statement/branch coverage pass; the 16 hosted Checks are still pending, + so no hosted security or review success is claimed. ## Open Issue inventory From cae142c0b9c640ac2683e87d2ae891f3da06dfdf Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 21 Aug 2026 09:04:59 +0900 Subject: [PATCH 45/70] docs: refresh current check evidence --- docs/doctoring/product-technical-gap-baseline.md | 9 +++++---- docs/product-technical-gap-baseline.md | 7 ++++--- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/docs/doctoring/product-technical-gap-baseline.md b/docs/doctoring/product-technical-gap-baseline.md index 6093380..354c4c9 100644 --- a/docs/doctoring/product-technical-gap-baseline.md +++ b/docs/doctoring/product-technical-gap-baseline.md @@ -206,10 +206,11 @@ https://www.rfc-editor.org/rfc/rfc8725.html head `d540515be66a6ca0aa538c61f977a57bf7a69fb8` adds a RED-to-GREEN regression for percent-encoded discovery markers and normalizes `public_issuer_url` before the no-fetch policy check. Local focused/full - tests, Ruff, Interrogate, and 100% statement/branch coverage pass; its 16 - hosted Checks remain pending, so hosted security and review success are not - claimed. The operator-admin trust boundary and the new URL-normalization - fix still require independent exact-head validation. PR + tests, Ruff, Interrogate, and 100% statement/branch coverage pass; 15 hosted + Checks remain pending while Devin Review is successful, so hosted security + and independent approval success are not claimed. The operator-admin trust + boundary and the new URL-normalization fix still require independent + exact-head validation. PR #100's pre-doctoring-refresh head was `c483bd53ea74aad5fcea7d3cec2f402e4d8f27c2`; successor head `3777f54a824d3b2d3458b94f88e5627a7761a2c0` adds a regression test that invokes diff --git a/docs/product-technical-gap-baseline.md b/docs/product-technical-gap-baseline.md index e2ba59a..13b8c76 100644 --- a/docs/product-technical-gap-baseline.md +++ b/docs/product-technical-gap-baseline.md @@ -88,7 +88,7 @@ rather than green. | [#106](https://github.com/ContextualWisdomLab/keyverse/pull/106) | `setup-uv` update, stacked on #112 lockfile refresh | PENDING: 1 queued, 19 successful, 0 terminal failures on `2f0e3fb19a63db7f51cdadfeae6155cd469a0c91` | review required | Obtain independent review on the refreshed #112 base; do not treat the queued Check as green. | | [#105](https://github.com/ContextualWisdomLab/keyverse/pull/105) | `harden-runner` update, stacked on #112 lockfile refresh | PENDING: 1 queued, 19 successful, 0 terminal failures on `ef03c5a93c891980588b125f6c774fa84bf0feef` | changes requested | Re-evaluate the prior requested changes against this refreshed #112 base and obtain current-head independent review. | | [#104](https://github.com/ContextualWisdomLab/keyverse/pull/104) | ADR and buyer README expansion, stacked on #112 | PENDING: 14 Checks queued, 0 terminal failures on `0353001438efb060b85373c121f4d54dfd48e8c8` | review required | Base is intentionally `fix/account-unification-lock-20260819`; the net diff has no lockfile change. Obtain independent review and terminal stacked-head Checks. | -| [#103](https://github.com/ContextualWisdomLab/keyverse/pull/103) | Hierarchical authorization, login helper, PATs | PENDING: 16 pending, 0 terminal failures on `d540515be66a6ca0aa538c61f977a57bf7a69fb8` | changes requested | Fresh head adds RED-to-GREEN rejection for percent-encoded discovery markers; wait for exact-head Strix, full Checks, and independent review before any merge claim. | +| [#103](https://github.com/ContextualWisdomLab/keyverse/pull/103) | Hierarchical authorization, login helper, PATs | PENDING: 15 pending, 1 successful Devin Review, 0 terminal failures on `d540515be66a6ca0aa538c61f977a57bf7a69fb8` | changes requested | Fresh head adds RED-to-GREEN rejection for percent-encoded discovery markers; wait for exact-head Strix, full Checks, and independent review before any merge claim. | | [#101](https://github.com/ContextualWisdomLab/keyverse/pull/101) | Atomic coupled Python dependency updates | PASS: 22 Checks successful, 0 queued on `50dd9c96cab5c230f775685e8baea939fba390dd` | changes requested | Obtain fresh independent review; this is the policy companion to the lockfile gap. | | [#100](https://github.com/ContextualWisdomLab/keyverse/pull/100) | `lineageweave-web` account-derived claims plus default validator-path coverage | PENDING: 14 Checks queued, 0 terminal failures on `0d4d1b98dfc8b722b5502dba942b322a1657902e` | changes requested; fresh review requested | Devin's exact-head coverage finding is addressed by the default-artifact regression test; obtain current-head review without self-approval. | | [#83](https://github.com/ContextualWisdomLab/keyverse/pull/83) | Remove runtime application RPs from portable realm | PASS: 22 Checks successful, 0 queued on `dd1ab7444a75342b42e3af013ccda6d1dbfb359d` | changes requested | Reconfirm current-head approval and latest-pusher rule before protected merge. | @@ -137,8 +137,9 @@ evidence. and `discoveryEndpoint` markers. The implementation normalizes `public_issuer_url` with the standard-library URL decoder before the existing no-fetch policy check. Local focused/full tests, Ruff, Interrogate, and - 100% statement/branch coverage pass; the 16 hosted Checks are still pending, - so no hosted security or review success is claimed. + 100% statement/branch coverage pass; 15 hosted Checks remain pending while + Devin Review is successful, so no hosted security or independent approval + success is claimed. ## Open Issue inventory From 99fdd8601bf037f324e4b47e3c611ef19abd11d8 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 21 Aug 2026 09:09:29 +0900 Subject: [PATCH 46/70] docs: record token rotation remediation --- .../product-technical-gap-baseline.md | 18 +++++++++--------- docs/product-technical-gap-baseline.md | 18 +++++++++--------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/docs/doctoring/product-technical-gap-baseline.md b/docs/doctoring/product-technical-gap-baseline.md index 354c4c9..f498289 100644 --- a/docs/doctoring/product-technical-gap-baseline.md +++ b/docs/doctoring/product-technical-gap-baseline.md @@ -202,15 +202,15 @@ https://www.rfc-editor.org/rfc/rfc8725.html hosted Checks remain unverified and #112 remains the lock-refresh prerequisite. PR #103's historical terminal Strix run 32092025335 / job 95576032571 - emitted a MEDIUM IDOR report with contradictory model text. Its next exact - head `d540515be66a6ca0aa538c61f977a57bf7a69fb8` adds a RED-to-GREEN - regression for percent-encoded discovery markers and normalizes - `public_issuer_url` before the no-fetch policy check. Local focused/full - tests, Ruff, Interrogate, and 100% statement/branch coverage pass; 15 hosted - Checks remain pending while Devin Review is successful, so hosted security - and independent approval success are not claimed. The operator-admin trust - boundary and the new URL-normalization fix still require independent - exact-head validation. PR + emitted a MEDIUM IDOR report with contradictory model text. Its exact head + `ec8a1a5210c84c854eff365934ac7c057cf477ed` adds RED-to-GREEN regressions for + percent-encoded discovery markers and invalid token rotation settings. It + normalizes `public_issuer_url` before the no-fetch policy check and validates + token replacement settings before revoking the active token. Local + focused/full tests, Ruff, Interrogate, and 100% statement/branch coverage + pass; 16 hosted Checks are pending, so hosted security and independent + approval success are not claimed. The operator-admin trust boundary and + both security fixes still require independent exact-head validation. PR #100's pre-doctoring-refresh head was `c483bd53ea74aad5fcea7d3cec2f402e4d8f27c2`; successor head `3777f54a824d3b2d3458b94f88e5627a7761a2c0` adds a regression test that invokes diff --git a/docs/product-technical-gap-baseline.md b/docs/product-technical-gap-baseline.md index 13b8c76..5a80699 100644 --- a/docs/product-technical-gap-baseline.md +++ b/docs/product-technical-gap-baseline.md @@ -88,7 +88,7 @@ rather than green. | [#106](https://github.com/ContextualWisdomLab/keyverse/pull/106) | `setup-uv` update, stacked on #112 lockfile refresh | PENDING: 1 queued, 19 successful, 0 terminal failures on `2f0e3fb19a63db7f51cdadfeae6155cd469a0c91` | review required | Obtain independent review on the refreshed #112 base; do not treat the queued Check as green. | | [#105](https://github.com/ContextualWisdomLab/keyverse/pull/105) | `harden-runner` update, stacked on #112 lockfile refresh | PENDING: 1 queued, 19 successful, 0 terminal failures on `ef03c5a93c891980588b125f6c774fa84bf0feef` | changes requested | Re-evaluate the prior requested changes against this refreshed #112 base and obtain current-head independent review. | | [#104](https://github.com/ContextualWisdomLab/keyverse/pull/104) | ADR and buyer README expansion, stacked on #112 | PENDING: 14 Checks queued, 0 terminal failures on `0353001438efb060b85373c121f4d54dfd48e8c8` | review required | Base is intentionally `fix/account-unification-lock-20260819`; the net diff has no lockfile change. Obtain independent review and terminal stacked-head Checks. | -| [#103](https://github.com/ContextualWisdomLab/keyverse/pull/103) | Hierarchical authorization, login helper, PATs | PENDING: 15 pending, 1 successful Devin Review, 0 terminal failures on `d540515be66a6ca0aa538c61f977a57bf7a69fb8` | changes requested | Fresh head adds RED-to-GREEN rejection for percent-encoded discovery markers; wait for exact-head Strix, full Checks, and independent review before any merge claim. | +| [#103](https://github.com/ContextualWisdomLab/keyverse/pull/103) | Hierarchical authorization, login helper, PATs | PENDING: 16 pending, 0 terminal failures on `ec8a1a5210c84c854eff365934ac7c057cf477ed` | changes requested | Fresh head adds RED-to-GREEN rejection for encoded discovery markers and preserves active tokens on invalid rotation; wait for exact-head security Checks and independent review before any merge claim. | | [#101](https://github.com/ContextualWisdomLab/keyverse/pull/101) | Atomic coupled Python dependency updates | PASS: 22 Checks successful, 0 queued on `50dd9c96cab5c230f775685e8baea939fba390dd` | changes requested | Obtain fresh independent review; this is the policy companion to the lockfile gap. | | [#100](https://github.com/ContextualWisdomLab/keyverse/pull/100) | `lineageweave-web` account-derived claims plus default validator-path coverage | PENDING: 14 Checks queued, 0 terminal failures on `0d4d1b98dfc8b722b5502dba942b322a1657902e` | changes requested; fresh review requested | Devin's exact-head coverage finding is addressed by the default-artifact regression test; obtain current-head review without self-approval. | | [#83](https://github.com/ContextualWisdomLab/keyverse/pull/83) | Remove runtime application RPs from portable realm | PASS: 22 Checks successful, 0 queued on `dd1ab7444a75342b42e3af013ccda6d1dbfb359d` | changes requested | Reconfirm current-head approval and latest-pusher rule before protected merge. | @@ -132,14 +132,14 @@ evidence. operator token does not expose distinct end-user principals; independent security validation must resolve that trust-boundary interpretation. Until then the failure remains blocking and is not converted into a pass. -- PR #103's next exact head `d540515be66a6ca0aa538c61f977a57bf7a69fb8` adds - a RED-to-GREEN regression for percent-encoded `.well-known`, `metadataUrl`, - and `discoveryEndpoint` markers. The implementation normalizes - `public_issuer_url` with the standard-library URL decoder before the existing - no-fetch policy check. Local focused/full tests, Ruff, Interrogate, and - 100% statement/branch coverage pass; 15 hosted Checks remain pending while - Devin Review is successful, so no hosted security or independent approval - success is claimed. +- PR #103's exact head `ec8a1a5210c84c854eff365934ac7c057cf477ed` adds + RED-to-GREEN regressions for percent-encoded `.well-known`, `metadataUrl`, + and `discoveryEndpoint` markers and for invalid token rotation settings. The + implementation normalizes `public_issuer_url` before the no-fetch policy + check and validates token replacement settings before revoking the active + token. Local focused/full tests, Ruff, Interrogate, and 100% statement/branch + coverage pass; its 16 hosted Checks are pending, so no hosted security or + independent approval success is claimed. ## Open Issue inventory From e23af12f6cbd679348c2e6569f7733f9ed055d3b Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 21 Aug 2026 09:32:09 +0900 Subject: [PATCH 47/70] docs: refresh open PR evidence --- .../product-technical-gap-baseline.md | 19 ++++++++-------- docs/product-technical-gap-baseline.md | 22 +++++++++---------- 2 files changed, 21 insertions(+), 20 deletions(-) diff --git a/docs/doctoring/product-technical-gap-baseline.md b/docs/doctoring/product-technical-gap-baseline.md index f498289..667095a 100644 --- a/docs/doctoring/product-technical-gap-baseline.md +++ b/docs/doctoring/product-technical-gap-baseline.md @@ -202,15 +202,16 @@ https://www.rfc-editor.org/rfc/rfc8725.html hosted Checks remain unverified and #112 remains the lock-refresh prerequisite. PR #103's historical terminal Strix run 32092025335 / job 95576032571 - emitted a MEDIUM IDOR report with contradictory model text. Its exact head - `ec8a1a5210c84c854eff365934ac7c057cf477ed` adds RED-to-GREEN regressions for - percent-encoded discovery markers and invalid token rotation settings. It - normalizes `public_issuer_url` before the no-fetch policy check and validates - token replacement settings before revoking the active token. Local - focused/full tests, Ruff, Interrogate, and 100% statement/branch coverage - pass; 16 hosted Checks are pending, so hosted security and independent - approval success are not claimed. The operator-admin trust boundary and - both security fixes still require independent exact-head validation. PR + emitted a MEDIUM IDOR report with contradictory model text. Its current exact + head `1f8c8ac29e6860d289d4b54e9bd6e418bf731638` adds RED-to-GREEN regressions + for percent-encoded discovery markers, invalid token rotation settings, + KV/audit lifecycle failures, direct router embedding, tenant isolation, + software-unit ABAC, runtime authentication, and untrusted public issuers. + Local focused/full tests, Ruff, Interrogate, and 100% application + statement/branch coverage pass; 16 hosted Checks are pending, so hosted + security and independent approval success are not claimed. The operator-admin + trust boundary and the fresh security changes still require independent + exact-head validation. PR #100's pre-doctoring-refresh head was `c483bd53ea74aad5fcea7d3cec2f402e4d8f27c2`; successor head `3777f54a824d3b2d3458b94f88e5627a7761a2c0` adds a regression test that invokes diff --git a/docs/product-technical-gap-baseline.md b/docs/product-technical-gap-baseline.md index 5a80699..61e0a59 100644 --- a/docs/product-technical-gap-baseline.md +++ b/docs/product-technical-gap-baseline.md @@ -66,7 +66,8 @@ tenant, or resource ownership. The following is the current open-PR inventory. `Checks` means the exact head rollup observed on 2026-08-21; it is not inherited from a predecessor commit. -This record was refreshed after the PR #100 validator-coverage test fix and the +This record was refreshed after the PR #100 validator-coverage test fix at +`99fdd8601bf037f324e4b47e3c611ef19abd11d8` and the intentional stacked-base rebase of PR #104. The live PR record is authoritative for the exact hash and Checks; predecessor evidence remains non-transferable. @@ -88,9 +89,9 @@ rather than green. | [#106](https://github.com/ContextualWisdomLab/keyverse/pull/106) | `setup-uv` update, stacked on #112 lockfile refresh | PENDING: 1 queued, 19 successful, 0 terminal failures on `2f0e3fb19a63db7f51cdadfeae6155cd469a0c91` | review required | Obtain independent review on the refreshed #112 base; do not treat the queued Check as green. | | [#105](https://github.com/ContextualWisdomLab/keyverse/pull/105) | `harden-runner` update, stacked on #112 lockfile refresh | PENDING: 1 queued, 19 successful, 0 terminal failures on `ef03c5a93c891980588b125f6c774fa84bf0feef` | changes requested | Re-evaluate the prior requested changes against this refreshed #112 base and obtain current-head independent review. | | [#104](https://github.com/ContextualWisdomLab/keyverse/pull/104) | ADR and buyer README expansion, stacked on #112 | PENDING: 14 Checks queued, 0 terminal failures on `0353001438efb060b85373c121f4d54dfd48e8c8` | review required | Base is intentionally `fix/account-unification-lock-20260819`; the net diff has no lockfile change. Obtain independent review and terminal stacked-head Checks. | -| [#103](https://github.com/ContextualWisdomLab/keyverse/pull/103) | Hierarchical authorization, login helper, PATs | PENDING: 16 pending, 0 terminal failures on `ec8a1a5210c84c854eff365934ac7c057cf477ed` | changes requested | Fresh head adds RED-to-GREEN rejection for encoded discovery markers and preserves active tokens on invalid rotation; wait for exact-head security Checks and independent review before any merge claim. | +| [#103](https://github.com/ContextualWisdomLab/keyverse/pull/103) | Hierarchical authorization, login helper, PATs | PENDING: 16 pending, 0 terminal failures on `1f8c8ac29e6860d289d4b54e9bd6e418bf731638` | changes requested; fresh review requested | Fresh head adds compensating token lifecycle recovery, separate runtime service authentication, tenant-qualified grant/combination isolation, software-unit ABAC, and trusted issuer binding; wait for exact-head security Checks and independent review before any merge claim. | | [#101](https://github.com/ContextualWisdomLab/keyverse/pull/101) | Atomic coupled Python dependency updates | PASS: 22 Checks successful, 0 queued on `50dd9c96cab5c230f775685e8baea939fba390dd` | changes requested | Obtain fresh independent review; this is the policy companion to the lockfile gap. | -| [#100](https://github.com/ContextualWisdomLab/keyverse/pull/100) | `lineageweave-web` account-derived claims plus default validator-path coverage | PENDING: 14 Checks queued, 0 terminal failures on `0d4d1b98dfc8b722b5502dba942b322a1657902e` | changes requested; fresh review requested | Devin's exact-head coverage finding is addressed by the default-artifact regression test; obtain current-head review without self-approval. | +| [#100](https://github.com/ContextualWisdomLab/keyverse/pull/100) | `lineageweave-web` account-derived claims plus default validator-path coverage | PENDING: 14 Checks queued, 0 terminal failures on `99fdd8601bf037f324e4b47e3c611ef19abd11d8` | changes requested; fresh review requested | The documentation successor records current #103 token-rotation evidence; obtain current-head review without self-approval. | | [#83](https://github.com/ContextualWisdomLab/keyverse/pull/83) | Remove runtime application RPs from portable realm | PASS: 22 Checks successful, 0 queued on `dd1ab7444a75342b42e3af013ccda6d1dbfb359d` | changes requested | Reconfirm current-head approval and latest-pusher rule before protected merge. | ### Historical check failure root causes observed @@ -132,14 +133,13 @@ evidence. operator token does not expose distinct end-user principals; independent security validation must resolve that trust-boundary interpretation. Until then the failure remains blocking and is not converted into a pass. -- PR #103's exact head `ec8a1a5210c84c854eff365934ac7c057cf477ed` adds - RED-to-GREEN regressions for percent-encoded `.well-known`, `metadataUrl`, - and `discoveryEndpoint` markers and for invalid token rotation settings. The - implementation normalizes `public_issuer_url` before the no-fetch policy - check and validates token replacement settings before revoking the active - token. Local focused/full tests, Ruff, Interrogate, and 100% statement/branch - coverage pass; its 16 hosted Checks are pending, so no hosted security or - independent approval success is claimed. +- PR #103's current exact head `1f8c8ac29e6860d289d4b54e9bd6e418bf731638` + adds RED-to-GREEN regressions for percent-encoded discovery markers, + invalid token rotation settings, KV/audit lifecycle failures, direct router + embedding, tenant isolation, software-unit ABAC, runtime authentication, and + untrusted public issuers. Local focused/full tests, Ruff, Interrogate, and + 100% application statement/branch coverage pass; its 16 hosted Checks are + pending, so no hosted security or independent approval success is claimed. ## Open Issue inventory From 6acb0641dfe9c46cc23a43a64f58906cd9167078 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 21 Aug 2026 09:44:26 +0900 Subject: [PATCH 48/70] docs: record current authorization PR head --- .../product-technical-gap-baseline.md | 18 +++++++++--------- docs/product-technical-gap-baseline.md | 15 ++++++++------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/docs/doctoring/product-technical-gap-baseline.md b/docs/doctoring/product-technical-gap-baseline.md index 667095a..7a7543b 100644 --- a/docs/doctoring/product-technical-gap-baseline.md +++ b/docs/doctoring/product-technical-gap-baseline.md @@ -203,15 +203,15 @@ https://www.rfc-editor.org/rfc/rfc8725.html prerequisite. PR #103's historical terminal Strix run 32092025335 / job 95576032571 emitted a MEDIUM IDOR report with contradictory model text. Its current exact - head `1f8c8ac29e6860d289d4b54e9bd6e418bf731638` adds RED-to-GREEN regressions - for percent-encoded discovery markers, invalid token rotation settings, - KV/audit lifecycle failures, direct router embedding, tenant isolation, - software-unit ABAC, runtime authentication, and untrusted public issuers. - Local focused/full tests, Ruff, Interrogate, and 100% application - statement/branch coverage pass; 16 hosted Checks are pending, so hosted - security and independent approval success are not claimed. The operator-admin - trust boundary and the fresh security changes still require independent - exact-head validation. PR + head `5514a24c1a3c56cc0a2a5c458ec4f8cb900c571a` adds RED-to-GREEN regressions + for percent-encoded discovery markers, inactive and expired token rotation, + invalid token rotation settings, KV/audit lifecycle failures, direct router + embedding, tenant isolation, software-unit ABAC, runtime authentication, and + untrusted public issuers. Local focused/full tests, Ruff, Interrogate, and + 100% application statement/branch coverage pass; required hosted Checks are + still pending or queued, so hosted security and independent approval success + are not claimed. The operator-admin trust boundary and the fresh security + changes still require independent exact-head validation. PR #100's pre-doctoring-refresh head was `c483bd53ea74aad5fcea7d3cec2f402e4d8f27c2`; successor head `3777f54a824d3b2d3458b94f88e5627a7761a2c0` adds a regression test that invokes diff --git a/docs/product-technical-gap-baseline.md b/docs/product-technical-gap-baseline.md index 61e0a59..19e7b12 100644 --- a/docs/product-technical-gap-baseline.md +++ b/docs/product-technical-gap-baseline.md @@ -89,7 +89,7 @@ rather than green. | [#106](https://github.com/ContextualWisdomLab/keyverse/pull/106) | `setup-uv` update, stacked on #112 lockfile refresh | PENDING: 1 queued, 19 successful, 0 terminal failures on `2f0e3fb19a63db7f51cdadfeae6155cd469a0c91` | review required | Obtain independent review on the refreshed #112 base; do not treat the queued Check as green. | | [#105](https://github.com/ContextualWisdomLab/keyverse/pull/105) | `harden-runner` update, stacked on #112 lockfile refresh | PENDING: 1 queued, 19 successful, 0 terminal failures on `ef03c5a93c891980588b125f6c774fa84bf0feef` | changes requested | Re-evaluate the prior requested changes against this refreshed #112 base and obtain current-head independent review. | | [#104](https://github.com/ContextualWisdomLab/keyverse/pull/104) | ADR and buyer README expansion, stacked on #112 | PENDING: 14 Checks queued, 0 terminal failures on `0353001438efb060b85373c121f4d54dfd48e8c8` | review required | Base is intentionally `fix/account-unification-lock-20260819`; the net diff has no lockfile change. Obtain independent review and terminal stacked-head Checks. | -| [#103](https://github.com/ContextualWisdomLab/keyverse/pull/103) | Hierarchical authorization, login helper, PATs | PENDING: 16 pending, 0 terminal failures on `1f8c8ac29e6860d289d4b54e9bd6e418bf731638` | changes requested; fresh review requested | Fresh head adds compensating token lifecycle recovery, separate runtime service authentication, tenant-qualified grant/combination isolation, software-unit ABAC, and trusted issuer binding; wait for exact-head security Checks and independent review before any merge claim. | +| [#103](https://github.com/ContextualWisdomLab/keyverse/pull/103) | Hierarchical authorization, login helper, PATs | PENDING: required Checks still pending/queued, 0 terminal failures on `5514a24c1a3c56cc0a2a5c458ec4f8cb900c571a` | changes requested; fresh review requested | Fresh head adds inactive/expired token-rotation denial, compensating token lifecycle recovery, separate runtime service authentication, tenant-qualified grant/combination isolation, software-unit ABAC, and trusted issuer binding; wait for exact-head security Checks and independent review before any merge claim. | | [#101](https://github.com/ContextualWisdomLab/keyverse/pull/101) | Atomic coupled Python dependency updates | PASS: 22 Checks successful, 0 queued on `50dd9c96cab5c230f775685e8baea939fba390dd` | changes requested | Obtain fresh independent review; this is the policy companion to the lockfile gap. | | [#100](https://github.com/ContextualWisdomLab/keyverse/pull/100) | `lineageweave-web` account-derived claims plus default validator-path coverage | PENDING: 14 Checks queued, 0 terminal failures on `99fdd8601bf037f324e4b47e3c611ef19abd11d8` | changes requested; fresh review requested | The documentation successor records current #103 token-rotation evidence; obtain current-head review without self-approval. | | [#83](https://github.com/ContextualWisdomLab/keyverse/pull/83) | Remove runtime application RPs from portable realm | PASS: 22 Checks successful, 0 queued on `dd1ab7444a75342b42e3af013ccda6d1dbfb359d` | changes requested | Reconfirm current-head approval and latest-pusher rule before protected merge. | @@ -133,13 +133,14 @@ evidence. operator token does not expose distinct end-user principals; independent security validation must resolve that trust-boundary interpretation. Until then the failure remains blocking and is not converted into a pass. -- PR #103's current exact head `1f8c8ac29e6860d289d4b54e9bd6e418bf731638` +- PR #103's current exact head `5514a24c1a3c56cc0a2a5c458ec4f8cb900c571a` adds RED-to-GREEN regressions for percent-encoded discovery markers, - invalid token rotation settings, KV/audit lifecycle failures, direct router - embedding, tenant isolation, software-unit ABAC, runtime authentication, and - untrusted public issuers. Local focused/full tests, Ruff, Interrogate, and - 100% application statement/branch coverage pass; its 16 hosted Checks are - pending, so no hosted security or independent approval success is claimed. + inactive and expired token rotation, invalid token rotation settings, KV/audit + lifecycle failures, direct router embedding, tenant isolation, software-unit + ABAC, runtime authentication, and untrusted public issuers. Local + focused/full tests, Ruff, Interrogate, and 100% application statement/branch + coverage pass; its required hosted Checks are still pending or queued, so no + hosted security or independent approval success is claimed. ## Open Issue inventory From 1604d8eda51a288a41ea5ac4cede4bfc77b59d2d Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 21 Aug 2026 09:48:02 +0900 Subject: [PATCH 49/70] docs: align baseline with final token fix --- docs/doctoring/product-technical-gap-baseline.md | 2 +- docs/product-technical-gap-baseline.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/doctoring/product-technical-gap-baseline.md b/docs/doctoring/product-technical-gap-baseline.md index 7a7543b..453beb0 100644 --- a/docs/doctoring/product-technical-gap-baseline.md +++ b/docs/doctoring/product-technical-gap-baseline.md @@ -203,7 +203,7 @@ https://www.rfc-editor.org/rfc/rfc8725.html prerequisite. PR #103's historical terminal Strix run 32092025335 / job 95576032571 emitted a MEDIUM IDOR report with contradictory model text. Its current exact - head `5514a24c1a3c56cc0a2a5c458ec4f8cb900c571a` adds RED-to-GREEN regressions + head `9274d3184443fba6c6294e08dff20734f3ae6fb4` adds RED-to-GREEN regressions for percent-encoded discovery markers, inactive and expired token rotation, invalid token rotation settings, KV/audit lifecycle failures, direct router embedding, tenant isolation, software-unit ABAC, runtime authentication, and diff --git a/docs/product-technical-gap-baseline.md b/docs/product-technical-gap-baseline.md index 19e7b12..923b3e4 100644 --- a/docs/product-technical-gap-baseline.md +++ b/docs/product-technical-gap-baseline.md @@ -89,7 +89,7 @@ rather than green. | [#106](https://github.com/ContextualWisdomLab/keyverse/pull/106) | `setup-uv` update, stacked on #112 lockfile refresh | PENDING: 1 queued, 19 successful, 0 terminal failures on `2f0e3fb19a63db7f51cdadfeae6155cd469a0c91` | review required | Obtain independent review on the refreshed #112 base; do not treat the queued Check as green. | | [#105](https://github.com/ContextualWisdomLab/keyverse/pull/105) | `harden-runner` update, stacked on #112 lockfile refresh | PENDING: 1 queued, 19 successful, 0 terminal failures on `ef03c5a93c891980588b125f6c774fa84bf0feef` | changes requested | Re-evaluate the prior requested changes against this refreshed #112 base and obtain current-head independent review. | | [#104](https://github.com/ContextualWisdomLab/keyverse/pull/104) | ADR and buyer README expansion, stacked on #112 | PENDING: 14 Checks queued, 0 terminal failures on `0353001438efb060b85373c121f4d54dfd48e8c8` | review required | Base is intentionally `fix/account-unification-lock-20260819`; the net diff has no lockfile change. Obtain independent review and terminal stacked-head Checks. | -| [#103](https://github.com/ContextualWisdomLab/keyverse/pull/103) | Hierarchical authorization, login helper, PATs | PENDING: required Checks still pending/queued, 0 terminal failures on `5514a24c1a3c56cc0a2a5c458ec4f8cb900c571a` | changes requested; fresh review requested | Fresh head adds inactive/expired token-rotation denial, compensating token lifecycle recovery, separate runtime service authentication, tenant-qualified grant/combination isolation, software-unit ABAC, and trusted issuer binding; wait for exact-head security Checks and independent review before any merge claim. | +| [#103](https://github.com/ContextualWisdomLab/keyverse/pull/103) | Hierarchical authorization, login helper, PATs | PENDING: required Checks still pending/queued, 0 terminal failures on `9274d3184443fba6c6294e08dff20734f3ae6fb4` | changes requested; fresh review requested | Fresh head adds inactive/expired token-rotation denial, compensating token lifecycle recovery, separate runtime service authentication, tenant-qualified grant/combination isolation, software-unit ABAC, and trusted issuer binding; wait for exact-head security Checks and independent review before any merge claim. | | [#101](https://github.com/ContextualWisdomLab/keyverse/pull/101) | Atomic coupled Python dependency updates | PASS: 22 Checks successful, 0 queued on `50dd9c96cab5c230f775685e8baea939fba390dd` | changes requested | Obtain fresh independent review; this is the policy companion to the lockfile gap. | | [#100](https://github.com/ContextualWisdomLab/keyverse/pull/100) | `lineageweave-web` account-derived claims plus default validator-path coverage | PENDING: 14 Checks queued, 0 terminal failures on `99fdd8601bf037f324e4b47e3c611ef19abd11d8` | changes requested; fresh review requested | The documentation successor records current #103 token-rotation evidence; obtain current-head review without self-approval. | | [#83](https://github.com/ContextualWisdomLab/keyverse/pull/83) | Remove runtime application RPs from portable realm | PASS: 22 Checks successful, 0 queued on `dd1ab7444a75342b42e3af013ccda6d1dbfb359d` | changes requested | Reconfirm current-head approval and latest-pusher rule before protected merge. | @@ -133,7 +133,7 @@ evidence. operator token does not expose distinct end-user principals; independent security validation must resolve that trust-boundary interpretation. Until then the failure remains blocking and is not converted into a pass. -- PR #103's current exact head `5514a24c1a3c56cc0a2a5c458ec4f8cb900c571a` +- PR #103's current exact head `9274d3184443fba6c6294e08dff20734f3ae6fb4` adds RED-to-GREEN regressions for percent-encoded discovery markers, inactive and expired token rotation, invalid token rotation settings, KV/audit lifecycle failures, direct router embedding, tenant isolation, software-unit From dbfea1419823d106be5f027d65c600891c01f007 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 21 Aug 2026 10:20:53 +0900 Subject: [PATCH 50/70] docs: refresh exact-head gap evidence --- .../product-technical-gap-baseline.md | 67 +++++++++---------- docs/product-technical-gap-baseline.md | 57 ++++++++-------- 2 files changed, 63 insertions(+), 61 deletions(-) diff --git a/docs/doctoring/product-technical-gap-baseline.md b/docs/doctoring/product-technical-gap-baseline.md index 453beb0..129cff8 100644 --- a/docs/doctoring/product-technical-gap-baseline.md +++ b/docs/doctoring/product-technical-gap-baseline.md @@ -159,48 +159,48 @@ https://www.rfc-editor.org/rfc/rfc8725.html and doctoring records. - Exact-head GitHub PR, review, issue, check-run, ruleset, and scheduled-run queries performed on 2026-08-21. Fourteen Keyverse PRs are open: #112, #101, - and #83 each have 22 successful Checks with no queued run; the other eleven - have queued or in-progress Checks without a terminal failure. #110, #111, - and #113 each have 18 successful Checks and two queued Checks after their - lock-refresh/external-security reruns. - No current open PR has a qualifying formal approval. - Queued Checks remain unverified. + and #83 each have 23 successful Checks with no queued run. #111's normal + branch update created current head `032f730b0239d062cf9803525ba66c740e0b2d2e` + with 14 queued Checks and one completed success; #113 has 22 successful and + one queued Check; #100 and #103 each have two successful and 14 queued + Checks. No current open PR has a qualifying formal approval. Queued Checks + remain unverified. PR #113's current SCIM lock head `50f19ec6338fb8eb959b8c797bdfa938e1071c87` includes the normal prerequisite lockfile history and a realistic SCIM PatchOp race plus spawned-process - SQLite lock regression; its hosted Checks now have 18 successful runs and - two queued reruns with no terminal failure. The earlier Strix job could not + SQLite lock regression; its hosted Checks now have 22 successful runs and + one queued rerun with no terminal failure. The earlier Strix job could not pull `ghcr.io/usestrix/strix-sandbox:1.3.0` because GHCR returned HTTP 500/EOF, and it produced no structured vulnerability report, so that run failed closed; the fresh exact-head rerun remains unverified while queued. Its local RED-to-GREEN, root-level SCIM error-wire, and cross-process sidecar evidence are not protected-main evidence. PR #112's lockfile head - `f02acf93367a40dbfb23a73985017dca8d42ff39` has 22 terminal-success Checks + `f02acf93367a40dbfb23a73985017dca8d42ff39` has 23 terminal-success Checks but still requires independent review. PR #111's current head - `e1d0fee6ce29cb9ec75d9fbdb38cd15242bf4fdc` is now stacked on #112. Its - prior `account-unification-tests` failure occurred against the old `main` - base because `uv sync --locked` found a stale `uv.lock` before tests began; - the rerun against the lock-refresh base now has no terminal failure and two - queued Checks. It remains coupled to #112 and #110. PR #110's current head - `07acd65145c9522a74858d1ff8761ea05a09e8f0` was likewise retargeted to #112 - after the same pre-test lock failure; its rerun now has 18 successful Checks - and two queued Checks with no terminal failure. + `032f730b0239d062cf9803525ba66c740e0b2d2e` now contains #112's lockfile + through a normal branch update. Its prior `account-unification-tests` + failure occurred before that update; the fresh run is queued and remains + unverified. It remains coupled to #112 and #110. PR #110's current head + `07acd65145c9522a74858d1ff8761ea05a09e8f0` remains on the #112 base with + 20 successful Checks and two queued Checks; its hosted reruns remain + unverified. The historical PR #105 exact head `72de5499d6e97ae7f7bd804ab78b3e1644dd5a4f` had a failed `account-unification-tests` Check: `uv 0.12.5` reproduced `uv sync --locked` refusing the stale `coverage==7.15.2` and `setuptools==83.0.0` lock entries while the current `pyproject.toml` required `7.15.4` and `84.0.0`; the current #105 head - `ef03c5a93c891980588b125f6c774fa84bf0feef` is now stacked on #112 and has - 19 successful Checks plus one queued Check with no terminal failure. The - current #106 and #109 heads remain stacked on #112 with that same rollup. + `ef03c5a93c891980588b125f6c774fa84bf0feef` is stacked on #112 and has + 21 successful Checks plus one queued Check with no terminal failure. The + current #106 and #109 heads remain stacked on #112 with 21 successful Checks + and one queued Check each. PR #107 was rebased cleanly onto #112 at `53842560d397aa20309a6b16aceb560540611686`, and PR #108 was rebased cleanly - onto #112 at `538cead991a7c1bed32f2dcb5413b5fc56f53e93`; each now has 14 - queued Checks and no terminal failure. Local `uv sync --locked --extra dev` - plus the full service pytest suite passed on both rebased trees. Their fresh - hosted Checks remain unverified and #112 remains the lock-refresh - prerequisite. + onto #112 at `538cead991a7c1bed32f2dcb5413b5fc56f53e93`; each now has one + completed success and 14 queued Checks with no terminal failure. Local + `uv sync --locked --extra dev` plus the full service pytest suite passed on + both rebased trees. Their fresh hosted Checks remain unverified and #112 + remains the lock-refresh prerequisite. PR #103's historical terminal Strix run 32092025335 / job 95576032571 emitted a MEDIUM IDOR report with contradictory model text. Its current exact head `9274d3184443fba6c6294e08dff20734f3ae6fb4` adds RED-to-GREEN regressions @@ -211,16 +211,15 @@ https://www.rfc-editor.org/rfc/rfc8725.html 100% application statement/branch coverage pass; required hosted Checks are still pending or queued, so hosted security and independent approval success are not claimed. The operator-admin trust boundary and the fresh security - changes still require independent exact-head validation. PR - #100's pre-doctoring-refresh head was - `c483bd53ea74aad5fcea7d3cec2f402e4d8f27c2`; successor head - `3777f54a824d3b2d3458b94f88e5627a7761a2c0` adds a regression test that invokes - the validator's committed default realm/profile paths after an exact-head - Devin coverage finding. The current documentation successor is - `0d4d1b98dfc8b722b5502dba942b322a1657902e`, with 14 queued Checks and no - terminal failure; its prior review state is not approval. PR #104 is ready for review at + changes still require independent exact-head validation. PR #100's current + documentation head is + `1604d8eda51a288a41ea5ac4cede4bfc77b59d2d`, with two successful and 14 + queued Checks; its prior review state is not approval. PR #104 is ready for review at `0353001438efb060b85373c121f4d54dfd48e8c8`, intentionally based on #112's - lockfile head with no net lockfile change; its stacked Checks remain queued. + lockfile head with no net lockfile change; its current rollup has 21 + successful and one queued Check. #100 is current at + `1604d8eda51a288a41ea5ac4cede4bfc77b59d2d` with two successful and 14 + queued Checks; its prior review state is not approval. This record travels in these PRs, so the live PR records remain authoritative for their changing exact hashes. The active ruleset requires two approving reviews, resolved threads, and diff --git a/docs/product-technical-gap-baseline.md b/docs/product-technical-gap-baseline.md index 923b3e4..4360936 100644 --- a/docs/product-technical-gap-baseline.md +++ b/docs/product-technical-gap-baseline.md @@ -66,33 +66,34 @@ tenant, or resource ownership. The following is the current open-PR inventory. `Checks` means the exact head rollup observed on 2026-08-21; it is not inherited from a predecessor commit. -This record was refreshed after the PR #100 validator-coverage test fix at -`99fdd8601bf037f324e4b47e3c611ef19abd11d8` and the -intentional stacked-base rebase of PR #104. The live PR record is authoritative -for the exact hash and Checks; predecessor evidence remains non-transferable. - -At this snapshot, 14 PRs are open: three have 22 successful Checks with none -queued, and the other eleven have queued Checks without a terminal failure. -#110, #111, and #113 each have 18 successful Checks and two queued Checks after -their lock-refresh/external-security reruns. Queued Checks remain unverified -rather than green. +This record was refreshed after the final PR #100 documentation head +`1604d8eda51a288a41ea5ac4cede4bfc77b59d2d`, the normal #111 branch update from +the #112 lock-refresh base, and the exact-head Checks audit below. The live PR +record is authoritative for the exact hash and Checks; predecessor evidence +remains non-transferable. + +At this snapshot, 14 PRs are open. #112, #101, and #83 each have 23 successful +Checks with no queued Check; #111 has a new branch-update head with 14 queued +Checks and one completed success; the remaining PRs have queued Checks. The +historical terminal failures are recorded separately and are not current-head +green evidence. Queued Checks remain unverified rather than green. | PR | Scope | Exact-head Checks | Review state | Next safe action | |---:|---|---|---|---| -| [#113](https://github.com/ContextualWisdomLab/keyverse/pull/113) | SCIM `PATCH active=false` shared operation lock, stacked on #112 lockfile refresh | PENDING: 2 queued, 18 successful, 0 terminal failures on `50f19ec6338fb8eb959b8c797bdfa938e1071c87` | review required | The earlier GHCR Strix image-pull failure was rerun; wait for the fresh exact-head security result and independent review. | -| [#112](https://github.com/ContextualWisdomLab/keyverse/pull/112) | Resync account-unification lockfile | PASS: 22 Checks successful, 0 queued on `f02acf93367a40dbfb23a73985017dca8d42ff39` | review required | Obtain independent review, then let protected automation re-check and merge. | -| [#111](https://github.com/ContextualWisdomLab/keyverse/pull/111) | CodeQL init 4.37.7 | PENDING: 2 queued, 18 successful, 0 terminal failures on `e1d0fee6ce29cb9ec75d9fbdb38cd15242bf4fdc` | review required | Now stacked on #112; the stale-lock failure is cleared on the new base, so wait for the remaining exact-head Checks and independent review. | -| [#110](https://github.com/ContextualWisdomLab/keyverse/pull/110) | CodeQL analyze 4.37.7, stacked on #112 lockfile refresh | PENDING: 2 queued, 18 successful, 0 terminal failures on `07acd65145c9522a74858d1ff8761ea05a09e8f0` | review required | Treat as the companion of #111 on the refreshed #112 base; wait for the remaining exact-head Checks and do not merge the action pair independently. | -| [#109](https://github.com/ContextualWisdomLab/keyverse/pull/109) | `typing-inspection` update, stacked on #112 lockfile refresh | PENDING: 1 queued, 19 successful, 0 terminal failures on `28a4e05b23baa75d44b37589ba662a3c46c67129` | review required | Obtain independent review on the refreshed #112 base; do not treat the queued Check as green. | -| [#108](https://github.com/ContextualWisdomLab/keyverse/pull/108) | Ruff update, stacked on #112 lockfile refresh | PENDING: 14 queued, 0 terminal failures on `538cead991a7c1bed32f2dcb5413b5fc56f53e93` | review required | The conflicting lockfile base was rebased cleanly onto #112; wait for the fresh exact-head Checks and independent review. | -| [#107](https://github.com/ContextualWisdomLab/keyverse/pull/107) | Uvicorn update, stacked on #112 lockfile refresh | PENDING: 14 queued, 0 terminal failures on `53842560d397aa20309a6b16aceb560540611686` | review required | The conflicting lockfile base was rebased cleanly onto #112; wait for the fresh exact-head Checks and independent review. | -| [#106](https://github.com/ContextualWisdomLab/keyverse/pull/106) | `setup-uv` update, stacked on #112 lockfile refresh | PENDING: 1 queued, 19 successful, 0 terminal failures on `2f0e3fb19a63db7f51cdadfeae6155cd469a0c91` | review required | Obtain independent review on the refreshed #112 base; do not treat the queued Check as green. | -| [#105](https://github.com/ContextualWisdomLab/keyverse/pull/105) | `harden-runner` update, stacked on #112 lockfile refresh | PENDING: 1 queued, 19 successful, 0 terminal failures on `ef03c5a93c891980588b125f6c774fa84bf0feef` | changes requested | Re-evaluate the prior requested changes against this refreshed #112 base and obtain current-head independent review. | -| [#104](https://github.com/ContextualWisdomLab/keyverse/pull/104) | ADR and buyer README expansion, stacked on #112 | PENDING: 14 Checks queued, 0 terminal failures on `0353001438efb060b85373c121f4d54dfd48e8c8` | review required | Base is intentionally `fix/account-unification-lock-20260819`; the net diff has no lockfile change. Obtain independent review and terminal stacked-head Checks. | +| [#113](https://github.com/ContextualWisdomLab/keyverse/pull/113) | SCIM `PATCH active=false` shared operation lock, stacked on #112 lockfile refresh | PENDING: 1 queued, 22 successful, 0 terminal failures on `50f19ec6338fb8eb959b8c797bdfa938e1071c87` | review required | The earlier GHCR Strix image-pull failure was rerun; wait for the fresh exact-head security result and independent review. | +| [#112](https://github.com/ContextualWisdomLab/keyverse/pull/112) | Resync account-unification lockfile | PASS: 23 Checks successful, 0 queued on `f02acf93367a40dbfb23a73985017dca8d42ff39` | review required | Obtain independent review, then let protected automation re-check and merge. | +| [#111](https://github.com/ContextualWisdomLab/keyverse/pull/111) | CodeQL init 4.37.7 | PENDING: 14 queued, 1 successful, 0 terminal failures on updated head `032f730b0239d062cf9803525ba66c740e0b2d2e` | review required | The normal branch update merged #112's lockfile base into the CodeQL branch; wait for fresh exact-head Checks and independent review. | +| [#110](https://github.com/ContextualWisdomLab/keyverse/pull/110) | CodeQL analyze 4.37.7, stacked on #112 lockfile refresh | PENDING: 2 queued, 20 successful, 0 terminal failures on `07acd65145c9522a74858d1ff8761ea05a09e8f0` | review required | Treat as the companion of #111 on the refreshed #112 base; wait for the remaining exact-head Checks and do not merge the action pair independently. | +| [#109](https://github.com/ContextualWisdomLab/keyverse/pull/109) | `typing-inspection` update, stacked on #112 lockfile refresh | PENDING: 1 queued, 21 successful, 0 terminal failures on `28a4e05b23baa75d44b37589ba662a3c46c67129` | review required | Obtain independent review on the refreshed #112 base; do not treat the queued Check as green. | +| [#108](https://github.com/ContextualWisdomLab/keyverse/pull/108) | Ruff update, stacked on #112 lockfile refresh | PENDING: 14 queued, 1 successful, 0 terminal failures on `538cead991a7c1bed32f2dcb5413b5fc56f53e93` | review required | The conflicting lockfile base was rebased cleanly onto #112; wait for the fresh exact-head Checks and independent review. | +| [#107](https://github.com/ContextualWisdomLab/keyverse/pull/107) | Uvicorn update, stacked on #112 lockfile refresh | PENDING: 14 queued, 1 successful, 0 terminal failures on `53842560d397aa20309a6b16aceb560540611686` | review required | The conflicting lockfile base was rebased cleanly onto #112; wait for the fresh exact-head Checks and independent review. | +| [#106](https://github.com/ContextualWisdomLab/keyverse/pull/106) | `setup-uv` update, stacked on #112 lockfile refresh | PENDING: 1 queued, 21 successful, 0 terminal failures on `2f0e3fb19a63db7f51cdadfeae6155cd469a0c91` | review required | Obtain independent review on the refreshed #112 base; do not treat the queued Check as green. | +| [#105](https://github.com/ContextualWisdomLab/keyverse/pull/105) | `harden-runner` update, stacked on #112 lockfile refresh | PENDING: 1 queued, 21 successful, 0 terminal failures on `ef03c5a93c891980588b125f6c774fa84bf0feef` | changes requested | Re-evaluate the prior requested changes against this refreshed #112 base and obtain current-head independent review. | +| [#104](https://github.com/ContextualWisdomLab/keyverse/pull/104) | ADR and buyer README expansion, stacked on #112 | PENDING: 1 queued, 21 successful, 0 terminal failures on `0353001438efb060b85373c121f4d54dfd48e8c8` | review required | Base is intentionally `fix/account-unification-lock-20260819`; the net diff has no lockfile change. Obtain independent review and terminal stacked-head Checks. | | [#103](https://github.com/ContextualWisdomLab/keyverse/pull/103) | Hierarchical authorization, login helper, PATs | PENDING: required Checks still pending/queued, 0 terminal failures on `9274d3184443fba6c6294e08dff20734f3ae6fb4` | changes requested; fresh review requested | Fresh head adds inactive/expired token-rotation denial, compensating token lifecycle recovery, separate runtime service authentication, tenant-qualified grant/combination isolation, software-unit ABAC, and trusted issuer binding; wait for exact-head security Checks and independent review before any merge claim. | -| [#101](https://github.com/ContextualWisdomLab/keyverse/pull/101) | Atomic coupled Python dependency updates | PASS: 22 Checks successful, 0 queued on `50dd9c96cab5c230f775685e8baea939fba390dd` | changes requested | Obtain fresh independent review; this is the policy companion to the lockfile gap. | -| [#100](https://github.com/ContextualWisdomLab/keyverse/pull/100) | `lineageweave-web` account-derived claims plus default validator-path coverage | PENDING: 14 Checks queued, 0 terminal failures on `99fdd8601bf037f324e4b47e3c611ef19abd11d8` | changes requested; fresh review requested | The documentation successor records current #103 token-rotation evidence; obtain current-head review without self-approval. | -| [#83](https://github.com/ContextualWisdomLab/keyverse/pull/83) | Remove runtime application RPs from portable realm | PASS: 22 Checks successful, 0 queued on `dd1ab7444a75342b42e3af013ccda6d1dbfb359d` | changes requested | Reconfirm current-head approval and latest-pusher rule before protected merge. | +| [#101](https://github.com/ContextualWisdomLab/keyverse/pull/101) | Atomic coupled Python dependency updates | PASS: 23 Checks successful, 0 queued on `50dd9c96cab5c230f775685e8baea939fba390dd` | changes requested | Obtain fresh independent review; this is the policy companion to the lockfile gap. | +| [#100](https://github.com/ContextualWisdomLab/keyverse/pull/100) | `lineageweave-web` account-derived claims plus default validator-path coverage | PENDING: 14 queued, 2 successful, 0 terminal failures on `1604d8eda51a288a41ea5ac4cede4bfc77b59d2d` | changes requested; fresh review requested | The documentation successor records current #103 token-rotation evidence; obtain current-head review without self-approval. | +| [#83](https://github.com/ContextualWisdomLab/keyverse/pull/83) | Remove runtime application RPs from portable realm | PASS: 23 Checks successful, 0 queued on `dd1ab7444a75342b42e3af013ccda6d1dbfb359d` | changes requested | Reconfirm current-head approval and latest-pusher rule before protected merge. | ### Historical check failure root causes observed @@ -108,10 +109,12 @@ evidence. required after the external image service recovers; no code change can make that exact failed run green. -- PR #111's exact-head `account-unification-tests` failure stopped before tests - at `uv sync --locked`: the branch carries a stale `uv.lock`. PR #112 is the - existing lock-refresh prerequisite; rebase or regenerate #111 only after - the protected dependency sequence is resolved. +- PR #111's prior exact-head `account-unification-tests` failure stopped before + tests at `uv sync --locked`: the branch tree did not contain the #112 lock + refresh even though its PR base had been retargeted. The normal, non-force + `gh pr update-branch 111` operation merged #112's base into the branch and + produced current head `032f730b`; its fresh `account-unification-tests` run + is queued, so the old failure is historical and the new result is unverified. - The representative account-test failure on Dependabot PRs stopped at `uv sync --locked`: the checked-in lockfile needed updating. This is a From 899fb2061e20ce8a731db6972252bc81191ace07 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 21 Aug 2026 10:22:53 +0900 Subject: [PATCH 51/70] docs: correct live gap snapshot --- docs/doctoring/product-technical-gap-baseline.md | 9 +++++---- docs/product-technical-gap-baseline.md | 4 ++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/docs/doctoring/product-technical-gap-baseline.md b/docs/doctoring/product-technical-gap-baseline.md index 129cff8..313d7a1 100644 --- a/docs/doctoring/product-technical-gap-baseline.md +++ b/docs/doctoring/product-technical-gap-baseline.md @@ -162,8 +162,9 @@ https://www.rfc-editor.org/rfc/rfc8725.html and #83 each have 23 successful Checks with no queued run. #111's normal branch update created current head `032f730b0239d062cf9803525ba66c740e0b2d2e` with 14 queued Checks and one completed success; #113 has 22 successful and - one queued Check; #100 and #103 each have two successful and 14 queued - Checks. No current open PR has a qualifying formal approval. Queued Checks + one queued Check; #100 has one successful and 15 queued Checks, while #103 + has two successful and 14 queued Checks. No current open PR has a qualifying + formal approval. Queued Checks remain unverified. PR #113's current SCIM lock head `50f19ec6338fb8eb959b8c797bdfa938e1071c87` includes the normal prerequisite @@ -213,12 +214,12 @@ https://www.rfc-editor.org/rfc/rfc8725.html are not claimed. The operator-admin trust boundary and the fresh security changes still require independent exact-head validation. PR #100's current documentation head is - `1604d8eda51a288a41ea5ac4cede4bfc77b59d2d`, with two successful and 14 + `dbfea1419823d106be5f027d65c600891c01f007`, with one successful and 15 queued Checks; its prior review state is not approval. PR #104 is ready for review at `0353001438efb060b85373c121f4d54dfd48e8c8`, intentionally based on #112's lockfile head with no net lockfile change; its current rollup has 21 successful and one queued Check. #100 is current at - `1604d8eda51a288a41ea5ac4cede4bfc77b59d2d` with two successful and 14 + `dbfea1419823d106be5f027d65c600891c01f007` with one successful and 15 queued Checks; its prior review state is not approval. This record travels in these PRs, so the live PR records remain authoritative for their changing exact hashes. diff --git a/docs/product-technical-gap-baseline.md b/docs/product-technical-gap-baseline.md index 4360936..0d4776c 100644 --- a/docs/product-technical-gap-baseline.md +++ b/docs/product-technical-gap-baseline.md @@ -67,7 +67,7 @@ tenant, or resource ownership. The following is the current open-PR inventory. `Checks` means the exact head rollup observed on 2026-08-21; it is not inherited from a predecessor commit. This record was refreshed after the final PR #100 documentation head -`1604d8eda51a288a41ea5ac4cede4bfc77b59d2d`, the normal #111 branch update from +`dbfea1419823d106be5f027d65c600891c01f007`, the normal #111 branch update from the #112 lock-refresh base, and the exact-head Checks audit below. The live PR record is authoritative for the exact hash and Checks; predecessor evidence remains non-transferable. @@ -92,7 +92,7 @@ green evidence. Queued Checks remain unverified rather than green. | [#104](https://github.com/ContextualWisdomLab/keyverse/pull/104) | ADR and buyer README expansion, stacked on #112 | PENDING: 1 queued, 21 successful, 0 terminal failures on `0353001438efb060b85373c121f4d54dfd48e8c8` | review required | Base is intentionally `fix/account-unification-lock-20260819`; the net diff has no lockfile change. Obtain independent review and terminal stacked-head Checks. | | [#103](https://github.com/ContextualWisdomLab/keyverse/pull/103) | Hierarchical authorization, login helper, PATs | PENDING: required Checks still pending/queued, 0 terminal failures on `9274d3184443fba6c6294e08dff20734f3ae6fb4` | changes requested; fresh review requested | Fresh head adds inactive/expired token-rotation denial, compensating token lifecycle recovery, separate runtime service authentication, tenant-qualified grant/combination isolation, software-unit ABAC, and trusted issuer binding; wait for exact-head security Checks and independent review before any merge claim. | | [#101](https://github.com/ContextualWisdomLab/keyverse/pull/101) | Atomic coupled Python dependency updates | PASS: 23 Checks successful, 0 queued on `50dd9c96cab5c230f775685e8baea939fba390dd` | changes requested | Obtain fresh independent review; this is the policy companion to the lockfile gap. | -| [#100](https://github.com/ContextualWisdomLab/keyverse/pull/100) | `lineageweave-web` account-derived claims plus default validator-path coverage | PENDING: 14 queued, 2 successful, 0 terminal failures on `1604d8eda51a288a41ea5ac4cede4bfc77b59d2d` | changes requested; fresh review requested | The documentation successor records current #103 token-rotation evidence; obtain current-head review without self-approval. | +| [#100](https://github.com/ContextualWisdomLab/keyverse/pull/100) | `lineageweave-web` account-derived claims plus default validator-path coverage | PENDING: 15 queued, 1 successful, 0 terminal failures on `dbfea1419823d106be5f027d65c600891c01f007` | changes requested; fresh review requested | The documentation successor records current #103 token-rotation evidence; obtain current-head review without self-approval. | | [#83](https://github.com/ContextualWisdomLab/keyverse/pull/83) | Remove runtime application RPs from portable realm | PASS: 23 Checks successful, 0 queued on `dd1ab7444a75342b42e3af013ccda6d1dbfb359d` | changes requested | Reconfirm current-head approval and latest-pusher rule before protected merge. | ### Historical check failure root causes observed From f2c4a1508fb3bb51873243db1b5a0d910a78b8ee Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 21 Aug 2026 10:29:51 +0900 Subject: [PATCH 52/70] docs: record stacked dependency updates --- .../product-technical-gap-baseline.md | 26 ++++++++++--------- docs/product-technical-gap-baseline.md | 22 ++++++++-------- 2 files changed, 25 insertions(+), 23 deletions(-) diff --git a/docs/doctoring/product-technical-gap-baseline.md b/docs/doctoring/product-technical-gap-baseline.md index 313d7a1..a7a902b 100644 --- a/docs/doctoring/product-technical-gap-baseline.md +++ b/docs/doctoring/product-technical-gap-baseline.md @@ -183,18 +183,21 @@ https://www.rfc-editor.org/rfc/rfc8725.html failure occurred before that update; the fresh run is queued and remains unverified. It remains coupled to #112 and #110. PR #110's current head `07acd65145c9522a74858d1ff8761ea05a09e8f0` remains on the #112 base with - 20 successful Checks and two queued Checks; its hosted reruns remain - unverified. + `c3e307fc3d4f6d98ec5a0514f35aa8038b2737b7` has one completed success and 14 + queued Checks; its hosted reruns remain unverified. The historical PR #105 exact head `72de5499d6e97ae7f7bd804ab78b3e1644dd5a4f` had a failed `account-unification-tests` Check: `uv 0.12.5` reproduced `uv sync --locked` refusing the stale `coverage==7.15.2` and `setuptools==83.0.0` lock entries while the current `pyproject.toml` required `7.15.4` and `84.0.0`; the current #105 head - `ef03c5a93c891980588b125f6c774fa84bf0feef` is stacked on #112 and has - 21 successful Checks plus one queued Check with no terminal failure. The - current #106 and #109 heads remain stacked on #112 with 21 successful Checks - and one queued Check each. + `77f83dfb2c4611345c0d48f92fceaa6195b4630c` is stacked on #112 and has one + completed success plus 14 queued Checks with no terminal failure. The + current #106 head `e7fafd4192cc3cc344b8f8e536bc0495afaa739f` likewise has + one completed success and 14 queued Checks. PR #109's merged head + `7b726b16d38ce16d13d00c946b5c8bc0c406191f` has 15 queued Checks; local + locked-install, full pytest, Ruff, Interrogate, and compileall verification + passed before its normal merge commit was pushed. PR #107 was rebased cleanly onto #112 at `53842560d397aa20309a6b16aceb560540611686`, and PR #108 was rebased cleanly onto #112 at `538cead991a7c1bed32f2dcb5413b5fc56f53e93`; each now has one @@ -214,12 +217,11 @@ https://www.rfc-editor.org/rfc/rfc8725.html are not claimed. The operator-admin trust boundary and the fresh security changes still require independent exact-head validation. PR #100's current documentation head is - `dbfea1419823d106be5f027d65c600891c01f007`, with one successful and 15 - queued Checks; its prior review state is not approval. PR #104 is ready for review at - `0353001438efb060b85373c121f4d54dfd48e8c8`, intentionally based on #112's - lockfile head with no net lockfile change; its current rollup has 21 - successful and one queued Check. #100 is current at - `dbfea1419823d106be5f027d65c600891c01f007` with one successful and 15 + `899fb2061e20ce8a731db6972252bc81191ace07`, with one successful and 15 + queued Checks; its prior review state is not approval. PR #104's updated + head `7da9d43087d5647fefb946eb154ee1e5c10c576d` is based on #112's lockfile + head and has two successful plus 14 queued Checks. #100 is current at + `899fb2061e20ce8a731db6972252bc81191ace07` with one successful and 15 queued Checks; its prior review state is not approval. This record travels in these PRs, so the live PR records remain authoritative for their changing exact hashes. diff --git a/docs/product-technical-gap-baseline.md b/docs/product-technical-gap-baseline.md index 0d4776c..ee081f0 100644 --- a/docs/product-technical-gap-baseline.md +++ b/docs/product-technical-gap-baseline.md @@ -66,11 +66,11 @@ tenant, or resource ownership. The following is the current open-PR inventory. `Checks` means the exact head rollup observed on 2026-08-21; it is not inherited from a predecessor commit. -This record was refreshed after the final PR #100 documentation head -`dbfea1419823d106be5f027d65c600891c01f007`, the normal #111 branch update from -the #112 lock-refresh base, and the exact-head Checks audit below. The live PR -record is authoritative for the exact hash and Checks; predecessor evidence -remains non-transferable. +This record was refreshed after PR #100 documentation head +`899fb2061e20ce8a731db6972252bc81191ace07`, normal branch updates from the +#112 lock-refresh base for the dependency/documentation stack, and the +exact-head Checks audit below. The live PR record is authoritative for the +exact hash and Checks; predecessor evidence remains non-transferable. At this snapshot, 14 PRs are open. #112, #101, and #83 each have 23 successful Checks with no queued Check; #111 has a new branch-update head with 14 queued @@ -83,16 +83,16 @@ green evidence. Queued Checks remain unverified rather than green. | [#113](https://github.com/ContextualWisdomLab/keyverse/pull/113) | SCIM `PATCH active=false` shared operation lock, stacked on #112 lockfile refresh | PENDING: 1 queued, 22 successful, 0 terminal failures on `50f19ec6338fb8eb959b8c797bdfa938e1071c87` | review required | The earlier GHCR Strix image-pull failure was rerun; wait for the fresh exact-head security result and independent review. | | [#112](https://github.com/ContextualWisdomLab/keyverse/pull/112) | Resync account-unification lockfile | PASS: 23 Checks successful, 0 queued on `f02acf93367a40dbfb23a73985017dca8d42ff39` | review required | Obtain independent review, then let protected automation re-check and merge. | | [#111](https://github.com/ContextualWisdomLab/keyverse/pull/111) | CodeQL init 4.37.7 | PENDING: 14 queued, 1 successful, 0 terminal failures on updated head `032f730b0239d062cf9803525ba66c740e0b2d2e` | review required | The normal branch update merged #112's lockfile base into the CodeQL branch; wait for fresh exact-head Checks and independent review. | -| [#110](https://github.com/ContextualWisdomLab/keyverse/pull/110) | CodeQL analyze 4.37.7, stacked on #112 lockfile refresh | PENDING: 2 queued, 20 successful, 0 terminal failures on `07acd65145c9522a74858d1ff8761ea05a09e8f0` | review required | Treat as the companion of #111 on the refreshed #112 base; wait for the remaining exact-head Checks and do not merge the action pair independently. | -| [#109](https://github.com/ContextualWisdomLab/keyverse/pull/109) | `typing-inspection` update, stacked on #112 lockfile refresh | PENDING: 1 queued, 21 successful, 0 terminal failures on `28a4e05b23baa75d44b37589ba662a3c46c67129` | review required | Obtain independent review on the refreshed #112 base; do not treat the queued Check as green. | +| [#110](https://github.com/ContextualWisdomLab/keyverse/pull/110) | CodeQL analyze 4.37.7, stacked on #112 lockfile refresh | PENDING: 14 queued, 1 successful, 0 terminal failures on updated head `c3e307fc3d4f6d98ec5a0514f35aa8038b2737b7` | review required | The normal branch update now includes #112's lock-refresh base; wait for fresh exact-head Checks and independent review. | +| [#109](https://github.com/ContextualWisdomLab/keyverse/pull/109) | `typing-inspection` update, stacked on #112 lockfile refresh | PENDING: 15 queued, 0 terminal failures on merged head `7b726b16d38ce16d13d00c946b5c8bc0c406191f` | review required | The lock conflict was resolved by a normal merge commit and local locked-install/full-suite verification; wait for fresh hosted Checks and independent review. | | [#108](https://github.com/ContextualWisdomLab/keyverse/pull/108) | Ruff update, stacked on #112 lockfile refresh | PENDING: 14 queued, 1 successful, 0 terminal failures on `538cead991a7c1bed32f2dcb5413b5fc56f53e93` | review required | The conflicting lockfile base was rebased cleanly onto #112; wait for the fresh exact-head Checks and independent review. | | [#107](https://github.com/ContextualWisdomLab/keyverse/pull/107) | Uvicorn update, stacked on #112 lockfile refresh | PENDING: 14 queued, 1 successful, 0 terminal failures on `53842560d397aa20309a6b16aceb560540611686` | review required | The conflicting lockfile base was rebased cleanly onto #112; wait for the fresh exact-head Checks and independent review. | -| [#106](https://github.com/ContextualWisdomLab/keyverse/pull/106) | `setup-uv` update, stacked on #112 lockfile refresh | PENDING: 1 queued, 21 successful, 0 terminal failures on `2f0e3fb19a63db7f51cdadfeae6155cd469a0c91` | review required | Obtain independent review on the refreshed #112 base; do not treat the queued Check as green. | -| [#105](https://github.com/ContextualWisdomLab/keyverse/pull/105) | `harden-runner` update, stacked on #112 lockfile refresh | PENDING: 1 queued, 21 successful, 0 terminal failures on `ef03c5a93c891980588b125f6c774fa84bf0feef` | changes requested | Re-evaluate the prior requested changes against this refreshed #112 base and obtain current-head independent review. | -| [#104](https://github.com/ContextualWisdomLab/keyverse/pull/104) | ADR and buyer README expansion, stacked on #112 | PENDING: 1 queued, 21 successful, 0 terminal failures on `0353001438efb060b85373c121f4d54dfd48e8c8` | review required | Base is intentionally `fix/account-unification-lock-20260819`; the net diff has no lockfile change. Obtain independent review and terminal stacked-head Checks. | +| [#106](https://github.com/ContextualWisdomLab/keyverse/pull/106) | `setup-uv` update, stacked on #112 lockfile refresh | PENDING: 14 queued, 1 successful, 0 terminal failures on updated head `e7fafd4192cc3cc344b8f8e536bc0495afaa739f` | review required | The normal branch update now includes #112's lock-refresh base; wait for fresh exact-head Checks and independent review. | +| [#105](https://github.com/ContextualWisdomLab/keyverse/pull/105) | `harden-runner` update, stacked on #112 lockfile refresh | PENDING: 14 queued, 1 successful, 0 terminal failures on updated head `77f83dfb2c4611345c0d48f92fceaa6195b4630c` | changes requested | The normal branch update now includes #112's lock-refresh base; obtain current-head independent review. | +| [#104](https://github.com/ContextualWisdomLab/keyverse/pull/104) | ADR and buyer README expansion, stacked on #112 | PENDING: 14 queued, 2 successful, 0 terminal failures on updated head `7da9d43087d5647fefb946eb154ee1e5c10c576d` | review required | Base is intentionally `fix/account-unification-lock-20260819`; the normal branch update now includes the lock-refresh base. Obtain independent review and terminal stacked-head Checks. | | [#103](https://github.com/ContextualWisdomLab/keyverse/pull/103) | Hierarchical authorization, login helper, PATs | PENDING: required Checks still pending/queued, 0 terminal failures on `9274d3184443fba6c6294e08dff20734f3ae6fb4` | changes requested; fresh review requested | Fresh head adds inactive/expired token-rotation denial, compensating token lifecycle recovery, separate runtime service authentication, tenant-qualified grant/combination isolation, software-unit ABAC, and trusted issuer binding; wait for exact-head security Checks and independent review before any merge claim. | | [#101](https://github.com/ContextualWisdomLab/keyverse/pull/101) | Atomic coupled Python dependency updates | PASS: 23 Checks successful, 0 queued on `50dd9c96cab5c230f775685e8baea939fba390dd` | changes requested | Obtain fresh independent review; this is the policy companion to the lockfile gap. | -| [#100](https://github.com/ContextualWisdomLab/keyverse/pull/100) | `lineageweave-web` account-derived claims plus default validator-path coverage | PENDING: 15 queued, 1 successful, 0 terminal failures on `dbfea1419823d106be5f027d65c600891c01f007` | changes requested; fresh review requested | The documentation successor records current #103 token-rotation evidence; obtain current-head review without self-approval. | +| [#100](https://github.com/ContextualWisdomLab/keyverse/pull/100) | `lineageweave-web` account-derived claims plus default validator-path coverage | PENDING: 15 queued, 1 successful, 0 terminal failures on `899fb2061e20ce8a731db6972252bc81191ace07` | changes requested; fresh review requested | The documentation successor records current #103 token-rotation evidence; obtain current-head review without self-approval. | | [#83](https://github.com/ContextualWisdomLab/keyverse/pull/83) | Remove runtime application RPs from portable realm | PASS: 23 Checks successful, 0 queued on `dd1ab7444a75342b42e3af013ccda6d1dbfb359d` | changes requested | Reconfirm current-head approval and latest-pusher rule before protected merge. | ### Historical check failure root causes observed From 58c6bb5b8ba5dd84dd7e3c73f4f629520ad0110c Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 21 Aug 2026 10:33:53 +0900 Subject: [PATCH 53/70] docs: record central coverage dependency --- docs/doctoring/product-technical-gap-baseline.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/doctoring/product-technical-gap-baseline.md b/docs/doctoring/product-technical-gap-baseline.md index a7a902b..92f1bef 100644 --- a/docs/doctoring/product-technical-gap-baseline.md +++ b/docs/doctoring/product-technical-gap-baseline.md @@ -130,6 +130,12 @@ placeholder credentials must not be committed to close it. failure; the cancelled scheduler run remains historical and the queued checks are unverified. Neither #1170 nor #1178 has qualifying formal approval or protected merge evidence. +- Central `.github` PR #1187 is open at exact head + `91c16ebf5187daad749ae57ec01d16cb7afec7b3` for scoped Rust coverage + evidence. Its current rollup has 8 successful, 16 pending, 15 skipped, and + 1 cancelled Check, with no terminal source failure; the cancelled + `scan-pr-queue` job has a newer queued retry. It has no qualifying formal + approval or protected merge evidence. - Keyverse's existing `Hourly product development` workflow remains active at `41 * * * *`; its latest observed scheduled runs succeeded. No duplicate scheduler was added. Activation of the central caller remains conditional on From bcd4b15220852cf85feaff4922ce6b2557d7688d Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 21 Aug 2026 10:52:02 +0900 Subject: [PATCH 54/70] docs: refresh exact-head gap evidence --- .../product-technical-gap-baseline.md | 55 +++++++++++-------- docs/product-technical-gap-baseline.md | 32 ++++++----- 2 files changed, 51 insertions(+), 36 deletions(-) diff --git a/docs/doctoring/product-technical-gap-baseline.md b/docs/doctoring/product-technical-gap-baseline.md index 92f1bef..85aa7a0 100644 --- a/docs/doctoring/product-technical-gap-baseline.md +++ b/docs/doctoring/product-technical-gap-baseline.md @@ -120,22 +120,30 @@ placeholder credentials must not be committed to close it. `.github` PR #1178; it must not be reopened or merged while #1178 owns this dispatch boundary. Central PR #1183 is also closed without merge. - Central `.github` PR #1170 is open at exact head - `4684f6e212ba40d12e5217f0f52ee1e90c796ed8` after the gateway fallback/privacy/ - reasoning fixes and the final docstring repair. Its current hosted rollup has - 16 queued Checks, 2 successes, and no terminal failure. + `01b8cacc155993f20306589ebbf17a1114cf7344` for routing OpenCode reviews + through the contextual gateway. Its current hosted rollup has 1 successful, + 2 pending, 17 cancelled, and 13 skipped Checks; no terminal source failure + or qualifying formal approval is recorded. - Central `.github` PR #1178 is the canonical contextual-orchestrator hourly caller, open at exact head - `97b084ac28b5ccf6de7f68fd2e019d8da6f80143`. Its current rollup has 18 - successful, 7 queued, 3 neutral, and 1 cancelled Check with no terminal - failure; the cancelled scheduler run remains historical and the queued - checks are unverified. Neither #1170 nor #1178 has qualifying formal approval - or protected merge evidence. + `97b084ac28b5ccf6de7f68fd2e019d8da6f80143`. Its current rollup has 26 + successful and 2 pending Checks, with 18 skipped and no terminal source + failure. Neither #1170 nor #1178 has qualifying formal approval or protected + merge evidence. +- Central `.github` PR #1176 is open at exact head + `33b85a8cf48d5b6e0880d5071b360ffa46f83457` to require central reviews for + stacked PRs. Its current rollup has 25 successful and 6 pending Checks, with + 18 skipped and no qualifying formal approval. - Central `.github` PR #1187 is open at exact head `91c16ebf5187daad749ae57ec01d16cb7afec7b3` for scoped Rust coverage evidence. Its current rollup has 8 successful, 16 pending, 15 skipped, and 1 cancelled Check, with no terminal source failure; the cancelled `scan-pr-queue` job has a newer queued retry. It has no qualifying formal approval or protected merge evidence. +- Central `.github` PR #1152 is open at exact head + `11491068712859e936e7ce4ed7f204f5c1157f0c` for the OpenCode retry path. Its + current rollup has 3 successful and 16 pending Checks, with 13 skipped and + no terminal source failure or qualifying formal approval. - Keyverse's existing `Hourly product development` workflow remains active at `41 * * * *`; its latest observed scheduled runs succeeded. No duplicate scheduler was added. Activation of the central caller remains conditional on @@ -168,8 +176,9 @@ https://www.rfc-editor.org/rfc/rfc8725.html and #83 each have 23 successful Checks with no queued run. #111's normal branch update created current head `032f730b0239d062cf9803525ba66c740e0b2d2e` with 14 queued Checks and one completed success; #113 has 22 successful and - one queued Check; #100 has one successful and 15 queued Checks, while #103 - has two successful and 14 queued Checks. No current open PR has a qualifying + one queued Check; #108 has 14 successful and six queued, #107 has 19 + successful and two queued, and #100 has two successful and 14 queued Checks. + No current open PR has a qualifying formal approval. Queued Checks remain unverified. PR #113's current SCIM lock head @@ -188,9 +197,9 @@ https://www.rfc-editor.org/rfc/rfc8725.html through a normal branch update. Its prior `account-unification-tests` failure occurred before that update; the fresh run is queued and remains unverified. It remains coupled to #112 and #110. PR #110's current head - `07acd65145c9522a74858d1ff8761ea05a09e8f0` remains on the #112 base with - `c3e307fc3d4f6d98ec5a0514f35aa8038b2737b7` has one completed success and 14 - queued Checks; its hosted reruns remain unverified. + `c3e307fc3d4f6d98ec5a0514f35aa8038b2737b7` remains on the #112 base with + one completed success and 14 queued Checks; its hosted reruns remain + unverified. The historical PR #105 exact head `72de5499d6e97ae7f7bd804ab78b3e1644dd5a4f` had a failed `account-unification-tests` Check: `uv 0.12.5` reproduced @@ -201,13 +210,15 @@ https://www.rfc-editor.org/rfc/rfc8725.html completed success plus 14 queued Checks with no terminal failure. The current #106 head `e7fafd4192cc3cc344b8f8e536bc0495afaa739f` likewise has one completed success and 14 queued Checks. PR #109's merged head - `7b726b16d38ce16d13d00c946b5c8bc0c406191f` has 15 queued Checks; local + `7b726b16d38ce16d13d00c946b5c8bc0c406191f` has one completed success and 14 + queued Checks; local locked-install, full pytest, Ruff, Interrogate, and compileall verification passed before its normal merge commit was pushed. PR #107 was rebased cleanly onto #112 at `53842560d397aa20309a6b16aceb560540611686`, and PR #108 was rebased cleanly - onto #112 at `538cead991a7c1bed32f2dcb5413b5fc56f53e93`; each now has one - completed success and 14 queued Checks with no terminal failure. Local + onto #112 at `538cead991a7c1bed32f2dcb5413b5fc56f53e93`; the latest rollups + are 19 successful plus two queued for #107 and 14 successful plus six queued + for #108, with no terminal failure. Local `uv sync --locked --extra dev` plus the full service pytest suite passed on both rebased trees. Their fresh hosted Checks remain unverified and #112 remains the lock-refresh prerequisite. @@ -221,14 +232,14 @@ https://www.rfc-editor.org/rfc/rfc8725.html 100% application statement/branch coverage pass; required hosted Checks are still pending or queued, so hosted security and independent approval success are not claimed. The operator-admin trust boundary and the fresh security - changes still require independent exact-head validation. PR #100's current - documentation head is - `899fb2061e20ce8a731db6972252bc81191ace07`, with one successful and 15 + changes still require independent exact-head validation. PR #100's + pre-refresh documentation head is + `58c6bb5b8ba5dd84dd7e3c73f4f629520ad0110c`, with two successful and 14 queued Checks; its prior review state is not approval. PR #104's updated head `7da9d43087d5647fefb946eb154ee1e5c10c576d` is based on #112's lockfile - head and has two successful plus 14 queued Checks. #100 is current at - `899fb2061e20ce8a731db6972252bc81191ace07` with one successful and 15 - queued Checks; its prior review state is not approval. + head and has two successful plus 14 queued Checks. The resulting #100 head + from this documentation refresh must be re-audited after the commit; its + pre-refresh review state is not approval. This record travels in these PRs, so the live PR records remain authoritative for their changing exact hashes. The active ruleset requires two approving reviews, resolved threads, and diff --git a/docs/product-technical-gap-baseline.md b/docs/product-technical-gap-baseline.md index ee081f0..3008a0e 100644 --- a/docs/product-technical-gap-baseline.md +++ b/docs/product-technical-gap-baseline.md @@ -66,17 +66,21 @@ tenant, or resource ownership. The following is the current open-PR inventory. `Checks` means the exact head rollup observed on 2026-08-21; it is not inherited from a predecessor commit. -This record was refreshed after PR #100 documentation head -`899fb2061e20ce8a731db6972252bc81191ace07`, normal branch updates from the -#112 lock-refresh base for the dependency/documentation stack, and the -exact-head Checks audit below. The live PR record is authoritative for the +This record was refreshed from a live exact-head audit while PR #100 stood at +`58c6bb5b8ba5dd84dd7e3c73f4f629520ad0110c`; the documentation commit that +updates this snapshot is intentionally not recursively named. The audit also +includes normal branch updates from the #112 lock-refresh base for the +dependency/documentation stack. The live PR record is authoritative for the exact hash and Checks; predecessor evidence remains non-transferable. -At this snapshot, 14 PRs are open. #112, #101, and #83 each have 23 successful -Checks with no queued Check; #111 has a new branch-update head with 14 queued -Checks and one completed success; the remaining PRs have queued Checks. The -historical terminal failures are recorded separately and are not current-head -green evidence. Queued Checks remain unverified rather than green. +At this snapshot, 14 PRs are open and none has a qualifying formal approval. +#112, #101, and #83 each have 23 successful Checks with no queued Check; +#113 has 22 successful and one queued Check; #108 has 14 successful and six +queued Checks; #107 has 19 successful and two queued Checks; #100 has two +successful and 14 queued Checks; and the remaining PRs have queued Checks. +There is no current terminal failure bucket in this inventory. Historical +terminal failures are recorded separately and are not current-head green +evidence. Queued Checks remain unverified rather than green. | PR | Scope | Exact-head Checks | Review state | Next safe action | |---:|---|---|---|---| @@ -84,15 +88,15 @@ green evidence. Queued Checks remain unverified rather than green. | [#112](https://github.com/ContextualWisdomLab/keyverse/pull/112) | Resync account-unification lockfile | PASS: 23 Checks successful, 0 queued on `f02acf93367a40dbfb23a73985017dca8d42ff39` | review required | Obtain independent review, then let protected automation re-check and merge. | | [#111](https://github.com/ContextualWisdomLab/keyverse/pull/111) | CodeQL init 4.37.7 | PENDING: 14 queued, 1 successful, 0 terminal failures on updated head `032f730b0239d062cf9803525ba66c740e0b2d2e` | review required | The normal branch update merged #112's lockfile base into the CodeQL branch; wait for fresh exact-head Checks and independent review. | | [#110](https://github.com/ContextualWisdomLab/keyverse/pull/110) | CodeQL analyze 4.37.7, stacked on #112 lockfile refresh | PENDING: 14 queued, 1 successful, 0 terminal failures on updated head `c3e307fc3d4f6d98ec5a0514f35aa8038b2737b7` | review required | The normal branch update now includes #112's lock-refresh base; wait for fresh exact-head Checks and independent review. | -| [#109](https://github.com/ContextualWisdomLab/keyverse/pull/109) | `typing-inspection` update, stacked on #112 lockfile refresh | PENDING: 15 queued, 0 terminal failures on merged head `7b726b16d38ce16d13d00c946b5c8bc0c406191f` | review required | The lock conflict was resolved by a normal merge commit and local locked-install/full-suite verification; wait for fresh hosted Checks and independent review. | -| [#108](https://github.com/ContextualWisdomLab/keyverse/pull/108) | Ruff update, stacked on #112 lockfile refresh | PENDING: 14 queued, 1 successful, 0 terminal failures on `538cead991a7c1bed32f2dcb5413b5fc56f53e93` | review required | The conflicting lockfile base was rebased cleanly onto #112; wait for the fresh exact-head Checks and independent review. | -| [#107](https://github.com/ContextualWisdomLab/keyverse/pull/107) | Uvicorn update, stacked on #112 lockfile refresh | PENDING: 14 queued, 1 successful, 0 terminal failures on `53842560d397aa20309a6b16aceb560540611686` | review required | The conflicting lockfile base was rebased cleanly onto #112; wait for the fresh exact-head Checks and independent review. | +| [#109](https://github.com/ContextualWisdomLab/keyverse/pull/109) | `typing-inspection` update, stacked on #112 lockfile refresh | PENDING: 14 queued, 1 successful, 0 terminal failures on merged head `7b726b16d38ce16d13d00c946b5c8bc0c406191f` | review required | The lock conflict was resolved by a normal merge commit and local locked-install/full-suite verification; wait for fresh hosted Checks and independent review. | +| [#108](https://github.com/ContextualWisdomLab/keyverse/pull/108) | Ruff update, stacked on #112 lockfile refresh | PENDING: 6 queued, 14 successful, 0 terminal failures on `538cead991a7c1bed32f2dcb5413b5fc56f53e93` | review required | The conflicting lockfile base was rebased cleanly onto #112; wait for the remaining exact-head Checks and independent review. | +| [#107](https://github.com/ContextualWisdomLab/keyverse/pull/107) | Uvicorn update, stacked on #112 lockfile refresh | PENDING: 2 queued, 19 successful, 0 terminal failures on `53842560d397aa20309a6b16aceb560540611686` | review required | The conflicting lockfile base was rebased cleanly onto #112; wait for the remaining exact-head Checks and independent review. | | [#106](https://github.com/ContextualWisdomLab/keyverse/pull/106) | `setup-uv` update, stacked on #112 lockfile refresh | PENDING: 14 queued, 1 successful, 0 terminal failures on updated head `e7fafd4192cc3cc344b8f8e536bc0495afaa739f` | review required | The normal branch update now includes #112's lock-refresh base; wait for fresh exact-head Checks and independent review. | | [#105](https://github.com/ContextualWisdomLab/keyverse/pull/105) | `harden-runner` update, stacked on #112 lockfile refresh | PENDING: 14 queued, 1 successful, 0 terminal failures on updated head `77f83dfb2c4611345c0d48f92fceaa6195b4630c` | changes requested | The normal branch update now includes #112's lock-refresh base; obtain current-head independent review. | | [#104](https://github.com/ContextualWisdomLab/keyverse/pull/104) | ADR and buyer README expansion, stacked on #112 | PENDING: 14 queued, 2 successful, 0 terminal failures on updated head `7da9d43087d5647fefb946eb154ee1e5c10c576d` | review required | Base is intentionally `fix/account-unification-lock-20260819`; the normal branch update now includes the lock-refresh base. Obtain independent review and terminal stacked-head Checks. | -| [#103](https://github.com/ContextualWisdomLab/keyverse/pull/103) | Hierarchical authorization, login helper, PATs | PENDING: required Checks still pending/queued, 0 terminal failures on `9274d3184443fba6c6294e08dff20734f3ae6fb4` | changes requested; fresh review requested | Fresh head adds inactive/expired token-rotation denial, compensating token lifecycle recovery, separate runtime service authentication, tenant-qualified grant/combination isolation, software-unit ABAC, and trusted issuer binding; wait for exact-head security Checks and independent review before any merge claim. | +| [#103](https://github.com/ContextualWisdomLab/keyverse/pull/103) | Hierarchical authorization, login helper, PATs | PENDING: 14 queued, 2 successful, 0 terminal failures on `9274d3184443fba6c6294e08dff20734f3ae6fb4` | changes requested; fresh review requested | Fresh head adds inactive/expired token-rotation denial, compensating token lifecycle recovery, separate runtime service authentication, tenant-qualified grant/combination isolation, software-unit ABAC, and trusted issuer binding; wait for exact-head security Checks and independent review before any merge claim. | | [#101](https://github.com/ContextualWisdomLab/keyverse/pull/101) | Atomic coupled Python dependency updates | PASS: 23 Checks successful, 0 queued on `50dd9c96cab5c230f775685e8baea939fba390dd` | changes requested | Obtain fresh independent review; this is the policy companion to the lockfile gap. | -| [#100](https://github.com/ContextualWisdomLab/keyverse/pull/100) | `lineageweave-web` account-derived claims plus default validator-path coverage | PENDING: 15 queued, 1 successful, 0 terminal failures on `899fb2061e20ce8a731db6972252bc81191ace07` | changes requested; fresh review requested | The documentation successor records current #103 token-rotation evidence; obtain current-head review without self-approval. | +| [#100](https://github.com/ContextualWisdomLab/keyverse/pull/100) | `lineageweave-web` account-derived claims plus default validator-path coverage | PENDING: 14 queued, 2 successful, 0 terminal failures on the pre-refresh snapshot head `58c6bb5b8ba5dd84dd7e3c73f4f629520ad0110c` | changes requested; fresh review requested | The documentation successor records current #103 token-rotation evidence; re-audit the resulting documentation head without self-approval. | | [#83](https://github.com/ContextualWisdomLab/keyverse/pull/83) | Remove runtime application RPs from portable realm | PASS: 23 Checks successful, 0 queued on `dd1ab7444a75342b42e3af013ccda6d1dbfb359d` | changes requested | Reconfirm current-head approval and latest-pusher rule before protected merge. | ### Historical check failure root causes observed From 6e0c92f7512ab8b1eded34e2e6ae9a0476896aba Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 21 Aug 2026 11:27:20 +0900 Subject: [PATCH 55/70] docs: refresh current queue evidence --- .../product-technical-gap-baseline.md | 88 +++++++++---------- docs/product-technical-gap-baseline.md | 45 ++++++---- 2 files changed, 70 insertions(+), 63 deletions(-) diff --git a/docs/doctoring/product-technical-gap-baseline.md b/docs/doctoring/product-technical-gap-baseline.md index 85aa7a0..fba5727 100644 --- a/docs/doctoring/product-technical-gap-baseline.md +++ b/docs/doctoring/product-technical-gap-baseline.md @@ -120,29 +120,31 @@ placeholder credentials must not be committed to close it. `.github` PR #1178; it must not be reopened or merged while #1178 owns this dispatch boundary. Central PR #1183 is also closed without merge. - Central `.github` PR #1170 is open at exact head - `01b8cacc155993f20306589ebbf17a1114cf7344` for routing OpenCode reviews - through the contextual gateway. Its current hosted rollup has 1 successful, - 2 pending, 17 cancelled, and 13 skipped Checks; no terminal source failure - or qualifying formal approval is recorded. + `1f2b93ead7205b33712de1865d84c004d93be7ed` for routing OpenCode reviews + through the contextual gateway. Its current hosted rollup has 4 successful, + 17 pending, and 13 skipped Checks; no terminal source failure or qualifying + formal approval is recorded. The current head removes inherited GitHub + credentials and workflow-file channels from the child gateway process and + has passed the focused contract test plus full local central verification. - Central `.github` PR #1178 is the canonical contextual-orchestrator hourly caller, open at exact head - `97b084ac28b5ccf6de7f68fd2e019d8da6f80143`. Its current rollup has 26 - successful and 2 pending Checks, with 18 skipped and no terminal source - failure. Neither #1170 nor #1178 has qualifying formal approval or protected + `97b084ac28b5ccf6de7f68fd2e019d8da6f80143`. Its current rollup has 25 + successful, 3 neutral, 2 pending, 1 cancelled, and 19 skipped Checks, with + no terminal source failure. Neither #1170 nor #1178 has qualifying formal approval or protected merge evidence. - Central `.github` PR #1176 is open at exact head `33b85a8cf48d5b6e0880d5071b360ffa46f83457` to require central reviews for - stacked PRs. Its current rollup has 25 successful and 6 pending Checks, with - 18 skipped and no qualifying formal approval. + stacked PRs. Its current rollup has 23 successful, 3 neutral, 6 pending, and + 15 skipped Checks, with no qualifying formal approval. - Central `.github` PR #1187 is open at exact head `91c16ebf5187daad749ae57ec01d16cb7afec7b3` for scoped Rust coverage - evidence. Its current rollup has 8 successful, 16 pending, 15 skipped, and + evidence. Its current rollup has 6 successful, 16 pending, 15 skipped, and 1 cancelled Check, with no terminal source failure; the cancelled `scan-pr-queue` job has a newer queued retry. It has no qualifying formal approval or protected merge evidence. - Central `.github` PR #1152 is open at exact head `11491068712859e936e7ce4ed7f204f5c1157f0c` for the OpenCode retry path. Its - current rollup has 3 successful and 16 pending Checks, with 13 skipped and + current rollup has 1 successful and 16 pending Checks, with 13 skipped and no terminal source failure or qualifying formal approval. - Keyverse's existing `Hourly product development` workflow remains active at `41 * * * *`; its latest observed scheduled runs succeeded. No duplicate @@ -173,52 +175,50 @@ https://www.rfc-editor.org/rfc/rfc8725.html and doctoring records. - Exact-head GitHub PR, review, issue, check-run, ruleset, and scheduled-run queries performed on 2026-08-21. Fourteen Keyverse PRs are open: #112, #101, - and #83 each have 23 successful Checks with no queued run. #111's normal - branch update created current head `032f730b0239d062cf9803525ba66c740e0b2d2e` - with 14 queued Checks and one completed success; #113 has 22 successful and - one queued Check; #108 has 14 successful and six queued, #107 has 19 - successful and two queued, and #100 has two successful and 14 queued Checks. - No current open PR has a qualifying - formal approval. Queued Checks - remain unverified. + and #83 each have 22 successful and 8 skipped Checks with no pending run. + #107 has 19 successful, 1 pending, and 8 skipped; #108 has 17 successful, + 2 pending, and 8 skipped; and #113, #100, #103, #104, #105, #106, #109, + #110, and #111 each have 14 pending and 7 skipped Checks. No current open PR + has a qualifying formal approval or terminal failure. Pending Checks remain + unverified. PR #113's current SCIM lock head - `50f19ec6338fb8eb959b8c797bdfa938e1071c87` includes the normal prerequisite - lockfile history and a realistic SCIM PatchOp race plus spawned-process - SQLite lock regression; its hosted Checks now have 22 successful runs and - one queued rerun with no terminal failure. The earlier Strix job could not - pull `ghcr.io/usestrix/strix-sandbox:1.3.0` because GHCR returned HTTP - 500/EOF, and it produced no structured vulnerability report, so that run - failed closed; the fresh exact-head rerun remains unverified while queued. - Its local RED-to-GREEN, root-level SCIM error-wire, and cross-process - sidecar evidence are not protected-main evidence. PR #112's lockfile head - `f02acf93367a40dbfb23a73985017dca8d42ff39` has 23 terminal-success Checks - but still requires independent review. PR #111's current head + `aaafc2ca2f42bc171c1a0d0b538a99eb2f461233` includes the normal prerequisite + lockfile history, a realistic SCIM PatchOp race, and the corrected valid + root-level deactivation payload. Its hosted Checks remain pending with no + terminal failure. Local focused/full verification and 100% statement/branch + coverage passed, but hosted security and independent approval remain + unverified. The earlier Strix job could not pull + `ghcr.io/usestrix/strix-sandbox:1.3.0` because GHCR returned HTTP 500/EOF and + produced no structured vulnerability report, so that run failed closed. + Its local RED-to-GREEN, root-level SCIM error-wire, and cross-process sidecar + evidence are not protected-main evidence. PR #112's lockfile head + `f02acf93367a40dbfb23a73985017dca8d42ff39` has 22 successful and 8 skipped + Checks but still requires independent review. PR #111's current head `032f730b0239d062cf9803525ba66c740e0b2d2e` now contains #112's lockfile through a normal branch update. Its prior `account-unification-tests` - failure occurred before that update; the fresh run is queued and remains - unverified. It remains coupled to #112 and #110. PR #110's current head + failure occurred before that update; the fresh run remains unverified. It + remains coupled to #112 and #110. PR #110's current head `c3e307fc3d4f6d98ec5a0514f35aa8038b2737b7` remains on the #112 base with - one completed success and 14 queued Checks; its hosted reruns remain - unverified. + 14 pending and 7 skipped Checks; its hosted reruns remain unverified. The historical PR #105 exact head `72de5499d6e97ae7f7bd804ab78b3e1644dd5a4f` had a failed `account-unification-tests` Check: `uv 0.12.5` reproduced `uv sync --locked` refusing the stale `coverage==7.15.2` and `setuptools==83.0.0` lock entries while the current `pyproject.toml` required `7.15.4` and `84.0.0`; the current #105 head - `77f83dfb2c4611345c0d48f92fceaa6195b4630c` is stacked on #112 and has one - completed success plus 14 queued Checks with no terminal failure. The + `77f83dfb2c4611345c0d48f92fceaa6195b4630c` is stacked on #112 and has 14 + pending and 7 skipped Checks with no terminal failure. The current #106 head `e7fafd4192cc3cc344b8f8e536bc0495afaa739f` likewise has - one completed success and 14 queued Checks. PR #109's merged head - `7b726b16d38ce16d13d00c946b5c8bc0c406191f` has one completed success and 14 - queued Checks; local + 14 pending and 7 skipped Checks. PR #109's head + `7b726b16d38ce16d13d00c946b5c8bc0c406191f` has 14 pending and 7 skipped + Checks; local locked-install, full pytest, Ruff, Interrogate, and compileall verification passed before its normal merge commit was pushed. PR #107 was rebased cleanly onto #112 at `53842560d397aa20309a6b16aceb560540611686`, and PR #108 was rebased cleanly onto #112 at `538cead991a7c1bed32f2dcb5413b5fc56f53e93`; the latest rollups - are 19 successful plus two queued for #107 and 14 successful plus six queued - for #108, with no terminal failure. Local + are 19 successful, 1 pending, and 8 skipped for #107 and 17 successful, + 2 pending, and 8 skipped for #108, with no terminal failure. Local `uv sync --locked --extra dev` plus the full service pytest suite passed on both rebased trees. Their fresh hosted Checks remain unverified and #112 remains the lock-refresh prerequisite. @@ -234,10 +234,10 @@ https://www.rfc-editor.org/rfc/rfc8725.html are not claimed. The operator-admin trust boundary and the fresh security changes still require independent exact-head validation. PR #100's pre-refresh documentation head is - `58c6bb5b8ba5dd84dd7e3c73f4f629520ad0110c`, with two successful and 14 - queued Checks; its prior review state is not approval. PR #104's updated + `bcd4b15220852cf85feaff4922ce6b2557d7688d`, with 14 pending and 7 skipped + Checks; its prior review state is not approval. PR #104's updated head `7da9d43087d5647fefb946eb154ee1e5c10c576d` is based on #112's lockfile - head and has two successful plus 14 queued Checks. The resulting #100 head + head and has 14 pending and 7 skipped Checks. The resulting #100 head from this documentation refresh must be re-audited after the commit; its pre-refresh review state is not approval. This record travels in these PRs, so the live PR records remain authoritative diff --git a/docs/product-technical-gap-baseline.md b/docs/product-technical-gap-baseline.md index 3008a0e..15c3389 100644 --- a/docs/product-technical-gap-baseline.md +++ b/docs/product-technical-gap-baseline.md @@ -67,37 +67,38 @@ tenant, or resource ownership. The following is the current open-PR inventory. `Checks` means the exact head rollup observed on 2026-08-21; it is not inherited from a predecessor commit. This record was refreshed from a live exact-head audit while PR #100 stood at -`58c6bb5b8ba5dd84dd7e3c73f4f629520ad0110c`; the documentation commit that +`bcd4b15220852cf85feaff4922ce6b2557d7688d`; the documentation commit that updates this snapshot is intentionally not recursively named. The audit also includes normal branch updates from the #112 lock-refresh base for the dependency/documentation stack. The live PR record is authoritative for the exact hash and Checks; predecessor evidence remains non-transferable. At this snapshot, 14 PRs are open and none has a qualifying formal approval. -#112, #101, and #83 each have 23 successful Checks with no queued Check; -#113 has 22 successful and one queued Check; #108 has 14 successful and six -queued Checks; #107 has 19 successful and two queued Checks; #100 has two -successful and 14 queued Checks; and the remaining PRs have queued Checks. +#112, #101, and #83 each have 22 successful and 8 skipped Checks with no +pending Check; #107 has 19 successful, 1 pending, and 8 skipped Checks; #108 +has 17 successful, 2 pending, and 8 skipped Checks; and #113, #100, #103, +#104, #105, #106, #109, #110, and #111 each have 14 pending and 7 skipped +Checks. There is no current terminal failure bucket in this inventory. Historical terminal failures are recorded separately and are not current-head green evidence. Queued Checks remain unverified rather than green. | PR | Scope | Exact-head Checks | Review state | Next safe action | |---:|---|---|---|---| -| [#113](https://github.com/ContextualWisdomLab/keyverse/pull/113) | SCIM `PATCH active=false` shared operation lock, stacked on #112 lockfile refresh | PENDING: 1 queued, 22 successful, 0 terminal failures on `50f19ec6338fb8eb959b8c797bdfa938e1071c87` | review required | The earlier GHCR Strix image-pull failure was rerun; wait for the fresh exact-head security result and independent review. | -| [#112](https://github.com/ContextualWisdomLab/keyverse/pull/112) | Resync account-unification lockfile | PASS: 23 Checks successful, 0 queued on `f02acf93367a40dbfb23a73985017dca8d42ff39` | review required | Obtain independent review, then let protected automation re-check and merge. | -| [#111](https://github.com/ContextualWisdomLab/keyverse/pull/111) | CodeQL init 4.37.7 | PENDING: 14 queued, 1 successful, 0 terminal failures on updated head `032f730b0239d062cf9803525ba66c740e0b2d2e` | review required | The normal branch update merged #112's lockfile base into the CodeQL branch; wait for fresh exact-head Checks and independent review. | -| [#110](https://github.com/ContextualWisdomLab/keyverse/pull/110) | CodeQL analyze 4.37.7, stacked on #112 lockfile refresh | PENDING: 14 queued, 1 successful, 0 terminal failures on updated head `c3e307fc3d4f6d98ec5a0514f35aa8038b2737b7` | review required | The normal branch update now includes #112's lock-refresh base; wait for fresh exact-head Checks and independent review. | -| [#109](https://github.com/ContextualWisdomLab/keyverse/pull/109) | `typing-inspection` update, stacked on #112 lockfile refresh | PENDING: 14 queued, 1 successful, 0 terminal failures on merged head `7b726b16d38ce16d13d00c946b5c8bc0c406191f` | review required | The lock conflict was resolved by a normal merge commit and local locked-install/full-suite verification; wait for fresh hosted Checks and independent review. | -| [#108](https://github.com/ContextualWisdomLab/keyverse/pull/108) | Ruff update, stacked on #112 lockfile refresh | PENDING: 6 queued, 14 successful, 0 terminal failures on `538cead991a7c1bed32f2dcb5413b5fc56f53e93` | review required | The conflicting lockfile base was rebased cleanly onto #112; wait for the remaining exact-head Checks and independent review. | -| [#107](https://github.com/ContextualWisdomLab/keyverse/pull/107) | Uvicorn update, stacked on #112 lockfile refresh | PENDING: 2 queued, 19 successful, 0 terminal failures on `53842560d397aa20309a6b16aceb560540611686` | review required | The conflicting lockfile base was rebased cleanly onto #112; wait for the remaining exact-head Checks and independent review. | -| [#106](https://github.com/ContextualWisdomLab/keyverse/pull/106) | `setup-uv` update, stacked on #112 lockfile refresh | PENDING: 14 queued, 1 successful, 0 terminal failures on updated head `e7fafd4192cc3cc344b8f8e536bc0495afaa739f` | review required | The normal branch update now includes #112's lock-refresh base; wait for fresh exact-head Checks and independent review. | -| [#105](https://github.com/ContextualWisdomLab/keyverse/pull/105) | `harden-runner` update, stacked on #112 lockfile refresh | PENDING: 14 queued, 1 successful, 0 terminal failures on updated head `77f83dfb2c4611345c0d48f92fceaa6195b4630c` | changes requested | The normal branch update now includes #112's lock-refresh base; obtain current-head independent review. | -| [#104](https://github.com/ContextualWisdomLab/keyverse/pull/104) | ADR and buyer README expansion, stacked on #112 | PENDING: 14 queued, 2 successful, 0 terminal failures on updated head `7da9d43087d5647fefb946eb154ee1e5c10c576d` | review required | Base is intentionally `fix/account-unification-lock-20260819`; the normal branch update now includes the lock-refresh base. Obtain independent review and terminal stacked-head Checks. | -| [#103](https://github.com/ContextualWisdomLab/keyverse/pull/103) | Hierarchical authorization, login helper, PATs | PENDING: 14 queued, 2 successful, 0 terminal failures on `9274d3184443fba6c6294e08dff20734f3ae6fb4` | changes requested; fresh review requested | Fresh head adds inactive/expired token-rotation denial, compensating token lifecycle recovery, separate runtime service authentication, tenant-qualified grant/combination isolation, software-unit ABAC, and trusted issuer binding; wait for exact-head security Checks and independent review before any merge claim. | -| [#101](https://github.com/ContextualWisdomLab/keyverse/pull/101) | Atomic coupled Python dependency updates | PASS: 23 Checks successful, 0 queued on `50dd9c96cab5c230f775685e8baea939fba390dd` | changes requested | Obtain fresh independent review; this is the policy companion to the lockfile gap. | -| [#100](https://github.com/ContextualWisdomLab/keyverse/pull/100) | `lineageweave-web` account-derived claims plus default validator-path coverage | PENDING: 14 queued, 2 successful, 0 terminal failures on the pre-refresh snapshot head `58c6bb5b8ba5dd84dd7e3c73f4f629520ad0110c` | changes requested; fresh review requested | The documentation successor records current #103 token-rotation evidence; re-audit the resulting documentation head without self-approval. | -| [#83](https://github.com/ContextualWisdomLab/keyverse/pull/83) | Remove runtime application RPs from portable realm | PASS: 23 Checks successful, 0 queued on `dd1ab7444a75342b42e3af013ccda6d1dbfb359d` | changes requested | Reconfirm current-head approval and latest-pusher rule before protected merge. | +| [#113](https://github.com/ContextualWisdomLab/keyverse/pull/113) | SCIM `PATCH active=false` shared operation lock, stacked on #112 lockfile refresh | PENDING: 14 pending, 7 skipped, 0 terminal failures on `aaafc2ca2f42bc171c1a0d0b538a99eb2f461233` | requested changes fixed; approval absent | The valid SCIM PatchOp review fix and local full verification are complete; wait for fresh exact-head hosted Checks and independent review. | +| [#112](https://github.com/ContextualWisdomLab/keyverse/pull/112) | Resync account-unification lockfile | PASS: 22 successful, 8 skipped, 0 pending on `f02acf93367a40dbfb23a73985017dca8d42ff39` | review required | Obtain independent review, then let protected automation re-check and merge. | +| [#111](https://github.com/ContextualWisdomLab/keyverse/pull/111) | CodeQL init 4.37.7 | PENDING: 14 pending, 7 skipped, 0 terminal failures on updated head `032f730b0239d062cf9803525ba66c740e0b2d2e` | review required | The normal branch update merged #112's lockfile base into the CodeQL branch; wait for exact-head Checks and independent review. | +| [#110](https://github.com/ContextualWisdomLab/keyverse/pull/110) | CodeQL analyze 4.37.7, stacked on #112 lockfile refresh | PENDING: 14 pending, 7 skipped, 0 terminal failures on updated head `c3e307fc3d4f6d98ec5a0514f35aa8038b2737b7` | review required | The normal branch update includes #112's lock-refresh base; wait for exact-head Checks and independent review. | +| [#109](https://github.com/ContextualWisdomLab/keyverse/pull/109) | `typing-inspection` update, stacked on #112 lockfile refresh | PENDING: 14 pending, 7 skipped, 0 terminal failures on `7b726b16d38ce16d13d00c946b5c8bc0c406191f` | review required | The normal merge and local locked-install/full-suite verification are complete; wait for fresh hosted Checks and independent review. | +| [#108](https://github.com/ContextualWisdomLab/keyverse/pull/108) | Ruff update, stacked on #112 lockfile refresh | PENDING: 2 pending, 17 successful, 8 skipped, 0 terminal failures on `538cead991a7c1bed32f2dcb5413b5fc56f53e93` | review required | The conflicting lockfile base was rebased cleanly onto #112; wait for remaining exact-head Checks and independent review. | +| [#107](https://github.com/ContextualWisdomLab/keyverse/pull/107) | Uvicorn update, stacked on #112 lockfile refresh | PENDING: 1 pending, 19 successful, 8 skipped, 0 terminal failures on `53842560d397aa20309a6b16aceb560540611686` | review required | The conflicting lockfile base was rebased cleanly onto #112; wait for the remaining exact-head Check and independent review. | +| [#106](https://github.com/ContextualWisdomLab/keyverse/pull/106) | `setup-uv` update, stacked on #112 lockfile refresh | PENDING: 14 pending, 7 skipped, 0 terminal failures on updated head `e7fafd4192cc3cc344b8f8e536bc0495afaa739f` | review required | The normal branch update includes #112's lockfile base; wait for exact-head Checks and independent review. | +| [#105](https://github.com/ContextualWisdomLab/keyverse/pull/105) | `harden-runner` update, stacked on #112 lockfile refresh | PENDING: 14 pending, 7 skipped, 0 terminal failures on updated head `77f83dfb2c4611345c0d48f92fceaa6195b4630c` | changes requested | The normal branch update includes #112's lockfile base; obtain current-head independent review. | +| [#104](https://github.com/ContextualWisdomLab/keyverse/pull/104) | ADR and buyer README expansion, stacked on #112 | PENDING: 14 pending, 7 skipped, 0 terminal failures on updated head `7da9d43087d5647fefb946eb154ee1e5c10c576d` | review required | Base remains `fix/account-unification-lock-20260819`; obtain independent review and terminal stacked-head Checks. | +| [#103](https://github.com/ContextualWisdomLab/keyverse/pull/103) | Hierarchical authorization, login helper, PATs | PENDING: 14 pending, 7 skipped, 0 terminal failures on `9274d3184443fba6c6294e08dff20734f3ae6fb4` | current findings addressed; approval absent | Exact-tree regressions and local 100% verification pass; wait for hosted security Checks and independent review before any merge claim. | +| [#101](https://github.com/ContextualWisdomLab/keyverse/pull/101) | Atomic coupled Python dependency updates | PASS: 22 successful, 8 skipped, 0 pending on `50dd9c96cab5c230f775685e8baea939fba390dd` | changes requested | Obtain fresh independent review; this is the policy companion to the lockfile gap. | +| [#100](https://github.com/ContextualWisdomLab/keyverse/pull/100) | `lineageweave-web` account-derived claims plus default validator-path coverage | PENDING: 14 pending, 7 skipped, 0 terminal failures on the pre-refresh snapshot head `bcd4b15220852cf85feaff4922ce6b2557d7688d` | current findings addressed; approval absent | The current-tree review findings are addressed; re-audit this documentation successor after its normal push without self-approval. | +| [#83](https://github.com/ContextualWisdomLab/keyverse/pull/83) | Remove runtime application RPs from portable realm | PASS: 22 successful, 8 skipped, 0 pending on `dd1ab7444a75342b42e3af013ccda6d1dbfb359d` | changes requested | Reconfirm current-head approval and latest-pusher rule before protected merge. | ### Historical check failure root causes observed @@ -113,6 +114,12 @@ evidence. required after the external image service recovers; no code change can make that exact failed run green. +- PR #113's current exact head + `aaafc2ca2f42bc171c1a0d0b538a99eb2f461233` contains the valid SCIM PatchOp + review correction and passed focused/full local verification with 100% + statement and branch coverage. Its hosted Checks remain pending with no + terminal failure, and independent approval is absent. + - PR #111's prior exact-head `account-unification-tests` failure stopped before tests at `uv sync --locked`: the branch tree did not contain the #112 lock refresh even though its PR base had been retargeted. The normal, non-force From 2c065e9fd754654c425052d2494e13e86148aa76 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 21 Aug 2026 11:36:39 +0900 Subject: [PATCH 56/70] docs: update latest review evidence --- docs/doctoring/product-technical-gap-baseline.md | 9 +++++---- docs/product-technical-gap-baseline.md | 4 ++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/docs/doctoring/product-technical-gap-baseline.md b/docs/doctoring/product-technical-gap-baseline.md index fba5727..16ec0bc 100644 --- a/docs/doctoring/product-technical-gap-baseline.md +++ b/docs/doctoring/product-technical-gap-baseline.md @@ -121,9 +121,10 @@ placeholder credentials must not be committed to close it. dispatch boundary. Central PR #1183 is also closed without merge. - Central `.github` PR #1170 is open at exact head `1f2b93ead7205b33712de1865d84c004d93be7ed` for routing OpenCode reviews - through the contextual gateway. Its current hosted rollup has 4 successful, - 17 pending, and 13 skipped Checks; no terminal source failure or qualifying - formal approval is recorded. The current head removes inherited GitHub + through the contextual gateway. Its current hosted rollup has 5 successful, + 16 pending, and 13 skipped Checks; no terminal source failure or qualifying + formal approval is recorded. Its current-head review threads are resolved. + The current head removes inherited GitHub credentials and workflow-file channels from the child gateway process and has passed the focused contract test plus full local central verification. - Central `.github` PR #1178 is the canonical contextual-orchestrator hourly @@ -234,7 +235,7 @@ https://www.rfc-editor.org/rfc/rfc8725.html are not claimed. The operator-admin trust boundary and the fresh security changes still require independent exact-head validation. PR #100's pre-refresh documentation head is - `bcd4b15220852cf85feaff4922ce6b2557d7688d`, with 14 pending and 7 skipped + `6e0c92f7512ab8b1eded34e2e6ae9a0476896aba`, with 14 pending and 7 skipped Checks; its prior review state is not approval. PR #104's updated head `7da9d43087d5647fefb946eb154ee1e5c10c576d` is based on #112's lockfile head and has 14 pending and 7 skipped Checks. The resulting #100 head diff --git a/docs/product-technical-gap-baseline.md b/docs/product-technical-gap-baseline.md index 15c3389..c4242e3 100644 --- a/docs/product-technical-gap-baseline.md +++ b/docs/product-technical-gap-baseline.md @@ -67,7 +67,7 @@ tenant, or resource ownership. The following is the current open-PR inventory. `Checks` means the exact head rollup observed on 2026-08-21; it is not inherited from a predecessor commit. This record was refreshed from a live exact-head audit while PR #100 stood at -`bcd4b15220852cf85feaff4922ce6b2557d7688d`; the documentation commit that +`6e0c92f7512ab8b1eded34e2e6ae9a0476896aba`; the documentation commit that updates this snapshot is intentionally not recursively named. The audit also includes normal branch updates from the #112 lock-refresh base for the dependency/documentation stack. The live PR record is authoritative for the @@ -97,7 +97,7 @@ evidence. Queued Checks remain unverified rather than green. | [#104](https://github.com/ContextualWisdomLab/keyverse/pull/104) | ADR and buyer README expansion, stacked on #112 | PENDING: 14 pending, 7 skipped, 0 terminal failures on updated head `7da9d43087d5647fefb946eb154ee1e5c10c576d` | review required | Base remains `fix/account-unification-lock-20260819`; obtain independent review and terminal stacked-head Checks. | | [#103](https://github.com/ContextualWisdomLab/keyverse/pull/103) | Hierarchical authorization, login helper, PATs | PENDING: 14 pending, 7 skipped, 0 terminal failures on `9274d3184443fba6c6294e08dff20734f3ae6fb4` | current findings addressed; approval absent | Exact-tree regressions and local 100% verification pass; wait for hosted security Checks and independent review before any merge claim. | | [#101](https://github.com/ContextualWisdomLab/keyverse/pull/101) | Atomic coupled Python dependency updates | PASS: 22 successful, 8 skipped, 0 pending on `50dd9c96cab5c230f775685e8baea939fba390dd` | changes requested | Obtain fresh independent review; this is the policy companion to the lockfile gap. | -| [#100](https://github.com/ContextualWisdomLab/keyverse/pull/100) | `lineageweave-web` account-derived claims plus default validator-path coverage | PENDING: 14 pending, 7 skipped, 0 terminal failures on the pre-refresh snapshot head `bcd4b15220852cf85feaff4922ce6b2557d7688d` | current findings addressed; approval absent | The current-tree review findings are addressed; re-audit this documentation successor after its normal push without self-approval. | +| [#100](https://github.com/ContextualWisdomLab/keyverse/pull/100) | `lineageweave-web` account-derived claims plus default validator-path coverage | PENDING: 14 pending, 7 skipped, 0 terminal failures on the pre-refresh snapshot head `6e0c92f7512ab8b1eded34e2e6ae9a0476896aba` | current findings addressed; approval absent | The current-tree review findings are addressed; re-audit this documentation successor after its normal push without self-approval. | | [#83](https://github.com/ContextualWisdomLab/keyverse/pull/83) | Remove runtime application RPs from portable realm | PASS: 22 successful, 8 skipped, 0 pending on `dd1ab7444a75342b42e3af013ccda6d1dbfb359d` | changes requested | Reconfirm current-head approval and latest-pusher rule before protected merge. | ### Historical check failure root causes observed From 624440257ea28df0e4ec6c234a8cbfeadb6c322e Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 21 Aug 2026 11:40:20 +0900 Subject: [PATCH 57/70] docs: track open MCP authorization gap --- docs/doctoring/product-technical-gap-baseline.md | 5 +++++ docs/product-technical-gap-baseline.md | 2 ++ 2 files changed, 7 insertions(+) diff --git a/docs/doctoring/product-technical-gap-baseline.md b/docs/doctoring/product-technical-gap-baseline.md index 16ec0bc..cc84ab2 100644 --- a/docs/doctoring/product-technical-gap-baseline.md +++ b/docs/doctoring/product-technical-gap-baseline.md @@ -174,6 +174,11 @@ https://www.rfc-editor.org/rfc/rfc8725.html `docs/THREAT_MODEL.md`, `docs/TEST_STRATEGY.md`, and `docs/TRACEABILITY.md`. - ADR-0008 and ADR-0009 plus their related specification, plan, operations, and doctoring records. +- The live open-Issue query performed on 2026-08-21 found five open issues; + newly tracked Issue #114 defines the buyer gap for MCP-compatible OAuth client + authorization for headless agents. Its standards list is issue scope, not + yet an adopted Keyverse runtime contract; implementation remains deferred + until the PR and Issue queue is exhausted. - Exact-head GitHub PR, review, issue, check-run, ruleset, and scheduled-run queries performed on 2026-08-21. Fourteen Keyverse PRs are open: #112, #101, and #83 each have 22 successful and 8 skipped Checks with no pending run. diff --git a/docs/product-technical-gap-baseline.md b/docs/product-technical-gap-baseline.md index c4242e3..b1a3c9c 100644 --- a/docs/product-technical-gap-baseline.md +++ b/docs/product-technical-gap-baseline.md @@ -44,6 +44,7 @@ tenant, or resource ownership. |---|---| | `implemented-main` | Source and tests are on the observed protected-main head. | | `active-PR` | Work exists in an open PR and is not part of protected-main evidence. | +| `active-issue` | A buyer or operational gap is tracked in an open issue and is not implemented evidence. | | `accepted-contract` | An ADR/specification defines the policy, but runtime or buyer acceptance may still be absent. | | `gap-not-claimed` | The repository deliberately makes no success claim until stronger evidence exists. | @@ -160,6 +161,7 @@ evidence. | Issue | Product signal | Classification | Required outcome | |---:|---|---|---| +| [#114](https://github.com/ContextualWisdomLab/keyverse/issues/114) | MCP-compatible OAuth client authorization for headless agents | `active-issue` | Define the Keyverse authorization-server and OIDC discovery contract, public-client authorization code + PKCE, exact redirects, resource-bound least-privilege tokens, centralized revocation/audit, and negative browser/client evidence. Evaluate RFC 8628 only for clients that cannot use a callback; do not implement it speculatively. | | [#102](https://github.com/ContextualWisdomLab/keyverse/issues/102) | Hierarchical authorization plane, login helper, PATs | `active-PR` | Security-review the proposed authority model and prove fail-closed token/tenant/resource behavior. | | [#99](https://github.com/ContextualWisdomLab/keyverse/issues/99) | Orphaned federation and product-loop workflow identities | `gap-not-claimed` | Live evidence at protected `main` `ce207dfd` found 43 active registry identities: 4 present repository paths, 37 missing repository paths, and 2 GitHub-owned dynamic paths. Disable only through the owning protected workflow/organization path and revalidate by workflow ID immediately before mutation. | | [#71](https://github.com/ContextualWisdomLab/keyverse/issues/71) | Remove runtime application RPs from portable import | `active-PR` | Merge #83 only after current-head protected evidence. | From 096c12c1ffe289ff4ad231c3b779a239786b9b65 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 21 Aug 2026 11:41:10 +0900 Subject: [PATCH 58/70] docs: record MCP cross-repo boundary --- docs/doctoring/product-technical-gap-baseline.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/doctoring/product-technical-gap-baseline.md b/docs/doctoring/product-technical-gap-baseline.md index cc84ab2..7dee33d 100644 --- a/docs/doctoring/product-technical-gap-baseline.md +++ b/docs/doctoring/product-technical-gap-baseline.md @@ -179,6 +179,10 @@ https://www.rfc-editor.org/rfc/rfc8725.html authorization for headless agents. Its standards list is issue scope, not yet an adopted Keyverse runtime contract; implementation remains deferred until the PR and Issue queue is exhausted. +- LineageWeave PRs #333 and #334 are both currently closed without merge; + their managed/static MCP API-key direction is superseded by Issue #114's + centralized Keyverse OAuth boundary and must not be revived as a second + identity, issuance, revocation, or audit system. - Exact-head GitHub PR, review, issue, check-run, ruleset, and scheduled-run queries performed on 2026-08-21. Fourteen Keyverse PRs are open: #112, #101, and #83 each have 22 successful and 8 skipped Checks with no pending run. From 920bed611b57ec9123d3da51a190e8fbc2cfbed3 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 21 Aug 2026 11:54:56 +0900 Subject: [PATCH 59/70] docs: record central automation failure evidence --- docs/doctoring/product-technical-gap-baseline.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/docs/doctoring/product-technical-gap-baseline.md b/docs/doctoring/product-technical-gap-baseline.md index 7dee33d..a9985c8 100644 --- a/docs/doctoring/product-technical-gap-baseline.md +++ b/docs/doctoring/product-technical-gap-baseline.md @@ -147,6 +147,22 @@ placeholder credentials must not be committed to close it. `11491068712859e936e7ce4ed7f204f5c1157f0c` for the OpenCode retry path. Its current rollup has 1 successful and 16 pending Checks, with 13 skipped and no terminal source failure or qualifying formal approval. +- Central `.github` PR #1174 is open at exact head + `11f397988f871b7566e6e1c5dcf5fd82be905dc0` for the mention-router + acknowledgement recovery path. Its current rollup has 26 terminal + successes, 1 pending (`opencode-review`), and 15 skipped Checks, with no + terminal source failure or qualifying formal approval. It is the normal + source fix for recent main-branch `Review Agent Mention Router` failures + (`32438800573`, `32438736861`, and `32438190241`) where a target + acknowledgement reaction returned HTTP 403 after durable dispatch. The + current head preserves the durable dispatch and retries only the cosmetic + acknowledgement without creating a duplicate dispatch. +- The scheduled central `.github` Organization Commercial Readiness Loop run + `32437647976` failed before coordination because the configured + `PR_REVIEW_MERGE_TOKEN` was unavailable. This is a fail-closed credential + configuration gap, not permission to substitute `GITHUB_TOKEN` or bypass the + reviewer credential boundary; remediation requires the owning secret + configuration or an explicit owner decision. - Keyverse's existing `Hourly product development` workflow remains active at `41 * * * *`; its latest observed scheduled runs succeeded. No duplicate scheduler was added. Activation of the central caller remains conditional on From 660e02e416f25c967d9980ea715c18bd99df8530 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 21 Aug 2026 12:02:37 +0900 Subject: [PATCH 60/70] docs: track central docstring repair --- docs/doctoring/product-technical-gap-baseline.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/doctoring/product-technical-gap-baseline.md b/docs/doctoring/product-technical-gap-baseline.md index a9985c8..98c7431 100644 --- a/docs/doctoring/product-technical-gap-baseline.md +++ b/docs/doctoring/product-technical-gap-baseline.md @@ -157,6 +157,13 @@ placeholder credentials must not be committed to close it. acknowledgement reaction returned HTTP 403 after durable dispatch. The current head preserves the durable dispatch and retries only the cosmetic acknowledgement without creating a duplicate dispatch. +- Central `.github` PR #1189 is open at exact head + `07cdefca207e8bc09e714e33740a47809cb5d9a4` to close the pre-existing + repository-wide docstring gap in the organization commercial-readiness + coordinator. The one-line behavior-neutral fix passed the full local suite, + 100% statement/branch coverage, and 100% interrogate verification; hosted + Checks are newly pending and no qualifying formal approval or protected + merge exists. - The scheduled central `.github` Organization Commercial Readiness Loop run `32437647976` failed before coordination because the configured `PR_REVIEW_MERGE_TOKEN` was unavailable. This is a fail-closed credential From d2b765ff2cbcc4e857a0e88e53d631a47ca4980d Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 21 Aug 2026 12:08:06 +0900 Subject: [PATCH 61/70] docs: record scheduler dispatch evidence --- docs/doctoring/product-technical-gap-baseline.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/doctoring/product-technical-gap-baseline.md b/docs/doctoring/product-technical-gap-baseline.md index 98c7431..01cb5fc 100644 --- a/docs/doctoring/product-technical-gap-baseline.md +++ b/docs/doctoring/product-technical-gap-baseline.md @@ -164,6 +164,14 @@ placeholder credentials must not be committed to close it. 100% statement/branch coverage, and 100% interrogate verification; hosted Checks are newly pending and no qualifying formal approval or protected merge exists. +- Central `.github` PR #1155 is open at exact head + `4b9a933d77a1d68459bf2c51abfbdba9e2d03d8b` for stable deduplication of + unscoped scheduler dispatches and bounded stale-review input. Its current + rollup has 26 successful, 3 neutral, 1 queued, and 15 skipped Checks, with + no qualifying formal approval. Historical run `32434533013` remains a + fail-closed malformed targeted dispatch for `ContextualWisdomLab/TEPP` + without a PR number; it is not treated as successful scheduler evidence or + as permission to weaken target validation. - The scheduled central `.github` Organization Commercial Readiness Loop run `32437647976` failed before coordination because the configured `PR_REVIEW_MERGE_TOKEN` was unavailable. This is a fail-closed credential From fbfbabd5e3c0aa753dce072ca3d3278c6c450948 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 21 Aug 2026 12:11:56 +0900 Subject: [PATCH 62/70] docs: refresh live PR baseline --- docs/product-technical-gap-baseline.md | 41 +++++++++++++------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/docs/product-technical-gap-baseline.md b/docs/product-technical-gap-baseline.md index b1a3c9c..55e0294 100644 --- a/docs/product-technical-gap-baseline.md +++ b/docs/product-technical-gap-baseline.md @@ -68,38 +68,39 @@ tenant, or resource ownership. The following is the current open-PR inventory. `Checks` means the exact head rollup observed on 2026-08-21; it is not inherited from a predecessor commit. This record was refreshed from a live exact-head audit while PR #100 stood at -`6e0c92f7512ab8b1eded34e2e6ae9a0476896aba`; the documentation commit that +`d2b765ff2cbcc4e857a0e88e53d631a47ca4980d`; the documentation commit that updates this snapshot is intentionally not recursively named. The audit also includes normal branch updates from the #112 lock-refresh base for the dependency/documentation stack. The live PR record is authoritative for the exact hash and Checks; predecessor evidence remains non-transferable. At this snapshot, 14 PRs are open and none has a qualifying formal approval. -#112, #101, and #83 each have 22 successful and 8 skipped Checks with no -pending Check; #107 has 19 successful, 1 pending, and 8 skipped Checks; #108 -has 17 successful, 2 pending, and 8 skipped Checks; and #113, #100, #103, -#104, #105, #106, #109, #110, and #111 each have 14 pending and 7 skipped -Checks. +#112, #101, and #83 each have 23 successful and 8 skipped Checks with no +queued Check; #107 has 20 successful, 1 queued, and 8 skipped Checks; #108 +has 18 successful, 2 queued, and 8 skipped Checks; #103 has 20 successful, +1 in-progress, 1 queued, and 7 skipped Checks; #113 has 2 successful, 14 +queued, and 7 skipped Checks; and #100, #104, #105, #106, #109, #110, and +#111 each have 1–2 successful, 14 queued, and 7 skipped Checks. There is no current terminal failure bucket in this inventory. Historical terminal failures are recorded separately and are not current-head green evidence. Queued Checks remain unverified rather than green. | PR | Scope | Exact-head Checks | Review state | Next safe action | |---:|---|---|---|---| -| [#113](https://github.com/ContextualWisdomLab/keyverse/pull/113) | SCIM `PATCH active=false` shared operation lock, stacked on #112 lockfile refresh | PENDING: 14 pending, 7 skipped, 0 terminal failures on `aaafc2ca2f42bc171c1a0d0b538a99eb2f461233` | requested changes fixed; approval absent | The valid SCIM PatchOp review fix and local full verification are complete; wait for fresh exact-head hosted Checks and independent review. | -| [#112](https://github.com/ContextualWisdomLab/keyverse/pull/112) | Resync account-unification lockfile | PASS: 22 successful, 8 skipped, 0 pending on `f02acf93367a40dbfb23a73985017dca8d42ff39` | review required | Obtain independent review, then let protected automation re-check and merge. | -| [#111](https://github.com/ContextualWisdomLab/keyverse/pull/111) | CodeQL init 4.37.7 | PENDING: 14 pending, 7 skipped, 0 terminal failures on updated head `032f730b0239d062cf9803525ba66c740e0b2d2e` | review required | The normal branch update merged #112's lockfile base into the CodeQL branch; wait for exact-head Checks and independent review. | -| [#110](https://github.com/ContextualWisdomLab/keyverse/pull/110) | CodeQL analyze 4.37.7, stacked on #112 lockfile refresh | PENDING: 14 pending, 7 skipped, 0 terminal failures on updated head `c3e307fc3d4f6d98ec5a0514f35aa8038b2737b7` | review required | The normal branch update includes #112's lock-refresh base; wait for exact-head Checks and independent review. | -| [#109](https://github.com/ContextualWisdomLab/keyverse/pull/109) | `typing-inspection` update, stacked on #112 lockfile refresh | PENDING: 14 pending, 7 skipped, 0 terminal failures on `7b726b16d38ce16d13d00c946b5c8bc0c406191f` | review required | The normal merge and local locked-install/full-suite verification are complete; wait for fresh hosted Checks and independent review. | -| [#108](https://github.com/ContextualWisdomLab/keyverse/pull/108) | Ruff update, stacked on #112 lockfile refresh | PENDING: 2 pending, 17 successful, 8 skipped, 0 terminal failures on `538cead991a7c1bed32f2dcb5413b5fc56f53e93` | review required | The conflicting lockfile base was rebased cleanly onto #112; wait for remaining exact-head Checks and independent review. | -| [#107](https://github.com/ContextualWisdomLab/keyverse/pull/107) | Uvicorn update, stacked on #112 lockfile refresh | PENDING: 1 pending, 19 successful, 8 skipped, 0 terminal failures on `53842560d397aa20309a6b16aceb560540611686` | review required | The conflicting lockfile base was rebased cleanly onto #112; wait for the remaining exact-head Check and independent review. | -| [#106](https://github.com/ContextualWisdomLab/keyverse/pull/106) | `setup-uv` update, stacked on #112 lockfile refresh | PENDING: 14 pending, 7 skipped, 0 terminal failures on updated head `e7fafd4192cc3cc344b8f8e536bc0495afaa739f` | review required | The normal branch update includes #112's lockfile base; wait for exact-head Checks and independent review. | -| [#105](https://github.com/ContextualWisdomLab/keyverse/pull/105) | `harden-runner` update, stacked on #112 lockfile refresh | PENDING: 14 pending, 7 skipped, 0 terminal failures on updated head `77f83dfb2c4611345c0d48f92fceaa6195b4630c` | changes requested | The normal branch update includes #112's lockfile base; obtain current-head independent review. | -| [#104](https://github.com/ContextualWisdomLab/keyverse/pull/104) | ADR and buyer README expansion, stacked on #112 | PENDING: 14 pending, 7 skipped, 0 terminal failures on updated head `7da9d43087d5647fefb946eb154ee1e5c10c576d` | review required | Base remains `fix/account-unification-lock-20260819`; obtain independent review and terminal stacked-head Checks. | -| [#103](https://github.com/ContextualWisdomLab/keyverse/pull/103) | Hierarchical authorization, login helper, PATs | PENDING: 14 pending, 7 skipped, 0 terminal failures on `9274d3184443fba6c6294e08dff20734f3ae6fb4` | current findings addressed; approval absent | Exact-tree regressions and local 100% verification pass; wait for hosted security Checks and independent review before any merge claim. | -| [#101](https://github.com/ContextualWisdomLab/keyverse/pull/101) | Atomic coupled Python dependency updates | PASS: 22 successful, 8 skipped, 0 pending on `50dd9c96cab5c230f775685e8baea939fba390dd` | changes requested | Obtain fresh independent review; this is the policy companion to the lockfile gap. | -| [#100](https://github.com/ContextualWisdomLab/keyverse/pull/100) | `lineageweave-web` account-derived claims plus default validator-path coverage | PENDING: 14 pending, 7 skipped, 0 terminal failures on the pre-refresh snapshot head `6e0c92f7512ab8b1eded34e2e6ae9a0476896aba` | current findings addressed; approval absent | The current-tree review findings are addressed; re-audit this documentation successor after its normal push without self-approval. | -| [#83](https://github.com/ContextualWisdomLab/keyverse/pull/83) | Remove runtime application RPs from portable realm | PASS: 22 successful, 8 skipped, 0 pending on `dd1ab7444a75342b42e3af013ccda6d1dbfb359d` | changes requested | Reconfirm current-head approval and latest-pusher rule before protected merge. | +| [#113](https://github.com/ContextualWisdomLab/keyverse/pull/113) | SCIM `PATCH active=false` shared operation lock, stacked on #112 lockfile refresh | PENDING: 2 successful, 14 queued, 7 skipped, 0 terminal failures on `aaafc2ca2f42bc171c1a0d0b538a99eb2f461233` | requested changes fixed; approval absent | The valid SCIM PatchOp review fix and local full verification are complete; wait for fresh exact-head hosted Checks and independent review. | +| [#112](https://github.com/ContextualWisdomLab/keyverse/pull/112) | Resync account-unification lockfile | PASS: 23 successful, 8 skipped, 0 queued on `f02acf93367a40dbfb23a73985017dca8d42ff39` | review required | Obtain independent review, then let protected automation re-check and merge. | +| [#111](https://github.com/ContextualWisdomLab/keyverse/pull/111) | CodeQL init 4.37.7 | PENDING: 1 successful, 14 queued, 7 skipped, 0 terminal failures on updated head `032f730b0239d062cf9803525ba66c740e0b2d2e` | review required | The normal branch update merged #112's lockfile base into the CodeQL branch; wait for exact-head Checks and independent review. | +| [#110](https://github.com/ContextualWisdomLab/keyverse/pull/110) | CodeQL analyze 4.37.7, stacked on #112 lockfile refresh | PENDING: 1 successful, 14 queued, 7 skipped, 0 terminal failures on updated head `c3e307fc3d4f6d98ec5a0514f35aa8038b2737b7` | review required | The normal branch update includes #112's lock-refresh base; wait for exact-head Checks and independent review. | +| [#109](https://github.com/ContextualWisdomLab/keyverse/pull/109) | `typing-inspection` update, stacked on #112 lockfile refresh | PENDING: 1 successful, 14 queued, 7 skipped, 0 terminal failures on `7b726b16d38ce16d13d00c946b5c8bc0c406191f` | review required | The normal merge and local locked-install/full-suite verification are complete; wait for fresh hosted Checks and independent review. | +| [#108](https://github.com/ContextualWisdomLab/keyverse/pull/108) | Ruff update, stacked on #112 lockfile refresh | PENDING: 18 successful, 2 queued, 8 skipped, 0 terminal failures on `538cead991a7c1bed32f2dcb5413b5fc56f53e93` | review required | The conflicting lockfile base was rebased cleanly onto #112; wait for remaining exact-head Checks and independent review. | +| [#107](https://github.com/ContextualWisdomLab/keyverse/pull/107) | Uvicorn update, stacked on #112 lockfile refresh | PENDING: 20 successful, 1 queued, 8 skipped, 0 terminal failures on `53842560d397aa20309a6b16aceb560540611686` | review required | The conflicting lockfile base was rebased cleanly onto #112; wait for the remaining exact-head Check and independent review. | +| [#106](https://github.com/ContextualWisdomLab/keyverse/pull/106) | `setup-uv` update, stacked on #112 lockfile refresh | PENDING: 1 successful, 14 queued, 7 skipped, 0 terminal failures on updated head `e7fafd4192cc3cc344b8f8e536bc0495afaa739f` | review required | The normal branch update includes #112's lockfile base; wait for exact-head Checks and independent review. | +| [#105](https://github.com/ContextualWisdomLab/keyverse/pull/105) | `harden-runner` update, stacked on #112 lockfile refresh | PENDING: 1 successful, 14 queued, 7 skipped, 0 terminal failures on updated head `77f83dfb2c4611345c0d48f92fceaa6195b4630c` | changes requested | The normal branch update includes #112's lockfile base; obtain current-head independent review. | +| [#104](https://github.com/ContextualWisdomLab/keyverse/pull/104) | ADR and buyer README expansion, stacked on #112 | PENDING: 2 successful, 14 queued, 7 skipped, 0 terminal failures on updated head `7da9d43087d5647fefb946eb154ee1e5c10c576d` | review required | Base remains `fix/account-unification-lock-20260819`; obtain independent review and terminal stacked-head Checks. | +| [#103](https://github.com/ContextualWisdomLab/keyverse/pull/103) | Hierarchical authorization, login helper, PATs | PENDING: 20 successful, 1 in-progress, 1 queued, 7 skipped, 0 terminal failures on `9274d3184443fba6c6294e08dff20734f3ae6fb4` | current findings addressed; approval absent | Exact-tree regressions and local 100% verification pass; wait for hosted security Checks and independent review before any merge claim. | +| [#101](https://github.com/ContextualWisdomLab/keyverse/pull/101) | Atomic coupled Python dependency updates | PASS: 23 successful, 8 skipped, 0 queued on `50dd9c96cab5c230f775685e8baea939fba390dd` | changes requested | Obtain fresh independent review; this is the policy companion to the lockfile gap. | +| [#100](https://github.com/ContextualWisdomLab/keyverse/pull/100) | `lineageweave-web` account-derived claims plus default validator-path coverage | PENDING: 1 successful, 1 pending, 14 queued, 7 skipped, 0 terminal failures on the pre-refresh snapshot head `d2b765ff2cbcc4e857a0e88e53d631a47ca4980d` | current findings addressed; approval absent | The current-tree review findings are addressed; re-audit this documentation successor after its normal push without self-approval. | +| [#83](https://github.com/ContextualWisdomLab/keyverse/pull/83) | Remove runtime application RPs from portable realm | PASS: 23 successful, 8 skipped, 0 queued on `dd1ab7444a75342b42e3af013ccda6d1dbfb359d` | changes requested | Reconfirm current-head approval and latest-pusher rule before protected merge. | ### Historical check failure root causes observed From daf2030fb31dea457a83e0c6b5826d5fd98b277a Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 21 Aug 2026 12:12:55 +0900 Subject: [PATCH 63/70] docs: refresh central check rollups --- docs/doctoring/product-technical-gap-baseline.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/docs/doctoring/product-technical-gap-baseline.md b/docs/doctoring/product-technical-gap-baseline.md index 01cb5fc..1cea4d1 100644 --- a/docs/doctoring/product-technical-gap-baseline.md +++ b/docs/doctoring/product-technical-gap-baseline.md @@ -150,8 +150,8 @@ placeholder credentials must not be committed to close it. - Central `.github` PR #1174 is open at exact head `11f397988f871b7566e6e1c5dcf5fd82be905dc0` for the mention-router acknowledgement recovery path. Its current rollup has 26 terminal - successes, 1 pending (`opencode-review`), and 15 skipped Checks, with no - terminal source failure or qualifying formal approval. It is the normal + successes, 3 neutral, 1 queued, and 15 skipped Checks, with no terminal + source failure or qualifying formal approval. It is the normal source fix for recent main-branch `Review Agent Mention Router` failures (`32438800573`, `32438736861`, and `32438190241`) where a target acknowledgement reaction returned HTTP 403 after durable dispatch. The @@ -161,9 +161,10 @@ placeholder credentials must not be committed to close it. `07cdefca207e8bc09e714e33740a47809cb5d9a4` to close the pre-existing repository-wide docstring gap in the organization commercial-readiness coordinator. The one-line behavior-neutral fix passed the full local suite, - 100% statement/branch coverage, and 100% interrogate verification; hosted - Checks are newly pending and no qualifying formal approval or protected - merge exists. + 100% statement/branch coverage, and 100% interrogate verification. Its + current hosted rollup has 3 successful, 16 queued, 1 cancelled, and 15 + skipped Checks, with no terminal source failure or qualifying formal approval + or protected merge. - Central `.github` PR #1155 is open at exact head `4b9a933d77a1d68459bf2c51abfbdba9e2d03d8b` for stable deduplication of unscoped scheduler dispatches and bounded stale-review input. Its current From 6f3c86153574d6b61168c31a9ab56421005c0b98 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 21 Aug 2026 12:16:20 +0900 Subject: [PATCH 64/70] docs: track scheduler hardening PRs --- docs/doctoring/product-technical-gap-baseline.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docs/doctoring/product-technical-gap-baseline.md b/docs/doctoring/product-technical-gap-baseline.md index 1cea4d1..bfc4865 100644 --- a/docs/doctoring/product-technical-gap-baseline.md +++ b/docs/doctoring/product-technical-gap-baseline.md @@ -173,6 +173,17 @@ placeholder credentials must not be committed to close it. fail-closed malformed targeted dispatch for `ContextualWisdomLab/TEPP` without a PR number; it is not treated as successful scheduler evidence or as permission to weaken target validation. +- Central `.github` PR #1171 is open at exact head + `ff65c16063f7b687df09253d31d84dac6517c0ea` to refuse scheduler head + mutations when required checks cannot be started. Its current rollup has 5 + successful, 16 queued, and 13 skipped Checks, with no qualifying formal + approval. The exact head passed the full local central suite and scheduler + 100% statement/branch coverage; hosted queued evidence remains unverified. +- Central `.github` PR #1188 is open at exact head + `7f9f9f0606ac5c88df3857eb5e5367d5bdbad420` to grant the DiskSage and + Clearfolio hourly reusable-workflow callers job-scoped OIDC permission. Its + current rollup has 4 successful, 16 queued, 15 skipped, and 1 cancelled + Check, with no qualifying formal approval or protected merge. - The scheduled central `.github` Organization Commercial Readiness Loop run `32437647976` failed before coordination because the configured `PR_REVIEW_MERGE_TOKEN` was unavailable. This is a fail-closed credential From 3b35084632052330bf150ebb8d1f0e9625d73584 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 21 Aug 2026 12:47:19 +0900 Subject: [PATCH 65/70] docs: record workflow registry lifecycle evidence --- ARCHITECTURE.md | 7 +++ CHANGELOG.md | 5 +++ docs/OPERABILITY.md | 20 +++++++++ .../product-technical-gap-baseline.md | 45 ++++++++++++++++--- docs/product-technical-gap-baseline.md | 2 +- 5 files changed, 71 insertions(+), 8 deletions(-) diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index abb98b0..5c6e402 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -221,6 +221,13 @@ explicitly documented deployment-controller responsibility. ## Automation boundaries +- GitHub Actions source files and the Actions workflow registry are separate + control-plane state. The central `.github` lifecycle inventory binds a + paginated registry observation to the exact protected default-branch tree and + reports dynamic identities separately from repository-path identities. The + inventory is read-only; any registry disablement requires a separately + reviewed, immediately revalidated operator action and a post-action + reconciliation. - The hourly PR steward advances only trusted same-repository PRs with exact-head approvals and required Checks. - The hourly product-development workflow runs OpenCode through diff --git a/CHANGELOG.md b/CHANGELOG.md index 46e4033..2063b03 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -116,6 +116,11 @@ Keep a Changelog, and releases use semantic versioning. ### Fixed +- Disabled 37 orphaned active GitHub Actions registry identities whose + repository paths were absent from protected `main`, while preserving the + four supported workflow identities and two GitHub-owned dynamic Dependabot + identities; recorded exact before/after reconciliation and operational smoke + evidence for issue #99. - Packaged the portable Keycloak realm under the required `cwl-realm.json` directory-import name in Compose and mapped it in Helm, with a deployment contract that prevents a healthy-but-empty identity realm. diff --git a/docs/OPERABILITY.md b/docs/OPERABILITY.md index f215903..bcf043a 100644 --- a/docs/OPERABILITY.md +++ b/docs/OPERABILITY.md @@ -100,6 +100,26 @@ Back up Keycloak PostgreSQL and Keyverse-owned configuration/audit/intent/receip PR #74 demonstrates that a workflow can appear successful while doing no useful work if a GitHub API gate fails open. Scheduled governance must classify transport failure separately from a valid empty/unhealthy result, fit its time budget, keep provider secrets in the broker phase only, and require exact `success` for protected evidence. With PR #74 integrated, operational closure requires a real protected-main scheduled/manual run. +## Workflow registry lifecycle + +The GitHub Actions registry is control-plane state separate from YAML in the +repository tree. For an inventory, bind the observation to a freshly resolved +protected default-branch SHA, paginate the complete workflow registry, and +compare each repository-path identity with the exact tree at that SHA. Classify +GitHub-owned dynamic identities separately; do not treat a name, one-shot +convention, or missing historical file alone as proof that a workflow is safe +to disable. + +The centrally owned read-only inventory in `ContextualWisdomLab/.github#1026` +is the implementation authority. It must fail closed on incomplete pagination, +permission loss, ambiguous 404/5xx responses, malformed paths, workflow-ID +reuse, and branch movement. Any operator mutation is a separately reviewed +step: re-fetch the branch and registry immediately, exclude supported +identities, mutate by numeric workflow ID only, then reconcile the registry +and protected tree again. Record workflow IDs, paths, states, exact SHA, +observation time, pagination receipts, and the resulting classification; never +record credentials or private payloads. + ## Release gate Release only after protected-head CI/security/review, 100% coverage/docstrings, realm/package/deployment validation, migrations/rollback/backup, passkey/federation/SCIM/RP controlled acceptance, secret scan, SBOM/provenance/image digest, runbooks/support, and CHANGELOG/version artifacts are coherent. A merged PR is not a release by itself. diff --git a/docs/doctoring/product-technical-gap-baseline.md b/docs/doctoring/product-technical-gap-baseline.md index bfc4865..99cea23 100644 --- a/docs/doctoring/product-technical-gap-baseline.md +++ b/docs/doctoring/product-technical-gap-baseline.md @@ -211,6 +211,9 @@ Sheffer, Y., Hardt, D., & Jones, M. (2020). *JSON Web Token best current practices* (RFC 8725). Internet Engineering Task Force. https://www.rfc-editor.org/rfc/rfc8725.html +GitHub. (2026). *REST API endpoints for workflows*. +https://docs.github.com/en/rest/actions/workflows?apiVersion=2022-11-28 + ## Evidence sources - `docs/PRD.md`, `docs/TRD.md`, `ARCHITECTURE.md`, `docs/OPERABILITY.md`, @@ -300,10 +303,38 @@ https://www.rfc-editor.org/rfc/rfc8725.html `OrganizationAdmin` always-bypass actor. The ordinary documentation push emitted GitHub's server-side bypass warning; no explicit bypass option, protected merge, or self-approval was used. A complete read-only Keyverse - Actions registry/tree reconciliation at protected `main` `ce207dfd` found 43 active identities: - four repository workflow paths present in the exact tree, 37 active - repository paths absent from it, and two `dynamic/*` GitHub-owned paths. The - workflow registry used one API page and the recursive protected-tree response - was not truncated. No workflow state was mutated; the evidence is recorded - on Keyverse issue #99 and central issue #945 for the owning lifecycle - operator. No credential, private payload, or PII is recorded here. + Actions registry/tree reconciliation at protected `main` `ce207dfd` found 43 + active identities: four repository workflow paths present in the exact tree, + 37 active repository paths absent from it, and two `dynamic/*` GitHub-owned + paths. The workflow registry used one API page and the recursive + protected-tree response was not truncated. This is the immutable + pre-mutation record for Keyverse issue #99; no credential, private payload, or + PII is recorded here. + +## 2026-08-21 workflow registry lifecycle remediation + +- The protected-main ref was re-fetched immediately before mutation and + remained `ce207dfd42975db61c82a5963e206fc1db14ac2b`. +- The four exact tree workflows (`ci.yml`, `codeql.yml`, + `hourly-pr-steward.yml`, and `hourly-product-development.yml`) were checked + for membership before any action and were excluded from mutation. +- The GitHub Actions workflow endpoint was used by numeric workflow ID with + the recommended JSON accept header. The 37 active repository-path identities + absent from the protected tree were set to `disabled_manually`; the two + `dynamic/*` Dependabot identities were not changed. GitHub documents that + this operation changes a workflow's state to `disabled_manually` and returns + HTTP 204 (GitHub, 2026). +- Fresh post-action reconciliation found 43 identities: 41 repository paths, + 4 active supported workflows, 37 `disabled_manually` orphan records, and 2 + unchanged active dynamic records. Active repository-path records absent from + the exact protected tree: zero. +- Operational smoke evidence remained intact: protected-main + `Hourly product development` run `32443743245` succeeded, the latest + completed `Hourly PR steward` run `32425875355` succeeded, and CodeQL run + `31783415830` succeeded on the protected SHA. The latest `ci.yml` success + (`31555831037`) predates the protected SHA and is recorded as such rather + than promoted to current-head evidence. +- This closes the live orphan cleanup portion of issue #99. A read-only + recurrence detector with pagination, path/ID reuse, branch movement, + permission-loss, transient HTTP failure, dynamic-workflow, and active-PR + cases remains required before the issue can close. diff --git a/docs/product-technical-gap-baseline.md b/docs/product-technical-gap-baseline.md index 55e0294..49ab95a 100644 --- a/docs/product-technical-gap-baseline.md +++ b/docs/product-technical-gap-baseline.md @@ -164,7 +164,7 @@ evidence. |---:|---|---|---| | [#114](https://github.com/ContextualWisdomLab/keyverse/issues/114) | MCP-compatible OAuth client authorization for headless agents | `active-issue` | Define the Keyverse authorization-server and OIDC discovery contract, public-client authorization code + PKCE, exact redirects, resource-bound least-privilege tokens, centralized revocation/audit, and negative browser/client evidence. Evaluate RFC 8628 only for clients that cannot use a callback; do not implement it speculatively. | | [#102](https://github.com/ContextualWisdomLab/keyverse/issues/102) | Hierarchical authorization plane, login helper, PATs | `active-PR` | Security-review the proposed authority model and prove fail-closed token/tenant/resource behavior. | -| [#99](https://github.com/ContextualWisdomLab/keyverse/issues/99) | Orphaned federation and product-loop workflow identities | `gap-not-claimed` | Live evidence at protected `main` `ce207dfd` found 43 active registry identities: 4 present repository paths, 37 missing repository paths, and 2 GitHub-owned dynamic paths. Disable only through the owning protected workflow/organization path and revalidate by workflow ID immediately before mutation. | +| [#99](https://github.com/ContextualWisdomLab/keyverse/issues/99) | Orphaned federation and product-loop workflow identities | `active-issue` | The exact protected-main cleanup completed: 43 registry identities remain, with 4 supported repository paths active, 37 orphan repository-path identities `disabled_manually`, and 2 GitHub-owned dynamic identities unchanged. The recurrence detector, adversarial tests, and central coordination acceptance remain open. | | [#71](https://github.com/ContextualWisdomLab/keyverse/issues/71) | Remove runtime application RPs from portable import | `active-PR` | Merge #83 only after current-head protected evidence. | | [#2](https://github.com/ContextualWisdomLab/keyverse/issues/2) | Central IdP plus external-IdP federation | `accepted-contract` | Use the existing closed preflight/apply boundary and add approved-environment acceptance. | From cde3910f3eba65a934c9750d0f63937c4212dd1e Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 21 Aug 2026 14:05:58 +0900 Subject: [PATCH 66/70] docs: refresh exact-head gap inventory --- .../product-technical-gap-baseline.md | 39 +++++++------- docs/product-technical-gap-baseline.md | 51 +++++++++++-------- 2 files changed, 52 insertions(+), 38 deletions(-) diff --git a/docs/doctoring/product-technical-gap-baseline.md b/docs/doctoring/product-technical-gap-baseline.md index 99cea23..270c26e 100644 --- a/docs/doctoring/product-technical-gap-baseline.md +++ b/docs/doctoring/product-technical-gap-baseline.md @@ -232,11 +232,12 @@ https://docs.github.com/en/rest/actions/workflows?apiVersion=2022-11-28 - Exact-head GitHub PR, review, issue, check-run, ruleset, and scheduled-run queries performed on 2026-08-21. Fourteen Keyverse PRs are open: #112, #101, and #83 each have 22 successful and 8 skipped Checks with no pending run. - #107 has 19 successful, 1 pending, and 8 skipped; #108 has 17 successful, - 2 pending, and 8 skipped; and #113, #100, #103, #104, #105, #106, #109, - #110, and #111 each have 14 pending and 7 skipped Checks. No current open PR - has a qualifying formal approval or terminal failure. Pending Checks remain - unverified. + #107 has 20 successful, 1 pending, and 8 skipped; #108 has 20 successful, + 1 pending, and 8 skipped. PRs #113 and #100 have 14 pending and 7 skipped; + #111 has 18 successful, 2 pending, and 7 skipped; and #103, #104, #105, + #106, #109, and #110 each have 19 successful, 1 pending, and 8 skipped + Checks. No current open PR has a qualifying formal approval or terminal + failure. Pending Checks remain unverified. PR #113's current SCIM lock head `aaafc2ca2f42bc171c1a0d0b538a99eb2f461233` includes the normal prerequisite lockfile history, a realistic SCIM PatchOp race, and the corrected valid @@ -252,29 +253,33 @@ https://docs.github.com/en/rest/actions/workflows?apiVersion=2022-11-28 Checks but still requires independent review. PR #111's current head `032f730b0239d062cf9803525ba66c740e0b2d2e` now contains #112's lockfile through a normal branch update. Its prior `account-unification-tests` - failure occurred before that update; the fresh run remains unverified. It - remains coupled to #112 and #110. PR #110's current head + failure occurred before that update; the fresh run remains unverified. Its + first Strix attempt also failed on contradictory model-generated Compose + evidence; a normal exact-head attempt 2 is queued. It remains coupled to + #112 and #110. PR #110's current head `c3e307fc3d4f6d98ec5a0514f35aa8038b2737b7` remains on the #112 base with - 14 pending and 7 skipped Checks; its hosted reruns remain unverified. + 19 successful, 1 pending, and 8 skipped Checks; its hosted reruns remain + unverified. The historical PR #105 exact head `72de5499d6e97ae7f7bd804ab78b3e1644dd5a4f` had a failed `account-unification-tests` Check: `uv 0.12.5` reproduced `uv sync --locked` refusing the stale `coverage==7.15.2` and `setuptools==83.0.0` lock entries while the current `pyproject.toml` required `7.15.4` and `84.0.0`; the current #105 head - `77f83dfb2c4611345c0d48f92fceaa6195b4630c` is stacked on #112 and has 14 - pending and 7 skipped Checks with no terminal failure. The + `77f83dfb2c4611345c0d48f92fceaa6195b4630c` is stacked on #112 and has 19 + successful, 1 pending, and 8 skipped Checks with no terminal failure. The current #106 head `e7fafd4192cc3cc344b8f8e536bc0495afaa739f` likewise has - 14 pending and 7 skipped Checks. PR #109's head - `7b726b16d38ce16d13d00c946b5c8bc0c406191f` has 14 pending and 7 skipped + 19 successful, 1 pending, and 8 skipped Checks. PR #109's head + `7b726b16d38ce16d13d00c946b5c8bc0c406191f` has 19 successful, 1 pending, + and 8 skipped Checks; local locked-install, full pytest, Ruff, Interrogate, and compileall verification passed before its normal merge commit was pushed. PR #107 was rebased cleanly onto #112 at `53842560d397aa20309a6b16aceb560540611686`, and PR #108 was rebased cleanly onto #112 at `538cead991a7c1bed32f2dcb5413b5fc56f53e93`; the latest rollups - are 19 successful, 1 pending, and 8 skipped for #107 and 17 successful, - 2 pending, and 8 skipped for #108, with no terminal failure. Local + are 20 successful, 1 pending, and 8 skipped for #107 and 20 successful, + 1 pending, and 8 skipped for #108, with no terminal failure. Local `uv sync --locked --extra dev` plus the full service pytest suite passed on both rebased trees. Their fresh hosted Checks remain unverified and #112 remains the lock-refresh prerequisite. @@ -289,11 +294,11 @@ https://docs.github.com/en/rest/actions/workflows?apiVersion=2022-11-28 still pending or queued, so hosted security and independent approval success are not claimed. The operator-admin trust boundary and the fresh security changes still require independent exact-head validation. PR #100's - pre-refresh documentation head is - `6e0c92f7512ab8b1eded34e2e6ae9a0476896aba`, with 14 pending and 7 skipped + observed documentation head is + `3b35084632052330bf150ebb8d1f0e9625d73584`, with 14 pending and 7 skipped Checks; its prior review state is not approval. PR #104's updated head `7da9d43087d5647fefb946eb154ee1e5c10c576d` is based on #112's lockfile - head and has 14 pending and 7 skipped Checks. The resulting #100 head + head and has 19 successful, 1 pending, and 8 skipped Checks. The resulting #100 head from this documentation refresh must be re-audited after the commit; its pre-refresh review state is not approval. This record travels in these PRs, so the live PR records remain authoritative diff --git a/docs/product-technical-gap-baseline.md b/docs/product-technical-gap-baseline.md index 49ab95a..15be8b7 100644 --- a/docs/product-technical-gap-baseline.md +++ b/docs/product-technical-gap-baseline.md @@ -68,39 +68,40 @@ tenant, or resource ownership. The following is the current open-PR inventory. `Checks` means the exact head rollup observed on 2026-08-21; it is not inherited from a predecessor commit. This record was refreshed from a live exact-head audit while PR #100 stood at -`d2b765ff2cbcc4e857a0e88e53d631a47ca4980d`; the documentation commit that +`3b35084632052330bf150ebb8d1f0e9625d73584`; the documentation commit that updates this snapshot is intentionally not recursively named. The audit also includes normal branch updates from the #112 lock-refresh base for the dependency/documentation stack. The live PR record is authoritative for the exact hash and Checks; predecessor evidence remains non-transferable. At this snapshot, 14 PRs are open and none has a qualifying formal approval. -#112, #101, and #83 each have 23 successful and 8 skipped Checks with no -queued Check; #107 has 20 successful, 1 queued, and 8 skipped Checks; #108 -has 18 successful, 2 queued, and 8 skipped Checks; #103 has 20 successful, -1 in-progress, 1 queued, and 7 skipped Checks; #113 has 2 successful, 14 -queued, and 7 skipped Checks; and #100, #104, #105, #106, #109, #110, and -#111 each have 1–2 successful, 14 queued, and 7 skipped Checks. +#112, #101, and #83 each have 22 successful and 8 skipped Checks with no +queued Check; #107 and #108 each have 20 successful, 1 queued, and 8 skipped +Checks; #103, #104, #105, #106, #109, and #110 each have 19 successful, 1 +queued, and 8 skipped Checks; #113 and #100 each have 0 successful, 14 queued, +and 7 skipped Checks; and #111 has 18 successful, 2 queued, and 7 skipped +Checks. The exact rollup is listed per PR below; queued Checks remain +unverified rather than green. There is no current terminal failure bucket in this inventory. Historical terminal failures are recorded separately and are not current-head green -evidence. Queued Checks remain unverified rather than green. +evidence. | PR | Scope | Exact-head Checks | Review state | Next safe action | |---:|---|---|---|---| -| [#113](https://github.com/ContextualWisdomLab/keyverse/pull/113) | SCIM `PATCH active=false` shared operation lock, stacked on #112 lockfile refresh | PENDING: 2 successful, 14 queued, 7 skipped, 0 terminal failures on `aaafc2ca2f42bc171c1a0d0b538a99eb2f461233` | requested changes fixed; approval absent | The valid SCIM PatchOp review fix and local full verification are complete; wait for fresh exact-head hosted Checks and independent review. | -| [#112](https://github.com/ContextualWisdomLab/keyverse/pull/112) | Resync account-unification lockfile | PASS: 23 successful, 8 skipped, 0 queued on `f02acf93367a40dbfb23a73985017dca8d42ff39` | review required | Obtain independent review, then let protected automation re-check and merge. | -| [#111](https://github.com/ContextualWisdomLab/keyverse/pull/111) | CodeQL init 4.37.7 | PENDING: 1 successful, 14 queued, 7 skipped, 0 terminal failures on updated head `032f730b0239d062cf9803525ba66c740e0b2d2e` | review required | The normal branch update merged #112's lockfile base into the CodeQL branch; wait for exact-head Checks and independent review. | -| [#110](https://github.com/ContextualWisdomLab/keyverse/pull/110) | CodeQL analyze 4.37.7, stacked on #112 lockfile refresh | PENDING: 1 successful, 14 queued, 7 skipped, 0 terminal failures on updated head `c3e307fc3d4f6d98ec5a0514f35aa8038b2737b7` | review required | The normal branch update includes #112's lock-refresh base; wait for exact-head Checks and independent review. | -| [#109](https://github.com/ContextualWisdomLab/keyverse/pull/109) | `typing-inspection` update, stacked on #112 lockfile refresh | PENDING: 1 successful, 14 queued, 7 skipped, 0 terminal failures on `7b726b16d38ce16d13d00c946b5c8bc0c406191f` | review required | The normal merge and local locked-install/full-suite verification are complete; wait for fresh hosted Checks and independent review. | -| [#108](https://github.com/ContextualWisdomLab/keyverse/pull/108) | Ruff update, stacked on #112 lockfile refresh | PENDING: 18 successful, 2 queued, 8 skipped, 0 terminal failures on `538cead991a7c1bed32f2dcb5413b5fc56f53e93` | review required | The conflicting lockfile base was rebased cleanly onto #112; wait for remaining exact-head Checks and independent review. | +| [#113](https://github.com/ContextualWisdomLab/keyverse/pull/113) | SCIM `PATCH active=false` shared operation lock, stacked on #112 lockfile refresh | PENDING: 0 successful, 14 queued, 7 skipped, 0 terminal failures on `aaafc2ca2f42bc171c1a0d0b538a99eb2f461233` | requested changes fixed; approval absent | The valid SCIM PatchOp review fix and local full verification are complete; wait for fresh exact-head hosted Checks and independent review. | +| [#112](https://github.com/ContextualWisdomLab/keyverse/pull/112) | Resync account-unification lockfile | PASS: 22 successful, 8 skipped, 0 queued on `f02acf93367a40dbfb23a73985017dca8d42ff39` | review required | Obtain independent review, then let protected automation re-check and merge. | +| [#111](https://github.com/ContextualWisdomLab/keyverse/pull/111) | CodeQL init 4.37.7 | PENDING: 18 successful, 2 queued, 7 skipped, 0 terminal failures on updated head `032f730b0239d062cf9803525ba66c740e0b2d2e` | review required | The normal branch update merged #112's lockfile base into the CodeQL branch; resolve the queued Strix retry and remaining coverage Check, then obtain independent review. | +| [#110](https://github.com/ContextualWisdomLab/keyverse/pull/110) | CodeQL analyze 4.37.7, stacked on #112 lockfile refresh | PENDING: 19 successful, 1 queued, 8 skipped, 0 terminal failures on updated head `c3e307fc3d4f6d98ec5a0514f35aa8038b2737b7` | review required | The normal branch update includes #112's lock-refresh base; wait for exact-head Checks and independent review. | +| [#109](https://github.com/ContextualWisdomLab/keyverse/pull/109) | `typing-inspection` update, stacked on #112 lockfile refresh | PENDING: 19 successful, 1 queued, 8 skipped, 0 terminal failures on `7b726b16d38ce16d13d00c946b5c8bc0c406191f` | review required | The normal merge and local locked-install/full-suite verification are complete; wait for fresh hosted Checks and independent review. | +| [#108](https://github.com/ContextualWisdomLab/keyverse/pull/108) | Ruff update, stacked on #112 lockfile refresh | PENDING: 20 successful, 1 queued, 8 skipped, 0 terminal failures on `538cead991a7c1bed32f2dcb5413b5fc56f53e93` | review required | The conflicting lockfile base was rebased cleanly onto #112; wait for remaining exact-head Checks and independent review. | | [#107](https://github.com/ContextualWisdomLab/keyverse/pull/107) | Uvicorn update, stacked on #112 lockfile refresh | PENDING: 20 successful, 1 queued, 8 skipped, 0 terminal failures on `53842560d397aa20309a6b16aceb560540611686` | review required | The conflicting lockfile base was rebased cleanly onto #112; wait for the remaining exact-head Check and independent review. | -| [#106](https://github.com/ContextualWisdomLab/keyverse/pull/106) | `setup-uv` update, stacked on #112 lockfile refresh | PENDING: 1 successful, 14 queued, 7 skipped, 0 terminal failures on updated head `e7fafd4192cc3cc344b8f8e536bc0495afaa739f` | review required | The normal branch update includes #112's lockfile base; wait for exact-head Checks and independent review. | -| [#105](https://github.com/ContextualWisdomLab/keyverse/pull/105) | `harden-runner` update, stacked on #112 lockfile refresh | PENDING: 1 successful, 14 queued, 7 skipped, 0 terminal failures on updated head `77f83dfb2c4611345c0d48f92fceaa6195b4630c` | changes requested | The normal branch update includes #112's lockfile base; obtain current-head independent review. | -| [#104](https://github.com/ContextualWisdomLab/keyverse/pull/104) | ADR and buyer README expansion, stacked on #112 | PENDING: 2 successful, 14 queued, 7 skipped, 0 terminal failures on updated head `7da9d43087d5647fefb946eb154ee1e5c10c576d` | review required | Base remains `fix/account-unification-lock-20260819`; obtain independent review and terminal stacked-head Checks. | -| [#103](https://github.com/ContextualWisdomLab/keyverse/pull/103) | Hierarchical authorization, login helper, PATs | PENDING: 20 successful, 1 in-progress, 1 queued, 7 skipped, 0 terminal failures on `9274d3184443fba6c6294e08dff20734f3ae6fb4` | current findings addressed; approval absent | Exact-tree regressions and local 100% verification pass; wait for hosted security Checks and independent review before any merge claim. | -| [#101](https://github.com/ContextualWisdomLab/keyverse/pull/101) | Atomic coupled Python dependency updates | PASS: 23 successful, 8 skipped, 0 queued on `50dd9c96cab5c230f775685e8baea939fba390dd` | changes requested | Obtain fresh independent review; this is the policy companion to the lockfile gap. | -| [#100](https://github.com/ContextualWisdomLab/keyverse/pull/100) | `lineageweave-web` account-derived claims plus default validator-path coverage | PENDING: 1 successful, 1 pending, 14 queued, 7 skipped, 0 terminal failures on the pre-refresh snapshot head `d2b765ff2cbcc4e857a0e88e53d631a47ca4980d` | current findings addressed; approval absent | The current-tree review findings are addressed; re-audit this documentation successor after its normal push without self-approval. | -| [#83](https://github.com/ContextualWisdomLab/keyverse/pull/83) | Remove runtime application RPs from portable realm | PASS: 23 successful, 8 skipped, 0 queued on `dd1ab7444a75342b42e3af013ccda6d1dbfb359d` | changes requested | Reconfirm current-head approval and latest-pusher rule before protected merge. | +| [#106](https://github.com/ContextualWisdomLab/keyverse/pull/106) | `setup-uv` update, stacked on #112 lockfile refresh | PENDING: 19 successful, 1 queued, 8 skipped, 0 terminal failures on updated head `e7fafd4192cc3cc344b8f8e536bc0495afaa739f` | review required | The normal branch update includes #112's lockfile base; wait for exact-head Checks and independent review. | +| [#105](https://github.com/ContextualWisdomLab/keyverse/pull/105) | `harden-runner` update, stacked on #112 lockfile refresh | PENDING: 19 successful, 1 queued, 8 skipped, 0 terminal failures on updated head `77f83dfb2c4611345c0d48f92fceaa6195b4630c` | changes requested | The normal branch update includes #112's lockfile base; obtain current-head independent review. | +| [#104](https://github.com/ContextualWisdomLab/keyverse/pull/104) | ADR and buyer README expansion, stacked on #112 | PENDING: 19 successful, 1 queued, 8 skipped, 0 terminal failures on updated head `7da9d43087d5647fefb946eb154ee1e5c10c576d` | review required | Base remains `fix/account-unification-lock-20260819`; obtain independent review and terminal stacked-head Checks. | +| [#103](https://github.com/ContextualWisdomLab/keyverse/pull/103) | Hierarchical authorization, login helper, PATs | PENDING: 19 successful, 1 queued, 8 skipped, 0 terminal failures on `9274d3184443fba6c6294e08dff20734f3ae6fb4` | current findings addressed; approval absent | Exact-tree regressions and local 100% verification pass; wait for hosted security Checks and independent review before any merge claim. | +| [#101](https://github.com/ContextualWisdomLab/keyverse/pull/101) | Atomic coupled Python dependency updates | PASS: 22 successful, 8 skipped, 0 queued on `50dd9c96cab5c230f775685e8baea939fba390dd` | changes requested | Obtain fresh independent review; this is the policy companion to the lockfile gap. | +| [#100](https://github.com/ContextualWisdomLab/keyverse/pull/100) | `lineageweave-web` account-derived claims plus default validator-path coverage | PENDING: 0 successful, 14 queued, 7 skipped, 0 terminal failures on observed head `3b35084632052330bf150ebb8d1f0e9625d73584` | current findings addressed; approval absent | The current-tree review findings are addressed; wait for exact-head Checks and independent review without self-approval. | +| [#83](https://github.com/ContextualWisdomLab/keyverse/pull/83) | Remove runtime application RPs from portable realm | PASS: 22 successful, 8 skipped, 0 queued on `dd1ab7444a75342b42e3af013ccda6d1dbfb359d` | changes requested | Reconfirm current-head approval and latest-pusher rule before protected merge. | ### Historical check failure root causes observed @@ -129,6 +130,14 @@ evidence. produced current head `032f730b`; its fresh `account-unification-tests` run is queued, so the old failure is historical and the new result is unverified. +- PR #111's first Strix attempt on the unchanged CodeQL-only diff failed after + the Nemotron provider emitted one critical Compose configuration finding. + The same Compose content passed the neighboring #110 and #112 scans, and the + report contradicted the checked configuration by describing an unset + password variable as a default credential. The failure is retained as + historical model evidence rather than silently converted to green; a normal + exact-head Strix retry is queued as run attempt 2. + - The representative account-test failure on Dependabot PRs stopped at `uv sync --locked`: the checked-in lockfile needed updating. This is a dependency-graph consistency failure, not evidence that the product tests From f331938a4f3cd6808101b8888b76c0f87b1eb841 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 21 Aug 2026 14:08:10 +0900 Subject: [PATCH 67/70] docs: distinguish neutral security evidence --- docs/doctoring/product-technical-gap-baseline.md | 3 ++- docs/product-technical-gap-baseline.md | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/doctoring/product-technical-gap-baseline.md b/docs/doctoring/product-technical-gap-baseline.md index 270c26e..5b997ac 100644 --- a/docs/doctoring/product-technical-gap-baseline.md +++ b/docs/doctoring/product-technical-gap-baseline.md @@ -255,7 +255,8 @@ https://docs.github.com/en/rest/actions/workflows?apiVersion=2022-11-28 through a normal branch update. Its prior `account-unification-tests` failure occurred before that update; the fresh run remains unverified. Its first Strix attempt also failed on contradictory model-generated Compose - evidence; a normal exact-head attempt 2 is queued. It remains coupled to + evidence; the neighboring #110 check used its neutral backend fallback and + #112 passed. A normal exact-head attempt 2 is queued. It remains coupled to #112 and #110. PR #110's current head `c3e307fc3d4f6d98ec5a0514f35aa8038b2737b7` remains on the #112 base with 19 successful, 1 pending, and 8 skipped Checks; its hosted reruns remain diff --git a/docs/product-technical-gap-baseline.md b/docs/product-technical-gap-baseline.md index 15be8b7..c7d6a29 100644 --- a/docs/product-technical-gap-baseline.md +++ b/docs/product-technical-gap-baseline.md @@ -132,8 +132,8 @@ evidence. - PR #111's first Strix attempt on the unchanged CodeQL-only diff failed after the Nemotron provider emitted one critical Compose configuration finding. - The same Compose content passed the neighboring #110 and #112 scans, and the - report contradicted the checked configuration by describing an unset + The neighboring #110 check completed through its neutral backend fallback + and #112 passed; the report contradicted the checked configuration by describing an unset password variable as a default credential. The failure is retained as historical model evidence rather than silently converted to green; a normal exact-head Strix retry is queued as run attempt 2. From d37d6275a740b0aeacab02f6b951d5d02de95fc2 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 21 Aug 2026 15:47:21 +0900 Subject: [PATCH 68/70] docs: refresh live product gap evidence --- .../product-technical-gap-baseline.md | 71 +++++++++++----- docs/product-technical-gap-baseline.md | 81 +++++++++++++------ 2 files changed, 105 insertions(+), 47 deletions(-) diff --git a/docs/doctoring/product-technical-gap-baseline.md b/docs/doctoring/product-technical-gap-baseline.md index 5b997ac..ccbde40 100644 --- a/docs/doctoring/product-technical-gap-baseline.md +++ b/docs/doctoring/product-technical-gap-baseline.md @@ -44,6 +44,23 @@ evidence gaps. mechanism that projects roles and user/session data into tokens. That vendor behavior does not establish that a receiving application enforces ABAC/RBAC. +## 2026-08-21 MCP OAuth design evidence + +- Issue #114 remains an active buyer gap. Keyverse must use Keycloak as the + authorization server, not add a static MCP API key or a second user/token + authority. +- Keyverse PR #115 is open at exact head + `7281c3d961f40bf47383b8cddeae750af1298ad5`. It adds proposed ADR-0013 and + `docs/doctoring/mcp-oauth-authorization.md`, covering OIDC/RFC 8414 + discovery, public-client authorization code plus `S256` PKCE, exact + redirects, RFC 8707 resource binding, RFC 9728 LineageWeave metadata, + centralized revocation/audit, and negative evidence. +- PR #115 is documentation-only. Its current rollup has 2 pending, 14 queued, + and 7 skipped Checks with review required; no MCP browser flow, resource + metadata endpoint, resource-bound token, revocation check, or LineageWeave + end-to-end result is claimed. RFC 8628 remains deferred until a real + callback-less client requires it. + ## 2026-08-21 local runtime probe This is partial protocol-readiness evidence, not login or release acceptance. @@ -211,6 +228,18 @@ Sheffer, Y., Hardt, D., & Jones, M. (2020). *JSON Web Token best current practices* (RFC 8725). Internet Engineering Task Force. https://www.rfc-editor.org/rfc/rfc8725.html +Internet Engineering Task Force. (2018). *OAuth 2.0 authorization server +metadata* (RFC 8414). https://doi.org/10.17487/RFC8414 + +Internet Engineering Task Force. (2024). *Resource indicators for OAuth 2.0* +(RFC 8707). https://doi.org/10.17487/RFC8707 + +Internet Engineering Task Force. (2024). *OAuth 2.0 protected resource +metadata* (RFC 9728). https://doi.org/10.17487/RFC9728 + +Model Context Protocol. (2025, November 25). *Authorization*. +https://modelcontextprotocol.io/specification/2025-11-25/basic/authorization + GitHub. (2026). *REST API endpoints for workflows*. https://docs.github.com/en/rest/actions/workflows?apiVersion=2022-11-28 @@ -218,28 +247,30 @@ https://docs.github.com/en/rest/actions/workflows?apiVersion=2022-11-28 - `docs/PRD.md`, `docs/TRD.md`, `ARCHITECTURE.md`, `docs/OPERABILITY.md`, `docs/THREAT_MODEL.md`, `docs/TEST_STRATEGY.md`, and `docs/TRACEABILITY.md`. -- ADR-0008 and ADR-0009 plus their related specification, plan, operations, - and doctoring records. +- ADR-0008, ADR-0009, and proposed ADR-0013 plus their related specification, + plan, operations, and doctoring records. - The live open-Issue query performed on 2026-08-21 found five open issues; newly tracked Issue #114 defines the buyer gap for MCP-compatible OAuth client - authorization for headless agents. Its standards list is issue scope, not - yet an adopted Keyverse runtime contract; implementation remains deferred - until the PR and Issue queue is exhausted. + authorization for headless agents. PR #115 proposes its design contract; + implementation remains deferred until that contract is independently + reviewed and the PR/Issue queue permits a bounded runtime change. - LineageWeave PRs #333 and #334 are both currently closed without merge; their managed/static MCP API-key direction is superseded by Issue #114's centralized Keyverse OAuth boundary and must not be revived as a second identity, issuance, revocation, or audit system. - Exact-head GitHub PR, review, issue, check-run, ruleset, and scheduled-run - queries performed on 2026-08-21. Fourteen Keyverse PRs are open: #112, #101, - and #83 each have 22 successful and 8 skipped Checks with no pending run. - #107 has 20 successful, 1 pending, and 8 skipped; #108 has 20 successful, - 1 pending, and 8 skipped. PRs #113 and #100 have 14 pending and 7 skipped; - #111 has 18 successful, 2 pending, and 7 skipped; and #103, #104, #105, - #106, #109, and #110 each have 19 successful, 1 pending, and 8 skipped - Checks. No current open PR has a qualifying formal approval or terminal - failure. Pending Checks remain unverified. + queries performed on 2026-08-21. Fifteen Keyverse PRs are open: #112, #101, + and #83 each have 23 successful and 8 skipped Checks with no pending run; + #108 and #107 each have 21 successful, 1 queued, and 8 skipped; #110 and + #109 each have 20 successful, 1 queued, and 8 skipped; #111 has 19 + successful, 2 queued, and 7 skipped; #106 and #105 each have 20 successful, + 1 queued, and 8 skipped; #104 has 21 successful, 1 queued, and 8 skipped; + #103 and #100 each have 2 successful, 14 queued, and 7 skipped; #113 has 2 + successful, 14 queued, and 7 skipped; and #115 has 2 pending, 14 queued, + and 7 skipped Checks. No current open PR has a qualifying formal approval or + terminal failure. Pending and queued Checks remain unverified. PR #113's current SCIM lock head - `aaafc2ca2f42bc171c1a0d0b538a99eb2f461233` includes the normal prerequisite + `49136c24fb07e3a8ed01171785e6946c559ea2a5` includes the normal prerequisite lockfile history, a realistic SCIM PatchOp race, and the corrected valid root-level deactivation payload. Its hosted Checks remain pending with no terminal failure. Local focused/full verification and 100% statement/branch @@ -286,7 +317,7 @@ https://docs.github.com/en/rest/actions/workflows?apiVersion=2022-11-28 remains the lock-refresh prerequisite. PR #103's historical terminal Strix run 32092025335 / job 95576032571 emitted a MEDIUM IDOR report with contradictory model text. Its current exact - head `9274d3184443fba6c6294e08dff20734f3ae6fb4` adds RED-to-GREEN regressions + head `e765f4860177af47b80b05ee3a918a4dc2cb4450` adds RED-to-GREEN regressions for percent-encoded discovery markers, inactive and expired token rotation, invalid token rotation settings, KV/audit lifecycle failures, direct router embedding, tenant isolation, software-unit ABAC, runtime authentication, and @@ -295,13 +326,11 @@ https://docs.github.com/en/rest/actions/workflows?apiVersion=2022-11-28 still pending or queued, so hosted security and independent approval success are not claimed. The operator-admin trust boundary and the fresh security changes still require independent exact-head validation. PR #100's - observed documentation head is - `3b35084632052330bf150ebb8d1f0e9625d73584`, with 14 pending and 7 skipped - Checks; its prior review state is not approval. PR #104's updated + current documentation head is + `f331938a4f3cd6808101b8888b76c0f87b1eb841`, with 2 successful, 14 queued, + and 7 skipped Checks; its changes-requested review state is not approval. PR #104's updated head `7da9d43087d5647fefb946eb154ee1e5c10c576d` is based on #112's lockfile - head and has 19 successful, 1 pending, and 8 skipped Checks. The resulting #100 head - from this documentation refresh must be re-audited after the commit; its - pre-refresh review state is not approval. + head and has 21 successful, 1 queued, and 8 skipped Checks. This record travels in these PRs, so the live PR records remain authoritative for their changing exact hashes. The active ruleset requires two approving reviews, resolved threads, and diff --git a/docs/product-technical-gap-baseline.md b/docs/product-technical-gap-baseline.md index c7d6a29..1f14b7e 100644 --- a/docs/product-technical-gap-baseline.md +++ b/docs/product-technical-gap-baseline.md @@ -68,40 +68,44 @@ tenant, or resource ownership. The following is the current open-PR inventory. `Checks` means the exact head rollup observed on 2026-08-21; it is not inherited from a predecessor commit. This record was refreshed from a live exact-head audit while PR #100 stood at -`3b35084632052330bf150ebb8d1f0e9625d73584`; the documentation commit that +`f331938a4f3cd6808101b8888b76c0f87b1eb841`; the documentation commit that updates this snapshot is intentionally not recursively named. The audit also includes normal branch updates from the #112 lock-refresh base for the dependency/documentation stack. The live PR record is authoritative for the exact hash and Checks; predecessor evidence remains non-transferable. -At this snapshot, 14 PRs are open and none has a qualifying formal approval. -#112, #101, and #83 each have 22 successful and 8 skipped Checks with no -queued Check; #107 and #108 each have 20 successful, 1 queued, and 8 skipped -Checks; #103, #104, #105, #106, #109, and #110 each have 19 successful, 1 -queued, and 8 skipped Checks; #113 and #100 each have 0 successful, 14 queued, -and 7 skipped Checks; and #111 has 18 successful, 2 queued, and 7 skipped -Checks. The exact rollup is listed per PR below; queued Checks remain -unverified rather than green. +At this snapshot, 15 PRs are open and none has a qualifying formal approval. +#112, #101, and #83 each have 23 successful and 8 skipped Checks with no +queued Check; #108 and #107 each have 21 successful, 1 queued, and 8 skipped +Checks; #110 and #109 each have 20 successful, 1 queued, and 8 skipped Checks; +#111 has 19 successful, 2 queued, and 7 skipped Checks; #106 and #105 each have +20 successful, 1 queued, and 8 skipped Checks; #104 has 21 successful, 1 +queued, and 8 skipped Checks; #103 and #100 each have 2 successful, 14 queued, +and 7 skipped Checks; #113 has 2 successful, 14 queued, and 7 skipped Checks; +and #115 has 2 pending, 14 queued, and 7 skipped Checks. The exact rollup is +listed per PR below; pending and queued Checks remain unverified rather than +green. There is no current terminal failure bucket in this inventory. Historical terminal failures are recorded separately and are not current-head green evidence. | PR | Scope | Exact-head Checks | Review state | Next safe action | |---:|---|---|---|---| -| [#113](https://github.com/ContextualWisdomLab/keyverse/pull/113) | SCIM `PATCH active=false` shared operation lock, stacked on #112 lockfile refresh | PENDING: 0 successful, 14 queued, 7 skipped, 0 terminal failures on `aaafc2ca2f42bc171c1a0d0b538a99eb2f461233` | requested changes fixed; approval absent | The valid SCIM PatchOp review fix and local full verification are complete; wait for fresh exact-head hosted Checks and independent review. | -| [#112](https://github.com/ContextualWisdomLab/keyverse/pull/112) | Resync account-unification lockfile | PASS: 22 successful, 8 skipped, 0 queued on `f02acf93367a40dbfb23a73985017dca8d42ff39` | review required | Obtain independent review, then let protected automation re-check and merge. | -| [#111](https://github.com/ContextualWisdomLab/keyverse/pull/111) | CodeQL init 4.37.7 | PENDING: 18 successful, 2 queued, 7 skipped, 0 terminal failures on updated head `032f730b0239d062cf9803525ba66c740e0b2d2e` | review required | The normal branch update merged #112's lockfile base into the CodeQL branch; resolve the queued Strix retry and remaining coverage Check, then obtain independent review. | -| [#110](https://github.com/ContextualWisdomLab/keyverse/pull/110) | CodeQL analyze 4.37.7, stacked on #112 lockfile refresh | PENDING: 19 successful, 1 queued, 8 skipped, 0 terminal failures on updated head `c3e307fc3d4f6d98ec5a0514f35aa8038b2737b7` | review required | The normal branch update includes #112's lock-refresh base; wait for exact-head Checks and independent review. | -| [#109](https://github.com/ContextualWisdomLab/keyverse/pull/109) | `typing-inspection` update, stacked on #112 lockfile refresh | PENDING: 19 successful, 1 queued, 8 skipped, 0 terminal failures on `7b726b16d38ce16d13d00c946b5c8bc0c406191f` | review required | The normal merge and local locked-install/full-suite verification are complete; wait for fresh hosted Checks and independent review. | -| [#108](https://github.com/ContextualWisdomLab/keyverse/pull/108) | Ruff update, stacked on #112 lockfile refresh | PENDING: 20 successful, 1 queued, 8 skipped, 0 terminal failures on `538cead991a7c1bed32f2dcb5413b5fc56f53e93` | review required | The conflicting lockfile base was rebased cleanly onto #112; wait for remaining exact-head Checks and independent review. | -| [#107](https://github.com/ContextualWisdomLab/keyverse/pull/107) | Uvicorn update, stacked on #112 lockfile refresh | PENDING: 20 successful, 1 queued, 8 skipped, 0 terminal failures on `53842560d397aa20309a6b16aceb560540611686` | review required | The conflicting lockfile base was rebased cleanly onto #112; wait for the remaining exact-head Check and independent review. | -| [#106](https://github.com/ContextualWisdomLab/keyverse/pull/106) | `setup-uv` update, stacked on #112 lockfile refresh | PENDING: 19 successful, 1 queued, 8 skipped, 0 terminal failures on updated head `e7fafd4192cc3cc344b8f8e536bc0495afaa739f` | review required | The normal branch update includes #112's lockfile base; wait for exact-head Checks and independent review. | -| [#105](https://github.com/ContextualWisdomLab/keyverse/pull/105) | `harden-runner` update, stacked on #112 lockfile refresh | PENDING: 19 successful, 1 queued, 8 skipped, 0 terminal failures on updated head `77f83dfb2c4611345c0d48f92fceaa6195b4630c` | changes requested | The normal branch update includes #112's lockfile base; obtain current-head independent review. | -| [#104](https://github.com/ContextualWisdomLab/keyverse/pull/104) | ADR and buyer README expansion, stacked on #112 | PENDING: 19 successful, 1 queued, 8 skipped, 0 terminal failures on updated head `7da9d43087d5647fefb946eb154ee1e5c10c576d` | review required | Base remains `fix/account-unification-lock-20260819`; obtain independent review and terminal stacked-head Checks. | -| [#103](https://github.com/ContextualWisdomLab/keyverse/pull/103) | Hierarchical authorization, login helper, PATs | PENDING: 19 successful, 1 queued, 8 skipped, 0 terminal failures on `9274d3184443fba6c6294e08dff20734f3ae6fb4` | current findings addressed; approval absent | Exact-tree regressions and local 100% verification pass; wait for hosted security Checks and independent review before any merge claim. | -| [#101](https://github.com/ContextualWisdomLab/keyverse/pull/101) | Atomic coupled Python dependency updates | PASS: 22 successful, 8 skipped, 0 queued on `50dd9c96cab5c230f775685e8baea939fba390dd` | changes requested | Obtain fresh independent review; this is the policy companion to the lockfile gap. | -| [#100](https://github.com/ContextualWisdomLab/keyverse/pull/100) | `lineageweave-web` account-derived claims plus default validator-path coverage | PENDING: 0 successful, 14 queued, 7 skipped, 0 terminal failures on observed head `3b35084632052330bf150ebb8d1f0e9625d73584` | current findings addressed; approval absent | The current-tree review findings are addressed; wait for exact-head Checks and independent review without self-approval. | -| [#83](https://github.com/ContextualWisdomLab/keyverse/pull/83) | Remove runtime application RPs from portable realm | PASS: 22 successful, 8 skipped, 0 queued on `dd1ab7444a75342b42e3af013ccda6d1dbfb359d` | changes requested | Reconfirm current-head approval and latest-pusher rule before protected merge. | +| [#115](https://github.com/ContextualWisdomLab/keyverse/pull/115) | Proposed ADR/doctoring for MCP-compatible OAuth client authorization | PENDING: 2 pending, 14 queued, 7 skipped, 0 terminal failures on `7281c3d961f40bf47383b8cddeae750af1298ad5` | review required | Obtain independent ADR review; do not treat the design PR as runtime MCP evidence or begin implementation before the trust boundary is accepted. | +| [#113](https://github.com/ContextualWisdomLab/keyverse/pull/113) | SCIM `PATCH active=false` shared operation lock, stacked on #112 lockfile refresh | PENDING: 2 successful, 14 queued, 7 skipped, 0 terminal failures on `49136c24fb07e3a8ed01171785e6946c559ea2a5` | review required | The valid SCIM PatchOp review fix and local full verification are complete; wait for fresh exact-head hosted Checks and independent review. | +| [#112](https://github.com/ContextualWisdomLab/keyverse/pull/112) | Resync account-unification lockfile | PASS: 23 successful, 8 skipped, 0 queued on `f02acf93367a40dbfb23a73985017dca8d42ff39` | review required | Obtain independent review, then let protected automation re-check and merge. | +| [#111](https://github.com/ContextualWisdomLab/keyverse/pull/111) | CodeQL init 4.37.7 | PENDING: 19 successful, 2 queued, 7 skipped, 0 terminal failures on updated head `032f730b0239d062cf9803525ba66c740e0b2d2e` | review required | The normal branch update merged #112's lockfile base into the CodeQL branch; resolve the queued Strix retry and remaining coverage Check, then obtain independent review. | +| [#110](https://github.com/ContextualWisdomLab/keyverse/pull/110) | CodeQL analyze 4.37.7, stacked on #112 lockfile refresh | PENDING: 20 successful, 1 queued, 8 skipped, 0 terminal failures on updated head `c3e307fc3d4f6d98ec5a0514f35aa8038b2737b7` | review required | The normal branch update includes #112's lock-refresh base; wait for exact-head Checks and independent review. | +| [#109](https://github.com/ContextualWisdomLab/keyverse/pull/109) | `typing-inspection` update, stacked on #112 lockfile refresh | PENDING: 20 successful, 1 queued, 8 skipped, 0 terminal failures on `7b726b16d38ce16d13d00c946b5c8bc0c406191f` | review required | The normal merge and local locked-install/full-suite verification are complete; wait for fresh hosted Checks and independent review. | +| [#108](https://github.com/ContextualWisdomLab/keyverse/pull/108) | Ruff update, stacked on #112 lockfile refresh | PENDING: 21 successful, 1 queued, 8 skipped, 0 terminal failures on `538cead991a7c1bed32f2dcb5413b5fc56f53e93` | review required | The conflicting lockfile base was rebased cleanly onto #112; wait for remaining exact-head Checks and independent review. | +| [#107](https://github.com/ContextualWisdomLab/keyverse/pull/107) | Uvicorn update, stacked on #112 lockfile refresh | PENDING: 21 successful, 1 queued, 8 skipped, 0 terminal failures on `53842560d397aa20309a6b16aceb560540611686` | review required | The conflicting lockfile base was rebased cleanly onto #112; wait for the remaining exact-head Check and independent review. | +| [#106](https://github.com/ContextualWisdomLab/keyverse/pull/106) | `setup-uv` update, stacked on #112 lockfile refresh | PENDING: 20 successful, 1 queued, 8 skipped, 0 terminal failures on updated head `e7fafd4192cc3cc344b8f8e536bc0495afaa739f` | review required | The normal branch update includes #112's lockfile base; wait for exact-head Checks and independent review. | +| [#105](https://github.com/ContextualWisdomLab/keyverse/pull/105) | `harden-runner` update, stacked on #112 lockfile refresh | PENDING: 20 successful, 1 queued, 8 skipped, 0 terminal failures on updated head `77f83dfb2c4611345c0d48f92fceaa6195b4630c` | changes requested | The normal branch update includes #112's lockfile base; obtain current-head independent review. | +| [#104](https://github.com/ContextualWisdomLab/keyverse/pull/104) | ADR and buyer README expansion, stacked on #112 | PENDING: 21 successful, 1 queued, 8 skipped, 0 terminal failures on updated head `7da9d43087d5647fefb946eb154ee1e5c10c576d` | review required | Base remains `fix/account-unification-lock-20260819`; obtain independent review and terminal stacked-head Checks. | +| [#103](https://github.com/ContextualWisdomLab/keyverse/pull/103) | Hierarchical authorization, login helper, PATs | PENDING: 2 successful, 14 queued, 7 skipped, 0 terminal failures on `e765f4860177af47b80b05ee3a918a4dc2cb4450` | changes requested | Exact-tree regressions and local 100% verification pass; wait for hosted security Checks and current-head independent review before any merge claim. | +| [#101](https://github.com/ContextualWisdomLab/keyverse/pull/101) | Atomic coupled Python dependency updates | PASS: 23 successful, 8 skipped, 0 queued on `50dd9c96cab5c230f775685e8baea939fba390dd` | changes requested | Obtain fresh independent review; this is the policy companion to the lockfile gap. | +| [#100](https://github.com/ContextualWisdomLab/keyverse/pull/100) | `lineageweave-web` account-derived claims plus default validator-path coverage | PENDING: 2 successful, 14 queued, 7 skipped, 0 terminal failures on observed head `f331938a4f3cd6808101b8888b76c0f87b1eb841` | changes requested | The current-tree review findings are addressed; wait for exact-head Checks and independent review without self-approval. | +| [#83](https://github.com/ContextualWisdomLab/keyverse/pull/83) | Remove runtime application RPs from portable realm | PASS: 23 successful, 8 skipped, 0 queued on `dd1ab7444a75342b42e3af013ccda6d1dbfb359d` | changes requested | Reconfirm current-head approval and latest-pusher rule before protected merge. | ### Historical check failure root causes observed @@ -118,7 +122,7 @@ evidence. that exact failed run green. - PR #113's current exact head - `aaafc2ca2f42bc171c1a0d0b538a99eb2f461233` contains the valid SCIM PatchOp + `49136c24fb07e3a8ed01171785e6946c559ea2a5` contains the valid SCIM PatchOp review correction and passed focused/full local verification with 100% statement and branch coverage. Its hosted Checks remain pending with no terminal failure, and independent approval is absent. @@ -158,7 +162,7 @@ evidence. operator token does not expose distinct end-user principals; independent security validation must resolve that trust-boundary interpretation. Until then the failure remains blocking and is not converted into a pass. -- PR #103's current exact head `9274d3184443fba6c6294e08dff20734f3ae6fb4` +- PR #103's current exact head `e765f4860177af47b80b05ee3a918a4dc2cb4450` adds RED-to-GREEN regressions for percent-encoded discovery markers, inactive and expired token rotation, invalid token rotation settings, KV/audit lifecycle failures, direct router embedding, tenant isolation, software-unit @@ -171,7 +175,7 @@ evidence. | Issue | Product signal | Classification | Required outcome | |---:|---|---|---| -| [#114](https://github.com/ContextualWisdomLab/keyverse/issues/114) | MCP-compatible OAuth client authorization for headless agents | `active-issue` | Define the Keyverse authorization-server and OIDC discovery contract, public-client authorization code + PKCE, exact redirects, resource-bound least-privilege tokens, centralized revocation/audit, and negative browser/client evidence. Evaluate RFC 8628 only for clients that cannot use a callback; do not implement it speculatively. | +| [#114](https://github.com/ContextualWisdomLab/keyverse/issues/114) | MCP-compatible OAuth client authorization for headless agents | `active-issue` / design `active-PR` | PR #115 proposes ADR-0013 and the doctoring record for Keycloak-backed discovery, public-client authorization code + PKCE, exact redirects, resource-bound least-privilege tokens, centralized revocation/audit, and negative browser/client evidence. Runtime implementation remains unclaimed; evaluate RFC 8628 only for clients that cannot use a callback. | | [#102](https://github.com/ContextualWisdomLab/keyverse/issues/102) | Hierarchical authorization plane, login helper, PATs | `active-PR` | Security-review the proposed authority model and prove fail-closed token/tenant/resource behavior. | | [#99](https://github.com/ContextualWisdomLab/keyverse/issues/99) | Orphaned federation and product-loop workflow identities | `active-issue` | The exact protected-main cleanup completed: 43 registry identities remain, with 4 supported repository paths active, 37 orphan repository-path identities `disabled_manually`, and 2 GitHub-owned dynamic identities unchanged. The recurrence detector, adversarial tests, and central coordination acceptance remain open. | | [#71](https://github.com/ContextualWisdomLab/keyverse/issues/71) | Remove runtime application RPs from portable import | `active-PR` | Merge #83 only after current-head protected evidence. | @@ -235,6 +239,27 @@ and verifier-unavailable fail-closed behavior. Keep secrets and PII out of repository artifacts. An unavailable issuer must remain `unavailable`, never be converted into a synthetic success. +### G8 — MCP-compatible OAuth resource authorization + +**State:** `active-PR` design; runtime remains `gap-not-claimed` +**Buyer impact:** An MCP client currently has no protected-main evidence for a +passwordless authorization-code path that is bound to one LineageWeave resource +and centrally revocable. + +**Current action:** PR #115 proposes ADR-0013 and its doctoring record. The +design keeps Keycloak as the authorization server, assigns RFC 9728 protected- +resource metadata to LineageWeave, requires exact public-client redirects and +`S256` PKCE, binds one canonical RFC 8707 resource URI to the token audience and +least-privilege scope set, and defers RFC 8628 until a real callback-less client +requires it. The PR is documentation-only; its pending/queued Checks and +review-required state are not runtime evidence. + +**Acceptance:** after ADR review, run a real browser/client flow and record +discovery agreement, exact redirect/PKCE/resource/scope checks, wrong +issuer/audience/resource/redirect/expiry/revocation denials, cross-tenant and +cross-workspace denials, and no static MCP API-key path. Keep discovery +side-effect-free in existing preflight tests and avoid bearer material in logs. + ### G4 — SCIM deactivation concurrency boundary **State:** `active-PR` with an explicit protected-main limitation @@ -330,6 +355,10 @@ before implementation is claimed. - Keycloak. (2026). *Server administration guide*. https://www.keycloak.org/docs/latest/server_admin/ - Lodderstedt, T., Bradley, J., Labunets, A., & Fett, D. (2025). *Best current practice for OAuth 2.0 security* (RFC 9700). Internet Engineering Task Force. https://www.rfc-editor.org/rfc/rfc9700.html - Sheffer, Y., Hardt, D., & Jones, M. (2020). *JSON Web Token best current practices* (RFC 8725). Internet Engineering Task Force. https://www.rfc-editor.org/rfc/rfc8725.html +- Internet Engineering Task Force. (2018). *OAuth 2.0 authorization server metadata* (RFC 8414). https://doi.org/10.17487/RFC8414 +- Internet Engineering Task Force. (2024). *Resource indicators for OAuth 2.0* (RFC 8707). https://doi.org/10.17487/RFC8707 +- Internet Engineering Task Force. (2024). *OAuth 2.0 protected resource metadata* (RFC 9728). https://doi.org/10.17487/RFC9728 +- Model Context Protocol. (2025, November 25). *Authorization*. https://modelcontextprotocol.io/specification/2025-11-25/basic/authorization Interpretations and repository evidence are maintained separately in [`docs/doctoring/product-technical-gap-baseline.md`](doctoring/product-technical-gap-baseline.md). From ee6c13f059b6074f990f51ae7cf26de62d2c6d67 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 21 Aug 2026 15:49:10 +0900 Subject: [PATCH 69/70] docs: correct MCP standards references --- docs/doctoring/product-technical-gap-baseline.md | 4 ++-- docs/product-technical-gap-baseline.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/doctoring/product-technical-gap-baseline.md b/docs/doctoring/product-technical-gap-baseline.md index ccbde40..e2f74f5 100644 --- a/docs/doctoring/product-technical-gap-baseline.md +++ b/docs/doctoring/product-technical-gap-baseline.md @@ -231,10 +231,10 @@ https://www.rfc-editor.org/rfc/rfc8725.html Internet Engineering Task Force. (2018). *OAuth 2.0 authorization server metadata* (RFC 8414). https://doi.org/10.17487/RFC8414 -Internet Engineering Task Force. (2024). *Resource indicators for OAuth 2.0* +Internet Engineering Task Force. (2020). *Resource indicators for OAuth 2.0* (RFC 8707). https://doi.org/10.17487/RFC8707 -Internet Engineering Task Force. (2024). *OAuth 2.0 protected resource +Internet Engineering Task Force. (2025). *OAuth 2.0 protected resource metadata* (RFC 9728). https://doi.org/10.17487/RFC9728 Model Context Protocol. (2025, November 25). *Authorization*. diff --git a/docs/product-technical-gap-baseline.md b/docs/product-technical-gap-baseline.md index 1f14b7e..f9d88fb 100644 --- a/docs/product-technical-gap-baseline.md +++ b/docs/product-technical-gap-baseline.md @@ -357,7 +357,7 @@ before implementation is claimed. - Sheffer, Y., Hardt, D., & Jones, M. (2020). *JSON Web Token best current practices* (RFC 8725). Internet Engineering Task Force. https://www.rfc-editor.org/rfc/rfc8725.html - Internet Engineering Task Force. (2018). *OAuth 2.0 authorization server metadata* (RFC 8414). https://doi.org/10.17487/RFC8414 - Internet Engineering Task Force. (2024). *Resource indicators for OAuth 2.0* (RFC 8707). https://doi.org/10.17487/RFC8707 -- Internet Engineering Task Force. (2024). *OAuth 2.0 protected resource metadata* (RFC 9728). https://doi.org/10.17487/RFC9728 +- Internet Engineering Task Force. (2025). *OAuth 2.0 protected resource metadata* (RFC 9728). https://doi.org/10.17487/RFC9728 - Model Context Protocol. (2025, November 25). *Authorization*. https://modelcontextprotocol.io/specification/2025-11-25/basic/authorization Interpretations and repository evidence are maintained separately in From 7be7b488c2a6565cf3948f8c4ac6b91e3cfb0f45 Mon Sep 17 00:00:00 2001 From: Seongho Bae Date: Fri, 21 Aug 2026 15:55:04 +0900 Subject: [PATCH 70/70] docs: record post-snapshot PR heads --- docs/doctoring/product-technical-gap-baseline.md | 10 +++++++++- docs/product-technical-gap-baseline.md | 15 +++++++++++++-- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/docs/doctoring/product-technical-gap-baseline.md b/docs/doctoring/product-technical-gap-baseline.md index e2f74f5..698925d 100644 --- a/docs/doctoring/product-technical-gap-baseline.md +++ b/docs/doctoring/product-technical-gap-baseline.md @@ -55,11 +55,15 @@ evidence gaps. discovery, public-client authorization code plus `S256` PKCE, exact redirects, RFC 8707 resource binding, RFC 9728 LineageWeave metadata, centralized revocation/audit, and negative evidence. -- PR #115 is documentation-only. Its current rollup has 2 pending, 14 queued, +- PR #115 is documentation-only. Its initial post-publication rollup had 2 pending, 14 queued, and 7 skipped Checks with review required; no MCP browser flow, resource metadata endpoint, resource-bound token, revocation check, or LineageWeave end-to-end result is claimed. RFC 8628 remains deferred until a real callback-less client requires it. +- After its review corrections, PR #115's current exact head is + `0e0c15c4ba7d631660693c549dcbb7e863d6287b`; its current rollup is 2 + successful, 14 queued, and 7 skipped Checks. This remains documentation + evidence only, not a protected merge or runtime acceptance. ## 2026-08-21 local runtime probe @@ -331,6 +335,10 @@ https://docs.github.com/en/rest/actions/workflows?apiVersion=2022-11-28 and 7 skipped Checks; its changes-requested review state is not approval. PR #104's updated head `7da9d43087d5647fefb946eb154ee1e5c10c576d` is based on #112's lockfile head and has 21 successful, 1 queued, and 8 skipped Checks. + After the baseline/reference update, PR #100 advanced normally to + `ee6c13f059b6074f990f51ae7cf26de62d2c6d67`; its current rollup is 1 + successful, 1 pending, 14 queued, and 7 skipped Checks with changes + requested. The new exact head remains unverified for protected merge. This record travels in these PRs, so the live PR records remain authoritative for their changing exact hashes. The active ruleset requires two approving reviews, resolved threads, and diff --git a/docs/product-technical-gap-baseline.md b/docs/product-technical-gap-baseline.md index f9d88fb..19c688c 100644 --- a/docs/product-technical-gap-baseline.md +++ b/docs/product-technical-gap-baseline.md @@ -89,9 +89,20 @@ There is no current terminal failure bucket in this inventory. Historical terminal failures are recorded separately and are not current-head green evidence. +### Post-snapshot exact-head delta + +After the inventory snapshot, PR #115 advanced normally to +`0e0c15c4ba7d631660693c549dcbb7e863d6287b` to correct review-verified +doctoring/ADR evidence. Its current rollup is 2 successful, 14 queued, and 7 +skipped Checks with no formal approval. PR #100 advanced normally to +`ee6c13f059b6074f990f51ae7cf26de62d2c6d67` after the baseline/reference +updates; its current rollup is 1 successful, 1 pending, 14 queued, and 7 +skipped Checks with a changes-requested review state. These later exact heads +remain unverified for protected merge. + | PR | Scope | Exact-head Checks | Review state | Next safe action | |---:|---|---|---|---| -| [#115](https://github.com/ContextualWisdomLab/keyverse/pull/115) | Proposed ADR/doctoring for MCP-compatible OAuth client authorization | PENDING: 2 pending, 14 queued, 7 skipped, 0 terminal failures on `7281c3d961f40bf47383b8cddeae750af1298ad5` | review required | Obtain independent ADR review; do not treat the design PR as runtime MCP evidence or begin implementation before the trust boundary is accepted. | +| [#115](https://github.com/ContextualWisdomLab/keyverse/pull/115) | Proposed ADR/doctoring for MCP-compatible OAuth client authorization | PENDING: 2 successful, 14 queued, 7 skipped, 0 terminal failures on `0e0c15c4ba7d631660693c549dcbb7e863d6287b` | review required | Obtain independent ADR review; do not treat the design PR as runtime MCP evidence or begin implementation before the trust boundary is accepted. | | [#113](https://github.com/ContextualWisdomLab/keyverse/pull/113) | SCIM `PATCH active=false` shared operation lock, stacked on #112 lockfile refresh | PENDING: 2 successful, 14 queued, 7 skipped, 0 terminal failures on `49136c24fb07e3a8ed01171785e6946c559ea2a5` | review required | The valid SCIM PatchOp review fix and local full verification are complete; wait for fresh exact-head hosted Checks and independent review. | | [#112](https://github.com/ContextualWisdomLab/keyverse/pull/112) | Resync account-unification lockfile | PASS: 23 successful, 8 skipped, 0 queued on `f02acf93367a40dbfb23a73985017dca8d42ff39` | review required | Obtain independent review, then let protected automation re-check and merge. | | [#111](https://github.com/ContextualWisdomLab/keyverse/pull/111) | CodeQL init 4.37.7 | PENDING: 19 successful, 2 queued, 7 skipped, 0 terminal failures on updated head `032f730b0239d062cf9803525ba66c740e0b2d2e` | review required | The normal branch update merged #112's lockfile base into the CodeQL branch; resolve the queued Strix retry and remaining coverage Check, then obtain independent review. | @@ -104,7 +115,7 @@ evidence. | [#104](https://github.com/ContextualWisdomLab/keyverse/pull/104) | ADR and buyer README expansion, stacked on #112 | PENDING: 21 successful, 1 queued, 8 skipped, 0 terminal failures on updated head `7da9d43087d5647fefb946eb154ee1e5c10c576d` | review required | Base remains `fix/account-unification-lock-20260819`; obtain independent review and terminal stacked-head Checks. | | [#103](https://github.com/ContextualWisdomLab/keyverse/pull/103) | Hierarchical authorization, login helper, PATs | PENDING: 2 successful, 14 queued, 7 skipped, 0 terminal failures on `e765f4860177af47b80b05ee3a918a4dc2cb4450` | changes requested | Exact-tree regressions and local 100% verification pass; wait for hosted security Checks and current-head independent review before any merge claim. | | [#101](https://github.com/ContextualWisdomLab/keyverse/pull/101) | Atomic coupled Python dependency updates | PASS: 23 successful, 8 skipped, 0 queued on `50dd9c96cab5c230f775685e8baea939fba390dd` | changes requested | Obtain fresh independent review; this is the policy companion to the lockfile gap. | -| [#100](https://github.com/ContextualWisdomLab/keyverse/pull/100) | `lineageweave-web` account-derived claims plus default validator-path coverage | PENDING: 2 successful, 14 queued, 7 skipped, 0 terminal failures on observed head `f331938a4f3cd6808101b8888b76c0f87b1eb841` | changes requested | The current-tree review findings are addressed; wait for exact-head Checks and independent review without self-approval. | +| [#100](https://github.com/ContextualWisdomLab/keyverse/pull/100) | `lineageweave-web` account-derived claims plus default validator-path coverage | PENDING: 1 successful, 1 pending, 14 queued, 7 skipped, 0 terminal failures on observed head `ee6c13f059b6074f990f51ae7cf26de62d2c6d67` | changes requested | The current-tree review findings are addressed; wait for exact-head Checks and independent review without self-approval. | | [#83](https://github.com/ContextualWisdomLab/keyverse/pull/83) | Remove runtime application RPs from portable realm | PASS: 23 successful, 8 skipped, 0 queued on `dd1ab7444a75342b42e3af013ccda6d1dbfb359d` | changes requested | Reconfirm current-head approval and latest-pusher rule before protected merge. | ### Historical check failure root causes observed