diff --git a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-12D2-guide-bound-policy-mutations.md b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-12D2-guide-bound-policy-mutations.md index 260919731..5d32b131e 100644 --- a/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-12D2-guide-bound-policy-mutations.md +++ b/.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-12D2-guide-bound-policy-mutations.md @@ -15,18 +15,22 @@ Add separately authorized routes for review and revision policy records after This contract is reconciled with REV-03P by WS-XINT-003-01. REV owns the immutable/versioned policy semantics; AUTH owns the mutation authorization, -PREP consumption, and decision evidence. Chunk WS-XINT-003-02 implements the -single path below; neither parent contract may build an alternate writer. +PREP consumption, and decision evidence. XINT-003-02A first adopts inactive +append-only persistence and removes the unused legacy paths; 02B implements and +activates the single path below. Neither parent contract may build an alternate +writer. ## One writer path -- Surviving API: separate `PUT /projects/{project_id}/review-policy` and - `PUT /projects/{project_id}/revision-policy` routes in - `backend/app/modules/projects/router.py`, each declaring its exact primary - ActionId. -- Surviving service: new `ProjectPolicyMutationService` methods +- Surviving API in 02B: separate + `PUT /projects/{project_id}/guides/{guide_id}/review-policy` and + `PUT /projects/{project_id}/guides/{guide_id}/revision-policy` routes in + `backend/app/modules/projects/policy_mutation_router.py`, each declaring its + exact primary ActionId. +- Surviving service in 02B: new `ProjectPolicyMutationService` methods `replace_review_policy()` and `replace_revision_policy()`. -- Surviving repository: new append-only +- Surviving repository primitives introduced inactive in 02A and consumed only + by 02B: append-only `ProjectRepository.add_review_policy_version()` and `ProjectRepository.add_revision_policy_version()` methods over the existing `ReviewPolicy` and `RevisionPolicy` tables/models, upgraded as necessary for @@ -37,6 +41,8 @@ single path below; neither parent contract may build an alternate writer. `ProjectService._revision_policy_model()`. - No compatibility route, alias, second model/table, fallback constructor, or dual repository path survives. +- Replay custody is the generalized project-mutation ledger shared with guide + mutations; a policy-only or in-memory replay path is forbidden. Policies may be appended or replaced only while the exact guide version is a draft. Activation freezes the selected policy versions: active-guide policy @@ -61,7 +67,11 @@ P1 ```text backend/app/modules/projects/models.py backend/app/modules/projects/repository.py -backend/app/modules/projects/router.py +backend/app/modules/projects/policy_mutation_router.py +backend/app/modules/projects/policy_mutation_service.py +backend/app/modules/projects/project_mutation_repository.py +backend/app/modules/projects/guide_mutation_repository.py +backend/app/modules/projects/guide_mutation_service.py backend/app/modules/projects/schemas.py backend/app/modules/projects/service.py backend/app/modules/projects/authorization_reads.py diff --git a/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/CHUNK_MAP.md b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/CHUNK_MAP.md index 8085762d3..3cf944181 100644 --- a/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/CHUNK_MAP.md +++ b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/CHUNK_MAP.md @@ -1,7 +1,8 @@ # Chunk Map: WS-REV-001 Review And Revision Lifecycle -REV-03P is reconciled into WS-XINT-003-02 and is not an independent policy -writer. AUTH activation follows the exact XINT-003 waves. +REV-03P is reconciled into WS-XINT-003-02A persistence and 02B mutation +activation and is not an independent policy writer. AUTH activation follows the +exact XINT-003 waves. ## Rule @@ -27,9 +28,9 @@ typed symbol/manifest, and tests. | `WS-REV-001-02B` | Locked Review Policy And Dormant Task Lifecycle Compatibility | L1 | Historical | Superseded; any upstream gap is reported to its owner | | `WS-REV-001-02C` | Submission Attribution, Context, And Immutable Lineage | L1 | Historical | Superseded as an ownership chunk; REV consumes owner-supplied Submission lineage | | `WS-REV-001-PLAN3` | Allow-Review Boundary Reset | L1 | Historical | Merged boundary correction | -| `WS-REV-001-03P` | Review And Revision Policy Persistence | L1 | Reconciled into `WS-XINT-003-02` | Planning input only; never executable independently | +| `WS-REV-001-03P` | Review And Revision Policy Persistence | L1 | Reconciled into `WS-XINT-003-02A` and `02B` | Planning input only; never executable independently | | `WS-REV-001-03` | Review Queue And Lease Persistence | L1 | PLAN3 | Non-executable split record | -| `WS-REV-001-03A` | Queue And Lease Base Persistence | L1 | merged `WS-XINT-003-02`; exact `allow_review`, Submission/artifact, and actor handoffs | Proposed contract; requires current-main refresh and explicit user request | +| `WS-REV-001-03A` | Queue And Lease Base Persistence | L1 | merged `WS-XINT-003-02B`; exact `allow_review`, Submission/artifact, and actor handoffs | Proposed contract; requires current-main refresh and explicit user request | | `WS-REV-001-03B` | Normalized Review Packet Manifest Persistence | L1 | 03A; exact ART packet-membership owner chunk merged | Proposed; owner chunk unscheduled | | `WS-REV-001-04` | Review Chain Persistence | L1 | 03B | Non-executable split record | | `WS-REV-001-04A` | Immutable Review Chain And Decision Request Persistence | L1 | 03B; current actor constraints | Proposed; no contract yet | @@ -76,7 +77,7 @@ typed symbol/manifest, and tests. ```text PLAN -> 01 -> 02(parent) -> PLAN2 -> 02A(historical, superseded) --> PLAN3(boundary reset) -> WS-XINT-003-02 (03P planning input) +-> PLAN3(boundary reset) -> WS-XINT-003-02A -> WS-XINT-003-02B (03P planning input) -> 03(parent) -> 03A -> 03B -> 04(parent) -> 04A -> 04B -> 05(parent) -> 05A -> 05B @@ -129,6 +130,6 @@ configuration, or coverage changes add CI integrity. ## Stop condition PLAN3 is complete. Never resume 02A, 02A1, 02A2, 02A3, 02A4, 02B, or 02C as -REV implementation. Policy work proceeds only through `WS-XINT-003-02`; later -REV feature chunks require current-main contract refresh and an explicit user -request under the ordinary engineering loop. +REV implementation. Policy work proceeds only through `WS-XINT-003-02A` and +then `WS-XINT-003-02B`; later REV feature chunks require current-main contract +refresh and an explicit user request under the ordinary engineering loop. diff --git a/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/STATUS.md b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/STATUS.md index 6b29b2d3c..580166b4b 100644 --- a/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/STATUS.md +++ b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/STATUS.md @@ -15,9 +15,9 @@ them. The attempted 02A1 runtime candidate was reverted in full. `WS-REV-001-PLAN3` is merged historical planning. It retires 02A/02A1/02A2/02A3/02A4/02B/02C as REV implementation authorization. The first -future policy work is the reconciled WS-XINT-003-02 writer cutover; 03P is not -an independent implementation path. Work starts through the repository's -ordinary intent/plan/bounded-change loop after an explicit user request. +future policy work is reconciled WS-XINT-003-02A persistence adoption followed +by 02B prepared writer activation; 03P is not an independent implementation +path. Work follows the repository's ordinary intent/plan/bounded-change loop. The historical text below records the superseded PLAN2/02A state and is not current implementation authority. Trusted main at that time was `44f2467c`, which additionally @@ -109,8 +109,8 @@ start statement in it is void under D28 and PLAN3. ## Human-owned gates -- Implement policy work only through reconciled WS-XINT-003-02 after its - current-main contract review and an explicit user request. +- Implement policy work only through reconciled WS-XINT-003-02A and 02B, one + reviewed PR at a time. Do not begin 02B automatically after 02A. - Start 03A only after 03P and after its current-main refresh proves every exact `allow_review`, Submission, artifact, and reviewer owner handoff. - Exact human Review revision-round counting, deadline anchor, and boundary diff --git a/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-03P-review-revision-policy-persistence.md b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-03P-review-revision-policy-persistence.md index 3e3b361b2..712f4d721 100644 --- a/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-03P-review-revision-policy-persistence.md +++ b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-03P-review-revision-policy-persistence.md @@ -2,8 +2,9 @@ ## Status -Reconciled planning input to `WS-XINT-003-02`. It is not an independent -implementation path. +Reconciled planning input to `WS-XINT-003-02A` and `02B`. It is not an +independent implementation path. PR #195 is preservation evidence only and +must not merge its historical migration or writer architecture. ## Goal @@ -12,7 +13,8 @@ later routing, lease, decision, and human revision behavior. REV owns field semantics, version identity, draft/active immutability, and the facts later lifecycle code consumes. AUTH-12D2 owns authority, PREP, evidence, -and the only mutation surface. The shared implementation is XINT-003-02. +and the only mutation surface. The shared implementation is XINT-003-02A for +inactive persistence adoption and 02B for the sole authorized writer. ## Canonical persistence path @@ -39,9 +41,9 @@ L1: policy immutability, duration/limit semantics, and later decision authority. ## Allowed files -The exact current-main project models, migration, policy schemas, canonical -writer service/repository, AUTH PREP integration, focused tests, and initiative -evidence must be fixed in the refreshed XINT-003-02 contract. +Exact files are fixed separately in the reviewed XINT-003-02A and 02B child +contracts. 02A owns current-head migration and inactive append-only persistence; +02B owns AUTH PREP integration and the only public writer. ## Not allowed @@ -77,5 +79,5 @@ reuse/dedup, docs, test-delta, and CI integrity. ## Stop -Do not implement this parent contract independently. Refresh and implement only -WS-XINT-003-02 after an explicit user request. +Do not implement this parent contract independently. Implement only one reviewed +XINT-003-02 child at a time, beginning with 02A, and stop after each PR. diff --git a/.agent-loop/initiatives/WS-XINT-003-rev-auth-end-to-end/ACTION_CUSTODY.md b/.agent-loop/initiatives/WS-XINT-003-rev-auth-end-to-end/ACTION_CUSTODY.md index db4603577..ae5a83ba7 100644 --- a/.agent-loop/initiatives/WS-XINT-003-rev-auth-end-to-end/ACTION_CUSTODY.md +++ b/.agent-loop/initiatives/WS-XINT-003-rev-auth-end-to-end/ACTION_CUSTODY.md @@ -6,8 +6,8 @@ This table is the planning source of truth for the v0.1 review and human-revisio | ActionId | PermissionId | Principal and scope | Resource family | Surface owner | State | Activation wave | |---|---|---|---|---|---|---| -| `project.review_policy.update` | `project.review_policy.manage` | Project Manager grant for exact project | draft guide + ReviewPolicy version | project/REV semantics; AUTH mutation | registered planned | `WS-XINT-003-02` | -| `project.revision_policy.update` | `project.review_policy.manage` | Project Manager grant for exact project | draft guide + RevisionPolicy version | project/REV semantics; AUTH mutation | registered planned | `WS-XINT-003-02` | +| `project.review_policy.update` | `project.review_policy.manage` | Project Manager grant for exact project | exact draft guide + ReviewPolicy version | project/REV semantics; AUTH mutation | registered planned | persistence prerequisite `02A`; activation `WS-XINT-003-02B` | +| `project.revision_policy.update` | `project.review_policy.manage` | Project Manager grant for exact project | exact draft guide + RevisionPolicy version | project/REV semantics; AUTH mutation | registered planned | persistence prerequisite `02A`; activation `WS-XINT-003-02B` | | `review.queue.read` | `review.queue.read` | reviewer grant; exact project; self-review denied | concealed current-work view | REV | registered planned | `WS-XINT-003-03A` | | `review.claim` | `review.claim` | reviewer grant; exact project; self-review denied | queue entry + global reviewer lease state | REV | registered planned | `WS-XINT-003-03A` | | `review.release` | `review.release` | owning reviewer and active lease | ReviewLease | REV | registered planned | `WS-XINT-003-03A` | @@ -64,8 +64,8 @@ These actions are not XINT-003 custody. Generic artifact download, adjudication, | ActionId | Exact prerequisite behavior/manifest | |---|---| -| `project.review_policy.update` | existing policy records plus refreshed REV-03P/AUTH-12D2 contract; implemented only by `WS-XINT-003-02` | -| `project.revision_policy.update` | existing policy records plus refreshed REV-03P/AUTH-12D2 contract; implemented only by `WS-XINT-003-02` | +| `project.review_policy.update` | merged inactive `WS-XINT-003-02A` persistence; implemented and activated only by `WS-XINT-003-02B` | +| `project.revision_policy.update` | merged inactive `WS-XINT-003-02A` persistence; implemented and activated only by `WS-XINT-003-02B` | | `review.queue.read` | merged hidden REV-05 concealed current-work view | | `review.claim` | merged hidden REV-05 queue admission and REV-06 atomic lease behavior | | `review.release` | merged hidden REV-06 lease release behavior | diff --git a/.agent-loop/initiatives/WS-XINT-003-rev-auth-end-to-end/CHUNK_MAP.md b/.agent-loop/initiatives/WS-XINT-003-rev-auth-end-to-end/CHUNK_MAP.md index ada054799..5c3384abd 100644 --- a/.agent-loop/initiatives/WS-XINT-003-rev-auth-end-to-end/CHUNK_MAP.md +++ b/.agent-loop/initiatives/WS-XINT-003-rev-auth-end-to-end/CHUNK_MAP.md @@ -3,8 +3,10 @@ | Chunk | Purpose | Risk | Dependency | |---|---|---|---| | `WS-XINT-003-01` | Reconcile policy ownership, complete REV catalogue, permissions, surfaces, resource families, and fixed-service matrix while actions stay planned. | L1 | approved plan | -| `WS-XINT-003-02` | Join REV policy semantics/persistence to AUTH-12D2 prepared policy mutation cutover and remove duplicate writer paths. | L1 | 01 plus refreshed REV-03P/AUTH-12D2 | -| `WS-XINT-003-03A` | Activate concealed reviewer current-work plus claim/release/preference with exact project grant, self-review denial, global lease limit, and atomic lease/packet-manifest freeze. | L1 | 02 plus hidden REV queue/lease behavior | +| `WS-XINT-003-02` | Non-executable split record joining REV policy persistence to AUTH mutation custody. | L1 | 01 plus refreshed REV-03P/AUTH-12D2 | +| `WS-XINT-003-02A` | Adopt immutable/versioned REV policy persistence on the current migration head and remove the four dead legacy writer/construction callables; activate nothing. | L1 | 01 and current-main persistence review | +| `WS-XINT-003-02B` | Add the sole policy mutation service/routes, consume AUTH PREP, append immutable policy versions, record decision evidence atomically, and activate only the two policy actions. | L1 | merged 02A | +| `WS-XINT-003-03A` | Activate concealed reviewer current-work plus claim/release/preference with exact project grant, self-review denial, global lease limit, and atomic lease/packet-manifest freeze. | L1 | merged 02B plus hidden REV queue/lease behavior | | `WS-XINT-003-03B` | Activate preference and lease expiry fixed services only. | L1 | 03A plus hidden timer behavior | | `WS-XINT-003-04` | Activate human `review.context.read` and reviewer finding evidence while consuming XINT-002-07A's ART-only packet/materialization/binding capability. | L1 | 03B plus hidden REV packet/evidence manifests and XINT-002-07A | | `WS-XINT-003-05` | Activate only bounded `review.chain.read`, consuming the active REV context and XINT-002 packet/materialization boundary. | L1 | 04 plus merged XINT-002-07A | @@ -15,7 +17,8 @@ | `WS-XINT-003-08B` | Activate both identities for the single `review.reconcile.run` ActionId together, plus artifact-reference, projection, and lifecycle-control surfaces. | L1 | 08A plus hidden REV jobs/projection/control | | `WS-XINT-003-09` | Prove end-to-end least privilege, revocation, replay, concurrency, atomicity, artifact isolation, and coherent route release. | L1 | 02-08B | -Chunks 02 through 09 are planning skeletons, not implementation-ready contracts, +Chunk 02B and chunks 03A through 09 are planning skeletons, not +implementation-ready contracts, until refreshed on current main with exact allowed files and commands. Each row maps to one PR unless its current-main contract is split into smaller children before implementation. A split cannot add a new permission, action, diff --git a/.agent-loop/initiatives/WS-XINT-003-rev-auth-end-to-end/DECISIONS.md b/.agent-loop/initiatives/WS-XINT-003-rev-auth-end-to-end/DECISIONS.md index 2b0ca509f..9565aa664 100644 --- a/.agent-loop/initiatives/WS-XINT-003-rev-auth-end-to-end/DECISIONS.md +++ b/.agent-loop/initiatives/WS-XINT-003-rev-auth-end-to-end/DECISIONS.md @@ -43,3 +43,11 @@ reconciled REV-03P/AUTH-12D2 contracts. 17. XINT-002-07A is the only review-evidence binding availability transition; 07B adds response-slot evaluator shape without changing availability. +18. XINT-003-02 is split into 02A persistence adoption and 02B prepared mutation + activation. 02A is merge-safe because the four retired callables have no + current-main call sites and both ActionIds remain planned. 02B is the only + external writer and policy-action availability transition. +19. PR #195 is preservation evidence, not a merge base or authorization source. + Valid policy semantics and PostgreSQL proofs must be recreated from current + head 0045; its historical 0034 migration, old writer path, merge intent, and + signed-start records are not adopted. diff --git a/.agent-loop/initiatives/WS-XINT-003-rev-auth-end-to-end/DISCOVERY.md b/.agent-loop/initiatives/WS-XINT-003-rev-auth-end-to-end/DISCOVERY.md index 8cd43af1c..fb59caa72 100644 --- a/.agent-loop/initiatives/WS-XINT-003-rev-auth-end-to-end/DISCOVERY.md +++ b/.agent-loop/initiatives/WS-XINT-003-rev-auth-end-to-end/DISCOVERY.md @@ -12,8 +12,9 @@ ## Baseline -Discovery was performed from `origin/main` merge `99dc0b34`, after AUTH-12D. -This initiative begins read-only and changes no application behavior. +Initial discovery was performed from `origin/main` merge `99dc0b34`, after +AUTH-12D. The 02 refresh re-ran discovery at merge `ad8da7e5`, after PRs #236 +and #237. This refresh changes planning only and no application behavior. ## Current implementation and plans @@ -30,6 +31,21 @@ This initiative begins read-only and changes no application behavior. `service.py` contain existing `ReviewPolicy` and `RevisionPolicy` behavior. `backend/app/modules/projects/authorization_reads.py` locks and composes these policies into current project authorization facts. +- Current Alembic head is `0045_guide_metadata_authority`; the old PR #195 + migration descended from historical head 0033 and is preservation input, not + a mergeable migration. +- `ProjectRepository.upsert_review_policy()`, + `upsert_revision_policy()`, `ProjectService._review_policy_model()`, and + `_revision_policy_model()` remain in current code but have no call sites. + Their removal is therefore a clean-cut deletion, not a compatibility break. +- `ActionId.PROJECT_REVIEW_POLICY_UPDATE` and + `PROJECT_REVISION_POLICY_UPDATE`, their catalogue mappings, and their strict + typed resource contexts already exist. Both actions remain planned and the + PREP service does not yet accept them. +- `GuideMutationService` and `guide_mutation_router.py` provide the current + project-scoped PREP/idempotency/decision-evidence composition convention. + Policy mutation must reuse that convention without turning guide mutation + into a generic service locator or retaining a second writer path. - AUTH-12D2 proposes separate review-policy and revision-policy mutation routes. REV-03P also proposes policy persistence. This is an ownership collision: there must be one persistence model and one mutation path. @@ -153,6 +169,9 @@ needs a closed typed context with only its valid shape. ## Dependencies - AUTH-12D2 and REV-03P must be reconciled before either policy writer is built. +- The reconciled implementation is split: 02A can merge because it activates + no route/action and removes only unused mutation callables; 02B is the only + action-availability and external-writer transition. - REV hidden feature chunks must merge before matching AUTH action activation. - XINT-002 remains the sole activation owner for ART review-artifact actions and shared human-review submission actions. WS-XINT-003-01 split the combined diff --git a/.agent-loop/initiatives/WS-XINT-003-rev-auth-end-to-end/PLAN.md b/.agent-loop/initiatives/WS-XINT-003-rev-auth-end-to-end/PLAN.md index 2afadd811..b0079de4c 100644 --- a/.agent-loop/initiatives/WS-XINT-003-rev-auth-end-to-end/PLAN.md +++ b/.agent-loop/initiatives/WS-XINT-003-rev-auth-end-to-end/PLAN.md @@ -7,8 +7,13 @@ activation waves: 1. Reconcile policy ownership, the complete catalogue, permissions, principal classes, fixed-service matrix, surface manifests, and planned availability. -2. Cut over review/revision policy configuration through one persistence path: - REV owns semantics; AUTH-12D2 owns authorization and PREP consumption. +2. Cut over review/revision policy configuration in two merge-safe steps. 02A + adopts the existing tables as immutable/versioned REV records on the current + migration head and removes the four unused legacy writer/construction + callables while activating nothing. 02B adds the only public mutation routes + and service, consumes AUTH PREP, appends through the sole internal repository + primitives, records bounded authorization evidence atomically, and activates + only the two policy ActionIds. 3. Activate concealed reviewer current-work, claim/release/preference, and timer services only after REV queue/lease behavior exists. 4. Amend XINT-002-07 into two ART-only owner waves: 07A is the only ActionId @@ -80,8 +85,21 @@ is required before returning a replayed mutation result. The existing policy persistence is adopted or migrated once; it is not duplicated. REV-03P defines immutable/versioned policy semantics and validation. AUTH-12D2 protects the two mutation routes and supplies authorization evidence. -The implementing chunk must explicitly retire overlapping legacy writer paths -and update both contracts together. +02A must retire the unused `upsert_review_policy`, `upsert_revision_policy`, +`_review_policy_model`, and `_revision_policy_model` callables before 02B +introduces the sole active writer. The child contracts and both parent contracts +must remain synchronized. + +## Policy mutation replay custody + +02B generalizes the existing project-owned guide mutation replay boundary into +one project-mutation replay ledger/repository. The migration preserves existing +guide replay rows, renames the guide-specific model/table/constraints and +repository deliberately, and expands the closed action constraint only for the +two policy actions. GuideMutationService and ProjectPolicyMutationService share +that repository; neither owns an in-memory, alternate, or policy-only replay +store. This is a bounded project composition abstraction, not a generic service +locator. ## Verification strategy @@ -105,8 +123,8 @@ hidden behavior are rejected. ## Stop boundary -This planning amendment creates no runtime code and activates no action. Chunks -02 through 09 are non-implementable planning skeletons until a current-main -refresh replaces every file/command placeholder with exact boundaries and the -user explicitly requests that chunk. Planning complete does not start runtime -work. +This planning amendment creates no runtime code and activates no action. 02A is +the only implementation-ready child. 02B remains non-implementable until 02A +merges and a current-main refresh freezes its exact migration and verification +commands. Chunks 03A through 09 remain planning skeletons. Planning completion +does not start the next child automatically. diff --git a/.agent-loop/initiatives/WS-XINT-003-rev-auth-end-to-end/REVIEW_LOG.md b/.agent-loop/initiatives/WS-XINT-003-rev-auth-end-to-end/REVIEW_LOG.md index 01a847e46..a7a48cfb6 100644 --- a/.agent-loop/initiatives/WS-XINT-003-rev-auth-end-to-end/REVIEW_LOG.md +++ b/.agent-loop/initiatives/WS-XINT-003-rev-auth-end-to-end/REVIEW_LOG.md @@ -64,3 +64,14 @@ findings corrected fixed-service identity drift, ART global-matrix wording, runtime owner versus sub-wave ambiguity, missing per-action dependencies, 07B/human activation order, and obsolete signed-start gates. All tracks passed; the final evidence is in `reviews/WS-XINT-003-01-internal-review.md`. + +## WS-XINT-003-02 planning refresh + +Architecture, QA/product, and security/docs/CI reviewed the current-main split +of the non-executable 02 parent into 02A persistence adoption and 02B prepared +mutation activation. Valid findings corrected replay-ledger custody and allowed +files, route placement, stale 02 parent dependencies, 02B readiness ambiguity, +and a no-activation test selector that initially collected zero tests. All +tracks pass after correction; the exact replacement authorization run passed 2 +tests with 378 deselected. Final evidence is in +`reviews/WS-XINT-003-02-PLAN-internal-review.md`. diff --git a/.agent-loop/initiatives/WS-XINT-003-rev-auth-end-to-end/STATUS.md b/.agent-loop/initiatives/WS-XINT-003-rev-auth-end-to-end/STATUS.md index cf21b03c8..621338ede 100644 --- a/.agent-loop/initiatives/WS-XINT-003-rev-auth-end-to-end/STATUS.md +++ b/.agent-loop/initiatives/WS-XINT-003-rev-auth-end-to-end/STATUS.md @@ -2,12 +2,15 @@ ## Current status -WS-XINT-003-01 contract reconciliation is complete and awaiting human -review/merge. No runtime code or action availability is changed. +WS-XINT-003-01 is merged. Current-main reconciliation split policy work into +02A immutable persistence adoption and 02B prepared mutation activation. No +runtime code or action availability is changed by this planning refresh. ## Baseline - Planning branch began from `origin/main` at `99dc0b34` after AUTH-12D merged. +- This refresh is reconciled against current `origin/main` at `ad8da7e5`, which + includes merged PRs #236 and #237 and uses migration head 0045. - Existing REV actions remain planned/unreleased as product surfaces. - XINT-002 remains the owner of review artifact materialization/binding and human-review submission-artifact activation. @@ -30,5 +33,5 @@ REV-owned semantics with AUTH-owned mutation authorization. ## Next step -Keep hosted exact-head gates green, resolve all external review, and obtain -human merge. Then stop before runtime policy work in WS-XINT-003-02. +Review and merge this contract refresh, then implement only WS-XINT-003-02A. +Do not begin 02B automatically and do not resume independent REV-03P work. diff --git a/.agent-loop/initiatives/WS-XINT-003-rev-auth-end-to-end/chunks/WS-XINT-003-02-policy-mutation-activation.md b/.agent-loop/initiatives/WS-XINT-003-rev-auth-end-to-end/chunks/WS-XINT-003-02-policy-mutation-activation.md index 4eef0b96b..b8d2b6838 100644 --- a/.agent-loop/initiatives/WS-XINT-003-rev-auth-end-to-end/chunks/WS-XINT-003-02-policy-mutation-activation.md +++ b/.agent-loop/initiatives/WS-XINT-003-rev-auth-end-to-end/chunks/WS-XINT-003-02-policy-mutation-activation.md @@ -1,25 +1,26 @@ -# Chunk Contract: WS-XINT-003-02 — Review And Revision Policy Mutation Activation +# Chunk Contract: WS-XINT-003-02 — Policy Persistence And Mutation Split Record ## Status -Non-implementable planning skeleton after 01. Before implementation, refresh on -current main with exact allowed files and commands, then require an explicit -user request for this chunk. +Non-executable parent. Current-main discovery at `ad8da7e5` split implementation +into 02A persistence adoption and 02B prepared mutation activation. ## Goal -Implement one immutable/versioned policy persistence path and authorize the two -covered-project policy mutation routes through the existing PREP protocol. +Deliver one immutable/versioned REV policy persistence path and one +AUTH-prepared covered-project mutation surface without a dual-writer interval. ## Risk class L1 policy and authorization mutation. -## Allowed files +## Child sequence -Must be enumerated exactly at current-main start. Only policy-owned project/REV -models, repository/service/routes, AUTH typed contexts/catalogue parity, -migration, focused tests, docs, and this initiative's evidence may be included. +1. `WS-XINT-003-02A`: adopt immutable persistence and remove unused legacy + writer/construction callables; keep both actions planned and add no route. +2. `WS-XINT-003-02B`: add the sole mutation service/routes, AUTH PREP + consumption, append-only repository calls, atomic decision evidence, and the + exact two action activations. ## Not allowed @@ -41,12 +42,15 @@ reputation, frontend, duplicate policy tables, or legacy writer compatibility. compatibility. - No review lifecycle action is activated. -## Verification +## Shared invariants -Focused PostgreSQL policy/authorization/migration/concurrency tests, Ruff, -90-percent changed-subsystem coverage, hosted full coverage, API contract proof, -and all required L1 reviewers. +- Existing ReviewPolicy and RevisionPolicy tables remain the only records. +- REV owns policy meaning/history; AUTH owns authority/PREP/evidence. +- ART, Task, Submission, Review execution, revision execution, and CON are not + modified by either child. +- PR #195 is discovery/preservation input only. No historical migration SHA, + stale base, old writer, merge intent, or signed-start evidence is adopted. ## Stop condition -Merge and stop before queue/lease activation. +Do not implement this parent. Implement one child per PR and stop after each. diff --git a/.agent-loop/initiatives/WS-XINT-003-rev-auth-end-to-end/chunks/WS-XINT-003-02A-policy-persistence-adoption.md b/.agent-loop/initiatives/WS-XINT-003-rev-auth-end-to-end/chunks/WS-XINT-003-02A-policy-persistence-adoption.md new file mode 100644 index 000000000..64c011284 --- /dev/null +++ b/.agent-loop/initiatives/WS-XINT-003-rev-auth-end-to-end/chunks/WS-XINT-003-02A-policy-persistence-adoption.md @@ -0,0 +1,105 @@ +# Chunk Contract: WS-XINT-003-02A — REV Policy Persistence Adoption + +## Goal + +Adopt the existing ReviewPolicy and RevisionPolicy tables as immutable, +versioned REV-owned history on current main, preserving legacy facts losslessly +and removing four unused legacy mutation/construction callables. Activate no +route or ActionId. + +## Why this chunk exists + +PR #195 proved useful persistence semantics but was built from migration head +0033 and an obsolete independent REV writer contract. Current main is at +`0045_guide_metadata_authority`. This child rebuilds only the valid persistence +boundary and leaves external mutation to 02B. + +## Risk class + +L1 database policy history and downgrade safety. + +## Allowed files + +```text +backend/alembic/versions/0046_review_revision_policy_persistence.py +backend/app/modules/projects/models.py +backend/app/modules/projects/repository.py +backend/app/modules/projects/schemas.py +backend/app/modules/projects/service.py +backend/tests/conftest.py +backend/tests/test_alembic.py +backend/tests/test_projects.py +backend/tests/test_tasks.py +backend/tests/test_artifact_admission.py +backend/scripts/api_contract_e2e.py +docs/architecture_data_model.md +docs/template_project_guide.md +.agent-loop/initiatives/WS-XINT-003-rev-auth-end-to-end/** +.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/STATUS.md +.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-03P-review-revision-policy-persistence.md +``` + +## Not allowed + +- Router, authorization catalogue/PREP/runtime, ActionId availability, grant, + permission, audit-decision, queue, lease, Review, finding, revision execution, + ART, CON, Task transition, Submission, frontend, or dependency changes. +- A second policy table/model, compatibility alias, in-place active-policy + update, public writer, or callable legacy upsert/construction path. + +## Acceptance criteria + +- Migration 0046 descends only from 0045 and creates no second head. +- Existing rows preserve retired values without inventing actor/provenance; + canonical rows expose explicit policy version/provenance and exact REV tokens. +- Each table has an integer `policy_generation`, immutable policy identity, + created provenance, nullable supersession provenance, and one database-enforced + current row per exact project/guide lineage. Migration-existing rows become + generation 1; 02A does not invent a human superseding actor. +- The database refuses update, delete, and truncate of immutable/activated + policy history and serializes draft-policy persistence with guide activation. +- Downgrade is lossless only for untouched migrated legacy rows and refuses + before DDL when canonical history cannot be represented at 0045. +- Models/schemas/read responses distinguish legacy-incomplete from canonical + policy facts without treating archival fields as active semantics. +- `upsert_review_policy`, `upsert_revision_policy`, `_review_policy_model`, and + `_revision_policy_model` are absent, with no replacement public writer. +- Internal `add_review_policy_version()` and + `add_revision_policy_version()` primitives append only, reject caller-facing + update semantics, and remain unused until 02B. +- Both policy ActionIds remain planned; no route or review lifecycle behavior + becomes available. +- Focused catalogue and OpenAPI proof confirms both policy actions remain + planned and no policy mutation route is registered. + +## Verification commands + +```text +cd backend && .venv/bin/alembic heads +cd backend && .venv/bin/pytest -q tests/test_alembic.py -k review_revision_policy +cd backend && .venv/bin/pytest -q tests/test_projects.py -k 'review_policy or revision_policy' +cd backend && .venv/bin/pytest -q tests/test_tasks.py -k 'review_policy or revision_policy' +cd backend && .venv/bin/pytest -q tests/test_artifact_admission.py::test_committed_put_and_independent_verification_are_fenced +cd backend && .venv/bin/pytest -q tests/test_authorization.py -k 'project_mutation_actions_cannot_issue_prepared_handles_while_planned or project_mutation_resources_and_prepared_scopes_are_closed' +cd backend && .venv/bin/ruff check app/modules/projects tests/conftest.py tests/test_alembic.py tests/test_projects.py tests/test_tasks.py tests/test_artifact_admission.py alembic/versions/0046_review_revision_policy_persistence.py +cd backend && .venv/bin/pytest --cov=app.modules.projects.models --cov=app.modules.projects.repository --cov=app.modules.projects.schemas --cov-branch --cov-report=term-missing --cov-fail-under=90 -q tests/test_projects.py -k 'review_policy or revision_policy' +python3 scripts/check_stale_workstream_wording.py +python3 scripts/check_markdown_links.py +git diff --check +``` + +The full suite and coverage floor run in GitHub Actions. + +## Required reviewers + +Senior engineering, QA/test, security/data, product/ops, architecture, +reuse/dedup, docs, test-delta, and CI integrity. + +## Human review focus + +Lossless legacy handling, append-only history, draft/activation race safety, +downgrade refusal, removal of dead writers, and absence of activation. + +## Stop + +Merge and stop. Do not begin 02B automatically. diff --git a/.agent-loop/initiatives/WS-XINT-003-rev-auth-end-to-end/chunks/WS-XINT-003-02B-policy-mutation-activation.md b/.agent-loop/initiatives/WS-XINT-003-rev-auth-end-to-end/chunks/WS-XINT-003-02B-policy-mutation-activation.md new file mode 100644 index 000000000..0b9dab616 --- /dev/null +++ b/.agent-loop/initiatives/WS-XINT-003-rev-auth-end-to-end/chunks/WS-XINT-003-02B-policy-mutation-activation.md @@ -0,0 +1,108 @@ +# Chunk Contract: WS-XINT-003-02B — Prepared Policy Mutation Activation + +## Goal + +Expose the only review/revision policy mutation surface for covered Project +Managers, consume AUTH PREP against final locked facts, append immutable policy +versions, record bounded decision evidence atomically, and activate only the two +policy ActionIds. + +## Prerequisite + +Merged 02A at the then-current main head. Refresh exact symbols and migration +state before implementation; do not duplicate 02A persistence. This contract is +non-implementable until that refresh replaces every conditional file and +verification placeholder. + +## Risk class + +L1 authorization and policy mutation. + +## Allowed files + +```text +backend/app/api/router.py +backend/app/api/deps/authorization.py +backend/app/modules/authorization/catalogue.py +backend/app/modules/authorization/kernel.py +backend/app/modules/authorization/prepared.py +backend/app/modules/authorization/runtime.py +backend/app/modules/projects/authorization_reads.py +backend/app/modules/projects/models.py +backend/app/modules/projects/guide_mutation_repository.py +backend/app/modules/projects/project_mutation_repository.py +backend/app/modules/projects/guide_mutation_service.py +backend/app/modules/projects/policy_mutation_router.py +backend/app/modules/projects/policy_mutation_service.py +backend/app/modules/projects/repository.py +backend/app/modules/projects/schemas.py +backend/alembic/versions/_project_policy_mutation_authority.py +backend/tests/test_alembic.py +backend/tests/test_authorization.py +backend/tests/test_projects.py +backend/scripts/api_contract_e2e.py +docs/spec_authorization_service.md +docs/operations_authorization_service.md +docs/operations_roles_permissions.md +.agent-loop/initiatives/WS-XINT-003-rev-auth-end-to-end/** +.agent-loop/initiatives/WS-AUTH-001-workstream-authorization-service/chunks/WS-AUTH-001-12D2-guide-bound-policy-mutations.md +``` + +The post-02A refresh must decide exact rename/delete paths and replace the +migration placeholder before implementation. + +## Not allowed + +- Policy persistence redesign, guide create/update compatibility, generic + mutation service locator, alternate writer/repository, direct grant reads in + project code, Review/queue/lease/revision execution, ART, CON, Task, + Submission, frontend, or dependency changes. + +## Acceptance criteria + +- Separate `PUT /api/v1/projects/{project_id}/guides/{guide_id}/review-policy` + and `/revision-policy` routes declare exactly their corresponding primary + ActionIds and require UUID idempotency keys before actor provisioning. Request + JSON cannot choose authoritative project/guide relationships. +- `ProjectPolicyMutationService` follows the established project mutation + composition convention without inheriting unrelated guide behavior. +- Only an active human Project Manager with the exact project grant and + `project.review_policy.manage` may mutate the matching draft guide lineage. +- PREP binds actor/link/grant, action, project, guide ID/version, current or + reserved policy identity/generation/digest, request digest, idempotency key, + session, and root transaction; final consumption uses locked current facts. +- The service calls only 02A's append-only repository primitives. Exact replay + returns the committed response after reauthorization; changed, copied, + cross-action/project/guide, revoked, stale, or concurrent requests fail closed. +- Policy row, authorization decision evidence, audit/provenance, and replay + result commit once; every injected failure rolls back all four. +- Existing guide replay rows are preserved while + `GuideMutationIdempotencyRecord`/`GuideMutationRepository` are deliberately + generalized to one closed project-mutation replay model/repository. Its + database action constraint admits the three existing guide actions and only + the two policy actions; both guide and policy services use that one ledger. +- Only `project.review_policy.update` and + `project.revision_policy.update` transition from planned to active. No review + execution action or product route is released. + +## Verification commands + +This section is intentionally not implementation-ready. Freeze exact focused +commands after 02A merges. They must include policy route, +authorization denial/replay, PostgreSQL concurrency/rollback, OpenAPI action +parity, Ruff, changed-subsystem 90-percent coverage, stale authorization docs, +Markdown links, diff integrity, and GitHub-hosted full coverage. + +## Required reviewers + +Senior engineering, QA/test, security/auth, product/ops, architecture, +reuse/dedup, docs, test-delta, and CI integrity. + +## Human review focus + +Single writer, exact covered-project authority, PREP final-fact binding, +idempotency, atomic evidence, and exactly two action activations. + +## Stop + +Merge and stop before reviewer queue/lease work. diff --git a/.agent-loop/initiatives/WS-XINT-003-rev-auth-end-to-end/reviews/WS-XINT-003-02-PLAN-internal-review.md b/.agent-loop/initiatives/WS-XINT-003-rev-auth-end-to-end/reviews/WS-XINT-003-02-PLAN-internal-review.md new file mode 100644 index 000000000..7cc7b767f --- /dev/null +++ b/.agent-loop/initiatives/WS-XINT-003-rev-auth-end-to-end/reviews/WS-XINT-003-02-PLAN-internal-review.md @@ -0,0 +1,34 @@ +# Internal Review: WS-XINT-003-02 Planning Refresh + +## Scope + +Current-main, documentation-only reconciliation of the non-executable 02 parent +into 02A persistence adoption and 02B prepared mutation activation. + +## Results + +- Architecture: PASS after making 02B non-implementable, choosing one shared + project-mutation replay ledger, fixing route placement, and synchronizing the + downstream 02A/02B dependency. +- QA/product: PASS after making only 02A implementation-ready, adding explicit + no-activation and focused coverage proof, and correcting the stale parent + reference in the REV stop condition. +- Security/docs/CI: PASS after replacing a zero-test selector with two exact + existing authorization tests. The focused run passed with 2 tests and 378 + deselected. No workflow, dependency, runner, or threshold changed. + +No reviewer finding remains open. All reviewer sessions completed. + +## Deterministic evidence + +- `python3 scripts/check_stale_workstream_wording.py` +- `python3 scripts/check_stale_authorization_docs.py` +- `python3 scripts/check_stale_artifact_contracts.py` +- `python3 scripts/check_markdown_links.py` +- `git diff --check` +- `cd backend && .venv/bin/pytest -q tests/test_authorization.py -k + 'project_mutation_actions_cannot_issue_prepared_handles_while_planned or + project_mutation_resources_and_prepared_scopes_are_closed'` + +The focused authorization run passed: 2 passed, 378 deselected. The full suite +and repository-wide coverage remain GitHub Actions-owned. diff --git a/.agent-loop/initiatives/WS-XINT-003-rev-auth-end-to-end/reviews/WS-XINT-003-02-PLAN-pr-trust-bundle.md b/.agent-loop/initiatives/WS-XINT-003-rev-auth-end-to-end/reviews/WS-XINT-003-02-PLAN-pr-trust-bundle.md new file mode 100644 index 000000000..fef3a2561 --- /dev/null +++ b/.agent-loop/initiatives/WS-XINT-003-rev-auth-end-to-end/reviews/WS-XINT-003-02-PLAN-pr-trust-bundle.md @@ -0,0 +1,63 @@ +# PR Trust Bundle: WS-XINT-003-02 Planning Refresh + +## Goal and result + +Reconcile the policy portion of the REV-AUTH plan with current main before any +runtime change. The result splits the retired 02 parent into one bounded, +implementation-ready persistence child (02A) and a later non-implementable +authorization/route activation child (02B). + +## Scope + +Planning and contract Markdown only. No runtime code, migration, route, +catalogue availability, contribution behavior, workflow, dependency, test, or +coverage configuration changed. + +## Design + +- 02A adopts the existing ReviewPolicy and RevisionPolicy tables as immutable, + append-only REV history on migration head 0045 and removes four unused legacy + callables. It activates nothing. +- 02B later adds exact guide-scoped routes, consumes AUTH PREP against locked + facts, and activates only the two policy actions. +- 02B deliberately generalizes the existing guide replay ledger into one + closed project-mutation replay ledger while preserving guide replay rows; it + forbids alternate, policy-only, or in-memory replay paths. +- 02B cannot be implemented until 02A merges and its exact files, migration, + symbols, and verification commands are refreshed from then-current main. +- Reviewer contribution and accept-only submitter contribution remain a later + typed CON boundary. This planning refresh changes no contribution policy, + record, award, fulfillment, or reputation behavior. + +## Proof + +All deterministic documentation checks pass. The exact existing authorization +tests proving planned policy-action closure and closed project-mutation resource +contexts pass: 2 passed, 378 deselected. + +## Internal review + +Architecture, QA/product, and security/docs/CI all pass after their valid +findings were corrected. No reviewer session remains open. + +## CI and external review + +No CI surface changed or weakened. GitHub Actions must run the full suite and +repository-wide coverage on the exact PR head. CodeRabbit comments must be +resolved before human merge. + +## Remaining risks + +02A is L1 database work and must prove lossless migration/downgrade refusal, +append-only enforcement, activation-race safety, and at least 90 percent focused +changed-subsystem coverage. 02B remains intentionally unavailable for start. + +## Human review focus + +Confirm the REV-owned persistence versus AUTH-owned mutation boundary, the +single replay architecture, exact guide lineage, absence of activation, and the +stop after 02A. + +## Human merge ownership + +Only the human may merge this PR.