diff --git a/.agent-loop/LOOP_STATE.md b/.agent-loop/LOOP_STATE.md index 5b718b50..a5e9c547 100644 --- a/.agent-loop/LOOP_STATE.md +++ b/.agent-loop/LOOP_STATE.md @@ -5,22 +5,24 @@ - This authored file is reviewed planning/history context, not canonical live post-merge state. Canonical state is the signed schema-v2 output on `automation/loop-memory`. -- Active initiatives include parallel `WS-AUTH-001`, `WS-ART-001`, and the - planning-only `WS-XINT-001` boundary reconciliation. -- Active planning chunk: `WS-XINT-001-PLAN` on - `codex/ws-xint-001-boundary-reconciliation`. -- Parallel implementation worktrees: reviewed `WS-AUTH-001-09A` fixed service - identity foundation at `c4200a7` and reviewed `WS-ART-001-02A3` ArtifactStore - v2 Local clean cut at `935b1a2`; neither is part of this planning branch. -- Start basis: PR #131 merged AUTH-08 into `main` as `aa0fdcd`, and PR #129 then - merged ART-02A2 into `main` as `9a04434`. +- Active initiatives include parallel `WS-AUTH-001` and `WS-ART-001`. +- PR #139 merged the planning-only `WS-XINT-001-PLAN` boundary reconciliation + into `main` as `5d353b6` on 2026-07-17. +- Active planning chunk: `WS-AUTH-001-XINT` on + `codex/ws-auth-001-xint-reconciliation`. +- PR #132 remains open at `79d1989` and conflicts with current `main`. Its + AUTH-09A fixed service foundation remains valid but must converge after this + AUTH planning amendment; AUTH-09B remains inactive. +- Start basis: trusted `main` at `5d353b6` after PR #139. - PR #119 merged `WS-AUTH-001-05B` as `ad71c7e`. - PR #120 merged `WS-ART-001-OBJECT-STORAGE-AMENDMENT` as `4408256`. - PR #122 merged the first automated post-merge memory implementation as `fc89fb6`; its schema-v1 cross-initiative next pointer is superseded by the schema-v2 initiative-local clean cut. -- Current gate: exact-SHA internal review and evidence for - `WS-XINT-001-PLAN`; no downstream runtime starts from this planning branch. +- Current gate: required internal review passes on the externally repaired + planning state at `bac3073`, and final deterministic closure passes on + evidence head `7cb02b5`; replacement external checks and the human checkpoint + remain for PR #140. No runtime starts from this planning branch. - Scope checkpoint: AWS S3 is the only v0.1 production provider; MinIO is local/CI S3 protocol proof; LocalStorage is focused development/test; R2 and Flow Node are deferred. Product modules receive narrow artifact capabilities, @@ -28,11 +30,10 @@ - Authorization checkpoint: merged main contains 74 PermissionIds and 57 ActionIds, with the two actor-self and seven AUTH-08 administrative actions active. AUTH-09A's reviewed parallel branch defines seven fixed artifact - service identities and eleven exact planned static matrix memberships. ART - feature chunks supply hidden canonical behavior/resource composition. Future - AUTH activation-custodian chunks alone integrate evaluators and change action - availability after that hidden behavior merges; `WS-XINT-001` activates - nothing. + service identities and eleven exact planned static matrix memberships. The + plan now requires availability-neutral ART/REV custody transfer, fixed-service + admission, prepared mutation authority, feature-owned hidden behavior, and + exact AUTH-only activation chunks. This planning amendment activates nothing. - Parallel artifact checkpoint: `WS-ART-001-02A1` was explicitly started and merged through PR #127 as `f64a8e5`; it is at the post-merge memory/stop checkpoint. ART-02A2 merged through PR #129, and ART-02A3 is reviewed in its diff --git a/.agent-loop/REVIEW_LOG.md b/.agent-loop/REVIEW_LOG.md index 29985807..4177a7a2 100644 --- a/.agent-loop/REVIEW_LOG.md +++ b/.agent-loop/REVIEW_LOG.md @@ -1,5 +1,27 @@ # Review Log +## 2026-07-17 - WS-AUTH-001-XINT External Review Repair Passed + +CodeRabbit posted nine actionable comments on PR #140. Eight valid contract, +least-privilege, migration, and Markdown findings were repaired at exact SHA +`c4c4f2e`; the requested runtime `AuthorityClaimHandle` rewrite was rejected as +a conflation with the distinct future PREP handle and as planning-scope creep. +Senior, QA, security, product, architecture, CI, docs, and reuse tracks pass the +repair. Earlier Agent Gates failures were repaired by the null schema-v2 +successor, and replacement Agent Gates and Backend runs pass. Evidence rebinding +and replacement external checks remain; no AUTH runtime successor is active. + +## 2026-07-17 - WS-AUTH-001-XINT Internal Review Passed + +Exact planning SHA `2acabdac0658c3f0109db4235458827b8a06bf31` passed senior +engineering, QA/test, security/auth, product/ops, architecture, CI integrity, +docs, and reuse/dedup review after all valid findings were repaired. The final +plan preserves merged XINT's eight ART custody owners, exact 25 ART / 19 REV +action map, uninterrupted AUTH-09A through 09E sequence, delta-based future +registrations, dormant adjudicator invalidation, and exact PREP lock order. All +80 agent-gate tests, stale wording, authorization-doc, Markdown-link, and diff +checks passed. PR publication is pending; no runtime successor is active. + ## 2026-07-16 - WS-AUTH-001-08 Internal Review Passed Exact implementation SHA `34f87a5aa7d75897349f64f5e904cb1847af019b` diff --git a/.agent-loop/WORK_QUEUE.md b/.agent-loop/WORK_QUEUE.md index 3d541d33..120611bc 100644 --- a/.agent-loop/WORK_QUEUE.md +++ b/.agent-loop/WORK_QUEUE.md @@ -4,7 +4,7 @@ | Chunk | Title | Risk | Status | |---|---|---:|---| -| `WS-XINT-001-PLAN` | Lifecycle Boundary Reconciliation | L1 | Planning-only coordination active after explicit user start on 2026-07-16 | +| `WS-AUTH-001-XINT` | Lifecycle Boundary Plan Reconciliation | L1 | Planning-only AUTH owner response to merged PR #139 | Live post-merge state remains read from signed `automation/loop-memory` output. This authored queue records the separately approved parallel chunks. @@ -14,7 +14,7 @@ output. This authored queue records the separately approved parallel chunks. | Chunk | Title | Risk | Status | |---|---|---:|---| | `WS-QUAL-001-01B2` | Baseline Evidence And CI Ratchet | L1 | Paused for AUTH priority; no valid replacement baseline yet | -| `WS-AUTH-001-09A` | Fixed Service Identity Foundation | L1 | Reviewed in PR #132; awaiting explicit human merge approval | +| `WS-AUTH-001-09A` | Fixed Service Identity Foundation | L1 | PR #132 remains unmerged/conflicting; converge on merged XINT and re-review after this plan merges | | `WS-QUAL-001-02` | Project Service Coverage | L1 | Inactive until 01B2 merge/memory plus explicit user start | | `WS-POL-002-04` | Locked Runtime Execution And Routing Hardening | L1 | Inactive pending relevant authorization proof and a separate explicit user start | | `WS-ART-001-02A3` | ArtifactStore v2 Local Clean Cut | L1 | Reviewed in isolated parallel worktree; pending its own PR and merge | @@ -72,6 +72,7 @@ output. This authored queue records the separately approved parallel chunks. | `WS-AUTH-001-07B` | Deny-By-Default Kernel And Self-Action Cutover | L1 | Merged through PR #130 as `90eca12` on 2026-07-15 | | `WS-AUTH-001-08` | Bootstrap Access Administrator Grant | L1 | Merged through PR #131 as `aa0fdcd` on 2026-07-16 | | `WS-ART-001-02A2` | Committed Source And Local Preparation | L1 | Merged through PR #129 as `9a04434` on 2026-07-16 | +| `WS-XINT-001-PLAN` | Lifecycle Boundary Reconciliation | L1 | Merged through PR #139 as `5d353b6` on 2026-07-17 | | `WS-ART-001-OBJECT-STORAGE-AMENDMENT` | AWS-First Object Storage Planning Amendment | L1 | Merged through PR #120 as `4408256` on 2026-07-14 | | `WS-ART-001-02A1` | External Service Adapter Foundation | L1 | Merged through PR #127 as `f64a8e5` on 2026-07-15 | | `WS-ENG-001-02` | Automated Post-Merge Memory | L1 | Merged through PR #122 as `fc89fb6`; schema-v1 output superseded by WS-ENG-001-03 | @@ -81,9 +82,10 @@ output. This authored queue records the separately approved parallel chunks. AUTH-05A merged through PR #115 as `8e1cde6`, and CAT plus its post-merge memory merged through PRs #117 and #118. AUTH-05B merged through PR #119 as `ad71c7e`. AUTH-06 merged through PR #124 as `f599551`. AUTH-07A, AUTH-07B, and AUTH-08 -merged through PRs #126, #130, and #131. AUTH-09A is reviewed in its isolated -parallel worktree; do not start an AUTH-09 successor or POL-002-04 -automatically. +merged through PRs #126, #130, and #131. WS-XINT planning merged through PR #139. +`WS-AUTH-001-XINT` now reconciles AUTH's owner plan. AUTH-09A remains open +and conflicting in PR #132; converge and re-review it only after this planning +amendment merges. Do not start an AUTH-09 successor or POL-002-04 automatically. Coverage R10 merged through PR #108. Do not start 01B2, chunk 02, or another coverage implementation chunk from this worktree. diff --git a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/ACTIVATION_CUSTODY.md b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/ACTIVATION_CUSTODY.md new file mode 100644 index 00000000..1ad84e0c --- /dev/null +++ b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/ACTIVATION_CUSTODY.md @@ -0,0 +1,163 @@ +# Activation Custody: WS-AUTH-001 + +## Authority + +This plan applies the merged `WS-XINT-001` handoffs to AUTH. It distinguishes: + +- feature/resource ownership: ART, REV, CON, project, task, submission, or + checker code owns facts, guards, state, and hidden behavior; +- activation custody: one exact AUTH chunk owns `ActionOwner`, evaluator + integration, and the `planned` to `active` transition; and +- transaction ownership: the request route or service command owns one commit + after AUTH and all feature participants have staged their evidence and state. + +Feature chunks never change availability. AUTH never invents feature facts or +performs feature lifecycle mutations. + +## Current catalogue baseline + +Trusted `main` after PR #139 contains 74 PermissionIds and 57 ActionIds: nine +active and 48 planned. Of the planned rows, 25 ART actions and 19 REV actions +still carry historical feature-chunk owner values. The two custody-transfer +chunks below change only those owner values. Counts, mappings, and availability +must remain identical. + +## ART custody transfer + +| AUTH activation chunk | Exact planned ActionIds | +|---|---| +| `WS-AUTH-001-ART-02D-INTERNAL` | `artifact.verification.execute`, `artifact.pending_work.scan`, `artifact.put_attempt.resolve` | +| `WS-AUTH-001-ART-02D-OPERATOR` | `artifact.binding.read`, `artifact.replica.read`, `artifact.receipt.read`, `artifact.verification_job.read`, `artifact.verification_job.retry`, `artifact.recovery_attempt.read`, `artifact.audit.read`, `operations.artifact_storage_admission.read` | +| `WS-AUTH-001-ART-03` | `artifact.guide_source.ingest`, `artifact.guide_source.read`, `artifact.guide_source.binding.create` | +| `WS-AUTH-001-ART-04A` | `artifact.upload_session.create`, `artifact.upload_session.read`, `artifact.upload_item.write`, `artifact.upload_session.seal`, `artifact.upload_session.cancel`, `artifact.upload_session.expire` | +| `WS-AUTH-001-ART-04B` | `artifact.pre_submit.checker_input.materialize` | +| `WS-AUTH-001-ART-05` | `artifact.submission.binding.create` | +| `WS-AUTH-001-ART-06A` | `artifact.post_submit.checker_input.materialize` | +| `WS-AUTH-001-ART-06B` | `artifact.checker_output.write`, `artifact.checker_output.binding.create` | + +`WS-AUTH-001-ART-CUSTODY` performs the atomic 25-row transfer to eight exact AUTH +groups and removes the seven historical ART owner enum values. It adds no migration because owner and +availability are typed metadata, while PostgreSQL preserves the exact +ActionId-to-PermissionId set. + +## REV custody transfer + +| AUTH activation chunk | Exact planned ActionIds | +|---|---| +| `WS-AUTH-001-REV-05` | `review.queue.read`, `review.queue.inspect` | +| `WS-AUTH-001-REV-06` | `review.claim`, `review.release`, `review.decline_preference`, `review.preference_expiry.run`, `review.lease_expiry.run` | +| `WS-AUTH-001-REV-07` | `review.context.read`, `review.chain.read`, `review.finding_evidence.ingest` | +| `WS-AUTH-001-REV-08` | `review.decision` | +| `WS-AUTH-001-REV-09A` | `review.finding_response_evidence.ingest` | +| `WS-AUTH-001-REV-11` | `review.lease.force_release`, `review.queue.routing.override`, `review.queue.routing.correct`, `review.queue.close`, `review.reconcile.run` | +| `WS-AUTH-001-REV-12` | `review.artifact_reference.reconcile`, `review.projection.rebuild` | + +`WS-AUTH-001-REV-CUSTODY` performs the atomic 19-row transfer and removes the +seven historical REV owner enum values. It changes no mapping or availability +and adds no migration. + +## Additive registration gates + +The following values are approved boundary proposals, not registered runtime +actions on trusted `main`: + +| Registration chunk | Future activation chunk | Proposed ActionId -> PermissionId | +|---|---|---| +| `WS-AUTH-001-REV-REG` | `WS-AUTH-001-REV-LIFECYCLE` | `review.revision_context.repair` -> `project.task.manage`; `review.revision_context.legacy_close` -> `operations.reconcile.run`; `review.revision_obligation.close` -> `project.task.manage`; `review.lifecycle.activation.manage` -> `operations.reconcile.run` | +| `WS-AUTH-001-ART-REV-EVIDENCE-REG` | `WS-AUTH-001-ART-REV-EVIDENCE` | `artifact.review_evidence.binding.create` -> `artifact.binding.create` | + +These are declared future registration gates, not executable chunk contracts. +Neither may receive a full contract or start until the owning feature publishes exact +principal class, typed resource context, canonical facts, guards, surfaces, +transaction revalidation, and hidden behavior dependencies. AUTH must not invent +those contracts. Registration is availability-neutral and requires typed plus +PostgreSQL audit mapping parity. Migration numbers are allocated from trusted +`main` when each registration contract becomes executable; they are not +reserved ahead of an incomplete feature contract. Each registration migration +takes a writer-blocking downgrade lock and refuses without mutation when any +decision, audit, idempotency, or linked evidence references an added ActionId. +Its proof includes populated refusal, empty safe downgrade, re-upgrade, and +fresh replay. + +Counts are derived from trusted `main` when a gate executes. REV registration +adds exactly four planned actions and zero active actions; evidence registration +adds exactly one planned action and zero active actions, in either order. +PermissionIds remain 74. The evidence-binding +registration also adds that exact action to the existing +`workstream.artifact.binding` static row, increasing matrix membership from 11 +to 12 without adding an identity or database grant. + +## Prepared mutation prerequisite + +`WS-AUTH-001-PREP` adds a session-bound, action-bound, opaque, single-use, +nonserializable prepared authority handle: + +```text +AUTH locks canonical current authority +-> feature locks its records +-> feature recomposes final typed facts +-> AUTH evaluates exactly once and stages decision evidence +-> feature participants flush +-> route or service command commits once +``` + +Reads retain `AuthorizationService.require()`. Mutations must not evaluate +against stale pre-lock facts or let dependency teardown commit shared state. + +## Activation gate + +Every activation chunk requires an immutable merged feature SHA and exact +manifest containing its action list, resource composer, facts, guards, primary +surface declarations, transaction owner, revalidation proof, and real-kernel +`action_unavailable` proof before activation. The AUTH chunk then integrates +only those evaluators, changes only those actions to active, proves the exact +availability delta, and preserves all unrelated rows. + +An activation entry in this map is a non-executable placeholder until that +manifest exists. Its later preimplementation contract must enumerate exact +allowed feature files, route/command and transaction tests, generated manifest +delta, allow/deny/revalidation/rollback matrix, PostgreSQL concurrency cases, +focused coverage commands for every changed subsystem at 90 percent or higher, +and the full backend suite preserving the global 78 percent floor. Generic “as +applicable” proof or AUTH-only tests cannot authorize activation. + +`WS-AUTH-001-ART-02D-INTERNAL` requires the exact merged ART-02C2 verification, +resolution, and scanner behavior plus ART-02C3 recovery/fencing foundations and +any ART-02D resource-composer dependency. ART-02D does not own the internal +behavior. Within `WS-AUTH-001-ART-02D-OPERATOR`, +`artifact.verification_job.retry` requires its own evaluator, guards, behavior +tests, and explicit availability assertion; passing the seven read/status cases +does not authorize retry. + +Service actions additionally require a previously reviewed exact fixed-service +identity and matrix extension plus controlled provisioning and AUTH-09E +admission. REV must publish exact timer, expiry, reconciliation, projection, +artifact-reference, and release-control service manifests before AUTH creates +those identity-specific extension contracts. No catch-all review service is +pre-created. + +`review.decision` additionally requires the merged flush-only CON participant +and one rollback-safe REV+CON transaction. Review-evidence binding additionally +requires ART and REV to define the in-process/service boundary, two independent +authorization decisions and evidence records, exact lock order, and one +transaction owner. Human authority cannot be silently converted into service +authority. + +## Sequencing + +```text +WS-AUTH-001-XINT planning reconciliation +-> repair and re-review PR #132 / AUTH-09A on trusted main +-> AUTH-09B -> 09C -> 09D -> 09E +-> WS-AUTH-001-ART-CUSTODY +-> WS-AUTH-001-REV-CUSTODY +-> WS-AUTH-001-PREP +-> AUTH-10 through AUTH-15 core cutovers +-> feature-gated registration and activation chunks as their manifests merge +-> AUTH-16 aggregate conformance and live proof +``` + +Only one WS-AUTH implementation chunk is active at a time. ART, REV, and CON +may build hidden behavior in their own worktrees while real actions remain +planned, but each merged AUTH activation must converge from current trusted +`main` and pass its own human checkpoint. diff --git a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/CHUNK_MAP.md b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/CHUNK_MAP.md index 25bf8a4f..ebecf260 100644 --- a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/CHUNK_MAP.md +++ b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/CHUNK_MAP.md @@ -27,20 +27,52 @@ stopped. | `WS-AUTH-001-07A` | Closed Permission And Action Catalogue | L1 | Merged through PR #126 as `e9d72a1` | | `WS-AUTH-001-07B` | Deny-By-Default Kernel And Self-Action Cutover | L1 | Merged through PR #130 as `90eca12` | | `WS-AUTH-001-08` | Bootstrap And Administrative Role Grants | L1 | Merged through PR #131 as `aa0fdcd` | +| `WS-AUTH-001-XINT` | Lifecycle Boundary Plan Reconciliation | L1 | Active planning-only correction after merged PR #139 | | `WS-AUTH-001-09` | Actor State, Identity Revocation, And Service Actors | L1 | Split before runtime implementation | -| `WS-AUTH-001-09A` | Fixed Service Identity Foundation | L1 | Implementation in PR #132; merge pending | +| `WS-AUTH-001-09A` | Fixed Service Identity Foundation | L1 | PR #132 remains open and conflicting; converge on XINT before merge | | `WS-AUTH-001-09B` | Controlled Service Actor Provisioning | L1 | Inactive until 09A merge/memory and explicit start | | `WS-AUTH-001-09C` | Actor And Identity-Link Administration Reads | L1 | Inactive until 09B merge/memory and explicit start | | `WS-AUTH-001-09D` | Actor And Identity-Link Lifecycle Mutations | L1 | Inactive until 09C merge/memory and explicit start | | `WS-AUTH-001-09E` | Fixed Service Runtime Admission | L1 | Inactive until 09D merge/memory and explicit start | +| `WS-AUTH-001-ART-CUSTODY` | ART Activation Custody Transfer | L1 | Inactive until 09E merge/memory and explicit start | +| `WS-AUTH-001-REV-CUSTODY` | REV Activation Custody Transfer | L1 | Inactive until 09E merge/memory and explicit start | +| `WS-AUTH-001-PREP` | Prepared Mutation Authorization Protocol | L1 | Inactive until 09E merge/memory and explicit start | | `WS-AUTH-001-10` | Project Qualification And Contributor Role Grants | L1 | Proposed | | `WS-AUTH-001-11` | Project Identity, Guide, Source, And Visibility Cutover | L1 | Proposed | | `WS-AUTH-001-12` | Project Policy And Setup Mutation Cutover | L1 | Proposed | | `WS-AUTH-001-13` | Task Management And Assignment Cutover | L1 | Proposed | | `WS-AUTH-001-14` | Submission, Checker, And Audit Visibility Cutover | L1 | Proposed | -| `WS-AUTH-001-15` | Remaining System Worker Cutover And Obsolete Authority Removal | L1 | Proposed | +| `WS-AUTH-001-15` | Remaining Internal Service Cutover And Obsolete Authority Removal | L1 | Proposed | | `WS-AUTH-001-16` | Conformance, Observability, And Live API Proof | L1 | Proposed | +## Feature-gated registration and activation chunks + +These identifiers are exact future gates, not executable chunk contracts or +automatic successors. AUTH materializes each contract only after its immutable +feature manifest exists, then requires a separate explicit start. + +| Chunk | Title | Risk | Status | +|---|---|---:|---| +| `WS-AUTH-001-REV-REG` | REV Lifecycle Action Registration | L1 | Blocked on complete REV typed manifests | +| `WS-AUTH-001-ART-REV-EVIDENCE-REG` | Review Evidence Binding Action Registration | L1 | Blocked on complete ART/REV dual-authority contract | +| `WS-AUTH-001-ART-02D-INTERNAL` | ART 02D Internal Action Activation | L1 | Feature-gated | +| `WS-AUTH-001-ART-02D-OPERATOR` | ART 02D Operator Read/Status And Independently Evaluated Retry Activation | L1 | Feature-gated | +| `WS-AUTH-001-ART-03` | ART 03 Guide Source Action Activation | L1 | Feature-gated | +| `WS-AUTH-001-ART-04A` | ART 04A Upload Action Activation | L1 | Feature-gated | +| `WS-AUTH-001-ART-04B` | ART 04B Pre-Submit Materialization Activation | L1 | Feature-gated | +| `WS-AUTH-001-ART-05` | ART 05 Submission Binding Activation | L1 | Feature-gated | +| `WS-AUTH-001-ART-06A` | ART 06A Post-Submit Materialization Activation | L1 | Feature-gated | +| `WS-AUTH-001-ART-06B` | ART 06B Checker Output Action Activation | L1 | Feature-gated | +| `WS-AUTH-001-REV-05` | REV 05 Queue Read Activation | L1 | Feature-gated | +| `WS-AUTH-001-REV-06` | REV 06 Claim Lease And Expiry Activation | L1 | Feature/service-gated | +| `WS-AUTH-001-REV-07` | REV 07 Context Chain And Finding Evidence Activation | L1 | Feature/ART-gated | +| `WS-AUTH-001-REV-08` | REV 08 Decision Activation | L1 | Feature/CON-gated | +| `WS-AUTH-001-REV-09A` | REV 09A Finding Response Evidence Activation | L1 | Feature/ART-gated | +| `WS-AUTH-001-REV-11` | REV 11 Recovery And Reconciliation Activation | L1 | Feature/service-gated | +| `WS-AUTH-001-REV-12` | REV 12 Artifact Reconciliation And Projection Activation | L1 | Feature/service-gated | +| `WS-AUTH-001-REV-LIFECYCLE` | REV Lifecycle Repair Action Activation | L1 | Blocked until REV-REG and four hidden manifests merge | +| `WS-AUTH-001-ART-REV-EVIDENCE` | Review Evidence Binding Action Activation | L1 | Blocked until registration and hidden ART/REV behavior merge | + ## Dependency order ```text @@ -57,17 +89,21 @@ WS-AUTH-001-PLAN -> WS-AUTH-001-07A -> WS-AUTH-001-07B -> WS-AUTH-001-08 +-> WS-AUTH-001-XINT -> WS-AUTH-001-09A -> WS-AUTH-001-09B -> WS-AUTH-001-09C -> WS-AUTH-001-09D -> WS-AUTH-001-09E +-> WS-AUTH-001-ART-CUSTODY and WS-AUTH-001-REV-CUSTODY +-> WS-AUTH-001-PREP -> WS-AUTH-001-10 -> WS-AUTH-001-11 -> WS-AUTH-001-12 -> WS-AUTH-001-13 -> WS-AUTH-001-14 -> WS-AUTH-001-15 +-> all registration/activation chunks whose feature surfaces have merged -> WS-AUTH-001-16 ``` @@ -90,9 +126,14 @@ WS-AUTH-001-PLAN - Parent chunk 07 was split before runtime implementation. Chunk 07A owns the closed permission/action catalogue and action-aware audit parity; chunk 07B owns the minimal deny-by-default kernel and actor self-action cutover. +- PR #139 merged the WS-XINT boundary contract. `WS-AUTH-001-XINT` is the + planning-only AUTH owner response; it changes no runtime. - Chunks 08-10 establish local grant truth before product cutover. Parent chunk - 09 is split into 09A through 09E; 09E separately admits fixed services without - entering human grant evaluation. + 09 is split into 09A through 09E with no inserted dependency; 09E separately + admits fixed services without entering human grant evaluation. ART/REV custody + transfer follows 09E and changes only owner metadata and availability-neutral + parity. PREP then establishes AUTH-first + locking and caller-owned commit before sensitive product/review mutations. - Chunks 11-15 migrate bounded complete product/system surfaces. - Artifact upload, read, retention, release/delete, replication, integrity, and reconciliation remain mechanically owned by the artifact subsystem but must @@ -105,11 +146,15 @@ WS-AUTH-001-PLAN behavior, and tests. Dedicated AUTH custodians integrate evaluators and alone change availability after the matching ART behavior merges. AUTH-12, AUTH-14, and AUTH-15 are not alternate artifact activation paths. WS-ART-001-02D starts - only after AUTH-09A through AUTH-09E and custody registration, then remains hidden until the - internal and Operator AUTH activation checkpoints pass. Later ART chunks use - the same sequence. AUTH-16 proves no bypass remains. -- Chunk 16 proves the complete initiative; it does not backfill missing audit - or idempotency evidence. + only after AUTH-09A through AUTH-09E and custody registration, then remains + hidden until the internal and Operator AUTH activation checkpoints pass. + Later ART and REV chunks use the same sequence. Exact mappings, registration + counts, service-extension gates, and activation proof live in + `ACTIVATION_CUSTODY.md`. +- Chunk 16 proves the complete initiative after every protected surface already + merged has its matching AUTH activation and every unimplemented registered + action still denies as planned. It does not backfill missing audit or + idempotency evidence. - `WS-POL-002-03` merged separately through PR #90 as `a7aa474`. This initiative does not own it; post-merge memory completed through PR #94. `WS-POL-002-04` remains inactive until the relevant project authorization cutover is complete @@ -140,5 +185,10 @@ signed automated memory completed, and the user explicitly started AUTH-07. Required L1 review rejected the combined contract before runtime edits and required 07A/07B. AUTH-07B merged through PR #130 as `90eca12`; AUTH-08 merged through PR #131 as `aa0fdcd`. Parent AUTH-09 was split before implementation. -AUTH-09A implementation and review are complete in PR #132 and await explicit -human merge approval. Do not start AUTH-09B or POL-002-04 automatically. +AUTH-09A implementation and review are complete in PR #132, but merged PR #139 +changed its planning base and the PR now conflicts with trusted `main`. Its +seven identities, eleven static matrix actions, and migration `0023` remain +valid. After this planning amendment merges, PR #132 must be converged without +restoring stale owner or combined-role wording, re-reviewed on the exact head, +and pass checks before human merge. Do not start AUTH-09B or POL-002-04 +automatically. diff --git a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/DECISIONS.md b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/DECISIONS.md index d72f537b..3d4cd706 100644 --- a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/DECISIONS.md +++ b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/DECISIONS.md @@ -253,14 +253,15 @@ declarations during its feature cutover, and AUTH-16 owns the aggregate generated route/command completeness manifest and final no-bypass proof. -Reserved planned metadata contains only stable `ActionId`, approved -`PermissionId`, owning specification/chunk, and availability. It cannot -authorize and does not predefine a foreign-domain target, facts, guards, or -composer. An owning feature cutover supplies its adopted domain contract, -canonical resource composer, route or command declaration, allow/deny behavior -proof, and generated manifest delta. A dedicated AUTH activation custodian alone -integrates the evaluator and changes action availability after that hidden -behavior has merged. +Reserved planned runtime metadata contains only stable `ActionId`, approved +`PermissionId`, exact AUTH activation custodian, and availability. It cannot +authorize and does not make AUTH the owner of foreign-domain facts or behavior. +Before a new planned action is registered, however, its owning feature must +publish a jointly approved typed contract naming principal class, canonical +resource type and facts, guards, surface, transaction owner, revalidation, and +hidden-behavior dependency. Registration records the four-field runtime row and +typed/PostgreSQL evidence mapping; activation later integrates the evaluator +only after hidden behavior merges. A feature chunk never changes availability. `ActionId` is security-significant evidence. AUTH-07A adds typed/PostgreSQL audit parity; AUTH-07B adds it to `AuthorizationDecision`, bounded logs/metrics, @@ -288,9 +289,13 @@ resources and state transitions. Migration custody is reconciled with merged main: AUTH-05A owns `0018`, AUTH-05B solely owns `0019`, AUTH-06 uses `0020`, AUTH-07A action evidence uses `0021`, -AUTH-08 uses `0022`, the AUTH-09A fixed-service identity foundation uses `0023`, -AUTH-10 uses `0024`, AUTH-12 uses `0025`, AUTH-13 uses `0026`, and AUTH-14 uses -`0027`. +AUTH-08 uses `0022`, and the AUTH-09A fixed-service identity foundation uses +`0023`. After `0023` merges, AUTH-10 uses `0024`, AUTH-11 uses `0025`, AUTH-12 +uses `0026`, AUTH-13 uses `0027`, AUTH-14 uses `0028`, and AUTH-15 uses `0029` +so every new protected surface receives typed/PostgreSQL ActionId evidence +parity in its owning cutover. Feature-gated REV/ART additive registrations use +the next trusted-main migration head when their complete contracts become +executable; they do not reserve a number while blocked. ## D16: Split AUTH-07 at the catalogue and executable-kernel boundary @@ -320,12 +325,14 @@ architecture, docs/security, and test/migration review. AUTH-07A expands the closed catalogue to exactly 74 PermissionIds and 50 planned ActionIds. `review.queue.override` is the only additive PermissionId and is explicitly the 25th post-`0020` permission; the historical 49-value set does -not change. Twenty planned actions are added: canonical `submission.create` -owned by `WS-AUTH-001-14`, plus 19 review actions owned by exact -`WS-REV-001-05`, `06`, `07`, `08`, `09A`, `11`, and `12` chunks. All additions -remain four-field planned metadata and cannot authorize until their owner -supplies resource composition, guards, candidates, surface declarations, -revalidation, and behavior tests. +not change. Twenty planned actions were added: canonical `submission.create` +under `WS-AUTH-001-14`, plus 19 review actions initially labelled with exact +`WS-REV-001-05`, `06`, `07`, `08`, `09A`, `11`, and `12` feature chunks. All +additions remain four-field planned metadata and cannot authorize. D25 +supersedes those feature labels as activation custody: REV still supplies +resource composition, guards, candidates, surface declarations, revalidation, +and behavior tests, while exact AUTH chunks own evaluator integration and +availability. Initial and revision submissions share the same `submission.create` action, permission, and route. There is no `submission.revise`, `review.assign`, @@ -433,9 +440,29 @@ clause. The v0.1 ProjectRoleGrant values are exactly `submitter`, `reviewer`, and `adjudicator`. A human may hold all three capabilities through independent immutable rows. Each role is independently issued, revoked, regranted, -invalidated, and revalidated. There is no cross-role replacement. The -adjudicator grant provides no adjudication operation until WS-REV defines the -lifecycle and AUTH activates exact actions. +invalidated, and revalidated. There is no `both`, cross-role replacement, +replacement event, replacement reason, or replacement/supersession field. + +Qualification evidence is bound by composite constraints to the same actor, +project, and exact requested role. One partial unique constraint permits only +one active row per actor/project/role while different roles can be issued +concurrently. Regrant after revocation creates new immutable history. Issue +idempotency hashes the requested role; revoke derives the role from the locked +grant. Same key/different role mismatches, new-key duplicate same-role issue is +a stable audited conflict, and replay reauthorizes before disclosure. + +AUTH-10 replaces current typed and PostgreSQL validators in migration `0024` +without editing `0018`, `0019`, or `0022`. It fails closed if obsolete combined +or replacement evidence exists and refuses an unsafe downgrade rather than +converting or deleting evidence. Only issued and revoked success events remain. +Linked invalidation preserves exact grant, actor, project, role, and cause. +Submitter revocation alone can enter AUTH-13 assignment reconciliation; +reviewer revocation may create only its exact REV-owned review obligation. +Adjudicator revocation persists exact invalidation only: it creates or consumes +no adjudication obligation until WS-REV separately defines that lifecycle and +AUTH activates its exact actions. No role revocation changes another project +role or an AdminRoleGrant. The adjudicator grant provides only exact-project +visibility until that separate activation. ## D22: Fixed service runtime admission is separate from human admission @@ -447,3 +474,100 @@ active identity link and service ActorProfile, validates the fixed `service_identity`, and selects only its exact static ActionId row. It never enters human first-access provisioning or human grant evaluation. AUTH-09E owns this admission path but activates no feature operation. + +## D23: Merged WS-XINT handoffs supersede stale AUTH boundary wording + +Status: accepted through merged PR #139 on 2026-07-17. + +The canonical AUTH/ART, AUTH/REV, AUTH role/service, ART/REV, and REV/CON +handoffs are binding planning inputs. AUTH owns grants, decision evidence, +evaluator integration, and action availability. Feature owners retain resource +facts, guards, hidden behavior, and product state. Request routes or service +commands own one transaction. Older combined-role, feature-owned activation, +or service-admission wording is not an alternate contract. + +PR #132's fixed service foundation remains technically valid: seven artifact +service identities, eleven exact static ActionId memberships, no database +assignment rows, and migration `0023`. Its branch must converge from trusted +`main` without restoring pre-XINT planning text. Convergence must preserve the +packaged frozen migration contract, zero mutable `app.modules` imports from the +migration, explicit Alembic-script-owned repository root, location-independent +built-wheel custody/replay proof, same-event-loop CLI execution and engine +disposal, and original `BaseException` precedence with cancellation/cleanup +tests. The exact converged head then repeats required internal review and +external checks before merge. + +## D24: Sensitive cross-module mutations use prepared authorization + +Status: adopted by the WS-XINT transaction contract; runtime remains proposed. + +`WS-AUTH-001-PREP` introduces an internal, opaque, non-Pydantic, single-use +`PreparedAuthorizationHandle` bound to the exact session, ActionId, actor +reference kind, actor reference, idempotency key, and canonical request digest. +It is never a route schema, caller input, or serialized reference. The existing +`AuthorityClaimHandle` remains a distinct internal idempotency-reservation +contract and is not the PREP handle. When final-admin safety applies, AUTH locks +`AuthorityControl(id=1)` first. It orders multiple authority +principals by `ActorProfile.id`; for each human it locks `ActorProfile`, the exact +`ActorIdentityLink`, then the exact matched admin or project grant; for each +service it locks `ActorProfile` then the exact `ActorIdentityLink`. It validates +the code-owned `service_identity`, static matrix membership, and action +availability after those locks; those values are not database lock targets. The +feature locks its records only after all authority rows, recomposes final typed +facts, and asks AUTH to evaluate exactly once and stage decision evidence. +Feature participants flush, and the route or service command commits once. +Reads retain `require()`. Before any feature mutation, consumption requires an +exact match on every handle binding. Reuse, cross-session/action use, +same-session/action cross-actor or cross-request substitution, authority loss, +evidence failure, participant failure, cancellation, and commit failure leave no +feature mutation or partial evidence. AUTH never imports a feature repository. + +## D25: ActionOwner is an exact AUTH activation custodian + +Status: accepted through merged PR #139; runtime transfer remains proposed. + +`ActionOwner` no longer names a resource-owning feature chunk. The exact +availability-neutral transfers and future activation groups are canonical in +`ACTIVATION_CUSTODY.md`. `WS-AUTH-001-ART-CUSTODY` atomically transfers all 25 +current ART rows to eight AUTH groups and removes seven ART owner values. +`WS-AUTH-001-REV-CUSTODY` atomically transfers all 19 current REV rows to seven +AUTH groups and removes seven REV owner values. Counts, mappings, and planned +availability remain unchanged; no migration is required for owner metadata. + +Every activation requires an immutable merged feature manifest, real-kernel +unavailable proof before activation, exact evaluator integration, and one exact +availability delta afterward. ART/REV/CON cannot activate actions, and AUTH-12, +AUTH-14, and AUTH-15 are not fallback activation paths. + +## D26: Proposed cross-initiative actions register only after complete contracts + +Status: exact identifiers approved by PR #139; registration remains blocked. + +The four proposed REV lifecycle actions and +`artifact.review_evidence.binding.create` are not current runtime actions. AUTH +registers them only in separate reviewed chunks after feature owners publish +principal, typed context, facts, guards, surfaces, transaction ownership, and +hidden dependency manifests. Registration is planned and availability-neutral, +uses existing PermissionIds, and adds typed/PostgreSQL evidence parity. + +The review-evidence binding action extends only +`workstream.artifact.binding`, making 12 exact matrix memberships across the +same seven identities. Its activation requires separate human and service +decisions, two evidence records, explicit lock order, and one transaction; a +human request is never silently converted to service authority. REV timer, +expiry, reconciliation, projection, artifact-reference, and release-control +services require later exact identity-specific contracts. No catch-all service +identity is pre-created. + +## D27: Each remaining AUTH surface owns exact action and migration parity + +Status: planning repair required before each future chunk starts. + +AUTH-10 through AUTH-15 must enumerate every new ActionId, retained +PermissionId mapping, canonical target, principal class, candidates, guards, +surface, and revalidation rule before runtime edits. Each owning migration +updates current typed and PostgreSQL audit validation; no chunk may promise an +active surface whose ActionId is absent. AUTH-11 therefore owns migration +`0025`, and later migration reservations shift through AUTH-15 as recorded in +D15. AUTH-16 aggregates proof; it does not discover or backfill missing +registrations. diff --git a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/DISCOVERY.md b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/DISCOVERY.md index ff3b603a..edabc88d 100644 --- a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/DISCOVERY.md +++ b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/DISCOVERY.md @@ -245,3 +245,68 @@ need an independently reviewable contract and production-code budget. configuration failure behavior, and migration/concurrency proof. - 04B is not activated by this split. It requires 04A merge/memory and a separate explicit user start. + +## WS-XINT Delta Discovery (2026-07-17) + +### Trusted merged inputs + +- PR #139 merged as `5d353b6` and makes + `.agent-loop/initiatives/WS-XINT-001-lifecycle-boundary-reconciliation/` + authoritative for AUTH/ART/REV/CON ownership, activation, transaction, role, + and service boundaries. +- PR #132 remains open at `79d1989` and conflicts with current `main`. Its seven + service identities, eleven exact static ActionId memberships, versioned + migration-only `0023` contract, and no-database-assignment design remain + valid. Its reviewed repairs also remain mandatory: a packaged frozen migration + contract with zero mutable `app.modules` imports, an explicit + Alembic-script-owned repository root, location-independent built-wheel + custody/replay proof, CLI execution and engine disposal on the same event + loop, and original `BaseException` precedence with cancellation/cleanup tests. + Its loop/planning/spec conflicts must not overwrite PR #139. + +### Current runtime gaps + +- `backend/app/modules/authorization/catalogue.py` has 74 PermissionIds and 57 + ActionIds: nine active and 48 planned. All 25 ART rows and 19 REV rows still + use feature-chunk `ActionOwner` values even though PR #139 now defines that + field as exact AUTH activation custody. +- `backend/app/modules/authorization/schemas.py`, + `backend/app/modules/authorization/service.py`, and + `backend/app/modules/audit/schemas.py` still accept `ProjectRole.BOTH`, + `replaced_grant_id`, replacement events, and replacement reasons. +- Migration `0022_bootstrap_admin_grants.py` recreates current PostgreSQL audit + and linked-idempotency validators with the same combined/replacement values. + Historical migrations remain immutable; AUTH-10 `0024` must replace current + validators and fail closed on incompatible evidence. +- The current kernel has request-scoped `require()` but no AUTH-first prepared + mutation handle. Cross-module mutations therefore lack the merged lock, + recompose, evaluate-once, flush, and caller-commit protocol. + +### Missing planning custody + +- No AUTH chunk transferred the 25 ART or 19 REV owner rows, and no exact AUTH + activation chunks existed for their feature-gated evaluators. +- Four approved REV lifecycle ActionIds and the ART review-evidence binding + ActionId are not registered. Their PermissionId mappings are known, but their + complete feature principal/resource/guard/transaction manifests are not, so + AUTH must not invent or register them yet. +- REV timer, expiry, reconciliation, projection, artifact-reference, and + release-control jobs need exact fixed-service identities. The owning REV + contract has not yet supplied that identity-to-ActionId matrix. A catch-all + review service would violate the fixed-service model. +- AUTH-10 through AUTH-15 promise protected surfaces without enumerating every + new ActionId and current PostgreSQL evidence change. Each contract requires + exact preimplementation repair; AUTH-11 now needs migration custody too. + +### Conventions to preserve + +- Feature modules own resource facts, loaders, guards, hidden behavior, and + lifecycle state. AUTH owns grants, evaluator integration, decision evidence, + and availability. +- The route or service command owns one transaction. AUTH and feature + participants flush only; dependency teardown never commits shared work. +- Hidden feature behavior may progress in parallel while the real kernel + returns `action_unavailable`. Only a later exact AUTH chunk activates it. +- New service identities require an exact owning-feature manifest, closed enum + and matrix extension, database constraint migration, controlled provisioning, + AUTH-09E admission reuse, and cross-service negative proof. diff --git a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/INTENT.md b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/INTENT.md index 412993f4..dae8de64 100644 --- a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/INTENT.md +++ b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/INTENT.md @@ -52,6 +52,11 @@ superseded. - One `AuthorizationService` combines registered permissions, grant scope, canonical resource ownership, actor state, lifecycle state, and explicit guards. +- Sensitive mutations use an AUTH-first prepared handle, feature-owned final + fact recomposition, one authorization evaluation, and one caller-owned commit. +- `ActionOwner` names one exact AUTH activation custodian; ART, REV, CON, and + product modules keep resource facts and behavior but never change action + availability. - Revocation and suspension take effect from database state without requiring token refresh. - Sensitive authority changes are idempotent, concurrency-safe, and auditable. @@ -117,6 +122,11 @@ namespace and remains canonical. - Building new approval endpoints on the obsolete bootstrap during cutover. - Coupling submitter, reviewer, and adjudicator authority into one grant row. - Allowing a service token to enter human first-access or grant evaluation. +- Letting a feature label remain an activation owner after PR #139. +- Registering or activating review/artifact actions before complete feature + manifests and transaction proof exist. +- Retaining `both` or replacement evidence in current typed or PostgreSQL + validators after independent project-role grants ship. ## What must not change diff --git a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/PLAN.md b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/PLAN.md index 2c102c08..d447db6b 100644 --- a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/PLAN.md +++ b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/PLAN.md @@ -24,6 +24,22 @@ Bearer token Token roles are never included as product authority. +Sensitive mutations use a second phase after authentication and candidate +resolution: + +```text +AUTH locks current authority and returns one prepared handle +-> feature locks canonical rows and recomposes final typed facts +-> AUTH evaluates once and stages evidence +-> feature participants flush +-> route or service command commits once +``` + +Fixed services use a structurally separate context resolved from an active +identity link, active service ActorProfile, immutable `service_identity`, exact +static ActionId row, and active action. They never enter human first access or +grant evaluation. + ## Migration strategy ### Legacy classification and actor identity @@ -60,6 +76,20 @@ grants and to prove authorization before separately starting `WS-POL-002-04`. This initiative does not own or advance PR #90. Task/submission/checker access follows after exact-project contributor grants and resource loaders exist. +Project contributor grants are independent immutable `submitter`, `reviewer`, +and `adjudicator` rows. AUTH-10 removes current `both` and replacement paths +from typed and PostgreSQL validation in a clean cut. It does not rewrite old +migrations, convert ambiguous evidence, or let one revocation alter another +project role or an AdminRoleGrant. + +Every cutover chunk enumerates its exact ActionIds before implementation and +updates current typed/PostgreSQL audit mapping validation in its own migration. +After AUTH-09A migration `0023`, core reservations are AUTH-10 `0024`, AUTH-11 +`0025`, AUTH-12 `0026`, AUTH-13 `0027`, AUTH-14 `0028`, and AUTH-15 `0029`. +Blocked cross-initiative additions allocate the next trusted-main migration head +only when their complete feature contracts become executable. No migration +number is reserved or allocated while the work remains blocked. + Chunk 06 preserves task claim/start/submission operability through an explicitly named `LegacyWorkflowEligibilityCompatibility` adapter. It reads only classified legacy workflow metadata, grants no product permission, and is @@ -90,6 +120,12 @@ system permissions. Requester identity serialized into a job remains audit evidence only. Actor-attributed mutations reload current profile and grant state before commit. +AUTH-09A's seven artifact identities and eleven exact matrix memberships remain +the first closed service set. New REV or CON services are not inferred or +grouped into a catch-all: each owning feature must first publish an exact +identity-to-ActionId manifest, followed by a reviewed AUTH constraint, matrix, +provisioning, admission, and cross-service denial extension. + ### Ownership and transaction boundaries - The existing `AuthVerifier` port/factory evolves in place; there is no second @@ -106,8 +142,12 @@ state before commit. authorization does not duplicate project/task queries. - Existing `AuditEvent` and `AuditRepository` evolve into the shared authority evidence path; no parallel authority-event ledger is added. -- The injected AsyncSession is the UnitOfWork boundary. Services own - commit/rollback; no generic parallel transaction wrapper is introduced. +- The injected AsyncSession is the UnitOfWork boundary. The request route or + service command owns commit/rollback; AUTH and feature participants flush + only. Dependency teardown never commits an arbitrary shared transaction. +- Sensitive cross-module mutations use the opaque prepared protocol from + `WS-AUTH-001-PREP`; AUTH locks authority first but never imports feature + repositories or commits feature state. ### Test preservation rule @@ -138,21 +178,31 @@ proving the same issuer role metadata alone no longer authorizes. then implement the minimal AuthorizationService kernel and canonical actor self-action cutover in 07B before protected authority-management APIs. 8. Implement bootstrap, `AuthorityControl`, and immutable admin-role grants. -9. Implement actor/link state administration and controlled service actors, - then add fixed service runtime admission without activating feature actions. -10. Implement qualification snapshots and exact-project contributor grants. -11. Cut project identity, guide, source, and visibility queries over to local +9. Reconcile merged WS-XINT boundaries and converge AUTH-09A on trusted `main`. +10. Complete the uninterrupted AUTH-09B through 09E sequence: controlled + provisioning, actor/link administration, lifecycle mutations, and fixed + service runtime admission without activating feature actions. +11. Transfer all current ART/REV owner labels to exact AUTH custodians without + changing availability, then add the prepared mutation authorization + protocol. +12. Implement qualification snapshots and independent contributor grants scoped + to the exact project, including the typed/PostgreSQL clean cut from `both` + and replacement evidence. +13. Cut project identity, guide, source, and visibility queries over to local permissions. -12. Cut project policy mutations, approvals, activation, and setup operations +14. Cut project policy mutations, approvals, activation, and setup operations over to local permissions. -13. Cut task management, queue, assignment, claim, and start operations over. -14. Cut submission, pre-submit, checker trigger/read, and task audit visibility +15. Cut task management, queue, assignment, claim, and start operations over. +16. Cut submission, pre-submit, checker trigger/read, and task audit visibility over. -15. Cut remaining internal workers over, verify the project-setup cutover, +17. Cut remaining internal services over, verify the project-setup cutover, remove old runtime authority, and enforce a deterministic stale-authority scanner. -16. Complete privacy/observability, full conformance, concurrency, and live - proof. +18. As ART, REV, and CON hidden manifests merge, run only their exact AUTH + registration and activation chunks from `ACTIVATION_CUSTODY.md`. +19. Complete privacy/observability, full conformance, concurrency, and live + proof after every exposed protected surface has matching activation and all + unimplemented planned actions still deny. ## Alternatives rejected @@ -162,7 +212,9 @@ proving the same issuer role metadata alone no longer authorizes. - Adding a generic policy-language engine. - Caching authorization decisions across requests. - Changing to `/v1` or exposing permanent `/v1` aliases. -- Implementing review lifecycle work before auth proof. +- Activating review lifecycle work before its AUTH, ART, and CON proof. Hidden + feature behavior may be built in parallel while the real kernel denies the + planned action. ## Boundaries preserved @@ -214,9 +266,13 @@ git diff --check The auth live drill must prove first human access, one-time bootstrap, scoped admin grants, independent project submitter/reviewer/adjudicator grants, -separation of duties, -revocation using the same unexpired token, suspension/reactivation, service -subject handling, cross-project denial, and final-admin concurrency safety. +concurrent three-role issue, independent revoke/regrant in every direction, +wrong-grant denial, submitter-only assignment invalidation, separation of +duties, revocation using the same unexpired token, transaction-time authority +loss, suspension/reactivation, fixed-service admission and cross-service denial, +prepared-handle rollback, action-owner/mapping/availability parity, +feature-manifest-before-activation ordering, cross-project denial, and +final-admin concurrency safety. ## Documentation strategy diff --git a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/RISKS.md b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/RISKS.md index bf35b1f7..3bbd7ab6 100644 --- a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/RISKS.md +++ b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/RISKS.md @@ -20,7 +20,7 @@ | A4 | Bootstrap races or the final Access Administrator is lost | Multiple trust roots or administrative lockout | Bootstrap and every final-admin-removal path lock `AuthorityControl(id=1) FOR UPDATE` before the effective-admin check and mutation | Different-target concurrent bootstrap plus revoke/suspend/deactivate concurrency tests | | A5 | Cross-project grant or IDOR | Unauthorized project access | Canonical DB resource resolution and composite ownership constraints | Cross-project read/mutation tests | | A6 | Revocation loses a race to mutation | Revoked actor commits sensitive change | Revalidate grants and state inside sensitive transaction | Grant-revoke versus command concurrency test | -| A7 | Worker job trusts serialized authority | Stale grant remains effective | Serialized context is evidence only; reload current authority before commit | Revoked queued-command test | +| A7 | Internal service job trusts serialized authority | Stale grant remains effective | Serialized context is evidence only; reload current authority before commit | Revoked queued-command test | | A8 | JWKS outage weakens verification | Unverifiable token accepted | Pinned algorithms, bounded cache, one refresh, fail closed | Cache/rotation/outage contract tests | | A9 | Claims or personal data leak | Security/privacy incident | Minimal verified token type, bounded logging, no raw token/JWKS persistence | Log/error/audit redaction tests | | A10 | Approval provenance breaks | Existing policy activation becomes unreadable or forgeable | Preserve historical values; new actions reference matched local grant | Migration and project approval tests | @@ -37,6 +37,12 @@ | A21 | Kernel APIs ship before their grant/resource authority exists | Fabricated authority, deny-only public surfaces, or hidden dual policy | Split AUTH-07 into 07A catalogue/audit and 07B self-only kernel; defer admin definitions to 08 and project context to 10 | Child-contract plan review, exact active-action tables, and no-grant/no-project surface scans | | A22 | Combined project role couples submitter, reviewer, and adjudicator authority | One revocation removes unrelated capability or forces replacement | One active immutable grant per actor/project/role; no cross-role replacement | Three-role issue/revoke/regrant concurrency and invalidation tests | | A23 | Service token enters human admission or uses another service row | Privilege escalation across human/service or workload boundaries | AUTH-09E fixed service admission and closed static matrix | Cross-service, human/service, inactive-link, and transaction-revalidation denials | +| A24 | Feature owner labels remain executable activation custody | Dual writer or action activation before behavior exists | Atomic ART/REV owner transfers to exact AUTH chunks | Exact owner/mapping/count parity and all-planned denial | +| A25 | Sensitive feature mutation evaluates stale pre-lock facts or crosses an inverse lock path | Revoked authority commits business state or transactions deadlock | Exact AuthorityControl/principal/profile/link/grant order, code-only service validation, then feature locks through a session/action-bound single-use prepared handle | Crossed link-revoke, suspend/deactivate, grant-revoke, final-admin, authority-loss, handle-reuse, cancellation, and rollback concurrency tests | +| A26 | Current validators keep `both` or replacement evidence | Combined authority survives the clean cut or history is silently converted | AUTH-10 replaces current typed/SQL validators and fails closed on obsolete evidence | Prior-head migration, no-conversion, downgrade-refusal, and stale-token tests | +| A27 | Wrong role invalidation reaches the wrong consumer | Reviewer/adjudicator revocation releases submitter work or one role removes another | Exact role in grant, cause event, obligation, and consumer filter | Three-role revoke/regrant and wrong-consumer negative tests | +| A28 | AUTH invents incomplete REV/ART/CON resource or service contracts | Cross-domain privilege, deadlock, or unreviewable coupling | Block registration until immutable feature manifests name facts, guards, service identity, and transaction owner | Registration gate plus manifest and cross-service parity tests | +| A29 | PR #132 convergence drops reviewed migration or cleanup repairs | Migration replay imports mutable runtime code, wheel installs fail, or cleanup hides the original error | Preserve frozen packaged contract, script-owned root, location-independent replay, same-loop cleanup, and original-exception precedence | Exact-head internal re-review plus wheel replay and cancellation/cleanup tests | ## Required reviewers diff --git a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/STATUS.md b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/STATUS.md index 9ec58599..3dad0543 100644 --- a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/STATUS.md +++ b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/STATUS.md @@ -84,23 +84,29 @@ as `90eca12`. Signed schema-v2 memory verified that merge and stopped at AUTH-08. The user explicitly started AUTH-08. Its inherited L1 contract failed initial security/architecture, QA/product, and senior/CI/docs review before runtime edits. The repaired contract passed all required preimplementation -tracks at `cbe7c6c`; bounded AUTH-08 implementation later merged through PR -#131 as `aa0fdcd`. AUTH-09 was split before runtime implementation. AUTH-09A is -reviewed through PR #132 and awaits explicit human merge approval; later -children remain inactive. +tracks at `cbe7c6c`; bounded AUTH-08 implementation later merged through PR #131 +as `aa0fdcd`. AUTH-09 was split before runtime implementation. AUTH-09A was +reviewed through PR #132. PR #139 then merged the authoritative WS-XINT boundary +reconciliation as `5d353b6` on 2026-07-17. PR #132 remains open and now +conflicts with trusted `main`; its fixed service foundation remains valid, but +its planning and evidence must converge from the merged XINT contract and be +re-reviewed before merge. `WS-AUTH-001-XINT` is the active planning-only AUTH +owner response. No runtime successor or feature action is active. ## Active planning chunk -None. +`WS-AUTH-001-XINT` - Lifecycle Boundary Plan Reconciliation. ## Active implementation chunk -None. `WS-AUTH-001-09A` has completed implementation and review and is at the -human merge checkpoint in PR #132. +None. `WS-AUTH-001-09A` has completed implementation on its PR branch, but its +prior review no longer authorizes merge until the branch converges on trusted +`main` and passes exact-head re-review. This chunk changes plans and future +contracts only. ## Current review branch -`codex/ws-auth-001-09-actor-state-service-actors` +`codex/ws-auth-001-xint-reconciliation` ## Chunk status @@ -122,22 +128,51 @@ human merge checkpoint in PR #132. | `WS-AUTH-001-07A` | Merged | `codex/ws-auth-001-07-authorization-kernel` | #126 | Merged as `e9d72a1`; 74 permissions, 50 planned actions, and action-aware audit parity only. | | `WS-AUTH-001-07B` | Merged | `codex/ws-auth-001-07b-deny-default-kernel` | #130 | Merged as `90eca12`; signed memory passed. | | `WS-AUTH-001-08` | Merged | `codex/ws-auth-001-08-bootstrap-admin-grants` | #131 | Merged as `aa0fdcd`; signed memory passed. | +| `WS-AUTH-001-XINT` | External repair reviewed | `codex/ws-auth-001-xint-reconciliation` | #140 | Exact repair state `bac3073` passed all required tracks; replacement external checks pending. | | `WS-AUTH-001-09` | Split | - | - | Split into 09A through 09E before runtime implementation. | -| `WS-AUTH-001-09A` | Awaiting human merge | `codex/ws-auth-001-09-actor-state-service-actors` | #132 | Implementation and review complete; fixed service identity and static matrix foundation. | -| `WS-AUTH-001-09B` | Proposed | - | - | Controlled service ActorProfile/ActorIdentityLink provisioning. | +| `WS-AUTH-001-09A` | Awaiting human merge | `codex/ws-auth-001-09-actor-state-service-actors` | #132 | Merge checkpoint is blocked: branch is open/conflicting; foundation valid, planning must converge on PR #139 and repeat exact-head review. | +| `WS-AUTH-001-09B` | Proposed | - | - | Controlled service ActorProfile/ActorIdentityLink provisioning after 09A. | | `WS-AUTH-001-09C` | Proposed | - | - | Actor and identity-link administrative reads. | | `WS-AUTH-001-09D` | Proposed | - | - | Actor and identity-link lifecycle mutations. | | `WS-AUTH-001-09E` | Proposed | - | - | Fixed service runtime admission after 09D. | +| `WS-AUTH-001-ART-CUSTODY` | Proposed | - | - | Availability-neutral 25-row ART owner transfer after 09E. | +| `WS-AUTH-001-REV-CUSTODY` | Proposed | - | - | Availability-neutral 19-row REV owner transfer after 09E. | +| `WS-AUTH-001-PREP` | Proposed | - | - | AUTH-first prepared mutation protocol after 09E. | | `WS-AUTH-001-10` | Proposed | - | - | Project contributor grants. | | `WS-AUTH-001-11` | Proposed | - | - | Project identity/guide/source/read cutover. | | `WS-AUTH-001-12` | Proposed | - | - | Project policy/setup mutation cutover. | | `WS-AUTH-001-13` | Proposed | - | - | Task management and assignment cutover. | | `WS-AUTH-001-14` | Proposed | - | - | Submission/checker/audit visibility cutover. | -| `WS-AUTH-001-15` | Proposed | - | - | Remaining system worker and obsolete authority removal. | +| `WS-AUTH-001-15` | Proposed | - | - | Remaining internal service and obsolete authority removal. | | `WS-AUTH-001-16` | Proposed | - | - | Conformance and live proof. | +Feature-gated registration and activation chunks are enumerated in +`CHUNK_MAP.md` and `ACTIVATION_CUSTODY.md`. They remain inactive until exact +merged feature manifests and separate human starts exist. + ## Blockers +PR #132 cannot merge unchanged because PR #139 modified overlapping AUTH loop, +plan, chunk, and public-spec files. Resolve this only after the planning +reconciliation merges: converge the 09A runtime/migration/evidence onto current +`main`, preserve XINT role/service/activation wording, repeat required internal +review on the exact head, and rerun external checks. The convergence must also +preserve PR #132's packaged frozen migration contract, zero mutable migration +imports, script-owned repository root, built-wheel location-independent replay, +same-event-loop CLI cleanup, and original-exception/cancellation behavior. + +The four proposed REV lifecycle actions and review-evidence binding action are +blocked on complete feature-owned typed manifests. REV fixed services are also +blocked on exact identity-to-ActionId contracts. These are deliberate +registration gates, not reasons to weaken AUTH or invent catch-all authority. + +AUTH-10 through AUTH-15 require exact action enumeration before each starts. +AUTH-10 additionally owns the clean cut across the typed `ProjectRole`, audit, +and idempotency contracts plus the current PostgreSQL validators recreated by +migration `0022`, removing obsolete `ProjectRole.BOTH` and replacement evidence. +AUTH-11 through AUTH-15 own shifted migrations `0025` through `0029` for their +action/evidence parity. + AUTH-05A and CAT post-merge memory have no remaining blocker and are merged. The combined AUTH-05 contract was rejected before runtime changes because shared audit evidence and diff --git a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-05A-shared-audit-authority-evidence.md b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-05A-shared-audit-authority-evidence.md index 1596227a..b70248d0 100644 --- a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-05A-shared-audit-authority-evidence.md +++ b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-05A-shared-audit-authority-evidence.md @@ -174,7 +174,7 @@ required and event-compatible as follows: | actor reactivate | `administrative_correction` | | initial Access Administrator bootstrap | `initial_access_bootstrap` | | admin/project grant issue | `authority_assignment` | -| project grant replacement | `authority_replacement` | +| project grant replacement | `authority_replacement` (historical foundation value; AUTH-10 removes current emission/validation under D21) | | admin/project grant revoke | `authority_revocation` | | admin grant/last-admin denial | `authorization_policy_denial` | | qualification snapshot | `qualification_evidence_captured` | diff --git a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-10-project-role-grants.md b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-10-project-role-grants.md index 1fc9d34e..51025c0f 100644 --- a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-10-project-role-grants.md +++ b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-10-project-role-grants.md @@ -1,14 +1,20 @@ # Chunk Contract: WS-AUTH-001-10 - Project Qualification And Contributor Role Grants +## Status + +Proposed and inactive. Before implementation review, this contract must add the +exact ActionId/target/guard inventory required by D27. AUTH-PREP is a hard +runtime prerequisite. + ## Parent initiative `WS-AUTH-001` - Workstream Authorization Service ## Goal -Implement immutable qualification snapshots and exact-project independent +Implement immutable qualification snapshots and independent `ProjectRoleGrant(submitter|reviewer|adjudicator)` create, list, and revoke -behavior under scoped Project Manager authority. +behavior scoped to the exact project under Project Manager authority. ## Why this chunk exists @@ -48,6 +54,7 @@ backend/scripts/api_contract_e2e.py docs/operations_authorization_service.md docs/spec_authorization_service.md .agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/** +.agent-loop/merge-intents/WS-AUTH-001-10.json .agent-loop/LOOP_STATE.md .agent-loop/WORK_QUEUE.md .agent-loop/REVIEW_LOG.md @@ -62,6 +69,9 @@ administrative project-grant operation admin roles satisfying submitter/reviewer/adjudicator permissions task/review lifecycle implementation project/task/checker authorization cutover +`both`, compatibility alias, replacement event/reason, `replaced_grant_id`, or +silent conversion of combined/replacement evidence +editing migrations `0018`, `0019`, or `0022` ``` ## Acceptance criteria @@ -89,9 +99,19 @@ project/task/checker authorization cutover concurrently. - Issue never revokes another role. Regrant after revocation creates a new immutable row. +- Typed schemas, audit facts, idempotency evidence, and current PostgreSQL + validators accept only `submitter`, `reviewer`, and `adjudicator`; only issued + and revoked success events remain. `both`, replacement fields/events/reasons, + aliases, and conversion branches are absent. +- Snapshot ownership is composite across snapshot ID, actor, project, and exact + requested role. There is no replacement/supersession column. - Create and revoke require canonical request hashing: same key and same request returns the committed graph; same key with different request is rejected. +- Issue hashing includes the exact requested role. Same key/different role is + `idempotency_mismatch`; a new-key duplicate same-role issue is a stable audited + conflict; distinct keys may issue different roles concurrently. Revoke derives + role from the locked grant and replay reloads/re-authorizes before disclosure. - State, idempotency result, audit event, and invalidation event commit in one transaction. - Only manual creation is enabled; automated schema value cannot be emitted. @@ -99,6 +119,12 @@ project/task/checker authorization cutover - Revocation evidence and invalidation identify the exact revoked role; downstream consumers reconcile only the matching task, review, or future adjudication responsibility. +- The linked invalidation retains exact grant and cause-event references. A + submitter revocation creates only the task-assignment obligation and reviewer + revocation may create only its exact REV-owned review obligation. Adjudicator + revocation persists exact invalidation only and creates or consumes no + adjudication obligation until that separately approved lifecycle is active. + No path changes another project role or an AdminRoleGrant. - Project manager/admin role alone never creates contributor capability. - PostgreSQL concurrency tests cover identical-role creates, concurrent different-role creates, regrant versus revoke, and revocation versus @@ -114,9 +140,13 @@ project/task/checker authorization cutover project deny, pagination/count concealment, minimal-field, rate-limit, and inactive/non-human exclusion tests; no UUID must be recovered from logs or direct database access. -- Migration enforces snapshot/grant ownership FKs, checks, partial unique and - supporting indexes, database-time fields, immutability, prior-head upgrade, - downgrade, and preserved history. +- Migration `0024` enforces exact three-role checks, composite snapshot/grant + ownership, partial unique/supporting indexes, database-time fields, and + immutability. Migration `0024` refuses upgrade when obsolete combined or + replacement evidence exists and never converts or deletes those rows. It + replaces current audit/idempotency validators without editing historical + migrations and refuses an unsafe downgrade without mutating evidence. + Prior-head, fresh replay, preserved history, and both refusal paths are tested. ## Verification commands @@ -156,4 +186,5 @@ privacy, independent issue/revoke semantics, and absence of implicit grants. ## Stop conditions Stop if contributor authority depends on a token role, inferred qualification, -or project ID supplied without canonical database resolution. +project ID supplied without canonical database resolution, compatibility for +`both`, evidence conversion, or a mutation path that bypasses AUTH-PREP. diff --git a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-11-project-read-cutover.md b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-11-project-read-cutover.md index 985bcfa3..9fd08db1 100644 --- a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-11-project-read-cutover.md +++ b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-11-project-read-cutover.md @@ -1,5 +1,10 @@ # Chunk Contract: WS-AUTH-001-11 - Project Identity, Guide, Source, And Visibility Cutover +## Status + +Proposed and inactive. The exact project read/list ActionId inventory and +migration `0025` mapping delta must be added before implementation review. + ## Parent initiative `WS-AUTH-001` - Workstream Authorization Service @@ -37,12 +42,16 @@ backend/app/modules/projects/service.py backend/app/modules/projects/repository.py backend/app/modules/projects/schemas.py backend/app/modules/authorization/** +backend/app/modules/audit/** +backend/alembic/versions/0025_*.py backend/app/api/deps/auth.py backend/tests/test_projects.py backend/tests/test_auth.py +backend/tests/test_alembic.py backend/scripts/api_contract_e2e.py docs/operations_authorization_service.md .agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/** +.agent-loop/merge-intents/WS-AUTH-001-11.json .agent-loop/LOOP_STATE.md .agent-loop/WORK_QUEUE.md .agent-loop/REVIEW_LOG.md @@ -70,12 +79,20 @@ issuer-role fallback or authorization pagination after unfiltered counts minimal-field, concealed-not-found, and pre-filtered count/cursor tests. - The adjudicator grant supplies no adjudication action in this chunk; it adds only the same minimal exact-project read projection. +- One actor may hold all three rows. A decision records the exact matched grant, + never a synthetic combined role. Revoking one role preserves minimal + `project.read` when another eligible exact-project role remains, and changes + no AdminRoleGrant. - Canonical project scope is resolved before filtering, counts, and cursors. - Every migrated project read/list route declares one primary registered action and its canonical project or collection-parent target; permission strings and secondary role policy do not live in the router. - Generated OpenAPI/command manifest-delta tests prove every protected project read/list surface migrated here has exactly one active `ActionId` declaration. +- Before runtime edits, the contract enumerates every new ActionId, existing + PermissionId mapping, canonical target, principal class, facts, guards, and + surface. Migration `0025` updates typed/PostgreSQL action-evidence parity and + proves prior-head upgrade, downgrade, re-upgrade, and fresh replay. - ProjectRepository remains the canonical project/guide/source persistence query owner and returns domain records. The project application service or a feature-owned resource loader composes ResourceContext; persistence does not @@ -94,6 +111,9 @@ issuer-role fallback or authorization pagination after unfiltered counts --cov=app.modules.authorization --cov-report=term-missing --cov-fail-under=90) (cd backend && WORKSTREAM_DATABASE_URL= .venv/bin/python -m pytest -q) (cd backend && WORKSTREAM_DATABASE_URL= .venv/bin/python scripts/api_contract_e2e.py) +(cd backend && WORKSTREAM_DATABASE_URL= .venv/bin/alembic upgrade head) +(cd backend && WORKSTREAM_DATABASE_URL= .venv/bin/alembic downgrade -1) +(cd backend && WORKSTREAM_DATABASE_URL= .venv/bin/alembic upgrade head) python3 scripts/check_stale_workstream_wording.py python3 scripts/check_markdown_links.py git diff --check diff --git a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-12-project-mutation-cutover.md b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-12-project-mutation-cutover.md index 8eeb02ea..2e5d2873 100644 --- a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-12-project-mutation-cutover.md +++ b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-12-project-mutation-cutover.md @@ -1,5 +1,10 @@ # Chunk Contract: WS-AUTH-001-12 - Project Policy And Setup Mutation Cutover +## Status + +Proposed and inactive. Exact ActionIds and migration `0026` mapping/provenance +delta must be enumerated before implementation; AUTH-PREP is required. + ## Parent initiative `WS-AUTH-001` - Workstream Authorization Service @@ -37,13 +42,14 @@ backend/app/modules/projects/** backend/app/modules/authorization/** backend/app/api/deps/auth.py backend/app/workers/project_setup.py -backend/alembic/versions/0025_*.py +backend/alembic/versions/0026_*.py backend/tests/test_projects.py backend/tests/test_auth.py backend/tests/test_alembic.py backend/scripts/api_contract_e2e.py docs/operations_authorization_service.md .agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/** +.agent-loop/merge-intents/WS-AUTH-001-12.json .agent-loop/LOOP_STATE.md .agent-loop/WORK_QUEUE.md .agent-loop/REVIEW_LOG.md @@ -62,6 +68,9 @@ unscoped project-manager access or token role fallback - System-scoped Project Manager can create projects; scoped managers mutate only covered projects. +- Submitter, reviewer, or adjudicator grants never substitute for Project + Manager authority, separately or together. Admin roles do not gain project + mutation outside their defined system/scoped permissions. - Project policy actions use registered permissions and transaction-local grant revalidation. - Project-guide source ingestion behavior and resource facts remain owned by @@ -80,12 +89,15 @@ unscoped project-manager access or token role fallback declaration. - Approval provenance records matched local grant/actor/scope while preserving historical bootstrap provenance. -- Migration `0025` adds matched local grant/scope provenance and ownership +- Migration `0026` adds exact action-evidence parity plus matched local + grant/scope provenance and ownership constraints to project policy approval records without rewriting historical bootstrap values; prior-head upgrade, downgrade, and re-upgrade preserve readable history. - Internal setup worker uses explicit system permission and current context. -- State, idempotency, audit, and invalidation effects remain atomic. +- Every sensitive mutation consumes AUTH-PREP after locking and recomposing + final project facts. State, idempotency, audit, and invalidation effects remain + atomic under one route/service-command commit. - No project mutation uses `require_any_role()` or token roles. - Full backend suite and API contract drill pass. @@ -125,5 +137,6 @@ worker behavior, and strict exclusion of WS-POL product changes. ## Stop conditions -Stop if project scope cannot be derived canonically or post-submit approval -behavior must change. +Stop if project scope cannot be derived canonically, post-submit approval +behavior must change, wrong project roles must substitute for management, or a +mutation would bypass AUTH-PREP. diff --git a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-13-task-assignment-cutover.md b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-13-task-assignment-cutover.md index 1d68623c..e61c12f4 100644 --- a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-13-task-assignment-cutover.md +++ b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-13-task-assignment-cutover.md @@ -1,5 +1,10 @@ # Chunk Contract: WS-AUTH-001-13 - Task Management And Assignment Cutover +## Status + +Proposed and inactive. Exact ActionIds and migration `0027` must be enumerated +before implementation; AUTH-PREP is required for mutations. + ## Parent initiative `WS-AUTH-001` - Workstream Authorization Service @@ -39,7 +44,7 @@ backend/app/modules/tasks/repository.py backend/app/modules/tasks/schemas.py backend/app/modules/tasks/models.py backend/app/modules/tasks/lifecycle.py -backend/alembic/versions/0026_*.py +backend/alembic/versions/0027_*.py backend/app/modules/authorization/** backend/app/modules/audit/** backend/app/api/deps/auth.py @@ -51,6 +56,7 @@ backend/tests/test_alembic.py backend/scripts/api_contract_e2e.py docs/operations_authorization_service.md .agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/** +.agent-loop/merge-intents/WS-AUTH-001-13.json .agent-loop/LOOP_STATE.md .agent-loop/WORK_QUEUE.md .agent-loop/REVIEW_LOG.md @@ -91,16 +97,20 @@ token role or legacy active-worker-profile fallback `operations.task.start_override` PermissionId/ActionId typed and PostgreSQL parity as planned metadata. This chunk promotes the action only with its task resource composer, Operator candidate, guards, surface declaration, reason, - evidence, and behavior tests. Migration `0026` owns task/assignment and - Contributor-field schema changes only; it does not change the permission or - action registry. + evidence, and behavior tests. Migration `0027` owns task/assignment, + Contributor-field, and exact new ActionId evidence parity; it changes no + PermissionId mapping. - Operator `operations.status.read` exposes a read-only cross-project task-queue operational projection with bounded fields; it does not grant task mutation. Audit Authority `audit.read` exposes only covered task evidence. Both paths filter before counts/cursors, conceal unauthorized resources, redact contributor details, and have explicit mutation-denial tests. -- ProjectRoleGrant revocation and ActorProfile suspension/deactivation/link - revocation reconcile exclusive submitter assignments idempotently. For +- Only revocation of the exact active `submitter` ProjectRoleGrant, or + ActorProfile suspension/deactivation/link revocation, reconciles exclusive + submitter assignments idempotently. Reviewer/adjudicator revocation must not + touch task assignment, and submitter revocation must preserve those roles and + every AdminRoleGrant. The consumer verifies cause event, grant ID, actor, + project, and exact role. For `claimed` or `in_progress`, the active assignment closes as `authority_revoked`, the task returns to `ready`, `assigned_to` clears, and immutable prior work/audit history remains. A `needs_revision` task instead @@ -110,9 +120,10 @@ token role or legacy active-worker-profile fallback revision context, supersession linkage, and replay requirements. Reactivation does not restore the old assignment. Submitted/evaluation/review-pending history is not rewritten. -- Reconciliation uses the authority invalidation event plus a durable worker or - same-transaction consuming service with retry/ownership defined in the - runbook. Review-lease reconciliation remains explicitly deferred to +- Reconciliation uses the authority invalidation event plus a durable internal + service or same-transaction consumer with retry/ownership defined in the + runbook. Mutations use AUTH-PREP and one caller-owned commit. Review-lease + reconciliation remains explicitly deferred to WS-REV-001. - When the durable worker path is selected, it is explicitly registered in the existing Celery include list; no second worker registry or scheduler is added. @@ -127,13 +138,14 @@ token role or legacy active-worker-profile fallback remains bounded only because chunk 14 still owns the final submission compatibility consumer; task queue/claim/start no longer depend on it. - The assignment persistence column, model/schema/service fields, response - contract, and new audit payload keys use `contributor_id`. Migration `0026` + contract, and new audit payload keys use `contributor_id`. Migration `0027` preserves every existing assignment owner, supports downgrade, and removes the legacy storage name without exposing a public compatibility alias. - Full backend suite and API contract drill pass. - Tests cover revoke/suspend/reactivate before claim, while claimed, while in progress, at needs-revision, after submit, duplicate reconciliation, reconciliation worker retry, a second contributor reclaiming released work, and needs-revision + wrong-role invalidation preserving assignments and all other grants, reassignment preserving prior findings, locked/rebased context, submission supersession, and high/medium finding replay requirements. @@ -174,4 +186,5 @@ absence of lifecycle changes. ## Stop conditions Stop if submission/checker behavior or task lifecycle semantics outside the -explicit authority-invalidation assignment release must change. +explicit submitter-authority invalidation release must change, if a wrong role +reaches task reconciliation, or if a mutation would bypass AUTH-PREP. diff --git a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-14-submission-checker-cutover.md b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-14-submission-checker-cutover.md index bd5885a6..6f61b261 100644 --- a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-14-submission-checker-cutover.md +++ b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-14-submission-checker-cutover.md @@ -1,5 +1,10 @@ # Chunk Contract: WS-AUTH-001-14 - Submission, Checker, And Audit Visibility Cutover +## Status + +Proposed and inactive. Exact ActionIds and migration `0028` must be enumerated +before implementation; AUTH-PREP is required for mutations. + ## Parent initiative `WS-AUTH-001` - Workstream Authorization Service @@ -41,7 +46,7 @@ backend/app/modules/checkers/** backend/app/modules/projects/schemas.py backend/app/modules/projects/service.py backend/app/adapters/project_agents/openai_agent_sdk.py -backend/alembic/versions/0027_*.py +backend/alembic/versions/0028_*.py backend/app/modules/authorization/** backend/app/modules/audit/** backend/app/api/deps/auth.py @@ -52,6 +57,7 @@ backend/tests/test_alembic.py backend/scripts/api_contract_e2e.py docs/operations_authorization_service.md .agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/** +.agent-loop/merge-intents/WS-AUTH-001-14.json .agent-loop/LOOP_STATE.md .agent-loop/WORK_QUEUE.md .agent-loop/REVIEW_LOG.md @@ -70,7 +76,9 @@ legacy active-worker-profile or workflow-eligibility compatibility fallback ## Acceptance criteria - An exact-project submitter grant plus active assignment is required to - create submissions; admin roles alone cannot submit. + create submissions; reviewer, adjudicator, and admin-only callers cannot + submit. After submitter revocation, retained reviewer/adjudicator/admin grants + do not preserve submission authority. - Contributor artifact staging behavior and resource facts remain owned by `WS-ART-001-04A`; this chunk neither activates upload actions nor provides direct provider access. Dedicated AUTH custodians activate the actions only @@ -93,8 +101,8 @@ legacy active-worker-profile or workflow-eligibility compatibility fallback PermissionId/ActionId typed and PostgreSQL parity as planned metadata. This chunk promotes each action only with its feature resource composer, Operator candidate, guards, surface declaration, reason, evidence, and behavior tests. - Migration `0027` owns submission/checker Contributor-field schema changes - only; it does not change the permission or action registry. + Migration `0028` owns submission/checker Contributor-field schema changes and + exact new ActionId evidence parity; it changes no PermissionId mapping. - Contributor reads preserve ownership, hidden-result redaction, and concealed not-found behavior. - Audit reads expose only permission-appropriate bounded fields before counts. @@ -113,7 +121,7 @@ legacy active-worker-profile or workflow-eligibility compatibility fallback `contributor_suggested_fix`, `contributor_evidence_refs`, and `contributor_visible` across persistence, models, schemas, services, runner contracts, audit payloads, and tests. Submission-policy JSON and derivation - contracts use `contributor_facing_fix`. Migration `0027` preserves all values, + contracts use `contributor_facing_fix`. Migration `0028` preserves all values, supports downgrade, and removes legacy storage/property names without public API aliases. - With the final consumer removed, the legacy `/api/v1/workers/me/profile` @@ -169,4 +177,5 @@ audit disclosure, and unchanged checker routing. ## Stop conditions Stop if authorization cutover requires changing checker outcomes, task states, -or review lifecycle behavior. +or review lifecycle behavior, if a wrong role can submit, or if a mutation +bypasses AUTH-PREP. diff --git a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-15-worker-authority-removal.md b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-15-worker-authority-removal.md index 9c4e9599..76dcebee 100644 --- a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-15-worker-authority-removal.md +++ b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-15-worker-authority-removal.md @@ -1,4 +1,9 @@ -# Chunk Contract: WS-AUTH-001-15 - Remaining System Worker Cutover And Obsolete Authority Removal +# Chunk Contract: WS-AUTH-001-15 - Remaining Internal Service Cutover And Obsolete Authority Removal + +## Status + +Proposed and inactive. Exact remaining command ActionIds, service identities, +and migration `0029` parity must be enumerated before implementation. ## Parent initiative @@ -6,8 +11,8 @@ ## Goal -Verify the project-setup worker cutover completed in chunk 12, move the -remaining pre-review and queued workers to explicit system permissions, +Verify the project-setup service cutover completed in chunk 12, move the +remaining pre-review and queued services to explicit system permissions, revalidate actor-attributed queued mutations, remove obsolete token-role runtime helpers/contexts, and add a deterministic stale-authority scanner. @@ -45,16 +50,20 @@ backend/app/modules/checkers/service.py backend/app/core/permissions.py backend/app/schemas/auth.py backend/app/api/deps/auth.py +backend/app/modules/audit/** +backend/alembic/versions/0029_*.py backend/scripts/api_contract_e2e.py backend/tests/test_projects.py backend/tests/test_tasks.py backend/tests/test_checkers.py backend/tests/test_auth.py +backend/tests/test_alembic.py scripts/check_stale_authorization_docs.py scripts/test_agent_gates.py .github/workflows/agent-gates.yml docs/operations_authorization_service.md .agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/** +.agent-loop/merge-intents/WS-AUTH-001-15.json .agent-loop/LOOP_STATE.md .agent-loop/WORK_QUEUE.md .agent-loop/REVIEW_LOG.md @@ -80,6 +89,10 @@ review/contribution/compensation implementation - Every remaining asynchronous command declares one primary registered action, canonical feature-owned target, and fixed service principal. Serialized human identity is provenance only and never executable command authority. +- Each new service identity is backed by an owning-feature exact manifest, + closed enum/constraint/matrix extension, controlled provisioning, AUTH-09E + admission, and all-pairs cross-service denial. No catch-all identity or + dynamic service grant is permitted. - Generated command-manifest delta tests prove every protected asynchronous surface migrated here has exactly one active `ActionId` declaration. - Project setup is verification/removal-only here; its behavioral cutover @@ -99,6 +112,9 @@ review/contribution/compensation implementation - Scanner has regression tests and runs in CI. - Scanner regression includes a known-bad fixture for each forbidden authority pattern and proves the gate fails rather than silently allowlisting it. +- Migration `0029` adds exact remaining command ActionId evidence parity and any + approved fixed-service constraints; it changes no existing permission mapping + and proves prior-head/fresh upgrade, downgrade, and re-upgrade. - Full backend suite and API contract drill pass. ## Verification commands @@ -113,6 +129,9 @@ python3 scripts/test_agent_gates.py --cov-report=term-missing --cov-fail-under=90) (cd backend && WORKSTREAM_DATABASE_URL= .venv/bin/python -m pytest -q) (cd backend && WORKSTREAM_DATABASE_URL= .venv/bin/python scripts/api_contract_e2e.py) +(cd backend && WORKSTREAM_DATABASE_URL= .venv/bin/alembic upgrade head) +(cd backend && WORKSTREAM_DATABASE_URL= .venv/bin/alembic downgrade -1) +(cd backend && WORKSTREAM_DATABASE_URL= .venv/bin/alembic upgrade head) python3 scripts/check_stale_workstream_wording.py python3 scripts/check_markdown_links.py git diff --check diff --git a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-16-evidence-live-proof.md b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-16-evidence-live-proof.md index e1dba964..e670eea1 100644 --- a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-16-evidence-live-proof.md +++ b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-16-evidence-live-proof.md @@ -1,5 +1,11 @@ # Chunk Contract: WS-AUTH-001-16 - Conformance, Observability, And Live API Proof +## Status + +Proposed final gate. It cannot start until every protected feature surface +already merged has its matching AUTH activation, while every registered action +without merged feature behavior still denies as planned. + ## Parent initiative `WS-AUTH-001` - Workstream Authorization Service @@ -50,6 +56,7 @@ docs/spec_authorization_service.md docs/architecture_data_model.md docs/roadmap_status.md .agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/** +.agent-loop/merge-intents/WS-AUTH-001-16.json .agent-loop/LOOP_STATE.md .agent-loop/WORK_QUEUE.md .agent-loop/REVIEW_LOG.md @@ -62,7 +69,7 @@ review/contribution/compensation implementation production credentials or private keys in fixtures/evidence direct database bootstrap or grant edits in live proof loosening issuer, scope, permission, or resource guards -starting WS-POL-002-03 automatically +starting WS-POL-002-04 or another initiative automatically ``` ## Acceptance criteria @@ -74,6 +81,15 @@ starting WS-POL-002-03 automatically - Tokens, raw claims, JWKS bodies, secrets, and unnecessary PII are absent from logs, errors, audit, and committed evidence. - Table-driven tests cover every permission role/scope allow and deny case. +- Exact conformance proves all 74 PermissionIds and derives the trusted-main + ActionId total at execution time. REV-REG contributes exactly four planned + actions and review-evidence registration contributes exactly one planned + action, in either order; both contribute zero active actions. It proves every + ActionId-to-PermissionId mapping, exact AUTH owner, and availability. Every + fixed-service/service-principal action has exactly its approved static + service-matrix membership, while every human-only action has no service-matrix + membership. No feature-valued activation owner or broader service authority + remains. - A generated conformance manifest covers every protected `/api/v1` route and asynchronous command with exactly one primary registered action, canonical resource type, and owning feature loader/composer. Unknown or missing @@ -82,6 +98,14 @@ starting WS-POL-002-03 automatically policy source. - PostgreSQL tests cover provisioning, grant, final-admin, revocation/command, and idempotency races. +- Prepared-mutation tests prove AUTH-first lock order and an internal, + non-Pydantic `PreparedAuthorizationHandle` bound to the exact session, action, + actor reference kind, actor reference, idempotency key, and request digest. + They prove same-session/action cross-actor or cross-request substitution and + every reuse deny before feature mutation, followed by final feature fact + recomposition, one evaluation, one caller-owned commit, and complete rollback + on authority loss, evidence/participant/commit failure, timeout, and + cancellation. - Live drill proves bootstrap, scoped admin grants, separate submitter, reviewer, and adjudicator grants and independent revocation, admin/contributor separation, same-token revocation, suspension/reactivation, @@ -90,6 +114,26 @@ starting WS-POL-002-03 automatically adjudication actions remain unavailable until WS-REV defines the lifecycle and AUTH activates exact adjudication actions; admin authority alone cannot submit, review, or adjudicate. +- One actor/project holds all three roles concurrently; issue/revoke/regrant is + proven independently in every direction, duplicate/concurrent issue constraints + hold, each revocation preserves the other two and all admin grants, and no + `both`, replacement field/event/reason, audit, idempotency, schema, or current + PostgreSQL validator path remains. +- Submitter revocation alone reaches task-assignment reconciliation; reviewer + revocation creates only the REV obligation; adjudicator invalidation remains + dormant until its lifecycle activates. Wrong-grant submit/review/adjudication + and same-token/transaction-time authority-loss cases deny. +- Fixed-service proof covers exact token/link/profile/identity/matrix/action + admission, human/service isolation, every cross-service denial, planned-action + denial, and transaction revalidation. Missing provisioned rows deny without + preventing application startup. +- Every activated feature action proves immutable feature-manifest-before-AUTH + ordering, real-kernel unavailable behavior before activation, exact + availability delta after activation, and no alternate feature writer. +- When review evidence binding is registered, proof includes distinct human and + binding-service decisions/evidence, exact lock order, and one transaction. + When `review.decision` is active, REV plus the flush-only CON participant + commit once or roll back together with no ART call or contribution fallback. - Live drill implements the complete adopted specification sequence, including Finance and Audit Authority capability separation, Project Manager inability to review by admin role alone, self-grant/self-revoke denials, full authorized @@ -111,8 +155,8 @@ starting WS-POL-002-03 automatically production dependency change requires separately recorded explicit human approval before modification. - No obsolete token-role authorization remains in runtime code. -- Initiative memory records proof and leaves `WS-POL-002-03` inactive until an - explicit user resume signal. +- Initiative memory records proof and does not start `WS-POL-002-04` or another + initiative without a separate explicit user signal. ## Verification commands diff --git a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-ART-CUSTODY-activation-custody-transfer.md b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-ART-CUSTODY-activation-custody-transfer.md new file mode 100644 index 00000000..69eb8bf1 --- /dev/null +++ b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-ART-CUSTODY-activation-custody-transfer.md @@ -0,0 +1,87 @@ +# Chunk Contract: WS-AUTH-001-ART-CUSTODY — ART Activation Custody Transfer + +## Parent initiative + +`WS-AUTH-001` - Workstream Authorization Service + +## Goal + +Atomically transfer all 25 current planned ART actions from historical feature +owner labels to the eight exact AUTH activation custodians in +`ACTIVATION_CUSTODY.md` without changing mappings or availability. + +## Why this chunk exists + +Merged XINT makes `ActionOwner` an AUTH activation custodian, while the current +25 ART rows still name historical feature owners. The metadata must be corrected +atomically before any ART action can be activated. + +## Risk class + +L1. + +## SLA + +P1. No ART activation may proceed while feature owner values remain in the +closed activation-custody registry. + +## Allowed files + +```text +backend/app/modules/authorization/catalogue.py +backend/tests/test_authorization.py +backend/tests/test_auth.py +docs/spec_authorization_service.md +docs/operations_authorization_service.md +.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/** +.agent-loop/merge-intents/WS-AUTH-001-ART-CUSTODY.json +.agent-loop/LOOP_STATE.md +.agent-loop/WORK_QUEUE.md +.agent-loop/REVIEW_LOG.md +``` + +## Not allowed + +```text +ActionId, PermissionId, mapping, or availability changes +database migration or audit-history rewrite +resource composer, evaluator, route, command, ART behavior, or adapter changes +service provisioning or action activation +partial transfer or retained ART activation-owner enum +``` + +## Acceptance criteria + +- Exactly the 25 canonical rows move to the eight AUTH owner values. +- All seven ART owner enum values are removed atomically. +- Catalogue ActionId, PermissionId, active/planned counts, static matrix rows, + and every ActionId-to-PermissionId pair remain exactly equal to the trusted + entry head; this chunk has a zero-count and zero-availability delta. +- Typed, PostgreSQL, audit, definition-owner, and documentation parity reject + missing, extra, dual, or changed mappings. +- Every ART action remains unavailable through the real kernel. + +## Verification commands + +```bash +(cd backend && .venv/bin/python -m ruff check app tests) +(cd backend && WORKSTREAM_DATABASE_URL= .venv/bin/python -m pytest -q tests/test_authorization.py tests/test_auth.py --cov=app.modules.authorization --cov-report=term-missing --cov-fail-under=90) +python3 scripts/check_stale_authorization_docs.py +python3 scripts/check_markdown_links.py +git diff --check +``` + +## Required reviewers + +Senior engineering, QA/test, security/auth, product/ops, architecture, +CI integrity, docs, reuse/dedup, and test delta. + +## Human review focus + +Verify exact 25-row/eight-owner custody transfer, unchanged mappings/counts, and zero +activation. + +## Stop conditions + +Stop if any mapping or availability must change, or if ART runtime behavior is +required. diff --git a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-PREP-prepared-mutation-protocol.md b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-PREP-prepared-mutation-protocol.md new file mode 100644 index 00000000..69413b49 --- /dev/null +++ b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-PREP-prepared-mutation-protocol.md @@ -0,0 +1,126 @@ +# Chunk Contract: WS-AUTH-001-PREP — Prepared Mutation Authorization Protocol + +## Parent initiative + +`WS-AUTH-001` - Workstream Authorization Service + +## Goal + +Add the AUTH-first, caller-committed prepared authorization protocol required +for sensitive cross-module mutations without changing feature behavior. + +## Why this chunk exists + +Request-scoped authorization against unlocked feature facts cannot guarantee +that authority, decision evidence, and business state remain consistent under +concurrency. Sensitive mutations need one explicit AUTH-first lock protocol and +one caller-owned transaction before feature cutovers consume it. + +## Risk class + +L1. + +## SLA + +P1. Sensitive cross-module mutation cutovers remain blocked until the prepared +protocol and its crossed-concurrency proof merge. + +## Prerequisites + +AUTH-09E is merged so human and fixed-service authority sources are structurally +separate and can be locked through one prepared protocol. + +## Allowed files + +```text +backend/app/api/deps/authorization.py +backend/app/modules/authorization/** +backend/app/modules/actors/** +backend/app/modules/audit/** +backend/tests/test_authorization.py +backend/tests/test_auth.py +backend/tests/test_api_controls.py +docs/spec_authorization_service.md +docs/operations_authorization_service.md +.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/** +.agent-loop/merge-intents/WS-AUTH-001-PREP.json +.agent-loop/LOOP_STATE.md +.agent-loop/WORK_QUEUE.md +.agent-loop/REVIEW_LOG.md +``` + +## Not allowed + +```text +feature repository imports or feature lifecycle mutations in AUTH +feature route, background-service, resource-composer, or adapter changes +new grant type, permission, action, service identity, or activation +dependency-teardown commit of an arbitrary shared session +serializable, reusable, cross-session, or caller-constructible prepared handles +``` + +## Acceptance criteria + +- AUTH creates an internal, opaque, non-Pydantic, single-use + `PreparedAuthorizationHandle` only after locking canonical current human or + service authority. It is bound to the exact session, ActionId, actor reference + kind, actor reference, idempotency key, and canonical request digest. +- The database lock order is exact: lock `AuthorityControl(id=1)` first when + final-admin safety applies; order multiple authority principals by + `ActorProfile.id`; for each human lock `ActorProfile`, its exact + `ActorIdentityLink`, then its exact matched `AdminRoleGrant` or + `ProjectRoleGrant`; for each service lock `ActorProfile` then its exact + `ActorIdentityLink`. Only after every authority row is locked may the feature + lock its rows in its documented order. +- `service_identity`, static service-action matrix membership, and action + availability are immutable code-owned validations performed after the service + profile/link locks. They are not database rows and must never be described or + implemented as lock targets. +- The feature locks its records and recomposes final typed facts before AUTH + evaluates exactly once and stages decision evidence. +- The route or service command owns one commit; AUTH and feature participants + flush only. +- Reads retain request-scoped `require()`. +- Before feature mutation, handle consumption requires exact equality for + session identity, ActionId, actor reference kind, actor reference, idempotency + key, and canonical request digest. Stale, reused, wrong-action, cross-session, + same-session/action cross-actor, same-session/action cross-request, serialized, + caller-constructed, or authority-lost handles deny before feature mutation. +- Evidence SQL failure, participant failure, commit failure, timeout, and + cancellation roll back all staged AUTH and feature state with a stable public + error and no partial evidence. +- Lock-order, concurrency, rollback, denial-concealment, and at-least-90-percent + focused authorization coverage are proven with real PostgreSQL behavior. +- Crossed concurrency proves PREP against identity-link revoke, actor suspend or + deactivate, exact grant revoke, and final-admin mutations without deadlock, + stale authorization, partial evidence, or partial feature state. Any existing + inverse actor-self/admin/lifecycle lock path is reconciled before a PREP + consumer is allowed to start. +- Replay/concurrency proof includes cross-actor and cross-request handle reuse in + the same session and for the same action, and proves rejection does not consume + a valid handle or stage feature/evidence state. + +## Verification commands + +```bash +(cd backend && .venv/bin/python -m ruff check app tests) +(cd backend && WORKSTREAM_DATABASE_URL= .venv/bin/python -m pytest -q tests/test_authorization.py tests/test_auth.py tests/test_api_controls.py --cov=app.modules.authorization --cov-report=term-missing --cov-fail-under=90) +(cd backend && WORKSTREAM_DATABASE_URL= .venv/bin/python -m pytest -q) +python3 scripts/check_stale_authorization_docs.py +git diff --check +``` + +## Required reviewers + +Senior engineering, QA/test, security/auth, product/ops, architecture, +CI integrity, docs, reuse/dedup, and test delta. + +## Human review focus + +Review lock order, handle non-reusability, caller-owned commit, and complete +rollback under failure and cancellation. + +## Stop conditions + +Stop if AUTH must own a feature repository, if the caller cannot own one +transaction, or if evidence can commit separately from feature state. diff --git a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-REV-CUSTODY-activation-custody-transfer.md b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-REV-CUSTODY-activation-custody-transfer.md new file mode 100644 index 00000000..d9c4db9f --- /dev/null +++ b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-REV-CUSTODY-activation-custody-transfer.md @@ -0,0 +1,85 @@ +# Chunk Contract: WS-AUTH-001-REV-CUSTODY — REV Activation Custody Transfer + +## Parent initiative + +`WS-AUTH-001` - Workstream Authorization Service + +## Goal + +Atomically transfer all 19 current planned REV actions from historical feature +owner labels to the seven exact AUTH activation custodians in +`ACTIVATION_CUSTODY.md` without changing mappings or availability. + +## Why this chunk exists + +Merged XINT makes `ActionOwner` an AUTH activation custodian, while the current +19 REV rows still name historical feature owners. The metadata must be corrected +atomically without registering or activating later REV lifecycle actions. + +## Risk class + +L1. + +## SLA + +P1. No REV activation may proceed while feature owner values remain in the +closed activation-custody registry. + +## Allowed files + +```text +backend/app/modules/authorization/catalogue.py +backend/tests/test_authorization.py +backend/tests/test_auth.py +docs/spec_authorization_service.md +docs/operations_authorization_service.md +.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/** +.agent-loop/merge-intents/WS-AUTH-001-REV-CUSTODY.json +.agent-loop/LOOP_STATE.md +.agent-loop/WORK_QUEUE.md +.agent-loop/REVIEW_LOG.md +``` + +## Not allowed + +```text +ActionId, PermissionId, mapping, or availability changes +registration of the four proposed lifecycle actions +database migration or audit-history rewrite +REV resource, evaluator, route, job, or lifecycle behavior changes +service identity invention or action activation +partial transfer or retained REV activation-owner enum +``` + +## Acceptance criteria + +- Exactly the 19 canonical rows move to the seven AUTH owner values. +- All seven REV owner enum values are removed atomically. +- Catalogue counts, mappings, active/planned state, PostgreSQL audit parity, + and denial behavior remain unchanged. +- Every REV action remains unavailable through the real kernel. + +## Verification commands + +```bash +(cd backend && .venv/bin/python -m ruff check app tests) +(cd backend && WORKSTREAM_DATABASE_URL= .venv/bin/python -m pytest -q tests/test_authorization.py tests/test_auth.py --cov=app.modules.authorization --cov-report=term-missing --cov-fail-under=90) +python3 scripts/check_stale_authorization_docs.py +python3 scripts/check_markdown_links.py +git diff --check +``` + +## Required reviewers + +Senior engineering, QA/test, security/auth, product/ops, architecture, +CI integrity, docs, reuse/dedup, and test delta. + +## Human review focus + +Verify exact 19-row custody transfer, unchanged mappings/counts, and zero +activation. + +## Stop conditions + +Stop if any mapping or availability must change, or if REV runtime behavior is +required. diff --git a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-XINT-boundary-plan-reconciliation.md b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-XINT-boundary-plan-reconciliation.md new file mode 100644 index 00000000..57baab54 --- /dev/null +++ b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-XINT-boundary-plan-reconciliation.md @@ -0,0 +1,115 @@ +# Chunk Contract: WS-AUTH-001-XINT — Lifecycle Boundary Plan Reconciliation + +## Parent initiative + +`WS-AUTH-001` - Workstream Authorization Service + +## Goal + +Reconcile the remaining AUTH plan with merged PR #139 and the canonical +`WS-XINT-001` AUTH/ART/REV/CON handoffs before any affected runtime work +continues. + +## Why this chunk exists + +The cross-initiative reconciliation changed the meaning of `ActionOwner`, +replaced the combined project-role model, required a prepared mutation +protocol, and made fixed-service admission a prerequisite rather than feature +authority. The existing AUTH plan reflects parts of those decisions but does +not yet provide complete, executable chunk custody. + +## Risk class + +L1 planning and security-contract correction. + +## SLA + +P1. Stop all affected AUTH runtime work until this boundary reconciliation is +reviewed and merged. + +## Allowed files + +```text +.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/** +.agent-loop/merge-intents/WS-AUTH-001-XINT.json +.agent-loop/LOOP_STATE.md +.agent-loop/WORK_QUEUE.md +.agent-loop/REVIEW_LOG.md +docs/spec_authorization_service.md +docs/operations_authorization_service.md +``` + +## Not allowed + +```text +backend runtime, migration, schema, route, background-service, or test implementation +ActionId or PermissionId registration +ActionOwner or ActionAvailability runtime changes +service provisioning or feature action activation +editing immutable historical migrations or archived reference specifications +starting AUTH-09B, ART, REV, CON, or POL runtime work +resolving PR #132 by restoring pre-XINT planning text +``` + +## Acceptance criteria + +- The plan records PR #139 and treats all four merged XINT handoffs as + authoritative inputs. +- PR #132's seven fixed identities, eleven static matrix actions, and migration + `0023` remain valid. Convergence must preserve its packaged frozen migration + contract, zero mutable `app.modules` imports from the migration, explicit + Alembic-script-owned repository root, location-independent built-wheel + custody/replay proof, same-event-loop CLI execution and engine disposal, and + original `BaseException` precedence with cancellation/cleanup tests. Its + planning conflicts are assigned to a separate exact-main convergence and + re-review step. +- `ActionOwner` means only an exact AUTH activation custodian. All 25 current + ART and 19 current REV mappings have explicit availability-neutral transfer + chunks and exact future AUTH activation chunks. +- The four proposed REV actions and the ART review-evidence binding action stay + unregistered until their owning features publish complete typed contracts; + their registration and activation are separate gates. +- AUTH gains a bounded prepared-mutation foundation before project and review + mutations consume it. +- AUTH-10 cleanly removes current `both` and replacement evidence from typed + and PostgreSQL validation without rewriting historical migrations or silently + converting rows. +- AUTH-10 through AUTH-16 state role-specific invalidation, wrong-grant denial, + idempotency, migration, conformance, and fixed-service proof exactly. +- Every future implementation chunk names one merge-intent file, required + reviewers, deterministic proof, and a stop condition. +- The amendment changes no runtime and declares no automatic successor start. + +## Verification commands + +```bash +python3 scripts/check_stale_workstream_wording.py +python3 scripts/check_stale_authorization_docs.py +python3 scripts/check_markdown_links.py +python3 scripts/test_agent_gates.py +python3 scripts/check_internal_review_evidence.py +git diff --check +``` + +## Required reviewers + +- senior engineering +- QA/test +- security/auth +- product/ops +- architecture +- CI integrity +- docs +- reuse/dedup + +## Human review focus + +Review whether authority custody, transaction ownership, service identity, +project-role independence, migration order, and downstream activation gates are +complete without moving ART, REV, or CON behavior into AUTH. + +## Stop conditions + +Stop if reconciliation requires inventing a foreign-domain resource contract, +activating a feature action, changing runtime, or overwriting the merged XINT +contract to preserve older AUTH wording. diff --git a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/reviews/WS-AUTH-001-XINT-external-review-response.md b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/reviews/WS-AUTH-001-XINT-external-review-response.md new file mode 100644 index 00000000..c68fe0f9 --- /dev/null +++ b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/reviews/WS-AUTH-001-XINT-external-review-response.md @@ -0,0 +1,51 @@ +# WS-AUTH-001-XINT External Review Response + +Reviewed repair SHA: `c4c4f2e63ab47c204b394e1825a54987765581cb` +Reviewed at: `2026-07-17T06:08:00Z` + +## GitHub Actions + +Agent Gates runs `29557932996` and `29558017415` failed on the earlier PR head +because the merge intent named AUTH-09A even though trusted `main` contains no +exact AUTH-09A chunk contract. Repair `223a15b` changed the schema-v2 successor +to null, leaving the next runtime priority at the human work queue. Replacement +Agent Gates run `29558216518` passed all 80 gate tests. + +Backend runs `29557932993` and `29558216526` both passed. The latter passed the +internal-review evidence gate, lint, docstring coverage, isolated database +runner, repository-wide coverage suite, all focused coverage ratchets, and the +real API contract drill. This external repair changes no backend, workflow, +dependency, test, or coverage configuration. + +## CodeRabbit Findings + +| Finding | Disposition | Evidence | +|---|---|---| +| Scope service-matrix proof to service actions | Fixed | AUTH-16 now requires exact approved membership for fixed-service actions and proves human-only actions have no membership. | +| Bind PREP to actor/request identity | Fixed | `PreparedAuthorizationHandle` matches session, ActionId, actor-ref kind/ref, idempotency key, and canonical request digest before feature mutation; substitution/replay tests are mandatory. | +| Replace the existing Pydantic `AuthorityClaimHandle` in runtime | Not applied | The comment conflated the current internal idempotency-reservation proof with the future PREP capability. The plan now names a distinct non-Pydantic `PreparedAuthorizationHandle`; runtime remains outside this planning-only PR. | +| Allocate blocked cross-initiative migration heads only when executable | Fixed | The plan forbids reservation or allocation while blocked and allocates from trusted main only when the complete feature contract becomes executable. | +| Clarify independent exact-project grant wording | Fixed | Plan and AUTH-10 goal now state independent contributor grants scoped to the exact project. | +| Prevent PR #131 from becoming a Markdown heading | Fixed | STATUS keeps `PR #131` in prose on the preceding line. | +| Name AUTH-10 clean-cut parity sources | Fixed | STATUS names typed ProjectRole, audit/idempotency contracts, and the PostgreSQL validators recreated by migration 0022. | +| Prevent PR #139 from becoming a Markdown heading | Fixed | WORK_QUEUE keeps `PR #139` in prose on the preceding line. | +| Align migration 0024 refusal semantics | Fixed | The specification and AUTH-10 contract share the normative sentence requiring upgrade refusal and prohibiting conversion or deletion of obsolete evidence. | + +## Review Result + +Exact-head senior engineering, architecture, reuse/dedup, QA/test, product/ops, +security/auth, CI integrity, and docs review passed. Reviewers agreed that +changing the current runtime `AuthorityClaimHandle` would be scope creep and a +contract conflation, not a valid repair for this planning PR. + +## CodeRabbit Pre-Merge Warning + +The PR-description warning was valid and is addressed. PR #140 now contains the +repository trust-bundle sections, and CodeRabbit's current Description check +passes. Replacement checks remain required after the repair head is pushed. + +## Remaining Gate + +Internal evidence must be rebound to the final reviewed response head, then +GitHub Actions and CodeRabbit must rerun. Explicit human approval remains the +only merge authority; this response starts no AUTH runtime chunk. diff --git a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/reviews/WS-AUTH-001-XINT-internal-review-evidence.md b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/reviews/WS-AUTH-001-XINT-internal-review-evidence.md new file mode 100644 index 00000000..cf9259f5 --- /dev/null +++ b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/reviews/WS-AUTH-001-XINT-internal-review-evidence.md @@ -0,0 +1,78 @@ +# WS-AUTH-001-XINT Internal Review Evidence + +Reviewed code SHA: `bac3073b147a923a4f8d6479cf4ce8710df2ed49` +Reviewed at: `2026-07-17T06:13:00Z` +Reviewer run IDs: auth_xint_roles, auth_xint_art_service, +auth_xint_rev_con +Reviewer tracks: senior engineering, QA/test, security/auth, product/ops, +architecture, CI integrity, docs, and reuse/dedup + +## Deterministic Evidence + +- Stale Workstream wording and stale authorization documentation checks passed. +- Markdown links passed for all changed Markdown files. +- All 80 agent-gate tests passed. +- Merge-intent validation passes with a null successor because trusted `main` + does not contain an exact AUTH-09A contract; runtime priority remains a human + work-queue decision. +- CodeRabbit's nine comments were triaged individually: eight valid contract, + least-privilege, migration, and Markdown findings are fixed; the requested + runtime `AuthorityClaimHandle` rewrite was rejected because it conflated the + current idempotency proof with the future PREP capability. +- Exact external-repair review proves the future non-Pydantic + `PreparedAuthorizationHandle` is bound to session/action/actor/idempotency/ + request identity without introducing a runtime change in this planning PR. +- A typed catalogue comparison proved the custody map contains exactly all 25 + current ART actions and all 19 current REV actions, with the canonical eight + ART custody groups. +- `git diff --check` passed against trusted main `5d353b6`. +- No runtime, schema, migration, test, workflow, dependency, package, coverage + configuration, or gate-script file changed. +- No local roadmap XLSX exists in this worktree, so spreadsheet verification was + not applicable. + +## Reviewer Results + +| Reviewer | Result | Blocking findings | Notes | +|---|---|---|---| +| senior engineering | PASS AFTER FIXES | none | Reduced speculative contract fanout and retained only four executable bounded contracts. | +| QA/test | PASS AFTER FIXES | none | Catalogue deltas are order-independent, adjudicator invalidation stays dormant, and future activation requires real feature behavior proof. | +| security/auth | PASS AFTER FIXES | none | PREP has exact database lock ordering, crossed concurrency, caller-owned commit, and rollback requirements. | +| product/ops | PASS AFTER FIXES | none | Independent submitter, reviewer, and adjudicator grants and exact invalidation ownership match merged XINT. | +| architecture | PASS AFTER FIXES | none | The final map preserves XINT's canonical eight ART owners and feature/AUTH transaction boundaries. | +| CI integrity | PASS | none | No CI, test, coverage, dependency, workflow, or gate configuration changed or weakened. | +| docs | PASS AFTER FIXES | none | Public docs distinguish current historical owners from the post-custody invariant and use delta-based future counts. | +| reuse/dedup | PASS AFTER FIXES | none | Premature duplicated activation contracts were removed; future contracts materialize only from immutable feature manifests. | + +## Findings Resolved + +The first review rejected stale absolute catalogue totals, insertion of custody +inside AUTH-09A through 09E, an incorrect ART behavior owner, missing contract +sections, duplicated speculative activation contracts, an incomplete PREP lock +protocol, insufficient PR #132 convergence guarantees, unsafe additive-action +downgrade proof, weak feature activation test requirements, and premature +adjudicator obligation creation. Each finding was repaired before re-review. + +The second review caught one remaining canonical mapping drift: retry had been +split into a ninth ART owner even though merged XINT assigns it to the Operator +custodian. The final head restores eight owners while requiring retry's own +evaluator, guards, behavior tests, and explicit availability assertion. It also +clarifies the current historical-owner exception in the operations runbook. + +External review then tightened fixed-service versus human-only matrix proof, +PREP actor/request binding and substitution tests, blocked migration allocation, +exact-project role wording, migration `0024` refusal parity, and Markdown PR +references. The distinct future `PreparedAuthorizationHandle` is now explicit; +the existing runtime `AuthorityClaimHandle` remains the separate idempotency +reservation contract. + +Valid findings addressed: yes + +Open sub-agent sessions: none + +## Remaining Gate + +PR publication, GitHub checks, CodeRabbit, and explicit human merge approval +remain pending. PR #132 must not merge until this reconciliation merges and its +runtime branch converges from trusted main with all reviewed migration and +cleanup guarantees preserved. diff --git a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/reviews/WS-AUTH-001-XINT-pr-trust-bundle.md b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/reviews/WS-AUTH-001-XINT-pr-trust-bundle.md new file mode 100644 index 00000000..628573e7 --- /dev/null +++ b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/reviews/WS-AUTH-001-XINT-pr-trust-bundle.md @@ -0,0 +1,68 @@ +# WS-AUTH-001-XINT PR Trust Bundle + +## Goal + +Reconcile the remaining AUTH plan with merged PR #139 before AUTH-09A or any +affected ART, REV, or CON authorization work continues. + +## What Changed + +- Adopted merged XINT role, fixed-service, activation-custody, prepared-mutation, + and feature-ownership boundaries throughout the AUTH plan and public docs. +- Kept AUTH-09A through 09E uninterrupted, then placed availability-neutral ART + and REV custody transfers and PREP before sensitive product cutovers. +- Mapped all 25 ART and 19 REV actions to exact future AUTH custodians without + changing runtime; retry remains independently proven under the canonical + Operator owner. +- Made proposed REV and review-evidence registrations feature-manifest gates + with order-independent deltas and safe downgrade requirements. +- Repaired AUTH-10 through AUTH-16 for independent project roles, exact-role + invalidation, dormant adjudicator lifecycle, action/migration custody, and + final conformance proof. +- Addressed external review with exact service-matrix least privilege, complete + PREP actor/request binding, non-reservation of blocked migration numbers, and + normative migration `0024` refusal behavior. +- Preserved the exact migration packaging, wheel replay, event-loop cleanup, + and exception-precedence guarantees that PR #132 must retain when converged. + +## Scope Boundary + +This PR changes planning, loop memory, and authorization documentation only. It +does not change backend runtime, tests, schemas, migrations, catalogue values, +action availability, service provisioning, or feature behavior. + +## Evidence + +- Stale wording and authorization-doc checks passed. +- Markdown links and diff integrity passed. +- All 80 agent-gate tests passed. +- Direct typed comparison proved the exact 25 ART / 19 REV custody map and eight + canonical ART owner groups. +- Required senior, QA, security, product, architecture, CI, docs, and reuse + tracks passed exact reviewed state SHA `bac3073` after all findings were fixed. + +Coverage is not recalculated for a documentation-only change. No threshold or +exclusion changed; future activation contracts require at least 90 percent for +every materially changed subsystem and preservation of the global 78 percent +floor. + +## Remaining Risks + +- PR #132 is still open and conflicting. It must converge only after this plan + merges, preserve its reviewed runtime/migration fixes, and pass fresh exact-head + internal and external review. +- Feature activation contracts remain intentionally unmaterialized until their + immutable feature manifests and real behavior tests exist. +- PREP remains proposed runtime work; no sensitive consumer may start until its + lock-order and crossed-concurrency proof merge. + +## Human Review Focus + +Review the AUTH-09A through 09E sequence, canonical custody mappings, PREP lock +order, independent grant/invalidation semantics, PR #132 preservation list, and +the absence of runtime activation. + +## Human Merge Ownership + +Only the human may approve and merge this PR. Internal review, GitHub checks, +and CodeRabbit do not authorize merge or start AUTH-09A. diff --git a/.agent-loop/merge-intents/WS-AUTH-001-XINT.json b/.agent-loop/merge-intents/WS-AUTH-001-XINT.json new file mode 100644 index 00000000..e83ad172 --- /dev/null +++ b/.agent-loop/merge-intents/WS-AUTH-001-XINT.json @@ -0,0 +1,9 @@ +{ + "chunk_id": "WS-AUTH-001-XINT", + "chunk_title": "Lifecycle Boundary Plan Reconciliation", + "initiative_id": "WS-AUTH-001", + "next_chunk_id": null, + "next_chunk_title": null, + "next_requires_explicit_start": true, + "schema_version": 2 +} diff --git a/docs/operations_authorization_service.md b/docs/operations_authorization_service.md index 4aa6bc46..79fc3fc9 100644 --- a/docs/operations_authorization_service.md +++ b/docs/operations_authorization_service.md @@ -502,10 +502,23 @@ resource loader, lifecycle guards, negative tests, and evidence path exist. The catalogue contains exactly 74 PermissionIds and 57 ActionIds. The two AUTH-07B actor-self actions and seven AUTH-08 administrative actions are active; -the other 48 entries remain planned and non-executable. Planned entries contain -only action, permission, owner, and availability and must not receive deployment -configuration, principals, resource facts, or guards. Startup validation failure -is a release blocker, not a reason to relax catalogue checks. +the other 48 entries remain planned and non-executable. The target post-custody +invariant is that planned runtime entries contain only action, permission, exact +AUTH activation owner, and availability. Until the availability-neutral custody +transfers merge, the 25 ART and 19 REV rows retain their historical feature +owner values as an explicitly blocked exception. +Their owning feature must publish the approved principal/resource/guard/surface/ +transaction contract before registration or activation, but those foreign facts +do not become free-form catalogue fields. Startup validation failure is a release +blocker, not a reason to relax catalogue checks. + +PR #139 requires availability-neutral transfer of all 25 ART and 19 REV owner +rows to exact AUTH chunks before feature activation. Counts and mappings remain +unchanged. Catalogue totals are derived from the trusted entry head: four later +REV registrations add exactly four planned and zero active actions, while the +review-evidence binding registration adds exactly one planned and zero active +action, in either order. Neither addition is operational until its complete +feature contract and separate reviewed AUTH registration exist. Migration `0021` preserves historical audit rows with null `action_id`. Inspect non-null action evidence only by bounded ActionId, request/correlation IDs, and @@ -521,7 +534,7 @@ historical status from identifier prefixes. All submission/review rows remain planned. Initial and revision submission share `submission.create`, and no revision-specific permission or preparation action exists. -Review code must consume the request-scoped public +Review reads consume the request-scoped public `AuthorizationService.require(action_id, typed_resource_context)` boundary. The service's bound caller-owned `AsyncSession` is the only transaction source; the method accepts no session or `uow` argument. Review code must not query @@ -531,6 +544,24 @@ ART-owned `artifact.verification_job.retry` action through `ArtifactOperatorRecoveryPort`; shared outbox dispatch/retry remains outside REV ownership. +Review and other sensitive mutations must wait for `WS-AUTH-001-PREP`. That +protocol locks `AuthorityControl(id=1)` first when final-admin safety applies, +orders multiple principals by ActorProfile ID, then locks each human profile, +exact link, and exact matched grant or each service profile and exact link. +Service identity, static matrix membership, and action availability are +code-owned validations, not database lock targets. Only then does AUTH create an +internal, non-Pydantic `PreparedAuthorizationHandle` bound to the exact session, +ActionId, actor reference kind, actor reference, idempotency key, and canonical +request digest. It is never a route schema or caller input. Consumption matches +every binding before the feature locks rows and recomposes final facts, then AUTH +evaluates and stages evidence once before one route/service-command commit. +Crossed tests must cover link revoke, actor suspend/deactivate, exact grant +revoke, final-admin mutation, and same-session/action cross-actor or +cross-request substitution. Never serialize or reuse the handle, let dependency +teardown commit it, or commit AUTH evidence separately from feature state. The +existing `AuthorityClaimHandle` is a separate idempotency-reservation contract, +not this prepared authorization handle. + Downgrade is allowed only while every action ID remains null and no permission outside migration `0018`'s historical 49-value set exists in the decision, target-reference, or invalidation-reference fields. The migration takes an @@ -542,6 +573,28 @@ Canonical actor self-read/self-update and the seven AUTH-08 administrative actions are active. Project capability context waits for AUTH-10 exact-project grants and canonical project composition. +AUTH-10 is a clean cut to independent `submitter`, `reviewer`, and +`adjudicator` grants. Before rollout, scan current typed schemas, audit facts, +idempotency records, and PostgreSQL validators for `both`, replacement fields, +replacement events, and replacement reasons. Migration `0024` must stop on any +incompatible evidence; operators must remediate through a separately approved +data decision, never an automatic conversion. A safe downgrade also refuses +rather than deleting adjudicator or new exact-role evidence. + +Project-role revocation is routed by exact role. Submitter invalidation may +reach task assignment; reviewer invalidation reaches only REV; adjudicator +invalidation remains dormant until that lifecycle exists. Verify grant ID, +actor, project, role, and cause event before a consumer changes product state. +Revoking one role must leave the other project roles and all AdminRoleGrants +unchanged. + +The first fixed-service set remains seven artifact identities and eleven matrix +memberships from AUTH-09A. Missing provisioned rows deny without stopping the +application. New REV/CON service identities require an exact owning-feature +manifest followed by AUTH-owned enum/constraint/matrix, provisioning, admission, +and cross-service denial proof. Do not create a shared review service or a +database service-grant table. + ## Actor Self Decision Operations `GET /api/v1/actors/me` declares `actor.profile.read_self`; it permits an diff --git a/docs/spec_authorization_service.md b/docs/spec_authorization_service.md index 67e21891..a8cee30c 100644 --- a/docs/spec_authorization_service.md +++ b/docs/spec_authorization_service.md @@ -110,6 +110,15 @@ never replaces another. Regrant after revocation creates a new immutable row. No observed token role, typed profile, skill, qualification, or reputation value creates a grant automatically. +The active model has no `both`, replacement field, replacement event, or +replacement reason. Qualification evidence is bound to the same actor, project, +and exact requested role. One active row is permitted per +actor/project/role. Issue idempotency includes the requested role; revoke derives +the role from the locked grant. Migration `0024` refuses upgrade when obsolete +combined or replacement evidence exists and never converts or deletes those +rows. It replaces current typed and PostgreSQL validators without changing +historical migrations. + ## Permission Catalog AUTH owns the closed PermissionId/ActionId catalog, exact mappings, and action @@ -235,6 +244,14 @@ required, and its dedicated AUTH activation custodian has integrated the exact evaluator and changed availability. Both halves are mandatory; registry or feature presence alone never grants authority. +The four proposed REV lifecycle actions and +`artifact.review_evidence.binding.create` are not part of the current runtime +registry. Catalogue totals are derived from trusted `main` when each gate runs: +REV registration adds exactly four planned and zero active actions, while the +review-evidence registration adds exactly one planned and zero active action, in +either order. Both retain 74 PermissionIds and stay blocked until complete +feature-owned typed and transaction manifests exist. + AUTH-07B activates `actor.profile.read_self` and `actor.profile.update_self`. AUTH-08 activates exactly seven administrative actions through migration `0022`; all other registered actions remain planned. @@ -244,10 +261,10 @@ four stable planned fields shown here; resource facts, candidates, guards, and hidden behavior remain with the listed feature owner. The current owner values are planned pre-transfer catalogue state, not permission for a feature chunk to activate. Before any review action activates, AUTH must transfer activation -custody according to the reviewed +custody according to `ACTIVATION_CUSTODY.md` and the reviewed `.agent-loop/initiatives/WS-XINT-001-lifecycle-boundary-reconciliation/AUTH_REV_HANDOFF.md`. -| ActionId | PermissionId | Current planned feature owner | +| ActionId | PermissionId | Historical pre-transfer owner value | |---|---|---| | `submission.create` | `submission.create` | `WS-AUTH-001-14` | | `review.queue.read` | `review.queue.read` | `WS-REV-001-05` | @@ -314,7 +331,7 @@ dynamically, or changes availability. The following table is the single source of truth for artifact ActionId-to- PermissionId mappings, principal/resource facts, and ART hidden-behavior ownership. AUTH-07A registers only each row's stable `ActionId`, approved -`PermissionId`, current planned feature owner, and `planned` + `PermissionId`, historical pre-transfer owner value, and `planned` availability. Its principal-class and canonical-resource columns are not AUTH registry fields and are not executable authority; the owning WS-ART chunk adopts them with its hidden canonical resource composer, guards, surface declaration, @@ -463,6 +480,39 @@ Each decision carries a bounded SHA-256 digest of its complete typed resource context so feature code cannot reuse it with substituted role, scope, target, or replay facts. List filtering occurs before counts and pagination cursors. +Sensitive mutations use the prepared protocol instead of evaluating final +authority against unlocked feature facts: + +```text +AUTH locks AuthorityControl first when final-admin safety applies +-> AUTH orders principals by ActorProfile ID +-> human: ActorProfile -> exact ActorIdentityLink -> exact matched grant +-> service: ActorProfile -> exact ActorIdentityLink -> code-owned validations +-> AUTH creates one internal non-Pydantic PreparedAuthorizationHandle bound to + session, action, actor reference, idempotency key, and request digest +-> feature locks its canonical rows and recomposes final typed facts +-> AUTH consumes the handle, evaluates once, and stages decision evidence +-> feature participants flush +-> route or service command commits once +``` + +Service identity, static service-action matrix membership, and action +availability are immutable code-owned validations after the service profile and +link locks; they are not database rows or lock targets. Existing actor-self, +administrative, and lifecycle mutations must use the same authority-row order +before any prepared consumer ships. + +The handle is single-use, nonserializable, and never a route schema or caller +input. Consumption matches the exact session, action, actor reference kind, +actor reference, idempotency key, and request digest before feature mutation. +Reuse, same-session/action cross-actor or cross-request substitution, authority +loss, evidence failure, participant failure, cancellation, or commit failure +leaves no feature mutation or partial authority evidence. Reads continue to use +request-scoped `require()`. AUTH never imports feature repositories, and +dependency teardown never commits shared feature work. +Crossed PostgreSQL tests cover PREP against link revocation, actor suspension or +deactivation, exact grant revocation, and final-admin mutation. + For the two active self actions, the default human authority source is `actor_self`; token roles and client-supplied permissions never enter the context. Self-read requires an active link and an active or suspended actor. @@ -526,6 +576,13 @@ human grant evaluation. Feature actions remain unavailable until their owning feature supplies canonical resource facts, guards, hidden behavior, and proof and AUTH separately activates them. +New fixed services are added only after the owning feature publishes an exact +identity-to-ActionId manifest. AUTH then owns one closed enum/constraint/matrix +extension, controlled provisioning, admission reuse, and all-pairs +cross-service denial. REV timer, expiry, reconciliation, projection, +artifact-reference, and release-control identities are not pre-created, and no +catch-all review service exists. + ## Bootstrap And Final-Administrator Safety The first Access Administrator is created through a local management command @@ -552,6 +609,13 @@ ordinary claimed/in-progress assignment may be released by the owning later chunk. A `needs_revision` task retains a durable revision obligation and cannot be returned as ordinary ready work. +Project-role invalidation is exact-role-specific. Submitter revocation alone can +enter task-assignment reconciliation. Reviewer revocation creates only the +REV-owned review obligation; adjudicator invalidation remains dormant until its +lifecycle is enabled. Revoking any one project role leaves the other roles and +all AdminRoleGrants unchanged. Consumers verify the cause event, grant ID, +actor, project, and role before changing product state. + ## Idempotency And Authority Evidence Authority-changing APIs require canonical request hashing and idempotency keys.