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 0d7921670..b93430b0a 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 @@ -2,128 +2,122 @@ ## Rule -One chunk maps to one PR. No runtime chunk starts until its AUTH, ART, and CON -gates are satisfied on current trusted `main` and the user gives a separate -explicit start signal. +One executable chunk maps to one PR. Merged parent IDs remain non-executable +split records. A proposed child is not executable until its own current-main +contract is authored, internally reviewed, explicitly started, and every owner +gate is proven by exact chunk ID, merged PR/SHA, migration head where relevant, +typed symbol/manifest, and tests. -## Chunks +## Current sequence | Chunk | Title | Risk | Gate | Status | |---|---|---:|---|---| -| `WS-REV-001-PLAN` | Review And Revision Lifecycle Planning | L1 | None | Merged through PR #128 at trusted main `0302bcf854a565d429e232ad6b076a1931ea74e4` | -| `WS-REV-001-01` | Canonical Contract Adoption And Dependency Conformance | L1 | Plan approval; current-main refresh; merged WS-XINT-001 handoffs, AUTH PR #140 planning contracts, AUTH-09A/09B foundations, and CON-01 canonical contract adoption | Merged through PR #145 at trusted main `b2b9016d5fee33ddca40882c97620a178d8e52f0` | -| `WS-REV-001-02` | Locked Review Policy And Task Lifecycle Alignment | L1 | Parent explicitly started; required L1 plan review | Split before runtime; non-executable parent | -| `WS-REV-001-02A` | Project Guide Activation Sequence And Publication Locking | L1 | AUTH-09D-A and the subsequent AUTH-owned contributor-field foundation merged; exact dependency SHA/head refresh; separate human start | Planning prepared; runtime blocked | -| `WS-REV-001-02B` | Locked Review Policy And Dormant Task Lifecycle Compatibility | L1 | 02A merged; approved preference/lease duration defaults; separate human start | Proposed | -| `WS-REV-001-02C` | Submission Attribution, Context, And Immutable Lineage | L1 | 02B merged; exact AUTH contributor/human-lineage constraints present; separate human start | Proposed | -| `WS-REV-001-03` | Review Queue And Lease Persistence | L1 | 02C merged; WS-CON ContributionPolicyVersion persistence merged | Proposed | -| `WS-REV-001-04` | Immutable Review, Final Acceptance, Findings, And Replay Persistence | L1 | 03 merged; shared transactional-outbox persistence and caller-transaction lifecycle-audit participant merged at exact refreshed SHAs | Proposed | -| `WS-REV-001-05` | Checker Admission, Preferred Routing, And Queue Views | L1 | 04; ART v2 submission/checker cutover; AUTH-10 reviewer grants and AUTH-11 project visibility; registered actions remain planned; hidden manifest later gates `WS-AUTH-001-REV-05` | Proposed | -| `WS-REV-001-06` | Atomic Claims, Release, Preference, And Timers | L1 | 05; merged `WS-AUTH-001-REV-CUSTODY` and `WS-AUTH-001-PREP`; merged AUTH-09A foundation and AUTH-09B provisioning capability plus exact expiry identity extensions/provisioning and AUTH-09E admission from the merged REV-01 manifest; WS-CON ReviewLease ContributionPolicyVersion freeze participant; hidden manifest later gates `WS-AUTH-001-REV-06` | Proposed | -| `WS-REV-001-07` | Artifact-Backed Review Context And Finding Evidence | L1 | 06; merged PREP consumer contract; approved and merged ART-owner amendment for v2 packet-read; separately approved `WS-ART-001-REV-EVIDENCE` candidate/finalize capability; `WS-AUTH-001-ART-REV-EVIDENCE-REG` plus exact binding service row; hidden manifests later gate `WS-AUTH-001-REV-07` and `WS-AUTH-001-ART-REV-EVIDENCE` | Proposed | -| `WS-REV-001-08` | Decision, Final Acceptance, And Task-Effect Contract | L1 | 07; merged PREP consumer contract; Review persistence and the accept-only FinalAcceptance write remain disabled until 10; complete hidden REV+CON composition later gates `WS-AUTH-001-REV-08` | Proposed | -| `WS-REV-001-09A` | Revision Context Preparation And Resubmission | L1 | 08; ADR 0010 adopted; retired compensation-context field removal merged; schema-only contributor-field foundation; PREP; registered planned `submission.create`; hidden manifest later gates `WS-AUTH-001-REV-09A` and amended AUTH-13/14 product cutovers | Proposed | -| `WS-REV-001-09B` | Finding Replay, Resolution, And Return Routing | L1 | 09A | Proposed | -| `WS-REV-001-10` | Final Acceptance, WS-CON Atomic Integration, And Hidden Composition | L1 | 09B; PREP; approved and merged ART/task-owner `Submission.artifact_hash` amendment; merged CON FinalAcceptance-sourced lineage schema and two-operation flush-only contribution/award participant; no mandatory contribution-evidence projection; completion later gates `WS-AUTH-001-REV-08` | Proposed | -| `WS-REV-001-11` | Admin Overrides, Reviewer-Revocation Recovery, And Reconciliation | L1 | 10; AUTH invalidation; `WS-AUTH-001-REV-REG` registered/planned from the merged REV-01 manifest; PREP; merged AUTH-09A foundation and AUTH-09B capability plus exact invalidation/reconciliation identity extensions/provisioning and AUTH-09E admission from that manifest; ART Operator recovery port; hidden manifest later gates `WS-AUTH-001-REV-11` | Proposed | -| `WS-REV-001-12` | Snapshot Projection, Notifications, And Observability | L1 | 11; ART projection port; outbox foundation; PREP; merged AUTH-09A foundation and AUTH-09B capability plus exact artifact-reference/projection identity extensions/provisioning and AUTH-09E admission from the merged REV-01 manifest; hidden manifest later gates `WS-AUTH-001-REV-12` | Proposed | -| `WS-REV-001-12A` | Joint Lifecycle Release-Control Foundation | L1 | 12 review drain-observation port; exact core WS-CON hidden-readiness manifest; `WS-AUTH-001-REV-REG`; PREP; CON obligation-writer, dispatch, and callback fence hooks plus fulfillment/outbox drain-cutoff and observation port; complete additive manifests later gate `WS-AUTH-001-REV-LIFECYCLE` | Proposed | -| `WS-REV-001-13` | Coherent Public Release, Live API Drill, And Release Proof | L1 | 12A; amended full AUTH-13/14 product cutovers; AUTH-14 `submission.create` active with prepared-revision proof; `WS-AUTH-001-REV-CUSTODY`; exact `WS-AUTH-001-REV-05/06/07/08/09A/11/12`, `WS-AUTH-001-REV-LIFECYCLE`, and ART evidence actions active after hidden behavior; ART/CON/outbox live readiness | Proposed | - -## Dependency order +| `WS-REV-001-PLAN` | Review And Revision Lifecycle Planning | L1 | None | Merged PR #128 | +| `WS-REV-001-01` | Canonical Contract Adoption And Dependency Conformance | L1 | PLAN | Merged PR #145 | +| `WS-REV-001-02` | Locked Review Policy And Task Lifecycle Alignment | L1 | 01 | Merged PR #147; non-executable split record | +| `WS-REV-001-PLAN2` | REV-02A Runtime Readiness Plan Refresh | L1 | 02; planning-only human start | Active planning/specification chunk; no runtime | +| `WS-REV-001-02A` | Project Guide Activation Sequence And Publication Locking | L1 | Exact merged AUTH contributor foundation; refreshed SHA/head; separate human start | Runtime blocked | +| `WS-REV-001-02B` | Locked Review Policy And Dormant Task Lifecycle Compatibility | L1 | 02A; approved duration defaults; separate start | Proposed | +| `WS-REV-001-02C` | Submission Attribution, Context, And Immutable Lineage | L1 | 02B; merged AUTH canonical contributor constraints; separate start | Proposed | +| `WS-REV-001-03` | Review Queue And Lease Persistence | L1 | 02C | Non-executable split record | +| `WS-REV-001-03A` | Queue And Lease Base Persistence | L1 | 02C; merged `WS-CON-001-03B`; contract review | Proposed; no contract yet | +| `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 | +| `WS-REV-001-04B` | Final Acceptance, Task Linkage, Audit, And Outbox Persistence | L1 | 04A; merged `WS-CON-001-02A` and `02C` | Proposed; no contract yet | +| `WS-REV-001-05` | Checker Routing And Queue Views | L1 | 04B | Non-executable split record | +| `WS-REV-001-05A` | Atomic Checker Admission Participant | L1 | 04B; merged ART 05/06A/06B exact admission facts | Proposed; no contract yet | +| `WS-REV-001-05B` | Server-Selected Reviewer And Admin Queue Reads | L1 | 05A; exact AUTH read contracts | Proposed; no contract yet | +| `WS-REV-001-06` | Claims, Preference, And Timers | L1 | 05B | Non-executable split record | +| `WS-REV-001-06A` | Atomic Claim, Lease, Packet, And Reviewer Policy Freeze | L1 | 05B; merged 03B persistence contract; merged `WS-CON-001-06`; AUTH PREP/custody/service contracts | Proposed; consumes 03B and owns no packet schema/migration | +| `WS-REV-001-06B` | Owned Release, Decline, And Preference Transitions | L1 | 06A; exact AUTH mutation contracts | Proposed; no contract yet | +| `WS-REV-001-06C` | Preference And Lease Expiry With Lazy Recovery | L1 | 06B; provisioned/admitted exact service identities | Proposed; no contract yet | +| `WS-REV-001-07` | Review Context And Finding Evidence | L1 | 06C | Non-executable split record | +| `WS-REV-001-07A` | Lease-Bounded Packet And Review Chain Context | L1 | 06C; exact ART packet-read owner chunk | Proposed; owner chunk unscheduled | +| `WS-REV-001-07B` | Reviewer Finding Evidence Candidate And Finalize | L1 | 07A; exact ART review-evidence owner chunk and AUTH binding contracts | Proposed; owner chunk unscheduled | +| `WS-REV-001-08` | Pure Decision, Final Acceptance, And Task-Effect Contract | L1 | 07B; typed participant contracts | Proposed; executable contract after repair, no canonical write | +| `WS-REV-001-02A2` | Prepared Superseded Guide Reactivation | L1 | 08; merged AUTH-PREP/custody; AUTH-12 contract amendment; `project.guide.activate` remains unavailable | Proposed hidden behavior; manifest gates AUTH-12 evaluator/cutover/activation | +| `WS-REV-001-09A` | Revision Context Preparation And Resubmission | L1 | 08 | Non-executable split record | +| `WS-REV-001-09A1` | Review-Rooted Revision Preparation Persistence | L1 | 02A2; approved human round/deadline semantics; migration/head refresh | Proposed; no contract yet | +| `WS-REV-001-09A2` | Revision Preparation Participant, Resolver, And Task Context | L1 | 09A1 | Proposed; task-owned flush-only participant, no transaction composition | +| `WS-REV-001-09A3` | Human Revision Response Evidence Finalize | L1 | 09A2; ART evidence port and exact AUTH action | Proposed; owner chunk unscheduled | +| `WS-REV-001-09A4` | Hidden Human Prepared N+1 And Checker Source Compatibility | L1 | 09A3; merged AUTH-14 contract amendment only; ART digest contract | Proposed; adds preparation binding/source XOR while retaining 02C checker source; AUTH-14 owns public request acknowledgement, authorization cutover, and activation | +| `WS-REV-001-09A5` | Hidden Replacement Assignment Preparation Transfer | L1 | 09A4; merged AUTH-13 contract amendment only | Proposed; AUTH-13 later owns public command/cutover/activation | +| `WS-REV-001-09B` | Finding Replay, Resolution, And Preferred Return Routing | L1 | 09A5 | Proposed | +| `WS-REV-001-10` | Canonical Review, Final Acceptance, And CON Atomic Integration | L1 | 09B; merged `WS-CON-001-03C` and `07`; stabilized digest owner chunk | Proposed; first canonical decision commit | +| `WS-REV-001-11` | Administrative Recovery And Reconciliation | L1 | 10 | Non-executable split record | +| `WS-REV-001-11A` | Privileged Queue And Lease Commands | L1 | 10; exact AUTH command contracts | Proposed; no contract yet | +| `WS-REV-001-11B` | Revision Repair And Obligation Closure | L1 | 11A; registered additive actions | Proposed; no contract yet | +| `WS-REV-001-11C` | Reconciliation Persistence, Historical Admission Scan, And Service Jobs | L1 | 11B; exact service identities/admission | Proposed; owns batched resumable audited scan/classification | +| `WS-REV-001-11D` | Legacy Closure And ART Recovery Delegation | L1 | 11C; ART Operator recovery port | Proposed; no contract yet | +| `WS-REV-001-12` | Projection And Observability | L1 | 11D | Non-executable split record | +| `WS-REV-001-12P1` | Deterministic Review Projection Handler | L1 | 11D; merged CON outbox dispatcher/handler registry | Proposed; no contract yet | +| `WS-REV-001-12P2` | Artifact Reference Reconciliation And Projection Rebuild Jobs | L1 | 12P1; exact services/actions/ART projection port | Proposed; no contract yet | +| `WS-REV-001-12P3` | Notifications, Admin Reads, Metrics, And Drain Observation | L1 | 12P2 | Proposed; no contract yet | +| `WS-REV-001-12A` | Joint Lifecycle Release Control | L1 | 12P3 | Non-executable split record; preserves canonical parent ID | +| `WS-REV-001-12A1` | Lifecycle Controller Persistence And Typed Ports | L1 | 12P3; exact core CON readiness manifest | Proposed; no contract yet | +| `WS-REV-001-12A2` | REV, Task, And Checker Mutation Fence Composition | L1 | 12A1 | Proposed; no contract yet | +| `WS-REV-001-12A3` | CON Writer, Dispatcher, Callback, Cutoff, And Drain Fences | L1 | 12A2; CON 03D/08A/08B/10B/11 hooks | Proposed; no contract yet | +| `WS-REV-001-12A4` | Operator Transition, Drain, And Crash Recovery | L1 | 12A3; exact AUTH Operator contract | Proposed; no contract yet | +| `WS-REV-001-13` | Coherent Product Release And Proof | L1 | 12A4 | Non-executable split record | +| `WS-REV-001-13A` | Exact Dependency Preflight, Manifests, And Drill Harness | L1 | 12A4; every owner gate exact and merged | Proposed; no contract yet | +| `WS-REV-001-13B` | Pre-Release Documentation And Generated Artifact Preparation | L1 | 13A; hidden behavior proof | Proposed; no contract yet | +| `WS-REV-001-13C` | Product Router Registration And Final HTTP Proof | L1 | 13B; exact AUTH activations; ART 07; CON 11 | Proposed; sole product release | + +## Same-initiative order ```text -PLAN -> 01 -> 02(parent split) -> 02A -> 02B -> 02C -> 03 -> 04 -> 05 -> 06 -> 07 -> 08 -> 09A -> 09B -> 10 -> 11 -> 12 -> 12A -> 13 +PLAN -> 01 -> 02(parent) -> PLAN2 -> 02A -> 02B -> 02C +-> 03(parent) -> 03A -> 03B +-> 04(parent) -> 04A -> 04B +-> 05(parent) -> 05A -> 05B +-> 06(parent) -> 06A -> 06B -> 06C +-> 07(parent) -> 07A -> 07B +-> 08 -> 02A2 +-> 09A(parent) -> 09A1 -> 09A2 -> 09A3 -> 09A4 -> 09A5 -> 09B +-> 10 +-> 11(parent) -> 11A -> 11B -> 11C -> 11D +-> 12(parent) -> 12P1 -> 12P2 -> 12P3 +-> 12A(parent) -> 12A1 -> 12A2 -> 12A3 -> 12A4 +-> 13(parent) -> 13A -> 13B -> 13C ``` -External initiative gates are inserted without changing same-initiative -successor order: +Non-executable parents do not consume a PR after this planning refresh. Their +first child is the successor of the preceding executable chunk. -```text -WS-REV-001-01 active contract and immutable registration/service manifests - -> WS-AUTH-001-REV-REG availability-neutral four-action registration - -> separately reviewed AUTH identity-specific extension contracts - -> corresponding REV mutation/service chunks may consume registered actions - and exact identities while every action remains unavailable - -AUTH-09D-A plus AUTH canonical human and the subsequent AUTH-owned -schema-only contributor-field foundation - + merged AUTH-08 transaction/error/timestamp invariants - + ART v2 stable contracts - -> WS-REV-001-02A -> WS-REV-001-02B -> WS-REV-001-02C - -WS-REV-001-02C - -> WS-CON exact attribution consumption and retired compensation-context field removal - -WS-REV-001-02C + merged WS-CON ContributionPolicyVersion persistence - -> WS-REV-001-03 +## Owner-gate rule -WS-REV-001-03 + merged CON-owned shared transactional-outbox persistence - -> WS-REV-001-04 +Phrases such as "AUTH contributor foundation", "ART owner amendment", or +"CON participant" describe required ownership but are not executable gates. +Before a child starts, replace each phrase in its new contract with: -merged CON-owned caller-transaction shared lifecycle-audit participant - -> WS-REV-001-04 - -WS-REV-001-04 stable Review, FinalAcceptance, ReviewLease, and Submission schemas - + merged ART submission/checker cutover with server-derived stabilized - Submission.artifact_hash - -> WS-CON exact FinalAcceptance-sourced contribution/award lineage persistence +```text +owner chunk ID + merged PR + merge SHA + migration head (if schema) ++ typed symbol/manifest + exact focused and regression test evidence +``` -WS-CON retired compensation-context field removal - -> WS-REV-001-09A +Known merged/planned CON IDs may be named, but proposed status remains blocked. +The contributor clean cut and ART packet-read/review-evidence/digest work do not +yet have trusted-main owner chunk IDs. REV neither invents those IDs nor edits +owner plans. -WS-REV-001-09A hidden prepared revision/replacement behavior - -> amended AUTH-13/14 full product cutovers - -> AUTH-14 submission.create activation after exact evaluator proof +## Parent split records -WS-REV-001-09B + WS-CON exact lineage schema + flush-only contribution/award participant - -> WS-REV-001-10 +Existing parent contract files for 03, 04, 05, 06, 07, 09A, 11, 12, former +12A release control, and 13 are non-executable historical planning records. +They must not be used as implementation authorization. New child contracts are +authored only from the then-current main when each child receives a human start. -WS-CON exact core hidden-readiness manifest + WS-REV-001-12 - -> WS-REV-001-12A hidden joint release-control foundation - -> AUTH activates each exact action through its named REV gate after hidden behavior - -> WS-REV-001-13 sole joint product release -``` +## Reviewers -The merged ART plan does not yet schedule `WS-ART-001-REV-EVIDENCE`. REV-07 is -therefore explicitly blocked until ART owns, approves, and merges that chunk; -REV planning does not create or start it on ART's behalf. - -## Chunk boundaries - -- 01 changes contracts and active documentation, not runtime behavior. -- 02 is a non-executable split record. 02A-02C and 03-04 land bounded - persistence and constraints, including immutable FinalAcceptance, without - public review mutations. -- 05-07 build routing, leases, and evidence consumption behind an unavailable - production composition boundary; registration remains availability-neutral. -- 08 freezes decision inputs, validation, task effects, and the - FinalAcceptance consequence of `accept`. It cannot commit a canonical Review - or an accept-path FinalAcceptance until the CON participant is installed. -- 09A prepares controlled revision context and immutable resubmission input. -- 09B completes finding replay, resolution, and preferred-return semantics. -- 10 creates the first transaction capable of committing every canonical Review - and, for `accept`, the additional FinalAcceptance record. It proves WS-CON - atomicity in hidden composition. -- 11-12 complete operations, recovery, projection, and observability. -- 12A lands hidden persisted release control and mandatory cross-domain fences. -- 13 performs fail-closed preflight, exposes the already-AUTH-active coherent - public API set, - proves the whole lifecycle, and closes generated/user/operator docs. - -## Required reviewer tracks - -Every chunk: senior engineering, QA/test, security/auth, and product/ops. - -Add architecture and reuse/dedup to 01-13, including split children 02A-02C. -Add docs to PLAN and every chunk that changes schema, routes, runtime jobs, -configuration, or active behavior. Add test-delta to every runtime chunk. Add -CI integrity whenever a -workflow, script, dependency, or coverage gate changes. +Every executable chunk requires senior engineering, QA/test, security/auth, and +product/ops. Architecture and reuse/dedup apply throughout. Schema/routes/jobs/ +active behavior add docs and test-delta. Workflows, scripts, dependencies, test +configuration, or coverage changes add CI integrity. ## Stop condition -Parent 02 planning may be reviewed and merged without runtime. Stop after its -automated memory names 02A. Do not start 02A until AUTH-09D-A and the subsequent -AUTH contributor foundation merge and the user provides a separate explicit -start. The duration defaults gate 02B, not 02A. +Complete and merge only `WS-REV-001-PLAN2`, then stop. Its schema-v2 merge +intent names `WS-REV-001-02A` and requires a separate explicit start after the +exact AUTH runtime foundation merges. Do not begin 02A or any later child from +this planning PR. diff --git a/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/CONFORMANCE_MATRIX.md b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/CONFORMANCE_MATRIX.md index f7ce55ea5..92dd1eeec 100644 --- a/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/CONFORMANCE_MATRIX.md +++ b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/CONFORMANCE_MATRIX.md @@ -1,25 +1,37 @@ # Conformance Matrix: WS-REV-001 -This matrix binds revised archival specification sections 25.1-25.9 to the -active reconciled contract, implementation chunks, executable proof, and final -live evidence. Chunk start must replace proposed test names with exact -collected node IDs; a section is not complete based only on prose. +Chunk starts replace proposed test descriptions with exact collected node IDs. +No row is complete from prose or an unmerged owner contract. -| Spec section | Owning chunks | Required executable proof | Live/evidence proof | +| Area | Owning chunks | Required executable proof | Release proof | |---|---|---|---| -| 25.1 Authority | 05-08, 09A, 10-13 | One exact registered ActionId and canonical typed scope for every endpoint/command; reads use request-scoped require while mutations use AUTH-first prepare with an opaque single-use handle bound to exact session/action/actor/idempotency/request identity; REV locks feature rows and recomposes final facts, then AUTH validates bindings/current authority, consumes once, evaluates once, and stages evidence before first feature mutation; wrong-binding/forged/serialized/caller-constructed misuse preserves the legitimate unconsumed handle without staging state, while stale/already-consumed or concurrent duplicate use remains consumed and stages no new state; evaluated authority/policy denial uses clean AUTH evidence after dirty rollback; human-only actor-kind DB enforcement; independent submitter/reviewer/adjudicator/admin/external matrices with exact reviewer grant, no combined role, no-self-review, and collateral-revocation denial; distinct fixed service ActorProfiles/static rows for preference expiry, lease expiry, authority-invalidation reconciliation, general review reconciliation, artifact-reference reconciliation, and projection through AUTH-09E plus exact identity extensions; chain read limited to exact submitter, active reviewer, currently reviewer-granted prior participant, or privileged inspector; two-phase evidence reauthorization leaves no canonical binding/relation/lifecycle mutation; human/service path isolation | Feature/release manifest plus separate AUTH custody/registration/availability manifest proves registration -> hidden behavior -> AUTH activation -> joint release for every action; separate misuse tests prove later exact first use only after rejected pre-consumption substitution and permanent rejection after consumption/duplicate use; denial/evidence-failure matrix distinguishes clean AUTH denial evidence from rolled-back feature effects and proves denial-restaging failure commits nothing; adjudication remains unavailable | -| 25.2 Queue routing | 03, 05-06, 09B, 11-12 | First-open, revision-preferred, immutable exact successful admitting-CheckerRun anchor, admission-versus-supersession both race orders, duplicate delivery, active preference conflict, expiry/decline/invalidation age preservation, admin time-limited assignment, preferred-before-open, current returns one/lease/none, arbitrary or stale ID denied | Existing `review_pending` activation scan, legacy remediation report, preferred return/takeover, admin assignment, operational counts/ages | -| 25.3 Leases | 03, 06, 11 | One lease per queue and canonical human `ActorProfile.id`; immutable ReviewPacketManifest; frozen reviewer ContributionPolicyVersion independent of guide context; release/expiry distinction, database time, exact reviewer-revocation effects with submitter/adjudicator grants unchanged, service/human isolation, races in both permutations, rollback injection | Claim/release/expiry/reclaim/revocation with AUTH-09E-admitted service jobs and lazy recovery enabled | -| 25.4 Reviews | 04, 08, 10 | Every decision appends one immutable Review; every submitted finding and later resolution is immutable; later rounds append rather than rewrite; canonical human reviewer identity; lease/queue/packet-manifest linkage; ReviewEvidenceArtifact slots; finding rules; reject reason; idempotency; CON reviewer operation runs before the decision branch; an `accept` Review additionally creates one immutable FinalAcceptance with unique task/Review/Submission and exact ReviewPolicy/actor lineage, then invokes the CON submitter operation; exact locked Review/Submission/lease/assignment/actor/ContributionPolicyVersion/stabilized artifact_hash lineage; reviewer contribution direct from Review, submitter contribution only from FinalAcceptance; REV-staged audit/outbox; no ART call or no-op participant; rollback | needs_revision without FinalAcceptance, accept with exactly one FinalAcceptance, reject without FinalAcceptance, exact contribution source shapes and task/assignment effects for all three decisions, explicit unpaid/payable awards, changed replay, revoked replay, crossed-lineage rejection, and atomic rollback across Review, the accept-path FinalAcceptance, contributions, and outbox | -| 25.5 Revisions | 02A-02C, 04, 09A-09B, 13 | Immutable same-task N-1 Submission chain; strict prepared cutover; immutable guide activation sequence; equal identity/sequence keeps and any different current active guide rebases; every preparation episode is bound to its Review/prior Submission/task/assignments/project and forms one non-branching chain; AUTH-13 replacement appends a target-assignment successor; preparation freezes guide/source/task-execution policy but no ContributionPolicyVersion; Submission N+1 and CheckerRun use the frozen context; TaskAssignment and ReviewLease contribution-policy freezes do not drift; Task Context uses the head; no reviewer rebase; all blocking findings answered/resolved | v1 guide context -> needs_revision -> same/forward/backward/unsafe classification -> optional authority-loss replacement -> prepared v2 context without contribution-policy drift -> contributor context -> checker readmission -> reviewer consumes v2 -> resolution -> accept | -| 25.6 Reject | 08, 10 | Queue close, lease consume, same-task assignment block, task `rejected` with bounded reason, grants unchanged, other tasks unaffected, later version denied, reviewer contribution only | Authorized reject plus API/database/audit/CON agreement; no `closed` status token or synthetic Review | -| 25.7 Recovery | 06, 09A, 11, 12A | Idempotent preference/lease sweeps and lazy repair; every actor/grant/self-review/policy invalidation; reason-bound covered Project Manager preparation-successor repair with stale-head/race proof; separate covered Project Manager D6 closure only after server-proven limit/deadline, with Operator/cross-project/not-reached denial; leased-without-active and consumed-without-Review detection; canonical reconciliation identity/generation with one unresolved partial uniqueness, duplicate/concurrent scan reload, one resolution, and post-resolution recurrence; Operator-only evidence-linked closure for legacy needs_revision without Review/root; no synthetic Review or silent immutable rewrite; persisted joint lifecycle phases, shared/exclusive advisory-lock mutation fencing, bounded drains, callbacks-through-drain, crash resume, and forward-only timeout recovery | Service-job loss/restart, revocation, preparation repair, D6 closure/replay/races, duplicate reconciliation, legacy unrecoverable closure, controlled recurrence, reconciliation alert, durable fence/drain/crash-resume/forward-reactivation procedure | -| 25.8 Artifact evidence | 05-09B, 11 | ART v2 only; active-lease read limited to immutable ReviewPacketManifest; chain history metadata-only; expired/consumed/prior/later/sibling/cross-task/project access denied; exact ReviewEvidenceArtifact finding/response slots; ART candidate intake outside locks then AUTH -> REV -> ART database finalization with one final AUTH evaluation; exact `artifact.review_evidence.binding.create` service action and binding identity; no raw store, v1 retention, generic retrieval/binding-read, provider locator, or human-token forwarding | Current packet bounded stream, prior history without bytes, finding/response finalize, orphan-only failed races, outage/integrity block with no adverse decision, ART-owned recovery, LocalStorage/MinIO/S3 conformance | -| 25.9 Projection | 04, 08, 10, 12 | REV stages canonical shared-outbox records after the reviewer contribution operation and, for `accept`, the submitter contribution operation; the request route or service command then commits once; accept projection includes FinalAcceptance lineage; no remote call in transaction; deterministic bytes; idempotent receipt; changed bytes conflict; retry/dead-letter/reconciliation; reauthorized disclosure | Forced pre-commit staging rollback and post-commit projection failure/retry, one ART receipt, unchanged Review and FinalAcceptance truth, bounded outbox/dead-letter evidence | +| Authority | 05B, 06A-C, 07A-B, 08, 02A2, 09A2-A5, 10, 11A-D, 12P2, 12A1-A4, 13C | Exact active/project reviewer grant; canonical human actors; AUTH-first prepared mutations; opaque one-use bindings; clean denial/restaging; service identity isolation; no direct grant reads; no adjudication authority | Exact merged feature manifests -> AUTH activation -> phase-enabled HTTP denial/allow matrix | +| Guide chronology | 02A, 02A2 | Positive immutable per-project sequence; exact status/provenance; Project-first publication/screening; immutable Task triplet; hidden prepared If-Match reactivation; both-order races | Forward/backward active guide changes without reviewer-side rebase or stale retry | +| Queue routing | 03A-B, 05A-B, 06A-C, 09B, 11A/C | Exact checker admission; one open/preferred entry; normalized packet membership; current returns lease/offer/none; duplicate/supersession races; authorized batched historical classification | New and historical eligible rows, preferred return, takeover, counts/age evidence | +| Leases | 03A-B, 06A-C, 11A/C | One active lease globally; canonical reviewer; packet manifest; reviewer ContributionPolicyVersion freeze; release/decline/expiry/revocation/lazy recovery and both-order races | Claim/release/expiry/reclaim/revocation through exact admitted service identities | +| Review history | 04A-B, 08, 10 | Every decision/finding/resolution immutable; exact predecessor/assignment lineage; reviewer CON operation before branch; accept-only FinalAcceptance and submitter operation; reject exact assignment; atomic rollback | Real accept/needs_revision/reject HTTP/database/audit/CON agreement and changed replay denial | +| Revision paths | 02C, 09A1-A5, 09B, 10, 11B-D | Human Review revision creates one immutable non-branching preparation before readable state; checker remediation persists unique immutable `remediation_source_checker_run_id`, keeps task context, creates no Review/preparation/CON record, and is never classified as legacy | Separate checker and human drills both reach corrected N+1 without policy or lineage drift | +| Revision context | 02A-C, 09A1-A5, 09B | Review-rooted task-owned preparation; kept/forward/backward/blocked; exact head acknowledgement; one winner per head; replacement successor; no contribution-policy rebase; checker path bypasses rebase | Human context display, checker rerun, prior-reviewer preference, resolution, final decision; checker correction returns open | +| Limits/deadlines | 09A1-A4, 11B | Human-approved round/deadline semantics only; DB time and frozen episode facts; checker retries excluded; repair cannot bypass exhaustion; D6 close only | Before/equal/after, exact replay/races, checker D6 denial, no synthetic Review/CON record | +| Reject/admin close | 10, 11B/D | Human reject only from Review; exact assignment blocked/task rejected. PM/Operator closes use canonical cancelled reasons and create no Review/CON | Authorized/denied/cross-project/rollback proof; no `closed` token | +| Artifact evidence | 03B, 07A-B, 09A3, 11D | Active-exact-lease bytes; metadata-only history; ART candidate/finalize; immutable slot plus append-only attachment; orphan-only failed finalization; no raw store/provider path | Local/MinIO/S3 owner conformance plus outage/integrity no-adverse-outcome drill | +| Projection | 04B, 10, 12P1-P3 | Shared outbox only; deterministic handler/receipt; reauthorized reads; independent projection/reconciliation services; no canonical truth change on failure | Forced post-commit failure/retry and one immutable receipt | +| Release control | 12P3, 12A1-A4, 13A-C | Persisted phase history; read/mutation classes; checker revision routing allowed with checker completion through revision-cutover fence; human preparation inside leased decision; REV/task/checker/CON fences; bounded drain/cutoff/crash resume | Static routes/AUTH mappings, phase-denied execution, scheduler runbook, forward reactivation, final real-HTTP drill | + +## Concurrency invariants + +- Concurrent initial creates produce one v1; loser exact replay or stable + conflict. They never produce v2. +- Concurrent creates against one human preparation head produce one N+1; loser + exact replay/conflict. Concurrent checker remediation likewise produces one + N+1 from its exact final CheckerRun state. N+2 requires a later human + Review/preparation or final needs-revision CheckerRun. +- Every mutation race uses independent PostgreSQL sessions and both lock/commit + orders. ## Closure rule -Chunk 13 validates every row against fresh real-PostgreSQL coverage evidence and -the privacy-safe HTTP drill. Missing node IDs, skipped mandatory cases, direct -database state fabrication, or an unavailable AUTH/ART/CON/outbox participant -blocks product release. +13C validates all rows against fresh real-PostgreSQL evidence, exact merged owner +SHAs, AUTH-active actions, mandatory phase fences, privacy-safe HTTP proof, and +active docs generated from the released behavior. Missing/skipped proof, direct +database fabrication, or an unavailable owner participant blocks release. diff --git a/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/DECISIONS.md b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/DECISIONS.md index 1a92e3354..22df469a2 100644 --- a/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/DECISIONS.md +++ b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/DECISIONS.md @@ -111,9 +111,10 @@ to append a successor rather than editing it. Database constraints enforce one root per episode, one child per preparation, same task/reviewed-assignment/ prior-Submission/episode across an edge, and a sequence increment of exactly one. The target assignment normally remains the reviewed assignment. After AUTH-13 -closes it for authority loss and a covered manager creates a replacement on the -durable `needs_revision` obligation, the same caller transaction appends one -successor bound to that replacement assignment and recomputes the current guide +closes it for authority loss and a covered manager creates a replacement while +the Task remains in durable human-review `needs_revision`, the same caller +transaction appends one successor bound to that replacement assignment and +recomputes the current guide classification. No edit or branch occurs, and the prior contributor loses submission authority. Submission N+1 binds to that successor's target TaskAssignment. @@ -153,7 +154,10 @@ Normal blocked/revoked/invalid preparation is recoverable only by a reason-bound idempotent covered Project Manager repair command that acknowledges the current head and appends one validated successor after project setup correction. It cannot create a root or rewrite a prior preparation. A legacy `needs_revision` -task with no originating Review/root cannot be repaired this way; an Operator +task is eligible only when neither an unambiguous human Review root nor an exact +final `needs_revision` CheckerRun exists. Valid CheckerRun-rooted remediation is +never legacy even when no human Review exists. The legacy state cannot be +repaired this way; an Operator may close it through the separately authorized, evidence-linked legacy closure with terminal reason `legacy_revision_context_unrecoverable`. That closure releases the assignment and creates no Review or WS-CON record. @@ -184,7 +188,7 @@ effect. The normal D6 command maps to existing `project.task.manage` and is not an Operator reconciliation shortcut. Operator-only `review.queue.close` and `review.revision_context.legacy_close` remain distinct recovery commands and -cannot close a healthy Review-rooted obligation merely because a limit or +cannot close a healthy Review-rooted revision merely because a limit or deadline exists. ### D7 - Artifact Preflight Does Not Hold Review Locks Across Remote Calls @@ -228,7 +232,7 @@ exposes current-work, claim, release, decline, context, decision, revision preparation/resubmission, chain reads, and authorized admin operations together only when AUTH, ART, WS-CON, audit, outbox, recovery, reconciliation, projection jobs, and live preflight are mandatory and -proven. REV-13 changes product composition, not AUTH availability. +proven. REV-13C changes product composition, not AUTH availability. **Human confirmed 2026-07-15.** @@ -420,7 +424,7 @@ freeze. A later lease may independently freeze the then-current reviewer terms. ### D18 - Authority-Loss Replacement Preserves Source And Changes Target Normal `needs_revision` returns to the same contributor. The AUTH-13/14 final -contract nevertheless preserves a durable unassigned revision obligation when +contract nevertheless preserves a durable unassigned human revision episode when that contributor loses authority and permits a covered manager to assign a replacement. WS-REV adopts that dependency rather than stranding the task. @@ -435,7 +439,8 @@ Submission, assignment, Review, finding, or preparation is rewritten. ### D19 - Joint Release Control Is A Hidden Persisted Foundation Safe product release/shutdown is product infrastructure, not proof-script state. -Chunk 12A owns one PostgreSQL-canonical `JointLifecycleReleaseControl`, the +Chunks 12A1 through 12A4 own one PostgreSQL-canonical +`JointLifecycleReleaseControl`, the hidden behavior and resource facts for the Operator-only `review.lifecycle.activation.manage` action, advisory-lock-based mutation fencing, typed internal fence ports, bounded drain observations, and @@ -443,7 +448,7 @@ crash-resumable phase history. Every canonical phase change is a fresh Operator-authorized adjacent transition; no background job replays the initiating human or advances phase. It lands with no production lifecycle route and no action availability change. `WS-AUTH-001-REV-LIFECYCLE` activates that exact action only -after 12A and all other additive hidden manifests merge. +after 12A1 through 12A4 and all other additive hidden manifests merge. Review, every task submission, review-queue admission, authority-loss replacement, every CON fulfillment-obligation root creation, requeue, successor, @@ -457,7 +462,7 @@ allocates its server-derived monotonic ordinal. The exclusive atomically stores the CON-derived maximum ordinal as the immutable generation cutoff. During `delivery_draining`, dispatch and callbacks may only complete a same-generation root at or below that cutoff; root creation, requeue, successor, -and repair work remains denied. REV-13 exposes and exercises the merged, +and repair work remains denied. REV-13C exposes and exercises the merged, AUTH-active foundation, performs the ordered writer fence, migration, and process cutover, and prohibits downgrade after protected rows exist. @@ -477,7 +482,7 @@ hidden behavior and feature-manifest deltas; the exact `WS-AUTH-001-REV-05/06/07/08/09A/11/12` gates later activate their action groups. `WS-AUTH-001-REV-REG` registers the four approved additions and `WS-AUTH-001-REV-LIFECYCLE` activates them only after all hidden manifests merge. -REV-13 performs the separate product-surface release. The 24 REV dependencies +REV-13C performs the separate product-surface release. The 24 REV dependencies are one registered planned submission action, 19 registered planned review actions, and four approved but unregistered additions; none is active. The separate ART review-evidence binding proposal is not one of the 24, so future @@ -495,8 +500,12 @@ chunk. Parent 02 is therefore a non-executable split record: -> 02C Submission attribution/context/immediate-predecessor immutability ``` -AUTH owns migration `0026` for AUTH-09D-A. After 09D-A merges, AUTH owns the -separately reviewed contributor-field foundation from the then-current head. +Trusted main does not assign REV a migration and does not contain the contributor +foundation. AUTH-09D-A merged through PR #148 as +`99ae4c963e53f317175dcb308b9e47c93ccf19ed`, establishing migration +`0026_actor_profile_lifecycle` and database-backed ActorProfile lifecycle +provenance without renaming either retired task field. AUTH next owns the +separately reviewed contributor-field foundation from that then-current head. That foundation clean-cuts both retired task-subsystem contributor-identity fields to `contributor_id`, preserves current behavior, and supplies database-backed canonical-human ActorProfile lineage. REV records its exact merged PR/SHA and @@ -512,3 +521,65 @@ persistence exists. The later reason-bound administrative command owns the The review preference and lease durations are independent positive policy values. Neither may be inferred from `ReviewPolicy.sla_hours`; their exact v0.1 migration defaults remain a human decision before 02B can start. + +### D22 - Checker Remediation Remains Distinct From Human Revision Rebase + +D22 preserves the existing CheckerRun-rooted `needs_revision` path without +expanding ADR 0010. Checker remediation keeps the Task's locked guide context, +creates no Review/finding/reviewer contribution, consumes no human ReviewPolicy +revision round/deadline, and does not use finding replay or D6 close. Controlled +RevisionContextPreparation remains rooted in an exact +`Review(needs_revision)`. Corrected Submission N+1 persists the server-derived, +unique, immutable `remediation_source_checker_run_id` for the exact completed, +needs-revision, current-at-selection CheckerRun on its immediate predecessor. +Treating exact checker history as legacy or inferring it from a later current run +is prohibited. + +### D23 - Human Revision Exhaustion Semantics Require Explicit Approval + +D6 fixes the outcome of an exhausted human Review revision but does not define +the round counting source, deadline anchor, or inclusive/exclusive boundary. +Those values remain a human-owned decision before 09A1. They cannot be inferred +from checker retries, task SLA, current time, or archival examples. Whatever is +approved freezes on the Review-rooted episode, uses database time, and cannot be +bypassed through context repair. + +### D24 - Guide Chronology Precedes Hidden Authorized Reactivation + +02A adds activation sequence, Project-first publication/screening locking, and +immutable Task guide stamps while preserving public superseded-candidate denial. +After AUTH-PREP/custody and an AUTH-12 contract amendment, 02A2 adds hidden +bodyless `If-Match` reactivation while `project.guide.activate` remains +unavailable. Its complete resource manifest gates AUTH-12 evaluator/cutover/ +activation. This prevents new behavior from appearing under legacy local roles +or an already-active centralized action. + +### D25 - Decision Lock Order Is Command Specific + +The decision command computes its canonical request key/digest without a +database lock, then locks AUTH authority, ReviewDecisionRequest, the review +lifecycle fence, ReviewLease, ReviewQueueEntry, WorkstreamTask, exact +`Submission.task_assignment_id`, exact +Submission, and subordinate immutable lineage rows in stable ID order. This +preserves AUTH-first semantics and the user-confirmed ReviewLease-before-queue +order. Other commands publish their own orders; no vague universal lock order +substitutes. + +### D26 - Lifecycle Phase Denies Execution, Not Static Registration + +D26 narrows D19. Persisted lifecycle phase controls command execution through +mandatory database fences. It does not unregister FastAPI routers, deactivate +AUTH actions, rewrite fixed-service memberships, or replace operational +scheduler suspension. Product reads and mutation classes are separate. +Checker revision routing is allowed wherever checker completion is allowed +through `revision_cutover_fenced`, then denied from `admission_fenced`; it creates +no preparation. Human Review preparation remains inside the already leased +decision command. + +### D27 - Oversized Parent Contracts Are Non-Executable + +Parents 03, 04, 05, 06, 07, 09A, 11, 12, 12A, and 13 are split records. Only +the unique children in `CHUNK_MAP.md` may receive future implementation +contracts. Chunk 08 is pure contracts/validation only; chunk 10 is the first +canonical Review/FinalAcceptance/CON commit. Active release docs and router +registration occur together only in 13C. diff --git a/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/DISCOVERY.md b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/DISCOVERY.md index a173acdff..8d1a1ac21 100644 --- a/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/DISCOVERY.md +++ b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/DISCOVERY.md @@ -1,334 +1,111 @@ # Discovery: WS-REV-001 Review And Revision Lifecycle -## Sources reviewed - -- Revised Markdown source: - `docs/reference_specs/WS-REV-001-review-lifecycle-specification.md` -- Revised 52-page PDF: - `docs/reference_specs/WS-REV-001-review-lifecycle-specification.pdf` -- `WS-AUTH-001`, `WS-CON-001`, `WS-IMP-001`, architecture lockdown, ADRs, - operations docs, current initiative plans, migrations, backend modules, and - tests -- Merged WS-XINT-001 PR #139 at trusted main `5d353b6`, including its - AUTH/REV, AUTH role/service, ART/REV, and REV/CON handoffs -- Merged AUTH reconciliation PR #140 at trusted main `d541521`, final reviewed - branch head `b80e898`, including exact REV activation custody, prepared - mutation, registration, and activation planning contracts -- Merged AUTH-09A PR #132 at trusted main `299363a`, reviewed code `fe61df6` - and final branch head `d4b6540`, including migration `0023`, the - seven-identity fixed-service foundation, eleven ART service-action - memberships, and eight planned AUTH-09 route actions - -The current revised Markdown contains 2,396 lines and 12,570 words. Its SHA-256 is -`fffadc271c267801250b044edc570e515a250eff48afdc64f9c1f8753e6ab058`. -The revised PDF SHA-256 is -`8c053bc752a7b0c64e04b3eda1873bb5dbc02bbdfef84bd17d07cbbf01bce2fd`. -The Markdown has 149 headings. PDF text extraction covers the base lifecycle, -evidence, projection, and error contract but does not contain Markdown section -4.6's closed action/permission table. The current Markdown is therefore newer -than its 52-page PDF companion; neither is treated as a generated twin. Both are -the authoritative supplied pair. The temporary `(2)` filenames were a local -duplicate-name accident; their contents were restored to the canonical paths, -and the duplicate paths were removed. Chunk 01 records the one-sided section -before producing the reconciled active contract. - -## Current proven behavior - -1. Project guide setup, policy derivation and approval, task policy locking, - task assignment, versioned submissions, submission finalization, durable - post-submit checker execution, and transition to `review_pending` exist. -2. `backend/app/modules/tasks/models.py::Submission` is already the immutable - versioned submission identity. It has `version`, `supersedes_submission_id`, - task ownership, locked policy fields, evidence, finalization time, and a - unique `(task_id, version)` constraint. -3. `backend/app/modules/checkers/service.py::_apply_pre_review_gate_result` - moves an allowed checker result to `review_pending`; it creates no review - queue entry. -4. `backend/app/modules/tasks/lifecycle.py` has statuses through - `needs_revision`. Canonical active docs use `accepted`, `rejected`, and - `cancelled`; the archival REV source's `closed/review_rejected` wording is - stale and must not introduce an undocumented `closed` status. -5. `TaskAssignment` supports one active assignment per task but has no blocked - fields or completed-review effects. -6. `ReviewPolicy` and `RevisionPolicy` exist, but review preference, review - lease, self-review, reject, and finding-evidence settings do not. -7. The current revision path creates a new `Submission` directly from - `needs_revision`; it does not create structured finding responses or run the - ADR 0010 context-preparation record. - -## Authorization boundary - -- The original discovery base was `f599551`, which merged AUTH-06. The latest - 2026-07-17 reconciliation rebased REV onto trusted main - `299363af5d9e8a68bcc9b17457188048483caeed`, which merges AUTH-09A PR #132 - after AUTH planning PR #140 and WS-XINT-001 PR #139. It includes AUTH-08, - ART-02A2, ADR 0015, the four lifecycle handoffs, AUTH decisions D23-D27, and - the fixed-service schema/catalogue foundation. -- Authority audit and mutation idempotency foundations exist. -- The request-scoped deny-by-default kernel exists. Actor self-read/self-update - and seven AUTH-08 administrative actions are active. Project grants, actor - state/service actor administration, product cutovers, and conformance proof - remain later WS-AUTH chunks. -- Product services still consume legacy `ActorContext`, role helpers, and - `LegacyWorkflowEligibility`. -- Review/task/contribution lineage must store canonical human - `ActorProfile.id`, not external subject, email, legacy typed-profile ID, or - role labels. Review authority requires the independent exact-project - `reviewer` grant; `submitter` and `adjudicator` grants do not substitute. -- AUTH-09A supplies the fixed-service enum/schema/migration and the closed - seven-identity ART matrix. Merged AUTH-09B supplies controlled provisioning - only for that closed registry and admits no service token. Protected review - jobs still require separately reviewed enum/constraint/matrix extensions for - each of REV's six exact identities, provisioning through the merged AUTH-09B - capability, and AUTH-09E admission. A generic system-principal or fabricated - human is not allowed. -- `review.queue.override` is present in the merged 74-PermissionId catalogue; - the review actions mapped to it remain planned/inactive. Artifact recovery already uses - the registered `artifact.verification_job.retry` action and ART-owned - `ArtifactOperatorRecoveryPort`; WS-REV must not add another recovery - permission or implementation. - -AUTH-07A/07B catalogue input is superseded as the live snapshot by merged -AUTH-08 PR #131 at trusted-main -`aa0fdcd6912e66609e39a2fbd7b65f67be6c62f3`, final branch head -`0832358a0262805f553d05b50b0d778e6e6ad995`. AUTH-08 retains exactly 57 closed -ActionIds, activates seven administrative actions alongside the two actor-self -actions, and leaves 48 planned. Canonical `submission.create` plus the 19 -registered review actions all remain planned/inactive. Proposed AUTH-13/14 -contracts assign the final `TaskAssignment.contributor_id` and -`Submission.contributor_id` names and authority-loss replacement-assignee - behavior. The four later revision-obligation-close, repair, legacy-close, and - joint-lifecycle-control ActionIds remain approved but unregistered AUTH-owned additions before - their owning hidden-behavior chunks. The merged 57-action count is a historical - AUTH-08 snapshot, not a future fixed total. WS-XINT-001 also proposes the - separate ART service action `artifact.review_evidence.binding.create`; each - later AUTH registration/activation contract must derive exact before/after - counts from current trusted main and account for its delta independently. - REV feature chunks build hidden behavior and typed facts; exact AUTH activation - custodians alone integrate evaluators and change availability. Current trusted - main after AUTH-09C contains 65 ActionIds: 12 active and 53 planned. - AUTH-09B activated `actor.service.provision`; AUTH-09C activates only the two - bounded actor-registry reads. No REV identity or action was added, and all 24 - REV dependencies remain unavailable. - -The merged AUTH plan contains an execution cycle: full AUTH-13/14 require -prepared revision/replacement behavior owned by REV-09A, while REV-02 needs -canonical contributor fields before REV-09A can exist. REV therefore requires an -AUTH-owned schema-only contributor-field foundation before REV-02. REV-09A -hidden behavior then precedes amended full AUTH-13/14 product cutovers. This is -an AUTH repair gate, not permission for REV to rename AUTH-owned fields. - -The 2026-07-18 parent-02 start audit against exact main `b2b9016d5fee33ddca40882c97620a178d8e52f0` -confirmed that the foundation is not yet present. Alembic head is -`0025_artifact_store_v2`; TaskAssignment and Submission still store -unconstrained retired contributor-identity strings; no contributor-foundation merge intent, -PR/SHA, migration, or database-backed child human-lineage constraint exists. -AUTH now owns migration `0026` for AUTH-09D-A profile lifecycle. The user -directed AUTH to make the contributor foundation its next priority after 09D-A, -from the then-current head, and authorized REV only for non-runtime planning and -test design meanwhile. - -The same required L1 plan review found parent REV-02 too broad. Guide activation -chronology/publication, review policy/dormant lifecycle, and Submission -attribution/lineage are three independent migration boundaries. The executable -work is therefore split into 02A, 02B, and 02C; parent 02 records no runtime. -Two policy inputs remain absent from every source reviewed: concrete v0.1 values -for the review preference window and review lease duration. They are explicit -human decisions and cannot be inferred from `ReviewPolicy.sla_hours`. - -Merged AUTH reconciliation PR #140 is planning-only. Its `74` PermissionId / -`57` ActionId / `9` active / `48` planned snapshot is now historical because -AUTH-09A PR #132 added eight planned actions. PR #140 defines -`WS-AUTH-001-REV-CUSTODY` as an availability-neutral transfer of the 19 registered -review actions to seven exact AUTH activation custodians, followed by the shared -`WS-AUTH-001-PREP` prerequisite. It also defines one future -`WS-AUTH-001-REV-REG` registration for the four approved REV additions, exact -per-feature activation gates `REV-05/06/07/08/09A/11/12`, and one -`WS-AUTH-001-REV-LIFECYCLE` activation after all four additive hidden manifests -merge. None of these planning contracts activates an action or starts runtime. - -AUTH-08 resolves the three consumption blockers found during the AUTH-07B -dependency review: successful dependency teardown now rolls back any open -request-session transaction; evidence-write SQL errors become typed -`AuthorizationEvidenceUnavailable` failures mapped to retryable `503`; and -successful existing-actor GET/PATCH requests advance -`ActorProfile.last_seen_at` and `ActorIdentityLink.last_verified_at` in the -route-owned transaction. Its internal evidence records 275 focused behavior -tests, 90.17 percent branch-aware focused coverage, and 17 isolated Alembic -tests. Final PR checks passed Backend, Agent Gates, and CodeRabbit. REV runtime -chunks must preserve these merged invariants and still wait for the later AUTH - definition-of-done gate owned by each consumer, exact REV identity extensions - and provisioning through merged AUTH-09B, AUTH-09E admission for protected - service callers, and the matching AUTH activation checkpoint. Reads consume - request-scoped `AuthorizationService.require`; mutations consume the future - authority-first prepared protocol and exactly one final evaluation without - importing grant persistence into the review module. - -## Artifact boundary - -- `ArtifactContent`, immutable `ArtifactBinding`, `ArtifactReplica`, operation - receipts, upload staging, the byte-only provider-neutral ART v2 - `ArtifactStore`, and `LocalStorageAdapter` exist. -- Merged ART-02A2 PR #129 at trusted main - `9a04434e2f23c5dec8939dadb943bba4d85110c0`, final head - `32aab89262a3944f305e9e5dc4c65a2d31e2e144`, adds an inactive - `PreparedArtifact`/`CommittedArtifactSource` boundary, bounded private - `ArtifactScratchManager`, deterministic cleanup mechanics, and shared bounded - file locking. Those preparation types remain internal ART mechanics. -- Merged ART-02A3 PR #141 at trusted main - `a10d9018007d2e847b4870e9b26cbd24e24c7bb4`, final branch head - `7606798e751abf40218d23886779c3659b76e974`, removes ArtifactStore v1 and - activates the byte-only v2 LocalStorage clean cut, namespace fencing, typed - product capabilities, migration, and scratch-cleanup wiring. It does not - implement S3/MinIO, submission/checker artifact cutovers, review packet read, - or review-evidence candidate/finalize behavior. -- ART scratch is bounded private ephemeral processing state, not artifact - storage or a product reference. REV never imports ART preparation/scratch - types, persists their paths or ledger identities, or creates a second scratch - manager. Future ART-owned intake capabilities may use that foundation behind - their port. -- The active WS-ART plan changes the production choice to AWS S3 behind - `S3CompatibleArtifactStore`, proves it with MinIO, removes the old - `flow_node` configuration value, and leaves review packet/evidence integration - to WS-REV. -- The byte-preserved archival WS-REV source intentionally still says production - Flow Node in sections 6.10, 25.8, and 27. Its exact hashes are recorded in - `SOURCE_MANIFEST.md`, the reference README, and `SHA256SUMS`; it is discovery - evidence, not canonical provider authority, and this planning chunk must not - edit it. Canonical adoption is not yet complete: chunk 01 must create - `docs/spec_review_lifecycle.md` with AWS S3 through - `S3CompatibleArtifactStore`, MinIO protocol proof, and no `flow_node` - configuration before that active contract can be treated as adopted. -- Review services should consume typed binding metadata, complete verified - retrieval, finding-evidence intake, retention, and projection capabilities - supplied through composition-root registration. Tests may use fakes; no - production bypass or provider import is acceptable. -- WS-XINT-001 assigns immutable bytes, commitments, bindings, verification, - recovery, and candidates to ART while REV owns `ReviewPacketManifest`, - `ReviewEvidenceArtifact`, packet membership, and lifecycle semantics. Exact - packet read uses `review.context.read`, never generic `artifact.retrieve` or - Operator-only `artifact.binding.read`. -- Evidence finalization requires the separate service action - `artifact.review_evidence.binding.create`, mapped to - `artifact.binding.create`, restricted to `workstream.artifact.binding`, backed - by a separately approved ART review-evidence capability, and activated only by - AUTH after its hidden behavior merges. - -## Contribution boundary - -- No contribution policy, award, fulfillment outbox, or callback - models are implemented in this snapshot. -- Revised WS-REV requires one reviewer contribution for every Review. On - `accept`, REV creates one immutable `FinalAcceptance`; the submitter - contribution consumes that fact rather than `Review.decision` directly. -- WS-CON requires the reviewer `ContributionPolicyVersion` to be frozen on the - `ReviewLease` and its flush-only contribution/award participant to commit or - roll back with Review, FinalAcceptance, task/assignment effects, audit, and - outbox. REV owns lifecycle orchestration and audit/outbox staging; the request - route or service command owns the caller transaction and only commit. -- Review core may be built behind an unexposed composition boundary, but the - public decision endpoint cannot be enabled with a no-op contribution path. -- Core contribution creation first receives locked Review, ReviewLease, - Submission, assignment, and policy facts from REV. For `accept`, the - participant's submitter operation also receives FinalAcceptance. CON copies - the stabilized versioned Submission - `artifact_hash` into `ContributionRecord.artifact_hash`, and performs no ART - call, provider I/O, or mandatory contribution-evidence artifact write. - -## WS-XINT-001 reconciliation findings - -1. Current `ActionOwner.REV_*` values are stale activation-custody encodings, - not feature ownership. `WS-AUTH-001-REV-CUSTODY` must transfer all 19 - registered review actions to the seven exact AUTH activation custodians - without changing counts, mappings, or availability. -2. Delivery order is AUTH registration, hidden dependency and REV behavior, - AUTH evaluator integration/activation, then REV joint product release. -3. Reviewer authority is one exact active independent `reviewer` grant; - reviewer revocation changes only review-owned state. -4. Preference expiry, lease expiry, review reconciliation, artifact-reference - reconciliation, and projection rebuild need distinct fixed service identities - and exact AUTH-09E static rows. -5. Review evidence uses ART candidate/finalize and its exact binding service - action. Final decisions use stabilized binding facts without provider I/O. -6. Contribution creation is a REV-request-owned single transaction using one - CON participant with ordered flush-only reviewer and submitter operations, - frozen `ContributionPolicyVersion` rows, REV-staged audit and outbox records, - and no core ART dependency or mandatory evidence projection. - -## Existing infrastructure - -- FastAPI routes are registered below `/api/v1`; archival examples using the - noncanonical prefix must be adapted to this convention. -- Celery exists for project setup and checker gates. There is no timer schedule, - review background job, generic transactional outbox dispatcher, or review - reconciliation job yet. -- The structured API error envelope and request/correlation IDs exist. -- `AuditEvent` is shared and append-only for authority evidence; lifecycle - audit input is still legacy-shaped and needs a bounded WS-REV event contract. -- Trusted main has 23 numbered migrations through AUTH-09A migration `0023`. - Parallel initiatives mean WS-REV contracts must allocate the next migration - number only when a chunk starts from current main; no REV number is reserved - in planning. -- The backend has 782 discovered test functions across 23 test modules. - -## Specification and documentation conflicts - -1. Revised WS-REV names Flow Node as the production artifact adapter; locked - repository policy names AWS S3 and MinIO. -2. Revised WS-REV does not describe ADR 0010 context rebase. The omission does - not repeal the accepted ADR. -3. WS-IMP still exposes reviewer preferred/open backlog arrays, while revised - WS-REV exposes only active lease, one next offer, or none. -4. WS-IMP and current runtime configuration still contain Flow Node production - wording superseded by the WS-ART amendment. -5. `operations_reviewer_workflow.md` uses high/medium/low findings, requires a - finding on reject, and says accept directly creates payment/reputation - records. Revised WS-REV uses blocking/advisory, makes reject findings - optional, delegates contributions/compensation to WS-CON, and defers - reputation. -6. `operations_revision_replay.md` and `architecture_lockdown.md` use legacy - contributor and reviewer closure tokens that do not map directly to - `SubmissionFindingResponse` plus `FindingResolution`. -7. The revised PDF says “Approved design baseline for implementation” while - Markdown says “Locked for implementation handoff.” This prevents treating - the supplied PDF as a reproducible semantic twin; the active reconciled - Markdown contract must declare precedence explicitly. - -## Baseline verification observation - -- `uv run pytest -q` did not reach repository collection because an ambient - user-level Web3 pytest plugin failed during plugin loading. Repository - verification must use the locked dev environment and isolated runner. -- `uv run --extra dev python -m pytest -q` completed with `586 passed`, `11 - failed`, and `403 errors` in 227.35 seconds. Database-backed setup failed - because `WORKSTREAM_TEST_DATABASE_URL` was not configured; this was an - environment failure, not valid green baseline evidence. -- Runtime chunks therefore require `scripts/run_isolated_tests.py` with a - disposable `WORKSTREAM_TEST_ADMIN_DATABASE_URL`, fresh coverage, and no - ambient plugin dependence. - -## Conventions to preserve - -- Async SQLAlchemy repositories under the owning module. -- Service-owned domain rules and thin FastAPI routers. -- PostgreSQL database time, row locks, partial unique indexes, and expected-race - error mapping. -- Shared structured error envelopes and request/correlation context. -- Celery jobs carry stable IDs and reload PostgreSQL state. -- New or materially changed subsystem coverage at or above 90 percent and the - repository floor at or above 78 percent. -- One approved chunk per PR, required internal reviewer tracks, explicit human - merge approval, one merge intent, automated post-merge memory, and stop. - -## Unknowns to resolve at each activation gate - -- Exact merged AUTH service, resource-context, invalidation, and system-actor - interfaces. -- Exact later merged ART S3, admission, verification/publication, read, - binding, intake, retention, recovery, service-scope, checker, and projection - interfaces. ART-02A3 provides the byte foundation and typed composition - boundary, not those review-facing capabilities. -- Exact WS-CON policy-freeze and transaction-participant interfaces. -- Whether a shared outbox foundation lands before the first review consumer. -- Production timer schedule and operational alert thresholds. -- The user decision for revision limits/deadlines without synthetic reject. +## Baseline + +Discovery was refreshed read-only from trusted main +`99ae4c963e53f317175dcb308b9e47c93ccf19ed` after REV parent chunk 02 merged +through PR #147 and AUTH-09D-A merged through PR #148. The active planning chunk +makes no backend/runtime changes. + +## Current backend + +- FastAPI/Python, async SQLAlchemy 2.x, Alembic, Pydantic, PostgreSQL. +- Single Alembic head: `0026_actor_profile_lifecycle`. +- `Submission` is the existing versioned submission entity; no separate + SubmissionVersion is needed. +- Both retired task-subsystem contributor-identity storage fields remain on + trusted main. REV must not build new schema against them. +- Existing checker routing can move a Task to `needs_revision` with + `review_decision_id=None`. The regression + `test_checker_caused_revision_resubmits_fixed_version_through_api` proves this + supported path. +- Existing project guide activation is a public bodyless route with legacy + registered-actor/local-role checks, locks the candidate before Project, uses + application time, and allows only draft activation/idempotent active repeat. + Superseded-guide reactivation must not be added under that authorization. +- Task screening currently does not share the Project-first publication lock. + +## AUTH discovery + +- Trusted catalogue: 74 PermissionIds, 65 ActionIds, 15 active, 50 planned. +- AUTH-09A/09B/09C and 09D-A are merged. PR #148 merged 09D-A as + `99ae4c963e53f317175dcb308b9e47c93ccf19ed` from reviewed head + `9c5ef8a1feffd6324acfd947e67042921955320b`, establishing database-backed + ActorProfile lifecycle status/provenance and migration + `0026_actor_profile_lifecycle`. +- 09D-A intentionally leaves both retired task-subsystem contributor-identity + fields unchanged. The user-directed contributor/canonical-human foundation + remains separate and has no trusted-main chunk ID, PR/SHA, or migration. +- AUTH-09D-B, 09E, AUTH-PREP, REV custody, AUTH-10 through 14, and matching + feature activations remain unmerged. AUTH-13/14 contracts require later + amendment for prepared revision/replacement facts and cannot be treated as + current runtime gates. +- All 24 REV lifecycle actions remain unavailable. REV never registers, + provisions, evaluates, or activates them. + +## ART discovery + +- ART v2 LocalStorage clean cut merged through PR #141 at `a10d901` despite + stale ART owner status wording. +- S3/MinIO and ART 02B1 onward remain proposed. +- Current ART map does not schedule an exact lease-scoped review packet-read + capability, review-evidence candidate/finalize capability, or server-derived + stabilized Submission artifact digest. REV-03B, 07A/07B, 09A3/09A4, 10, and + projection work remain blocked on exact owner chunks. +- REV must consume typed capability ports and never ArtifactStore, concrete + adapters, provider references, scratch paths, or ART repositories. + +## CON discovery + +- CON-01 canonical specification/ADR is merged; runtime 02A onward remains + proposed on trusted main. +- An unmerged CON outbox branch also claims migration `0026`. It must rebase and + renumber after the winning migration; REV consumes neither worktree. +- Exact planned dependencies are CON-02A outbox, 02C audit participant, 03B + ContributionPolicyVersion, 03C contribution/award persistence, 06 lease + freeze, 07 atomic two-operation participant, and later delivery/readiness + hooks. Proposed contracts are not runtime proof. +- The stable boundary is reviewer contribution from Review for every decision + and submitter contribution from accept-only FinalAcceptance. + +## Product findings + +- All reviewer decisions/findings/resolutions are append-only. +- Checker-caused remediation is supported but accepted ADRs scope controlled + guide rebase/preparation to human Review revision. The plan must preserve a + distinct CheckerRun-rooted N+1 path rather than treating it as legacy or + silently applying human RevisionPolicy/D6 behavior. Current Submission storage + lacks immutable causal CheckerRun lineage, so 02C must add and backfill + `remediation_source_checker_run_id` before human prepared cutover adds the + source XOR. +- Human revision context is task-owned. REV supplies exact human decision/ + finding facts through a typed task participant. Checker remediation retains + its existing task/checker path and locked context. +- Task guide identity and reviewer packet access require database-enforced + immutability/lease scope, not service convention. +- The exact decision lock order must put AUTH authority first, then + ReviewDecisionRequest, ReviewLease, queue, task, exact Submission assignment, + Submission, and stable subordinate rows. + +## Plan-review findings incorporated + +- Split unsafe oversized parents 03-07, 09A, 11, 12/12A, and 13. +- Keep 08 pure; keep 10 as the first canonical decision transaction. +- Separate 02A chronology from later hidden 02A2 reactivation. 02A2 must merge + before AUTH-12 evaluator/cutover/activation, not after an active action. +- Move historical admission scan to authorized reconciliation child 11C. +- Separate persisted phase execution denial from static router/AUTH membership + and operational scheduler state. +- Keep active release docs and route registration together in 13C. + +## Unknowns and owner actions + +- AUTH must name/merge the contributor foundation and later amend AUTH-12/13/14 + contracts. +- ART must schedule/merge packet-read, review-evidence, digest, and projection + capabilities. +- CON must merge its runtime foundations from the then-current migration head. +- Human must approve the two positive 02B duration defaults. + +Until those facts are on trusted main, REV planning may continue but runtime +must stop at each affected gate. diff --git a/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/INTENT.md b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/INTENT.md index c9bbf099d..c287b1dfd 100644 --- a/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/INTENT.md +++ b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/INTENT.md @@ -45,6 +45,12 @@ outcomes. Exact match keeps context; any different active identity or sequence rebases forward or backward; missing, incomplete, or unsafe active context blocks. Return routing prefers the prior reviewer before falling back to open FIFO. +- A supported checker-caused `needs_revision` remains a distinct CheckerRun- + rooted remediation that keeps task context and persists a unique server- + derived immutable source-CheckerRun relation on corrected N+1. It creates no + synthetic Review, finding, reviewer contribution, or human actor. Controlled + preparation/rebase, finding replay, human revision policy, and D6 closure apply + only to an exact `Review(needs_revision)`. - Artifact outage or integrity failure blocks judgment without creating an adverse contributor outcome. - Every committed Review joins the `WS-CON-001` contribution and conditional @@ -105,8 +111,8 @@ outcomes. visibility uses the frozen preparation, and no reviewer-side guide exists. 3. D6's recommendation is approved: limit/deadline blocks further submission while leaving `needs_revision` active, with only the covered Project Manager's - explicit reason-bound revision-obligation closure and never a fabricated - human `reject` Review. + explicit reason-bound `review.revision_obligation.close` command and never a + fabricated human `reject` Review. 4. The revised reviewer `current` endpoint controls over the older WS-IMP full-backlog reviewer response. 5. Production enables the coherent lifecycle route set only after the @@ -132,7 +138,12 @@ outcomes. 10. Merged AUTH reconciliation PR #140 is planning authority, not runtime proof. Exact AUTH custody, PREP, registration, service-identity, and activation gates apply per consumer so hidden REV work can proceed while every action remains - unavailable; REV-13 alone releases product surfaces. + unavailable; REV-13C alone releases product surfaces. +11. Guide chronology/task locking lands before hidden superseded-guide + reactivation. Reactivation uses AUTH PREP plus a current-active If-Match + precondition and must merge before AUTH-12 evaluator/cutover/activation. +12. Persisted release phase denies execution but does not dynamically unregister + routers, deactivate AUTH mappings, or replace operational scheduler control. Items 3-5 and the proposed chunk sequence were approved by the human on 2026-07-15 for planning publication. This approval does not activate a successor diff --git a/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/PLAN.md b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/PLAN.md index 99c16ac04..f135f8cf7 100644 --- a/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/PLAN.md +++ b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/PLAN.md @@ -1,834 +1,353 @@ # Plan: WS-REV-001 Review And Revision Lifecycle -## Approach +## Planning authority + +This plan is reconciled from trusted main +`99ae4c963e53f317175dcb308b9e47c93ccf19ed`, which contains merged REV parent +chunk 02 through PR #147 and merged AUTH-09D-A through PR #148. Worktree +branches, unmerged PRs, and proposed owner changes are discovery evidence only. +They are not runtime dependencies until their exact owner chunk, PR, merge SHA, +schema head, typed contract, and tests exist on trusted main. + +Current merged facts are: + +- the single Alembic head is `0026_actor_profile_lifecycle`; +- task assignment and submission attribution still use the retired contributor- + identity storage names; +- the AUTH catalogue contains 74 PermissionIds and 65 ActionIds, with 15 active + and 50 planned; +- all 24 REV lifecycle action dependencies remain unavailable; +- ART v2 LocalStorage is merged, but review packet reads, review-evidence + candidate/finalize, and server-derived stabilized Submission artifact lineage + do not have merged owner contracts; +- CON has merged its canonical specification, but its outbox, audit, + contribution-policy, contribution/award, freeze, and atomic participant + runtime chunks remain proposed. + +AUTH-09D-A is merged through PR #148 at +`99ae4c963e53f317175dcb308b9e47c93ccf19ed` (reviewed branch head +`9c5ef8a1feffd6324acfd947e67042921955320b`) and supplies database-backed +ActorProfile lifecycle status/provenance and migration `0026`. It does not rename +task/submission contributor fields. REV-02 runtime remains blocked until AUTH +publishes a real contributor-foundation chunk ID and merges it with exact +`contributor_id`, database-backed canonical-human ActorProfile constraints, +migration, regression tests, and PR/SHA evidence. REV never codes against +those retired fields or reserves a migration number while waiting. + +## Shipping boundary + +The v0.1 product path is: -Build the lifecycle as one review-owned backend module integrated with existing -tasks, submissions, checkers, audit, authorization, artifact, job execution, and API -composition boundaries. Land persistence before behavior, keep every public -mutation hidden until its invariants and cross-domain participants exist, and -use PostgreSQL constraints as final race guards. - -## Dependency gates +```text +project guide -> task -> submission -> checkers -> review/revision +-> FinalAcceptance on accept -> ContributionRecord +-> CompensationAward where frozen policy permits +-> asynchronous external fulfillment +``` -### Authorization gate +Review decisions stored by the product are only `accept`, `needs_revision`, and +`reject`. Every valid Review, every submitted finding, and every later finding +resolution is immutable. A later round appends new records. -Merged WS-XINT-001 and AUTH reconciliation PR #140 fix one delivery protocol for -every protected REV surface: +Adjudication is disabled and unimplemented. This initiative adds no +adjudication action, state, queue, lease, policy, decision, contribution, or +readiness dependency. Stable origin and lineage interfaces may accept a new +future origin kind only through a separately approved migration and lifecycle; +that future compatibility does not implement adjudication now. -```text -AUTH planned registration and activation-custody assignment --> required ART/CON capability plus REV hidden behavior and canonical facts --> AUTH evaluator integration and exact action activation --> REV joint product-surface release -``` +## Canonical decision transaction -REV never registers an ActionId, edits `ActionOwner`, integrates an AUTH -evaluator, or changes action availability. A REV feature chunk owning hidden -behavior and resource facts produces lifecycle guards, a canonical typed -ResourceContext composer, and a feature-manifest delta while the real kernel returns -`action_unavailable`. AUTH alone activates the action after that evidence and -all required hidden participants merge. REV-13 exposes only already-active -surfaces after a separate joint readiness check. - -PR #140 changes planning only. Merged AUTH-09A PR #132 now provides the common -fixed-service enum/schema/migration and the closed seven-identity ART matrix, -but it activates no action, provisions no actor, admits no service token, and -does not add REV's six identities. `WS-AUTH-001-REV-CUSTODY` must first transfer all -19 registered planned review actions to seven exact AUTH activation custodians -without changing mappings, counts, or availability. `WS-AUTH-001-PREP` then lands -the shared prepared-mutation runtime. Exact feature gates -`WS-AUTH-001-REV-05/06/07/08/09A/11/12` integrate evaluators and activate only -their merged hidden behavior. After REV-01 publishes the immutable registration -manifest, `WS-AUTH-001-REV-REG` registers the four approved REV additions as -planned; `WS-AUTH-001-REV-LIFECYCLE` activates those additions -only after the REV-11 and REV-12A manifests are complete. - -REV-01 turns this reviewed plan into the active contract and publishes two -immutable, availability-neutral inputs before runtime feature chunks: the -complete four-action registration manifest consumed by -`WS-AUTH-001-REV-REG`, and six independent service identity-to-ActionId manifests -consumed by later AUTH identity-specific extension contracts. Those manifests -name required hidden dependencies but do not claim behavior is implemented. -AUTH may register planned actions and define/provision exact REV identity -extensions from the merged REV-01 SHA while REV persistence chunks continue in -parallel. Those extensions build on, and do not replace, AUTH-09A's fixed-service -foundation. Hidden behavior -chunks later emit separate activation manifests; no registration or identity -extension activates an action or exposes a product surface. - -Merged AUTH-08 PR #131 establishes the current public kernel and resolves the -three AUTH-07B consumption blockers. Every runtime chunk retains proof that: - -- the reusable authorization dependency never commits a feature-owned open - transaction during generic successful teardown; every read or mutation owner - commits its own business-plus-decision unit explicitly; -- SQL failures while staging authorization evidence map centrally to the stable - retryable service-unavailable response and leave no business mutation or - partial decision evidence; and -- AUTH documents and restores its canonical `ActorProfile.last_seen_at` and - `ActorIdentityLink.last_verified_at` semantics for successful existing-actor - GET/PATCH access, with API regression proof. REV does not prescribe AUTH's - sequencing or lifecycle-denial timestamp policy. - -After the exact owning AUTH gates merge, WS-REV consumes: - -- canonical actors: every human lifecycle FK stores the active canonical - `ActorProfile.id`; external issuer/subject, email, legacy profile row IDs, - token roles, and contributor profile labels never substitute for actor - identity; -- one exact active project `reviewer` grant for human review. Separate - `submitter`, `adjudicator`, and administrative grants never substitute, and - revoking reviewer authority never mutates another grant; -- exact REV identity extensions, controlled provisioning through merged - AUTH-09B, and AUTH-09E fixed-service admission for protected jobs. - Preference expiry, lease - expiry, reviewer-authority invalidation reconciliation, general review - reconciliation, artifact-reference reconciliation, and projection rebuild - use distinct immutable service identities and exact static ActionId rows, - never a generic service, human reviewer, or Operator fallback; -- exact service identities are registered only after REV publishes each - identity-to-ActionId manifest; generic AUTH-09E admission does not pre-create a - catch-all review service or make a later identity extension executable; -- 24 non-executable review-lifecycle action dependencies: registered planned - `submission.create`, 19 registered planned review actions, and four approved - but unregistered REV actions for revision closure/recovery and joint release - control. The separate ART evidence-binding action is not one of the 24; -- AUTH-14 activation of `submission.create` only after merged REV-09A prepared - revision/replay behavior, exact final-fact recomposition, and initial/revision - API proof; this action is a required REV-13 release gate alongside the named - review activations; -- `review.revision_context.repair` maps to existing PermissionId - `project.task.manage`, a covered Project Manager candidate, and an exact typed - task/assignment/prior-Submission/episode/head resource with transaction - revalidation; -- `review.revision_context.legacy_close` maps to existing PermissionId - `operations.reconcile.run`, an Operator AdminRoleGrant candidate, and an exact - typed unresolved reconciliation-finding/project/task/no-Review/no-root - resource with transaction revalidation; -- `review.revision_obligation.close` maps to existing PermissionId - `project.task.manage`, a covered Project Manager candidate, and the exact - task/assignment/needs-revision Review/current preparation head/observed - limit-or-deadline resource with transaction revalidation; -- `review.lifecycle.activation.manage` maps to existing PermissionId - `operations.reconcile.run`, an Operator AdminRoleGrant candidate, and the - exact singleton control/current phase/target phase/manifest digest resource - with transaction revalidation; -- registered permissions, with `review.queue.override` as the only additive - PermissionId; -- canonical resource contexts and project mismatch handling; -- request-scoped `AuthorizationService.require(action_id, resource_context)` for - reads only; -- the AUTH prepared mutation protocol for writes: AUTH returns an opaque, - non-Pydantic, single-use `PreparedAuthorizationHandle` bound to the exact - `AsyncSession`, ActionId, actor-reference kind and ID, idempotency key, and - canonical request digest after locking current authority. REV locks canonical - feature rows and recomposes final typed facts, then calls AUTH with those facts - and the opaque handle. AUTH validates every binding and current authority, - consumes the handle exactly once, evaluates exactly once, and stages bounded - decision evidence before the first feature mutation; participants flush; and - the request route or service command commits once. Binding substitution, - serialization, caller construction, already-consumed replay, or authority loss - denies before feature mutation; -- immutable authorization decisions and audit links; -- revocation invalidation used to recover active review leases. - -Prepared-handle protocol rejection and evaluated denial are different outcomes. -An unconsumed handle presented with a wrong session/action/actor/request binding, -or a serialized, caller-constructed, or forged substitute, stages no -AuthorizationDecision/evidence, does not consume the legitimate handle, and -must allow that handle's later exact first use. A stale or already-consumed -handle, including the losing side of concurrent duplicate use, stages no new -decision/evidence or feature state, remains consumed, and can never become valid -again; exactly one concurrent exact consumer may win. When an exactly bound -handle reaches evaluation but current authority or policy denies, the request -route or service command rolls back the dirty caller transaction; AUTH restages -the unchanged bounded denial evidence in a clean transaction; and the request -route or service command commits that evidence once. No REV/task/ART/CON mutation -or feature/shared audit/outbox effect survives. If denial-evidence restaging -fails, nothing commits. - -REV owns its typed ResourceContext composers and lifecycle guards. It imports -the public AUTH service and `ActionId` types only; it never imports AUTH -repositories/models, queries grants, or reconstructs permission unions. -The four additive ActionIds and their closed mappings are registered together by -`WS-AUTH-001-REV-REG`, not review code. Their hidden manifests land in chunks 11 -and 12A; `WS-AUTH-001-REV-LIFECYCLE` later integrates their evaluators and -activates them together. They add no PermissionId. The AUTH-08 runtime snapshot -contained 57 actions: 9 active and 48 planned. That is historical provenance, -not a fixed future total. Current trusted main after AUTH-09C contains 65 -actions: 12 active and 53 planned. AUTH-09B activates -`actor.service.provision`; AUTH-09C activates only `actor.profile.read` and -`actor.identity_link.read`. Neither adds a REV identity or action, and all 24 -REV dependencies remain unavailable. -WS-XINT-001 separately proposes -`artifact.review_evidence.binding.create -> artifact.binding.create` for the -ART binding service. Every later AUTH registration or activation chunk derives -the exact before/after count and SHA from then-current trusted main and proves -typed catalogue, activation custodian, PostgreSQL audit parity, allowed/denied -evidence, upgrade, and unsafe-downgrade behavior. The four REV proposals and the -separate ART service action are never silently combined into a hard-coded total. - -### Artifact gate - -Artifact-sensitive work starts only after the required WS-ART contracts are -merged and proven. WS-REV consumes: - -- immutable ART binding IDs and server commitments; -- a narrow active-lease packet-read capability that revalidates exact packet - membership and returns a bounded stream; -- ART-owned two-phase evidence candidate/finalize ports for finding and response - evidence; -- stable verification/availability facts and deterministic projection storage; -- LocalStorage and MinIO conformance with AWS S3 as production provider. - -Merged ART-02A2 PR #129 established the committed-source/private-scratch -foundation. Merged ART-02A3 PR #141 at trusted main -`a10d9018007d2e847b4870e9b26cbd24e24c7bb4`, final branch head -`7606798e751abf40218d23886779c3659b76e974`, removes v1 and activates the -byte-only ART v2 LocalStorage clean cut and typed product capability boundary. -`ArtifactScratchManager`, `PreparedArtifact`, `CommittedArtifactSource`, and the -raw byte store are ART-internal mechanics, not REV capabilities or durable -product references; review code never imports or stores them. Later ART-owned -S3/MinIO, submission/checker binding cutovers, admission, -verification/publication, packet read, evidence candidate/finalize, projection, -and live-proof chunks remain hard gates. ART owns candidate retention and -Operator recovery; REV does not consume the raw store, -`artifact.binding.read`, or a generic artifact-retrieval action. - -The current merged ART plan does not yet assign two other exact XINT -requirements to an approved owner chunk: a narrow active-lease packet-read port -and server-derived verified `Submission.artifact_hash` persistence in the -submission/checker cutover. Both require ART/task-owner amendments, approval, -and merge before their REV consumers; the existing artifact-set context or -caller `package_hash` is not equivalent. REV does not name a dependency chunk -until the ART owner publishes one. - -REV owns immutable `ReviewPacketManifest` and `ReviewEvidenceArtifact` semantic -records. The manifest names the exact queue/lease, versioned Submission, -admitting CheckerRun/results, locked guide/revision context, response-evidence -relations, and ART binding IDs. It contains no bytes, digest, provider reference, -object key, signed URL, scratch path, receipt, or authorization-matrix data. - -Evidence binding additionally requires the separately registered -`artifact.review_evidence.binding.create` service action, mapped to existing -`artifact.binding.create` and available only to `workstream.artifact.binding`. -A separately approved `WS-ART-001-REV-EVIDENCE` capability supplies hidden -canonical facts and binding behavior; AUTH alone integrates its evaluator and -activates it. That ART owner chunk is not scheduled by the currently merged ART -plan, so REV-07 remains blocked until ART adds, approves, and merges it together -with an approved packet-read owner contract. No Operator read action or generic -PermissionId substitutes. - -### Contribution gate - -Merged CON-01 at `e118e33afcd89b8ee78ecfc8f0e0d585ae0ee4b9` publishes -`docs/spec_contribution_compensation.md` and ADR 0016 as the canonical CON -boundary. They require FinalAcceptance as the sole submitter-acceptance source, -REV-owned decision orchestration and sole commit, ordered flush-only CON -operations, and REV staging of shared audit/outbox inputs returned by CON. The -older WS-XINT `REV_CON_HANDOFF.md` remains historical supporting handoff -material; it no longer outranks the merged CON contract. CON-01 implements no -runtime, so its later persistence, freeze, lineage, and participant chunks still -gate canonical Review composition. - -The cross-initiative sequence is explicit: - -- AUTH first repairs the circular AUTH-13/14 graph and merges a separately - reviewed schema-only contributor-field foundation. That foundation performs - only the canonical TaskAssignment/Submission field clean cuts and preserves - current behavior; full AUTH-13/14 product cutovers are explicitly later; -- parent `WS-REV-001-02` is a non-executable split record. After the exact - AUTH foundation merge, 02A establishes guide activation chronology and Task - stamps, 02B establishes immutable review/revision policy plus dormant - task/assignment compatibility, and 02C establishes immutable - `Submission.task_assignment_id` attribution and lineage; -- WS-CON's approved replacement chunks then freeze submitter - `ContributionPolicyVersion` on `TaskAssignment` and remove legacy - compensation-context fields and - consumers before `WS-REV-001-09A`; -- merged WS-CON contribution-policy persistence precedes `WS-REV-001-03`, so - ReviewLease FKs target a real owner; -- merged shared outbox persistence and caller-transaction lifecycle audit - participants precede `WS-REV-001-04`, where REV adds immutable - `FinalAcceptance` persistence beside Review; -- the WS-CON ReviewLease freeze capability precedes `WS-REV-001-06`; -- REV-04's `FinalAcceptance` schema and REV-09B's stable lineage precede CON's - exact source-lineage schema and flush-only contribution/award participant; -- that exact CON participant precedes `WS-REV-001-10`; -- REV-09A's hidden prepared revision/replacement behavior precedes the amended - full AUTH-13/14 product cutovers and AUTH-14 activation of `submission.create`; -- those AUTH cutovers and activation precede REV-13 product release; and -- the exact WS-CON readiness manifest, mandatory fulfillment obligation-writer, - dispatch, and callback fence hooks, and same-session fulfillment/outbox - drain-cutoff and observation port - precede hidden joint release-control integration in `WS-REV-001-12A`; and -- all matching AUTH actions activate after their hidden behavior, and the merged - 12A controller and fences precede the sole joint product release in - `WS-REV-001-13`. - -Contribution policy context is independent of guide/review execution context. A -forward or backward Project Guide rebase never changes the submitter's frozen -TaskAssignment `ContributionPolicyVersion`. Each new ReviewLease independently -freezes the current reviewer `ContributionPolicyVersion`. Review services do not -implement rules, awards, fulfillment, evidence projection, or provider delivery. - -Every valid `review.decision` request appends one immutable Review. Every finding -and resolution submitted with that decision is also appended as an immutable -record. A later review round creates new records; it never updates the history -from an earlier round. After closing the lease and queue entry, the request calls -the reviewer operation on one mandatory typed CON participant. That operation -creates `completed_review` directly from Review and ReviewLease lineage and -evaluates the lease-frozen reviewer rule. - -Only after that common reviewer-contribution operation does REV apply the -decision branch. When the decision is `accept`, REV creates one immutable -`FinalAcceptance`, applies accepted Task and TaskAssignment effects, and calls the -participant's submitter operation. That operation creates `accepted_submission` -from FinalAcceptance and TaskAssignment lineage and evaluates the -assignment-frozen rule. -`needs_revision` and `reject` apply their Task and TaskAssignment effects without -FinalAcceptance or the submitter contribution operation. - -Both operations belong to the same mandatory participant, use the caller's -AsyncSession, flush without commit, copy the stabilized versioned Submission -`artifact_hash`, and return typed audit and outbox inputs. CON never infers -acceptance from `Review.decision`, calls ART, rederives the digest, or commits. -REV stages the shared audit and outbox rows, and the request route or service -command commits once. -Any contribution-evidence document is a later optional asynchronous projection -with its own action and failure state, not a core transaction or joint-release -gate. - -### Transactional outbox gate - -The shared PostgreSQL transactional-outbox contract, ownership, and lock-order -position must be frozen before immutable review-chain persistence starts. The -preferred implementation is the merged shared foundation used by WS-CON. If it -does not exist at activation, WS-REV-001-04 is blocked until a separately -approved foundation chunk lands; WS-REV must not improvise a private competing -outbox. - -### Shared audit gate - -WS-REV appends to the existing shared `AuditEvent` ledger through its -caller-transaction-aware audit participant, preserving request/correlation and -AuthorizationDecision links. If bounded lifecycle event inputs are not merged, -an audit-owner foundation chunk lands before chunk 04. A `ReviewAuditEvent` -table, review-private audit repository, or commit-owning audit writer is -prohibited. - -## Data model alignment - -### Existing records extended - -- `Submission` remains the versioned submission record and receives structured - finding-response relationships where needed. PostgreSQL enforces immutable - rows, same-task immediate predecessor lineage, version N-1 linkage, and the - canonical submitter Actor mapping. It also stores the exact immutable - TaskAssignment that produced it, constrained to the same task and contributor, so - history and WS-CON never infer attribution from a later active assignment. - Its submitter and assignment contributor are canonical human - `ActorProfile.id` values. The ART submission/checker cutover supplies one - server-derived verified `artifact_hash` on this existing versioned row; the - XINT shorthand `SubmissionVersion.artifact_hash` does not create a duplicate - entity, and no participant trusts caller `package_hash`. -- `WorkstreamTask` receives canonical `accepted`, `rejected`, and `cancelled` - transitions plus bounded terminal reasons. Human reject enters `rejected`; - the approved administrative revision-limit/deadline closure enters - `cancelled` with its exact reason and creates no Review. -- `TaskAssignment` receives dormant completed/blocked compatibility fields. - No service path enters either state and no reject Review reference is added - until Review persistence and the owning decision/task participant exist. -- `ReviewPolicy` receives positive preference/lease durations, capacity fixed - to one, self-review fixed false, close-task reject, and typed finding-evidence - settings. Existing policy migration uses separately approved duration - defaults and never infers either duration from `sla_hours`. -- Existing locked non-compensation task/submission policy references remain the - immutable execution-context anchor. - -### New review-owned records - -- `ReviewQueueEntry` -- `ReviewLease` -- `ReviewPacketManifest`, an immutable lease/packet projection over exact queue, - Submission version, admitting CheckerRun/results, locked guide/revision - context, response-evidence relations, and ART binding IDs -- `Review` -- `FinalAcceptance`, an internal immutable fact created only when a new Review - has decision `accept`; it links exactly one task, versioned Submission, source - Review, accepted submitter, recording reviewer, acceptance time, and immutable - ReviewPolicy context -- `ReviewFinding` -- `SubmissionFindingResponse` -- `FindingResolution` -- `ReviewEvidenceArtifact`, an immutable semantic relation from a pre-decision - lease-scoped evidence slot to one finalized ART binding, later linked to its - exact ReviewFinding or SubmissionFindingResponse without changing the binding - identity -- review-owned `ReviewDecisionRequest` idempotency aggregate bound to actor, - operation, lease, submission, and canonical payload (the existing - AUTH-owned authority idempotency record is not reused) -- `ReviewAdministrativeCommandRequest`, a separate bounded administrative - idempotency aggregate for repair/closure resources and payloads; it does not - widen or overload lease/submission-bound `ReviewDecisionRequest` -- `ReviewReconciliationFinding` with immutable canonical defect/evidence facts, - a set-once resolution pointer, and one-to-one immutable - `ReviewReconciliationResolution` for domain inconsistency evidence -- one canonical shared outbox event for review snapshot projection; delivery - attempts/status remain owned by the shared outbox and immutable artifact - receipts remain owned by ART, with no review-private delivery table - -All mutable-state compatibility, predecessor, uniqueness, packet-membership, -evidence-slot, and partial-active invariants are enforced in PostgreSQL as well -as in services. `ReviewLease` remains the permanent attempt identity; -`ReviewDecisionRequest` remains request idempotency. No mutable ReviewAttempt or -ReviewVersion entity is introduced. - -`ReviewLease.reviewer_id`, `Review.reviewer_id`, preferred-reviewer references, -and every human administrative actor reference use canonical `ActorProfile.id` -with database-enforced human actor kind and status checks at mutation time. -Schema chunks use a composite immutable actor-kind key plus local -`actor_kind='human'` check, or an equivalently reviewed deferred constraint -trigger; a plain actor-profile FK is insufficient. Audit attribution additionally -preserves the AUTH-defined actor-reference kind so service/system work is not -misrepresented as a human reviewer. - -## Application flow +The review request or service command owns the only transaction and commit. +AUTH, task, REV, CON, audit, and outbox collaborators are session-bound, +flush-only participants. ```text -durable checker allow_review - -> verify required retained binding facts - -> create at most one open/preferred ReviewQueueEntry for an admitted version - with task review_pending and the exact admitting CheckerRun ID - -> server selects current lease or one next offer - -> preliminary request-scoped authority and concealment gate permits bounded - artifact availability preflight without disclosing packet facts - -> final transaction: AUTH prepares and locks reviewer authority; REV locks - the selected queue and canonical packet rows and recomposes final facts; - AUTH evaluates once; REV and typed participants flush the ReviewLease and - immutable ReviewPacketManifest; the request route or service command commits once - -> authorized Review Context shows the bounded immutable chain but retrieves - artifact content only for the currently leased Submission version - -> finding evidence is ingested and verified before decision - -> decision transaction locks AUTH authority first, then REV canonical rows, - recomposes final facts, and evaluates once - -> REV appends the immutable Review, submitted findings, and resolutions, then - consumes the lease and closes the queue entry - -> CON reviewer operation creates completed_review, evaluates the - lease-frozen reviewer policy, and appends any reviewer award - -> REV applies the decision branch - -> accept: append FinalAcceptance, accept task, complete assignment, then - CON submitter operation creates accepted_submission, evaluates the - assignment-frozen submitter policy, and appends any submitter award - -> needs_revision: set task needs_revision; no FinalAcceptance and no - submitter operation - -> reject: block assignment and then reject task; no FinalAcceptance and no - submitter operation - -> REV stages shared audit and outbox records - -> request route or service command commits once - -> projection and notifications execute from the canonical shared outbox - event after commit; optional contribution-evidence export is outside the - core readiness contract +compute canonical request key/digest without a database lock +-> AUTH prepare and authority lock +-> reserve/lock ReviewDecisionRequest +-> lock the review lifecycle fence +-> lock ReviewLease +-> lock ReviewQueueEntry +-> lock WorkstreamTask +-> lock the exact Submission.task_assignment_id row +-> lock the exact Submission +-> lock predecessor Review/finding/resolution/evidence rows in stable ID order +-> recompose final facts and consume/evaluate AUTH handle once +-> append immutable Review and submitted findings/resolutions +-> consume ReviewLease and close ReviewQueueEntry +-> CON reviewer operation creates completed_review and evaluates reviewer freeze +-> apply decision branch +-> stage shared audit/outbox rows +-> commit once ``` -### Decision invariants and outcomes - -Every valid decision follows one common append-only path. After AUTH prepares -and locks reviewer authority, REV locks idempotency and the applicable lifecycle -fence, queue, ReviewLease, task, TaskAssignment, Submission, predecessor Review, -and evidence facts. REV recomposes the final context, AUTH evaluates once, and -REV appends one immutable Review plus every submitted immutable finding and -resolution. REV then consumes the ReviewLease and closes the ReviewQueueEntry. -REV next invokes the mandatory CON participant's reviewer operation, which -creates `completed_review`, evaluates the ReviewLease-frozen rule, and appends -any reviewer award. Later revision rounds append a different Review and never -update that history. - -The outcome-specific effects are exact: - -- `accept`: append FinalAcceptance linked to the new Review; set Task to - `accepted`; set TaskAssignment to `completed`; invoke the same CON - participant's submitter operation to create `accepted_submission` from - FinalAcceptance, evaluate the assignment-frozen rule, and append any submitter - award. -- `needs_revision`: set Task to `needs_revision`; keep the TaskAssignment active; - append no FinalAcceptance and invoke no submitter operation. -- `reject`: block the same-task TaskAssignment, then set Task to canonical - `rejected` with the bounded human reason; append no FinalAcceptance and invoke - no submitter operation. No other task or project grant changes. - -CON flushes contribution and award rows and returns typed audit and outbox -inputs. REV stages the shared records, and the request route or service command -commits once. Any failure -rolls back the immutable records, lifecycle state changes, contributions, -awards, audit records, and outbox records together. - -## Application dependency direction - -`reviews` owns review orchestration. Task-owned `TaskReviewEffectsParticipant` -and `TaskSubmissionParticipant` operations accept the caller's `AsyncSession`, -flush without commit, and reuse `TaskRepository`, the existing `Submission`, -version allocation, locked-policy checks, lifecycle guards, audit ordering, and -post-commit dispatch contract. The public task adapter owns commit and dispatch; -review code never imports `TaskRepository` or clones task rules. - -Checker owns a typed review-context reader. CheckerService accepts a typed -review-admission participant implemented by reviews; the durable -`_apply_pre_review_gate_result` transaction invokes it directly and never polls -or recomputes `allow_review`. One explicit `app.composition.review_lifecycle` -constructor assembly supplies these ports to checker routers, task services, -checker execution processes, and review routers. It is not a service locator and has no -fallback constructor. Models may hold database relationships without creating -repository/service import cycles. Import-boundary tests enforce the direction. - -AUTH, ART, CON, shared audit, and shared outbox are likewise injected ports. - -## Joint release control - -Product-surface release and shutdown use one hidden PostgreSQL-canonical -`JointLifecycleReleaseControl`, not shell-script or process-local state. Chunk -12A persists compare-and-set phase history, exposes a typed mandatory mutation -fence, and installs that fence through explicit composition across review -mutations, every task submission, review-queue admission, authority-loss -replacement, every CON-owned fulfillment-obligation root creation, requeue, -successor, and repair writer, and the exact CON-owned fulfillment dispatch and -callback hooks. Every obligation writer acquires the fence before allocating its -monotonic ordinal. It adds no public production route. - -The fence uses matching PostgreSQL advisory locks so a phase transition waits -for admitted mutation transactions and then applies the persisted command-class -matrix. A dedicated `revision_cutover_fenced` phase keeps initial submission and -checker admission open while blocking legacy revision/replacement writers; -shutdown phases separately fence all new admission, drain review commands and -leases, capture the immutable fulfillment-obligation cutoff, drain only -pre-cutoff fulfillment work and completion-only callbacks, and then disable. -`disabled(N) -> pre_activation(N+1)` is the only reactivation edge and -requires a newly reviewed manifest. Every edge and observation is a fresh -Operator-authorized lifecycle command; lease draining reuses fresh -`review.lease.force_release` commands rather than widening lifecycle authority. -No background job replays human authority or advances phase. Timeout leaves phase -unchanged for forward retry and no edge attempts schema downgrade. After 12A's -hidden behavior and the other additive manifests merge, -`WS-AUTH-001-REV-LIFECYCLE` activates -`review.lifecycle.activation.manage` with the other three registered additions. -Chunk 13 then exposes the already-active Operator surface, performs the ordered -product cutover, and proves crash resume and coherent reactivation. The -controller's `pre_activation` state is a REV product-release phase, not AUTH -action availability. - -## Revision flow +The user-confirmed ReviewLease-before-queue order controls this command. Other +commands must publish their own order and may not refer vaguely to a universal +canonical order. Cross-domain rows of the same type lock by ascending primary +key. Database time is read after the relevant locks. No remote ART or external +fulfillment call occurs in the transaction. + +Decision branches are exact: + +- `accept`: append `FinalAcceptance`, set Task `accepted`, complete the exact + reviewed TaskAssignment, invoke CON submitter operation from + `FinalAcceptance`, then stage shared audit/outbox. +- `needs_revision`: invoke the task-owned preparation participant, append the + human-Review-rooted initial preparation, set Task + `needs_revision`, keep the assignment active, and create no FinalAcceptance or + submitter contribution. +- `reject`: block the exact immutable `Submission.task_assignment_id`, set Task + `rejected`, and create no FinalAcceptance or submitter contribution. + +Every branch creates the reviewer `completed_review` ContributionRecord. CON +failure rolls back the Review and all lifecycle effects. External award/points +delivery is post-commit outbox work and cannot roll back acceptance. + +## FinalAcceptance + +`FinalAcceptance` is an immutable internal derived fact created only by the +successful accept branch. It has no public/manual create API and no separate +authorization action. It records project, task, exact Submission, source Review, +accepted submitter, database acceptance time, recording reviewer, and frozen +ReviewPolicy context. PostgreSQL enforces unique task, source Review, and +Submission plus exact same-chain actor/policy lineage. + +Submitter `accepted_submission` contribution consumes FinalAcceptance and never +infers acceptance from `Review.decision`. Reviewer `completed_review` +contribution consumes Review and ReviewLease directly. + +## One Project Guide pipeline + +Project Guide is the single task and review authority. Task stamps one immutable +guide identity triplet when leaving draft. Submission copies the exact task or +prepared-revision context used for that attempt. The reviewer reads the context +stamped on the exact leased Submission and never performs a separate rebase. + +Project Guide activation receives an immutable per-project positive +`activation_sequence`. Version strings are never ordered. A superseded guide +retains its original sequence and provenance if intentionally reactivated. + +Publication and task screening both lock Project first. Publication then locks +candidate/current guide and every exact generation input in a declared stable +type/ID order. Task screening locks Project, Task, and the selected active guide +before stamping. This prevents activation from changing the active generation +between task context selection and commit. + +02A preserves the existing public behavior: draft first activation and the +idempotent repeat of the sole active candidate are allowed, while a superseded +candidate remains denied. After the pure REV contracts and AUTH-PREP/custody +merge, 02A2 adds the hidden prepared-authorized reactivation branch while +`project.guide.activate` remains unavailable. Its reviewed resource manifest +then gates AUTH-12 evaluator/cutover/activation. The bodyless command requires `If-Match` for +the exact current active guide ETag; missing precondition fails with 428 and a +stale/mismatched precondition fails with 412. Therefore a delayed retry cannot +silently replace a newer guide. + +Task guide ID, version, and activation sequence are nullable only together while +draft and complete thereafter. PostgreSQL validates that the triplet names one +same-project guide and rejects every valid-to-valid mutation after allocation. + +## Human Review revision preparation + +Controlled Project Guide rebase is rooted only in an immutable +`Review(needs_revision)` and its exact prior Submission. Checker-caused +`needs_revision` remains a distinct supported upstream remediation path anchored +to its final CheckerRun. It keeps the Task's existing locked context, creates no +Review/ReviewFinding/reviewer contribution, consumes no human ReviewPolicy +revision round/deadline, and does not use D6 close or human finding replay. +Corrected N+1 persists the unique server-derived +`remediation_source_checker_run_id` for that exact predecessor CheckerRun. + +`RevisionContextPreparation` is task-owned and directly references the exact +Review and prior Submission. It forms an immutable non-branching root/successor +chain with one head. The task participant owns guide resolution, Task Context, +and N+1 validation; REV invokes it through typed human-review facts without +importing task/project repositories. ```text -needs_revision Review - -> task remains assigned and enters needs_revision - -> compare prior Submission's stamped guide identity/activation sequence with - the project's currently active Project Guide - -> exact match keeps; any different active identity/sequence rebases forward - or backward; missing, incomplete, or unsafe active context blocks - -> contributor sees prior findings and context delta - -> same submission.create action creates next existing Submission version - -> one SubmissionFindingResponse per unresolved blocking finding - -> response evidence uses verified ArtifactBinding IDs - -> existing finalization/checker spine runs - -> allow_review creates queue entry preferred to prior reviewer - -> preference expiry/decline/invalidation opens entry without resetting age - -> later Review records one FindingResolution per required prior finding +Review(needs_revision) after reviewer CON operation +-> append the Review-rooted initial preparation +-> Task needs_revision -> REV audit/outbox -> review transaction commits once ``` -If the current preparation becomes blocked, revoked, corrupt, or invalid after -project correction, the covered Project Manager invokes the authorized -idempotent repair command with reason and current head ID/digest. The command -locks and revalidates current authority, project context, task/assignment, prior -Submission, episode, and head, then appends exactly one successor. Concurrent -repair or submission resolves to one successor/replay or a stable stale-head -conflict. It never fabricates an episode root. - -Legacy `needs_revision` rows without an originating Review/root remain readable -but cannot advance. Reconciliation reports them; an Operator-only, -evidence-linked closure releases the assignment and closes any queue with stable -terminal reason `legacy_revision_context_unrecoverable`, producing audit/outbox -evidence but no Review, contribution, award, payment, or reputation effect. - -The task pipeline owns the only guide binding. TaskAssignment stores only -`task_id`; it carries no duplicate guide/context field. Each Submission stamps -its resolved context immutably. During `needs_revision`, the Task Context API resolves -the prepared next-attempt context so the submitter sees the guide context selected -from the active guide and frozen during preparation before resubmission. The -reviewer never rebases: it consumes the guide and -task-execution policy context stamped on the single Submission covered by its -active lease. -Preparation freezes exact guide/source-snapshot and task-execution policy IDs, -versions, and hashes; Task Context and Submission N+1 must use that same record. -It never freezes or rebases `ContributionPolicyVersion`. Later guide -activation does not silently drift it, while invalidation requires explicit -re-preparation. - -Activation sequence records chronology but does not overrule the active guide. -When the current active guide differs, preparation records `rebased` plus -`forward` or `backward` transition direction and freezes that active guide's -complete context. A lower sequence is therefore a deliberate backward rebase, -not a manager-repair condition. - -The immutable `RevisionContextPreparation` stores the complete next-attempt -context and digest. Each episode is rooted in the exact `needs_revision` Review; -manager repair appends a non-branching successor with an incremented preparation -sequence. One root per episode, one child per preparation, and same-lineage edge -constraints leave one head. Task Context selects that head before validation and -reads without mutation; an invalid or blocked head never falls back. Revision -submission acknowledges the head ID/digest. Chunk 09A replaces the current -Submission-to-task and CheckerRun-to-task context-equality FKs with direct -project/context integrity and exact Submission/preparation/checker-run bindings, -preserving original task locks and prior Submission rows. - -Normal revision returns to the same assigned contributor. AUTH-13 authority-loss -reconciliation is the exceptional transfer path: it closes the old assignment -without changing history and leaves a durable unassigned obligation. A covered -manager's replacement assignment transaction invokes the review-owned -preparation-transfer participant, which appends one successor bound to the new -target TaskAssignment and the then-authoritative Project Guide context. The -episode keeps the reviewed Submission and its original assignment as immutable -source lineage; Submission N+1 and the submitter contribution-policy freeze use -the replacement target assignment. Partial transfer rolls back assignment and preparation -together. - -History access and artifact-content access are separate. Authorized history may -show every Submission/Review version, findings, responses, resolutions, -guide-version transitions, and bounded audit facts. ART packet read is limited -to the immutable `ReviewPacketManifest` anchored to the active lease and its -versioned Submission: -submission, the queue's exact admitting checker-run, current finding-response evidence, and -required locked-context bindings. No prior-version packet bytes are disclosed -merely because they appear in the chain. - -Historical packet projection is limited to binding ID, relation purpose/kind, -media type, verification/availability state, and required/optional class. It -contains no digest, provider locator/key/CID, signed capability, replica/receipt -detail, service scope, content excerpt, or credential. - -`review.chain.read` is relationship-scoped, not project-reviewer-wide. A current -submitter may read a chain containing a Submission bound to their exact -TaskAssignment; an active reviewer may read the chain anchored to their exact -lease; a prior participating reviewer may read metadata only when they authored -a Review in that chain and still hold the exact current project `reviewer` -grant; and an -Operator/Project Manager needs the explicit inspection permission. The server -resolves these relationships from canonical rows. Arbitrary same-project, -cross-project, revoked, or caller-supplied chain IDs confer no access. Only the -active exact lease can authorize current-packet content. - -Evidence intake is two phase across PostgreSQL and ART. Request-scoped preflight -derives exact scope, then ART ingests and verifies an idempotent unbound candidate -without review locks. In finalization AUTH prepares and locks human authority; -REV locks lease or prepared assignment, Submission, finding/response slot, and -packet lineage; an ART participant locks candidate/admission/binding state; REV -recomposes final facts; AUTH evaluates once; and ART binding plus -`ReviewEvidenceArtifact` relation flush together. Failure after upload can leave only an ART-owned -orphan candidate under ART retention/cleanup; it creates no Workstream binding, -review/submission relation, or lifecycle effect. Decision and submission -transactions validate the canonical binding and authority again. If merged ART -does not expose this candidate/finalize contract, chunk 07 stops for an ART-owned -foundation change rather than adding review-private storage state. - -## Concurrency design - -- After a preliminary request-scoped authority and concealment gate, preflight - remote artifact availability before acquiring review row locks. -- Inside claims and decisions, use database time and targeted `FOR UPDATE` or - atomic conditional updates over canonical rows. -- Every mutation starts with AUTH locking current actor/link/exact grant or - service-matrix authority in AUTH-defined order and returning its opaque, - single-use prepared handle. REV locks feature rows and recomposes final facts, - then calls AUTH before the first feature mutation. AUTH proves exact session, - ActionId, actor-reference kind and ID, idempotency key, canonical request digest, - and current authority; consumes the handle exactly once; evaluates exactly - once; and stages decision evidence. Wrong-binding, forged, serialized, and - caller-constructed attempts do not consume the legitimate unconsumed handle; - stale/already-consumed or concurrent duplicate attempts remain invalid and add - no feature or evidence state. Authority loss follows the evaluated-denial path. -- Before REV-12A, hidden claim order after AUTH is review idempotency, queue, - Task/Assignment/Submission/CheckerRun, then lease and packet-manifest rows; - it has no public or background-command entry point. REV-12A inserts the - lifecycle fence between idempotency and queue before product release. -- Before REV-12A, hidden evidence-finalization order after AUTH is lease or - prepared assignment, Submission, finding/response slot, packet lineage, then - an ART-owned database-local participant locks candidate/admission/binding - state. REV-12A inserts the lifecycle fence before those REV rows before - product release. - REV never imports or directly locks ArtifactBinding/Replica repositories. -- Before REV-12A, hidden decision lock order after AUTH is decision idempotency, - queue, lease, Task, Assignment, Submission, Review predecessor, relevant - finding and resolution rows, and stabilized typed binding facts. REV then - appends the immutable Review, findings, and resolutions; consumes the lease; - and closes the queue. The CON reviewer operation owns the reviewer policy, - contribution, and award locks and writes. REV then applies the decision - branch. For `accept`, REV appends FinalAcceptance, applies the accepted Task and - TaskAssignment effects, and invokes the CON submitter operation. That operation - owns the submitter policy, contribution, and award locks and writes. REV - appends shared audit and outbox rows after the branch. REV-12A inserts the - lifecycle fence between idempotency and queue before REV-13 releases the - surface. -- Revision, administrative, and service commands publish their smaller ordered - row sets in their owning chunk and preserve the same AUTH-first prefix. Rows of - one type lock by ascending primary key. Audit and outbox append after state - locks. The request route or service command commits once. -- Partial unique indexes enforce one active lease per queue entry and reviewer. -- Consume stabilized typed binding facts inside the decision transaction; do - not call a remote provider or import ART persistence while holding locks. -- Map expected constraint races to stable 409 or replay results. -- Timer jobs use deterministic batches with `SKIP LOCKED`; user claims do - not. -- Lazy request-time recovery shares the same transition service as sweeps. -- Retry only database-classified serialization/deadlock failures, with a - bounded attempt count. Real-Postgres tests use independent sessions and - barriers to run both conflicting permutations and inject rollback failures - after each cross-domain participant. -- Project-guide publication adopts the same Project-to-policy lock prefix. - Concurrent publication versus `needs_revision` preparation must freeze one - complete old or new context, never a mixed context, and must not deadlock. -- Checker retry/supersession and queue admission both use the - Submission-to-CheckerRun-to-ReviewQueueEntry portion of this order, so neither - can validate a run and then anchor a different generation. -- Decision idempotency reuses `app.core.hashing.canonical_json_hash`, shared - request/correlation identifiers, and the proven reserve/lock/complete - transaction shape while retaining a review-owned operation/response matrix. - No second JSON canonicalizer or generic idempotency framework is introduced. - -## API design - -Use existing `/api/v1` and structured error conventions. - -- Reviewer current work: active lease, one next offer, or none. -- Administrative queue inspection: complete authorized project view. -- Claim, release, decline preference, decision, context read, and chain read are - separate capabilities. -- Override, force release, and administrative closure require dedicated - permissions, reasons, and audit. Artifact verification recovery consumes the - existing `artifact.verification_job.retry` action through the ART-owned - `ArtifactOperatorRecoveryPort`; WS-REV adds no recovery permission or - execution path. -- Request JSON never supplies authoritative project relationships, provider - paths, CIDs, URLs, or service scopes. -- No reviewer, contributor, compensation, or lifecycle-control router is - included in production `/api/v1` composition before chunk 13. Chunks 05-12A - prove internal service, recovery, fence, and operational contracts while - OpenAPI tests prove those mutations remain absent. - -## Dependency ownership rule - -WS-REV contracts import only merged AUTH, ART, CON, audit, and outbox ports. They -do not list dependency-module wildcards as editable scope. At chunk start, each -chunk replaces any composition locator with an exact existing file path. A -missing typed capability becomes a separately approved dependency-owner chunk; -it is not added opportunistically to a WS-REV PR. - -The pre-WS-CON task/project schema may still contain retired compensation-context -locks when children 02A-02C land. Those are transitional migration inputs only. -WS-CON owns their consumer cutover and schema removal; WS-REV-09A and every -public/final context operate only after that removal and must not replace the -frozen `ContributionPolicyVersion` with a moving current policy. - -## Background processing - -- Preference-expiry sweep -- Lease-expiry sweep -- Reviewer-grant revocation reconciliation -- Queue/lease/review orphan reconciliation -- Review snapshot projection -- Artifact-reference reconciliation through an ART-owned typed port -- Event-driven notifications - -Correctness does not depend only on scheduled delivery. Jobs reload current -PostgreSQL state and are idempotent under duplicate execution. -Protected commands use these exact proposed service rows: - -| Service identity | Exact review action | -|---|---| -| `workstream.review.preference_expiry` | `review.preference_expiry.run` | -| `workstream.review.lease_expiry` | `review.lease_expiry.run` | -| `workstream.review.authority_invalidation_reconciliation` | `review.reconcile.run` | -| `workstream.review.reconciliation` | `review.reconcile.run` | -| `workstream.review.artifact_reference_reconciliation` | `review.artifact_reference.reconcile` | -| `workstream.review.projection` | `review.projection.rebuild` | - -AUTH-09A's merged seven-identity ART set contains none of these identities, and -generic AUTH-09E admission creates none of them. Each requires a reviewed REV -identity-to-ActionId manifest followed by its own AUTH enum, -constraint, provisioning, static-membership, admission, and later action- -activation proof. No service row exists for the -human Operator `review.lifecycle.activation.manage` action, and shared outbox -dispatch retains its separately owned service identity. -All review jobs reuse `run_async_task`, fresh execution engine/session disposal, -stable Celery task IDs, and `sync_task_settings`. The shared outbox dispatcher -is the sole claimant/retry/dead-letter owner; reviews registers only a typed, -deterministic projection handler and records ART receipts. - -## Documentation alignment - -Before runtime code, adopt the reconciled active contract while preserving all -archival inputs and update precedence material. Before final proof, align -glossary, architecture lockdown, reviewer -workflow, revision replay, first-user flows, roles/permissions, templates, and -operator docs with blocking/advisory findings, server-selected offers, -contribution boundaries, controlled rebase, and deferred reputation. - -## Alternatives rejected - -- **Create a new SubmissionVersion table:** duplicates the existing versioned - Submission identity and violates WS-IMP integration rules. -- **Implement temporary local role checks:** creates an authorization bypass - that becomes difficult to remove and violates WS-AUTH precedence. -- **Let reviewers choose from the full queue:** leaks operational data and - enables cherry-picking against the revised contract. -- **Call storage inside the decision transaction:** risks long locks and - ambiguous cross-system atomicity. -- **Emit only ContributionRecordRequested:** conflicts with the merged - flush-only WS-CON atomic participant contract. -- **Derive submitter contribution directly from `Review.decision`:** couples CON - to REV decision semantics and removes the stable one-time acceptance fact. -- **Expose a FinalAcceptance create action or route:** permits acceptance facts - outside the already-authorized review transaction and breaks one-write-path - integrity. -- **Treat revision limits or artifact errors as reject:** fabricates human - judgment and contaminates contributor history. -- **Build frontend concurrently:** violates backend-first sequencing before - lifecycle guards and contracts are stable. +No contributor-readable human-review-caused `needs_revision` state may exist +without one preparation head. Unsafe context creates a blocked head rather than +a missing root. + +Preparation compares the prior Submission guide identity/sequence to the +currently active guide: + +- exact pair: `kept`; +- any different internally consistent active pair: `rebased` with `forward` or + `backward` direction; +- missing, incomplete, revoked, inconsistent, or unsafe pair: `blocked`. + +It freezes guide/source/task-execution policy context, not contribution policy. +Task Context returns the exact head. Submission N+1 acknowledges the head ID and +digest; a later guide activation does not silently change it. + +Human revision requires one immutable response for every unresolved blocking +ReviewFinding and later resolution during review, and returns prefer the prior +reviewer. Checker remediation shows contributor-safe checker messages/fixes, +creates no fake ReviewFinding response/resolution, preserves current guide/task +context, and returns to ordinary open routing after corrected checker admission. + +## Revision limits and deadlines + +The exact human Review revision-round counting source, deadline anchor, and +boundary remain a human-owned product decision before 09A1. They are not +inferred from checker retries, task SLA, current time, or archival examples. +Whatever values are approved freeze on the Review-rooted episode and use +database time. At exhaustion, Task remains `needs_revision` and assignment +active; context repair cannot bypass exhaustion, and only exact D6 close may +terminate the human revision episode. No synthetic reject is created. + +An exact final CheckerRun proves a checker-remediation task is not a rootless +human revision. Only state that claims human Review revision but has no +unambiguous originating Review/preparation is +`legacy_revision_context_unrecoverable`; migration never fabricates a Review. + +## Artifact boundary + +REV consumes typed ART capabilities only. It never receives ArtifactStore, +provider adapters/references, scratch paths, or raw repository access. + +- Queue admission uses stabilized submission/checker facts from exact ART-owned + cutover contracts. +- Claim creates a normalized immutable ReviewPacketManifest and item rows only + after ART defines exact packet membership relations. JSON/opaque ID sets are + prohibited. +- Context content reads require an active exact lease for the exact Submission. + History is metadata-only; prior, sibling, later, expired, and consumed leases + grant no byte access. +- Reviewer finding evidence uses an ART-owned candidate/finalize port and an + exact binding service action. Revision response evidence is owned only by the + human Review revision chunk. +- Core Review/CON transactions copy stabilized digest lineage and make no ART + call. + +ART currently has no scheduled owner chunks for packet read, review evidence, +or server-derived Submission artifact digest. Those are hard blockers. REV may +record required capability shapes but must not invent ART chunk IDs or start ART +work. + +## Contribution and outbox boundary + +CON owns ContributionPolicyVersion persistence, TaskAssignment/ReviewLease +freezes, ContributionRecord and award persistence, delivery records, and the +two-operation flush-only decision participant. REV owns Review, +FinalAcceptance, lifecycle orchestration, shared audit/outbox staging, and the +single commit. + +Exact merged CON gates are consumed by chunk ID, PR, SHA, migration head, typed +symbol, and tests. `WS-CON-001-03B` precedes the ReviewLease policy FK; +`WS-CON-001-02A` and `02C` precede Review/FinalAcceptance shared outbox/audit +persistence; `WS-CON-001-06` precedes claim freeze; `WS-CON-001-03C` and `07` +precede the first canonical decision commit. Proposed status is not readiness. + +## Authorization boundary + +Reads use request-scoped AUTH `require`; protected mutations use AUTH's exact +merged prepared protocol. REV does not query grants, register actions, provision +service identities, integrate evaluators, or change availability. + +Every external AUTH edge must name the owner chunk and prove merged PR/SHA, +typed actor/action/resource contracts, static service rows where applicable, +and denial/race tests. Placeholder names remain fail-closed planning labels, +not executable dependencies. All actions remain unavailable until AUTH merges +the matching feature-gated activation after hidden behavior. + +## Persistence and immutability + +`Submission` remains the only versioned submission entity. Submission and +Review predecessor chains are exact N-1 and non-branching. Human identity fields +use canonical human ActorProfile IDs after the AUTH foundation. Service/system +actors remain explicitly typed and cannot occupy contributor/reviewer fields. + +Evidence binding identity and scope are immutable. Pre-decision evidence uses +an immutable slot/binding relation; attachment to a finding/response is a +separately appended immutable relation in the Review or submission transaction. +No row described as immutable is later updated set-once. + +PostgreSQL owns uniqueness, XOR, same-chain, actor-kind, status/provenance, +immutability, and deferred cross-row integrity. Services validate for useful +errors but do not substitute for database enforcement. + +## Chunk strategy + +Merged parent references remain as non-executable split records. Only 02A has a +current executable contract after this refresh. Every later child is proposed +and must receive a current-main chunk contract, risk routing, plan review, +explicit start, and exact owner evidence before code. + +The detailed order is maintained in `CHUNK_MAP.md`. The important boundaries +are: + +- 02A establishes chronology/task locking. 02A2 lands after 08 and adds hidden + prepared-authorized, stale-retry-safe reactivation before AUTH-12 activation. +- 03A queue/lease base schema; 03B normalized packet manifest after ART contract. +- 04A immutable review-chain persistence; 04B FinalAcceptance/task linkage and + shared audit/outbox persistence primitives. +- 05A online checker admission; 05B server-selected reviewer/admin reads. + Historical admission classification/scan belongs to 11C reconciliation. +- 06A claim/freeze; 06B release/decline/preferences; 06C expiry/lazy recovery. +- 07A lease-bounded context; 07B reviewer finding evidence only. +- 08 pure decision schemas, validation, and typed participant inputs only. +- 09A1 Review-rooted preparation schema; 09A2 preparation resolver and Task + Context; 09A3 human response evidence; 09A4 internal prepared human N+1 plus + the exact source XOR that retains 02C's immutable checker-remediation + `remediation_source_checker_run_id`; + 09A5 replacement-assignment transfer; 09B replay/resolution/return routing. +- 10 first hidden canonical Review/FinalAcceptance/CON transaction. +- 11A privileged queue/lease commands; 11B PM repair/D6 close; 11C + reconciliation persistence/jobs; 11D true-legacy close and ART delegation. +- 12P1 projection; 12P2 projection/artifact reconciliation jobs; 12P3 reads, + notifications, metrics, and drain observation. +- 12A1-12A4 separately build hidden release controller, REV fences, CON fences, + and Operator transition/drain recovery. +- 13A preflight/manifests/drill harness; 13B pre-release docs/generated preparation; + 13C sole product router registration and final HTTP proof. + +## Release control + +Persisted lifecycle phase controls whether already-registered commands may +execute. It does not dynamically unregister FastAPI routes or rewrite AUTH +action/static-service catalogues. Scheduler shutdown is an operational action; +database fences remain the correctness boundary. + +Product reads and mutation classes are defined separately. A disabled phase may +allow bounded readiness/administrative reads while denying product mutations. +Forward reactivation reuses static router registration and AUTH mappings after +phase, drain, service, and dependency checks pass. + +Checker needs-revision routing is one server-derived checker-completion class: +it is allowed with checker completion through `revision_cutover_fenced` and +denied from `admission_fenced`. It creates only CheckerRun-rooted task state, +audit, and outbox under the existing locked task context. Human Review +preparation is an internal consequence of leased `review.decision` and shares +that completion class; it is never an independently phase-enabled command. + +Chunk 13C is the only product router-registration and active-release-document +point. Earlier chunks keep routes absent, build hidden composition, add reusable +drill scenarios, and may update only planned/pre-release documentation. ## Verification strategy -Every chunk runs focused tests and lint. Every runtime chunk also runs a fresh -isolated real-PostgreSQL coverage invocation; a stale `.coverage` file is never -accepted as evidence. The runner requires a disposable administrative database -URL through `WORKSTREAM_TEST_ADMIN_DATABASE_URL`, creates independent databases -for concurrent test processes, and fails rather than silently falling back. Artifact -chunks use provider-neutral fakes plus LocalStorage and MinIO conformance as -applicable. The common runtime evidence is: +Every runtime chunk must run focused tests, Ruff, real-PostgreSQL isolated full +suite at the repository 78 percent floor, and at least 90 percent coverage for +materially changed backend subsystems. Migration chunks additionally prove one +head, preflight, upgrade, downgrade/re-upgrade where safe, protected-row refusal, +transactional failure behavior, and direct-SQL constraints. -```text -(metadata_dir="$(mktemp -d)" && trap 'rm -rf "$metadata_dir"' EXIT && (cd backend && WORKSTREAM_TEST_ADMIN_DATABASE_URL=postgresql+asyncpg://workstream:workstream@localhost:5433/postgres .venv/bin/python scripts/run_isolated_tests.py --metadata-json "$metadata_dir/result.json" --timeout-seconds 12600 -- .venv/bin/python -m pytest -q --ignore=tests/test_isolated_database_runner.py --cov=app --cov-report=term-missing --cov-fail-under=78)) -cd backend && coverage report --include='app/modules/reviews/*,app/workers/reviews.py' --precision=2 --fail-under=90 -cd backend && ruff check app tests scripts -python3 scripts/check_internal_review_evidence.py -python3 scripts/check_markdown_links.py -python3 scripts/check_stale_workstream_wording.py -``` +Every chunk runs stale Workstream/AUTH/ART/REV wording scans applicable on +current main, Markdown links, `git diff --check`, merge-intent validation through +agent gates, and required internal reviewer fanout. Test changes may not weaken, +skip, or rewrite existing checker-caused revision coverage. + +## Stop rule -Each contract's focused test command is diagnostic evidence in addition to, -not instead of, this common runtime evidence. New/materially changed review -code remains at or above 90 percent and repository-wide coverage remains at or -above 78 percent on the same fresh run. - -The final live proof covers first submit, needs revision, controlled -continuation, preferred return, preference expiry/takeover, accept with exactly -one FinalAcceptance, reject, -lease expiry, revocation during lease, evidence attachment, provider outage, -integrity failure, recovery, atomicity across FinalAcceptance and contributions, -and projection retry. -The versioned conformance matrix maps specification sections 25.1-25.9 to the -owning chunk, executable tests, live drill cases, and retained evidence. - -## Delivery rule - -Only one WS-REV chunk may be active. A chunk begins from current trusted main, -refreshes dependency discovery, runs required internal review, receives external -and human approval, merges, records automated memory, and stops. Cross-initiative -gates do not authorize starting the next WS-REV chunk automatically. +`WS-REV-001-PLAN2` changes planning/specification only. After it merges, +automated memory names `WS-REV-001-02A` with an explicit-start gate. Runtime +starts only after the exact AUTH contributor foundation and all 02A-specific +conditions merge and the user explicitly starts 02A. No chunk starts its +successor automatically. diff --git a/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/REVIEW_LOG.md b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/REVIEW_LOG.md index 0310f3edc..dd5ff917e 100644 --- a/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/REVIEW_LOG.md +++ b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/REVIEW_LOG.md @@ -915,3 +915,56 @@ authorization/Workstream/review/artifact scanners, Markdown links, 87 agent gates, diff integrity, and the schema-v2 merge-intent validator pass. Remaining gates are the dependency-owned AUTH merges, a separate 02A start, and the two human-owned duration defaults before 02B. + +## WS-REV-001-PLAN2 Runtime Readiness Reconciliation - 2026-07-18 + +The user authorized a complete planning-only refresh while REV runtime remained +blocked on AUTH's contributor-field foundation. The refresh contracts the older +initiative, splits oversized runtime parents, separates pure decision contracts +from canonical transaction composition, preserves accept-only FinalAcceptance, +and keeps adjudication disabled in v0.1. + +Internal review found and repaired ambiguous checker/human revision wording, a +missing immutable causal CheckerRun relation, stale successor and merge-intent +identity, incomplete Project-first writer locking, future focused-coverage/CI +scope, and AUTH-14 source-constraint ownership drift. Final planning assigns +server-derived `remediation_source_checker_run_id` to 02C and the final +human/checker source XOR to 09A4. + +The branch rebased cleanly onto AUTH-09D-A PR #148 at trusted main +`99ae4c963e53f317175dcb308b9e47c93ccf19ed`. The final candidate records sole +migration head `0026_actor_profile_lifecycle`, exact merged ActorProfile +lifecycle proof, the unchanged retired task contributor fields, and the live +AUTH catalogue split of 15 active / 50 planned. All 24 REV dependencies remain +unavailable, and the separate contributor foundation is still the only +unmerged AUTH runtime gate for 02A. + +Candidate `f6c41d5a42ec598b513b25b4677f6ac725645920` passes senior engineering, +QA/test, security/auth, product/ops, architecture, docs, reuse/dedup, test delta, +and CI-integrity review. Diff integrity, all four stale scanners, Markdown links, +87 agent gates, Alembic single-head proof, catalogue arithmetic, changed scope, +and the schema-v2 PLAN2 merge intent pass. No runtime, migration, test, workflow, +frozen `docs/reference_specs/` source, or cross-owner file changed. PLAN2 may publish; +02A remains stopped until its exact contributor foundation merges and the user +explicitly starts it. + +## WS-REV-001-PLAN2 External Review Repair - 2026-07-18 + +CodeRabbit reviewed PR #150 and posted six actionable planning findings. The +repair makes 03B the sole ReviewPacketManifest/item schema, migration, +repository, and persistence-test owner while 06A consumes that contract at +claim time; restores explicit executable verification commands for 08; and +makes 09A2 deliver the task-owned flush-only preparation participant consumed by +10 without widening 10 into task-owned files. + +The repair also excludes every exact CheckerRun-rooted remediation from legacy +closure, classifies `docs/spec_review_lifecycle.md` accurately as one of PLAN2's +four active product documents while preserving the frozen `docs/reference_specs/` +boundary, and assigns release-controller implementation only to 12A1 through +12A4. AUTH-14 wording now consistently names public request acknowledgement, +authorization cutover, and activation. No runtime, migration, test, workflow, +AUTH/ART/CON owner plan, or frozen reference source changed. + +The repaired candidate requires fresh exact-SHA internal review, deterministic +gates, evidence rebinding, push, CodeRabbit re-review, and GitHub CI before PR +#150 is ready for the user's merge decision. diff --git a/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/RISKS.md b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/RISKS.md index c8fca7ad5..cb4fc9dba 100644 --- a/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/RISKS.md +++ b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/RISKS.md @@ -21,23 +21,23 @@ | R17 | Operational timers rely on Celery delivery or web-server time for correctness | High | Database-time transitions, lazy recovery on requests, idempotent sweeps, and reconciliation. | | R18 | Finding text or artifact details leak into logs/metrics | High | Bounded audit projections, no raw content/provider secrets, cardinality controls, and security review. | | R19 | Half-built public routes expose claims or private context before recovery and operations are coherent | Critical | Keep lifecycle routers absent through 12A; AUTH activates exact actions only after hidden behavior, and 13 exposes the complete product set after joint readiness. | -| R20 | Cross-domain transactions deadlock under claim, decision, revocation, expiry, or reconciliation races | Critical | Freeze one AUTH-to-WS-CON lock order, sort same-type rows, use bounded database-classified retries, and test both permutations with independent Postgres sessions. | +| R20 | Cross-domain transactions deadlock under claim, decision, revocation, expiry, or reconciliation races | Critical | Publish an exact AUTH-first command-specific lock order, sort same-type rows, use bounded database-classified retries, and test both permutations with independent Postgres sessions. | | R21 | Historical submissions are indiscriminately queued without current checker/artifact proof | High | No queue backfill in schema migration; later audited admission is limited to unambiguous latest eligible rows and fails closed otherwise. | | R22 | Review duplicates task submission/checker/audit/outbox/job mechanics or creates repository cycles | High | Use caller-transaction task participants, typed checker admission/context ports, the shared audit ledger/dispatcher, canonical hashing, one explicit composition assembly, and existing Celery/session utilities with import-boundary tests. | -| R23 | Rebased submissions pass service checks but fail or drift at checker, queue, preparation, or contribution constraints | Critical | Replace task-equality FKs as one reviewed migration, bind checkers to Submission context, root each non-branching preparation episode in its Review, persist the exact admitting CheckerRun, and derive WS-CON only from constrained immutable lineage. | -| R24 | Invalid preparation or legacy needs_revision state strands work indefinitely or tempts synthetic history repair | High | Provide only a reason-bound successor repair for valid episodes, fail closed on legacy missing roots, and use an Operator-only evidence-linked terminal closure that creates no Review or contribution. | +| R23 | Rebased submissions pass service checks but fail or drift at checker, queue, preparation, or contribution constraints | Critical | Replace task-equality FKs as one reviewed migration, bind checkers to Submission context, root each non-branching preparation episode in its exact human Review, persist the admitting CheckerRun, preserve distinct checker remediation context, and derive WS-CON only from constrained immutable lineage. | +| R24 | Invalid preparation or truly rootless human needs_revision state strands work indefinitely or tempts synthetic history repair | High | Keep exact CheckerRun remediation distinct from legacy, provide reason-bound successor repair for valid human episodes, fail closed on ambiguous human roots, and reserve Operator evidence-linked closure for genuinely unrecoverable history. | | R25 | UUID-shaped external, legacy, or service identity is stored as a human reviewer/submitter | Critical | Require canonical `ActorProfile.id` FKs, human-kind and current-status revalidation, explicit actor-reference kinds in audit, and direct-SQL/cross-kind tests. | | R26 | Forward/backward guide rebase silently changes compensation | Critical | Keep compensation outside preparation/Submission/checker context; freeze submitter terms on TaskAssignment and reviewer terms per ReviewLease; test both rebase directions. | | R27 | Contribution lineage trusts caller `package_hash` or invents a parallel digest | Critical | Require the ART submission/checker cutover to persist server-derived verified `Submission.artifact_hash`; copy it to `ContributionRecord.artifact_hash` without an ART call. | | R28 | Review routes release without the complete CON participant or from a stale manifest | Critical | Consume the exact merged core CON readiness manifest; CON owns its routes, while REV-13 exposes only REV surfaces after all required actions are AUTH-active. | | R29 | AUTH authority-loss reassignment strands a Review-rooted revision episode or rewrites source attribution | Critical | Preserve reviewed-assignment lineage, append one atomic preparation successor for the replacement target assignment, deny the old contributor, and race replacement against repair/submission. | -| R30 | A hidden preparation migration blocks the still-public legacy revision route before coherent activation | Critical | Land nullable/conditional preparation schema in REV-09A, then require amended AUTH-14 to install the global `NOT VALID` rule and replace the legacy submission branch while `submission.create` remains unavailable; REV-13 verifies and exposes the merged cutover and proves no raw IntegrityError. | -| R31 | Joint activation or shutdown partially fences review while task replacement or compensation delivery keeps mutating | Critical | Land one hidden persisted release controller in 12A, require shared/exclusive PostgreSQL advisory-lock fences across every named mutation class, capture an immutable CON-owned fulfillment-obligation cutoff after completion commands drain, allow only pre-cutoff completion work during delivery drain, resume from durable phase after crash, and use forward recovery rather than downgrade after protected rows exist. | +| R30 | A hidden preparation migration blocks the still-public legacy revision route before coherent activation | Critical | REV-09A4 installs, backfills, validates, and enforces the hidden Submission source-XOR rule while `submission.create` remains unavailable. Amended AUTH-14 owns only public request acknowledgement, authorization cutover, and activation; REV-13 verifies and exposes the merged cutover and proves no raw IntegrityError. | +| R31 | Joint activation or shutdown partially fences review while task replacement or compensation delivery keeps mutating | Critical | Land one hidden persisted release controller through 12A1-12A4 while 12A remains non-executable, require shared/exclusive PostgreSQL advisory-lock fences across every named mutation class, capture an immutable CON-owned fulfillment-obligation cutoff after completion commands drain, allow only pre-cutoff completion work during delivery drain, resume from durable phase after crash, and use forward recovery rather than downgrade after protected rows exist. | | R32 | AUTH dependency teardown regresses and silently commits feature-owned review mutations | Critical | Preserve merged AUTH-08 rollback-only teardown and require the request route or service command to own the explicit commit plus rollback fault injection in every consumer chunk. | | R33 | Authorization decision-evidence persistence failure regresses to an unstructured 500 | High | Preserve merged AUTH-08 typed retryable 503 mapping and test that no review mutation or partial evidence survives. | | R34 | A later AUTH or REV route change leaves canonical actor verification timestamps stale | Medium | Preserve AUTH-08's route-owned database-time semantics and successful/denied/failed existing-actor regression proof for both canonical timestamps. | | R35 | REV or ART becomes a second action-availability writer | Critical | Enforce registration -> hidden behavior -> AUTH activation -> joint release; scan every chunk for feature-owned activation wording and verify separate AUTH manifests. | -| R36 | Hard-coded catalogue totals omit independently added actions | High | Treat 57/9/48 only as AUTH-08 history, 65/9/56 only as AUTH-09A history, and 65/10/55 only as AUTH-09B history; current trusted main after AUTH-09C is 65/12/53. Derive exact counts/SHA at each registration and activation gate, with the four REV proposals and ART binding action separately inventoried. | +| R36 | Hard-coded catalogue totals omit independently added actions | High | Treat 57/9/48 only as AUTH-08 history, 65/9/56 only as AUTH-09A history, 65/10/55 only as AUTH-09B history, and 65/12/53 only as AUTH-09C history; current trusted main after AUTH-09D-A is 65/15/50. Derive exact counts/SHA at each registration and activation gate, with the four REV proposals and ART binding action separately inventoried. | | R37 | A generic service identity or human Operator executes protected review jobs | Critical | Use distinct fixed service ActorProfiles/static rows through AUTH-09E and prove cross-service plus human/service denial. | | R38 | Reviewer revocation removes submitter/adjudicator authority or vice versa | Critical | Consume exact role-specific invalidation; REV mutates only review preference/lease/queue state and tests every independent-revocation direction. | | R39 | Evidence finalization partially binds bytes after authority or lineage drift | Critical | Provider I/O precedes AUTH -> REV -> ART database finalization; one final AUTH evaluation; only an ART orphan candidate may survive failure. | @@ -55,3 +55,10 @@ | R51 | Review preference or lease duration is invented from unrelated SLA data | High | Require two explicit positive human-approved defaults before 02B; never infer either from `sla_hours`, current timestamps, or archival examples. | | R52 | Dormant terminal schema accidentally enables a human outcome without Review | Critical | 02B defines storage/constants only, adds no terminal transition edges or reject Review FK, and proves checker/limit/deadline paths create no terminal Task/Assignment or downstream effect. | | R53 | Finalized Submission immutability blocks later ART-owned verified digest publication | High | 02C defines the finalization guard with an explicit future set-once `artifact_hash` exception owned by the approved ART/task amendment; it never permits overwrite or caller digest promotion. | +| R54 | Supported checker-caused revision is misclassified as legacy or silently expanded into human rebase policy because no Review exists | Critical | Preserve its exact CheckerRun-rooted task-context path, exclude human preparation/limits/D6, preserve the existing checker regression, and create no synthetic Review. | +| R55 | Concurrent submissions consume N and N+1 without an intervening revision origin | Critical | Persist unique immutable `remediation_source_checker_run_id` for checker N+1 and the preparation ID for human N+1; lock/revalidate the exact source and enforce the final XOR/direct-SQL constraints. Loser replays exactly or conflicts; N+2 requires a later committed human Review/preparation or final needs-revision CheckerRun. | +| R56 | Superseded guide reactivation ships under legacy role checks or an already-active incomplete AUTH evaluator | Critical | 02A keeps public denial; 02A2 builds hidden prepared/If-Match behavior while the action is unavailable, then its full manifest gates AUTH-12 cutover/activation. | +| R57 | Persisted release phase is mistaken for router/action/service deactivation | Critical | Keep static routing and AUTH membership owner-controlled; deny execution through mandatory phase fences, separate read/mutation classes and scheduler runbooks, and prove crash-resumable forward transitions. | +| R58 | Checker completion is allowed during cutover but checker needs-revision routing is phase-denied | Critical | Classify checker needs-revision routing with checker completion through `revision_cutover_fenced`; deny both from admission fencing, and test atomic rollback in every phase. | +| R59 | AUTH/ART/CON prose placeholders create circular or fictional dependencies | Critical | Require exact owner chunk ID, merged PR/SHA, migration head, typed symbol/manifest, and tests; distinguish contract amendment from later runtime activation/cutover. | +| R60 | Oversized parent contract hides multiple L1 migrations, commands, services, and release boundaries | High | Treat the parent as non-executable and implement only the reviewed unique child sequence in CHUNK_MAP. | diff --git a/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/SOURCE_MANIFEST.md b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/SOURCE_MANIFEST.md index de639876e..9b794ed8c 100644 --- a/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/SOURCE_MANIFEST.md +++ b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/SOURCE_MANIFEST.md @@ -52,9 +52,9 @@ On 2026-07-17 the human explicitly amended the merged REV/CON handoff for v0.1: work. This explicit amendment supersedes conflicting contribution-trigger and -audit/outbox-staging wording in the original merged handoff. This planning PR -updates the shared handoff text; the corresponding CON owner changes must still -merge before any runtime REV consumer starts. +audit/outbox-staging wording in the original merged handoff. The merged handoff +already records this boundary; this planning PR does not edit it. Corresponding +CON runtime changes must still merge before any REV consumer starts. ## Merged AUTH reconciliation authority @@ -94,7 +94,7 @@ controlled route may provision only identities already present in AUTH's closed registry. It adds none of REV's six identities, admits no service token, and activates no review action; all 24 REV dependencies remain unavailable. -AUTH-09C PR #146 later merged to current trusted main +AUTH-09C PR #146 later merged as an ancestor of current trusted main `0ffdabf3dbb77e4e066683fde1a095d744ff1f43` from final branch head `a3d6babc`. It keeps 74 PermissionIds and 65 ActionIds while activating only `actor.profile.read` and `actor.identity_link.read`, moving the split to 12 @@ -111,7 +111,7 @@ dependencies remain unavailable. ## Merged CON planning authority -WS-CON-001 planning PR #142 merged to current main +WS-CON-001 planning PR #142 merged as an ancestor of current main `a947b8693a97bdb94c9dc63202a51e197834d613` from final branch head `4b13c3ee28ecddd7c92be70ad2059c130604f9d1`. Its PLAN3 reconciliation is now the repository-owned CON planning authority. It confirms: @@ -129,7 +129,7 @@ chunks remain proposed/inactive and continue to gate REV implementation. ## Merged CON canonical contract -CON-01 PR #144 later merged to current trusted main +CON-01 PR #144 later merged as an ancestor of current trusted main `e118e33afcd89b8ee78ecfc8f0e0d585ae0ee4b9`. It publishes `docs/spec_contribution_compensation.md` and ADR 0016 as repository-owned CON authority. It preserves the ordered reviewer and accept-only submitter @@ -209,6 +209,38 @@ Planning merged through PR #128 at trusted main `docs/spec_review_lifecycle.md` the active normative contract while the four archival files remain literal-hash and trusted-base-diff protected inputs. +## Parent 02 merge and planning-refresh base + +Parent `WS-REV-001-02` merged through PR #147 at trusted main +`f18b620932bb257dc1dc355bc0504271813dc6b1`. It is a non-executable split +record. `WS-REV-001-PLAN2` refreshes planning/specification only from that +base and was rebased after AUTH-09D-A merged. + +AUTH-09D-A merged through PR #148 at trusted main +`99ae4c963e53f317175dcb308b9e47c93ccf19ed` from reviewed branch head +`9c5ef8a1feffd6324acfd947e67042921955320b`. Its exact migration +`0026_actor_profile_lifecycle`, ActorProfile lifecycle fields/constraints, +direct-SQL history guards, service behavior, and tests are merged authority. + +The following are explicitly unmerged discovery evidence and not authority: + +- the human-directed but unnamed AUTH contributor/canonical-human foundation; +- any unmerged CON outbox work that still claims the now-consumed `0026` number. + +Trusted main has the single head `0026_actor_profile_lifecycle`, retains both +retired task contributor storage names, and contains no merged contributor +foundation. +Current Submission storage also has no immutable causal field for the exact +needs-revision CheckerRun that admits a corrected checker-remediation N+1. 02C +owns the planned server-derived `remediation_source_checker_run_id`, exact +backfill, PostgreSQL lineage/uniqueness/immutability, and currentness locking; +09A4 later adds the human preparation binding and final source XOR. AUTH-14 must +own only public request acknowledgement, authorization cutover, and activation +for that path after an exact contract amendment, not these REV lifecycle +columns or constraints. +Every runtime gate must replace worktree prose with exact owner chunk ID, +merged PR/SHA, migration head, typed symbol/manifest, and tests. + The active contract, its four-action registration manifest, and its six-service identity manifest become immutable inputs for downstream AUTH gates only after this chunk is reviewed and merged. Until their owning chunks and AUTH activation @@ -219,4 +251,7 @@ After the initial exact-SHA review, the branch pulled merged CON PR #142 at archive-integrity proofs remain fixed. The branch then pulled merged AUTH-09B PR #143 at `053242b90d927ace3fab92eeca72da27a61cecec` and merged CON-01 PR #144 at `e118e33afcd89b8ee78ecfc8f0e0d585ae0ee4b9`; final PR scope and -exact-SHA review use the newest merged-main boundary. +exact-SHA review use the newest merged-main boundary. The branch then rebased +cleanly onto merged AUTH-09D-A PR #148 at +`99ae4c963e53f317175dcb308b9e47c93ccf19ed`; the post-rebase review base is +that trusted commit. 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 7f346f7dc..31657818e 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 @@ -2,157 +2,93 @@ ## Current status -`WS-REV-001-01` merged through PR #145 at trusted main -`b2b9016d5fee33ddca40882c97620a178d8e52f0`. The user explicitly started -parent `WS-REV-001-02` on 2026-07-18. Required L1 plan review failed the -combined implementation boundary and required a 02A/02B/02C split before any -runtime or migration edit. - -REV may continue planning and test design only. AUTH currently owns migration -`0026` for AUTH-09D-A profile lifecycle. After AUTH-09D-A merges, AUTH owns the -next-priority, separately reviewed contributor-field foundation from the -then-current migration head. That foundation must clean-cut both retired -task-subsystem contributor-identity fields to `contributor_id`, preserve -existing behavior, establish -database-backed canonical-human ActorProfile lineage, and provide an exact -merged PR/SHA. REV runtime remains blocked until that merge. - -The parent 02 contract is now non-executable. Planning defines 02A guide -activation chronology/publication locking, 02B immutable policy and dormant -task/assignment lifecycle compatibility, and 02C Submission -attribution/context/lineage. No backend model, service, migration, or persistence -test has changed. - -Planning candidate `0292825a52f884f42d82e1522637f2ff2bf4bb7a` passed the -repaired circuit breaker, all required internal reviewer tracks, mandatory -contract scanners, Markdown links, 87 agent gates, and schema-v2 merge-intent -validation. It is planning-publication ready, not runtime-ready. - -## Chunk 01 merge history - -While Chunk 01 was under review, CON planning PR #142 merged to main at -`a947b8693a97bdb94c9dc63202a51e197834d613`. The branch pulled that merge and -reconciled its shared active documents. PR #142 changes planning/contracts only; -no CON runtime behavior became active. - -AUTH-09B PR #143 then merged to main at -`053242b90d927ace3fab92eeca72da27a61cecec`. The branch pulled it cleanly; -only the shared agent-gate test file overlapped. AUTH-09B activates controlled -`actor.service.provision`, not service admission or any REV action. - -CON-01 PR #144 then merged to main at -`e118e33afcd89b8ee78ecfc8f0e0d585ae0ee4b9`. The branch reconciled its -`architecture_data_model.md` overlap by retaining the exact shared -FinalAcceptance fields and ActorProfile/ReviewPolicy lineage. CON-01 publishes -the active CON contract and ADR 0016 but changes no runtime. - -ART-02A3 PR #141 then merged to main at -`a10d9018007d2e847b4870e9b26cbd24e24c7bb4`. It atomically removes -ArtifactStore v1 and activates the byte-only ART v2 LocalStorage clean cut plus -typed product capability composition. It does not implement S3/MinIO, -submission/checker artifact cutovers, lease-scoped review packet reads, or -review-evidence candidate/finalize behavior. - -AUTH-09C PR #146 then merged to main at -`0ffdabf3dbb77e4e066683fde1a095d744ff1f43`. The sole REV conflict was in the -shared agent-gate lifecycle assertions. The resolution retains REV's -branch-sensitive ART proof while adopting main's merged ART-02A3 and AUTH-09C -state. AUTH-09C activates only two bounded actor-registry reads and no REV -action. - -Chunk 01 adopts `docs/spec_review_lifecycle.md` as the active normative -contract, preserves the supplied WS-REV and WS-IMP archival Markdown/PDF bytes, -reconciles active documentation, and adds a fail-closed stale review-contract -gate. It changes no backend, migration, AUTH, ART, or CON runtime code. - -## Dependency state - -- AUTH-08 remains the historical 74-PermissionId, 57-ActionId snapshot: 9 - active and 48 planned. Current trusted main after AUTH-09C has 74 - PermissionIds and 65 ActionIds: 12 active and 53 planned. -- All 24 REV lifecycle action dependencies remain unavailable: planned - `submission.create`, 19 planned review actions, and four approved but - unregistered REV additions. The separately proposed ART evidence-binding - service action is not included in those 24. -- AUTH owns registration, service identity admission, evaluator integration, - activation, and prepared-mutation authority. REV publishes immutable feature - manifests and hidden behavior evidence; it does not activate actions. -- Merged AUTH-09B supplies controlled provisioning only for identities already - in AUTH's closed registry. None of REV's six identities exists yet; their - exact extensions, provisioning, AUTH-09E admission, and feature activation - remain downstream gates. -- Merged AUTH-09C supplies only bounded system-authorized actor-profile and - identity-link reads. It adds no REV identity or action and changes none of - REV's lifecycle, lease, artifact, or contribution boundaries. -- Merged ART-02A3 supplies the active byte-only ART v2 store beneath typed - product capabilities. Review still consumes only later approved packet-read - and evidence candidate/finalize ports; it never imports the raw byte store, - ART scratch/source types, a concrete provider, or repository APIs. -- Merged CON-01 publishes the canonical frozen-policy, ContributionRecord, - FinalAcceptance trigger, award, and ordered two-operation participant - contracts. It implements none of them. -- Later CON chunks must provide frozen contribution-policy persistence and the - ordered flush-only participant before a canonical Review can commit. Every - valid Review creates reviewer contribution; only an accept-created - FinalAcceptance creates submitter contribution. -- AUTH-09D-A is in progress and owns migration `0026`. No AUTH contributor - foundation PR/SHA or migration exists on this REV base. REV assigns no - migration number and performs no runtime preparation against retired - contributor-identity storage. -- After AUTH-09D-A, AUTH must merge the bounded contributor-field foundation. - ART submission commitment/packet-read contracts, CON - persistence/participant contracts, and the remaining per-child gates stay - external prerequisites exactly as listed in `CHUNK_MAP.md`. -- Two product values remain human-owned before 02B implementation: - `review_preference_window_seconds` and - `review_lease_duration_seconds`. Neither is inferred from `sla_hours`. - -## Canonical lifecycle boundary - -- Every valid reviewer decision appends an immutable Review. Submitted findings - and later finding resolutions are also immutable history. -- `accept` additionally creates one internal immutable FinalAcceptance. The - submitter `accepted_submission` contribution consumes that fact rather than - inferring acceptance from `Review.decision`. -- `needs_revision` prepares a controlled next-attempt context. An exact match - with the currently active Project Guide identity and activation sequence keeps - context; any different internally consistent active pair rebases forward or - backward; missing or inconsistent active context blocks preparation. -- The reviewer always uses the Project Guide context stamped on the exact leased - Submission and never performs a separate review-guide rebase. -- `reject` blocks the submitter assignment and sets the Task to `rejected`. - Approved administrative revision-obligation closure uses `cancelled` with a - bounded reason. -- Adjudication remains disabled and unimplemented in v0.1. Reputation mutation - is deferred to its owning future initiative. Interfaces retain typed lineage - so either can be added later without changing the immutable Review contract. - -## Chunk 01 evidence state - -Candidate `6da45b2765de68dc5a0628024bdfeacb98d1ea85` passed all nine required -tracks against trusted current main -`053242b90d927ace3fab92eeca72da27a61cecec`: senior engineering, QA/test, -security/auth, product/ops, architecture, docs, reuse/dedup, test delta, and CI -integrity. All 80 current-main agent tests and seven REV additions are retained; -87 agent-gate tests and the deterministic contract gates pass. - -Chunk 01 was published and merged as PR #145. CodeRabbit's nine actionable findings and one -Markdown lint nit were repaired without runtime or successor-scope expansion. -After ART-02A3 PR #141 advanced main, the branch merged and reconciled its -active byte-only v2 LocalStorage clean cut while retaining every later -review-facing ART gate. Candidate -`e239282e7d2a2b4d46137707f673f76fda55e4b8` passed the plan gate and all nine -internal reviewer tracks against -`0ffdabf3dbb77e4e066683fde1a095d744ff1f43`; 87 agent gates, Ruff, scanners, -links, checksums, renderer checks, merge-intent validation, and the exact -71-entry A/M reviewed-scope comparison passed. Status-change, removal, -rename-as-D+A, and addition probes failed closed. This chunk activated no review -action or endpoint. +Trusted main is `99ae4c963e53f317175dcb308b9e47c93ccf19ed`, which includes REV +parent chunk 02 through PR #147 and AUTH-09D-A through PR #148. Parent 02 is a +merged non-executable split record. `WS-REV-001-PLAN2` is the active planning/ +specification-only refresh. No backend runtime, migration, model, repository, +service, route, or persistence test is authorized in this chunk. + +The user previously started 02A preparation, then accepted AUTH's runtime block +and explicitly authorized continued planning/read-only work. After this refresh, +02A requires a renewed explicit start because its exact runtime dependencies are +not all merged. + +## Trusted dependency truth + +- Single Alembic head: `0026_actor_profile_lifecycle`. +- Both retired task-subsystem contributor-identity fields remain on trusted main. +- AUTH catalogue: 74 PermissionIds, 65 ActionIds, 15 active, 50 planned. +- All 24 REV lifecycle action dependencies remain unavailable. +- AUTH-09D-A merged through PR #148 at + `99ae4c963e53f317175dcb308b9e47c93ccf19ed` with reviewed head + `9c5ef8a1feffd6324acfd947e67042921955320b`. Its ActorProfile lifecycle + status/provenance and direct-SQL guards are trusted dependencies. The separate + human-approved contributor clean cut still has no trusted-main chunk + ID/PR/SHA/migration, and both retired task fields remain. +- ART v2 LocalStorage merged through PR #141 at `a10d901`, but ART has no + scheduled review packet-read, review-evidence candidate/finalize, or + server-derived Submission artifact-digest owner chunk. +- CON-01 merged its specification. CON runtime chunks 02A onward remain + proposed on trusted main. Any unmerged CON work that previously claimed + `0026` must rebase from AUTH-09D-A's merged head before it is consumable. +- Sibling AUTH/ART/CON status files contain stale post-merge wording. REV records + actual merge facts but does not edit owner initiative memory. + +## Plan-refresh results + +- 02A now owns only activation sequence, Project-first publication/screening, + immutable Task guide triplet, and unchanged superseded-candidate denial. +- Proposed 02A2 owns prepared-authorized, `If-Match` protected superseded-guide + reactivation after AUTH-PREP and AUTH-12. This preserves backward rebase + without broadening the legacy public route. +- Existing oversized parent contracts are non-executable split records. Only + the children in `CHUNK_MAP.md` may later receive implementation contracts. +- Chunk 08 is pure contract/validation only. Chunk 10 remains the first canonical + Review/FinalAcceptance/CON transaction. +- Controlled revision preparation remains task-owned and rooted in an exact + human `Review(needs_revision)`. Checker-caused `needs_revision` remains a + distinct supported CheckerRun path, keeps existing task context, and never + fabricates Review/finding/reviewer contribution or consumes human rebase/D6. +- Limit/deadline exhaustion cannot be repaired around; only exact D6 close may + terminate that frozen human revision episode. +- Persisted release phase denies command execution. It does not unregister + routers, change AUTH action availability/static membership, or replace + scheduler operations. + +## Canonical lifecycle + +- Every valid reviewer decision appends immutable Review history; findings and + later resolutions are also immutable. +- Every decision creates reviewer `completed_review` through CON. +- Accept alone creates immutable FinalAcceptance, accepts Task/completes exact + assignment, and creates submitter `accepted_submission` from that fact. +- Needs revision creates no FinalAcceptance/submitter contribution and atomically + appends the Review-rooted task-owned initial preparation. +- Reject blocks the exact reviewed Submission assignment and rejects Task; it + creates no FinalAcceptance/submitter contribution. +- Checker needs revision atomically records the final CheckerRun transition with + the Task's existing locked context and creates no Review, preparation, or CON + record. Corrected N+1 persists the unique server-derived + `remediation_source_checker_run_id`; later human N+1 instead persists its + preparation ID, never both. +- Adjudication and reputation mutation remain deferred and unimplemented. + +## Human-owned gates + +- A real merged AUTH contributor/canonical-human foundation with exact ID, + PR/SHA, migration, constraints, and tests before 02A. +- Separate 02A start after this refresh merges. +- Exact positive `review_preference_window_seconds` and + `review_lease_duration_seconds` before 02B. Neither derives from `sla_hours`. +- Exact human Review revision-round counting, deadline anchor, and boundary + before 09A1; checker retries are excluded unless a separate product/ADR + amendment is explicitly approved. +- Exact merged AUTH-14 contract amendment before 09A4 must leave REV ownership + of Submission revision-source columns/constraints intact and limit AUTH to + public request acknowledgement, authorization cutover, and activation. +- Every later external owner dependency and child start as listed in the map. ## Stop condition -Complete parent-02 planning review only. Do not edit backend runtime, migration, -or persistence tests. After the exact AUTH contributor-foundation merge and -human approval of the planning split, 02A still requires a separate explicit -start. The duration defaults gate 02B. No child starts its successor -automatically. +Publish only `WS-REV-001-PLAN2`, let automated memory name 02A with an +explicit-start gate, and stop. Do not implement 02A, 02A2, or 02B from this PR. diff --git a/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/TEST_DESIGN_WS-REV-001-02.md b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/TEST_DESIGN_WS-REV-001-02.md index 3e64a5884..fe3313b73 100644 --- a/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/TEST_DESIGN_WS-REV-001-02.md +++ b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/TEST_DESIGN_WS-REV-001-02.md @@ -1,197 +1,162 @@ -# Test Design: WS-REV-001-02 Split +# Test Design: WS-REV-001 Runtime Foundation And Revision Cutover ## Status -Planning-only test design. No backend test or fixture is implemented until the -AUTH-owned contributor-field foundation merges and the relevant child receives -a separate human start. - -## Shared dependency gate - -Every child begins with a deterministic dependency test that records: - -- trusted-main SHA and single Alembic head; -- merged AUTH-09D-A PR/SHA; -- merged AUTH contributor-foundation PR/SHA and migration ID; -- absence of both retired task-subsystem contributor-identity storage names; -- presence of canonical `contributor_id` on TaskAssignment and Submission; -- database-backed canonical-human ActorProfile lineage; -- preserved task, submission, checker, and legacy-revision regression tests. - -Any missing proof stops before a REV migration is generated. - -## 02A - Guide Activation And Task Context - -### Migration fixtures - -| Case | Expected proof | -|---|---| -| Multiple projects with draft, active, and superseded guides | Active/superseded rows number independently per project; drafts remain null. | -| Historical rows with different effective times | Sequence follows `effective_at`, `created_at`, then `id`. | -| Activated guide missing required provenance | Upgrade fails and names the project/guide plus remediation. | -| Non-draft Task with exact same-project guide version | Task guide ID and activation sequence backfill exactly. | -| Task with missing, cross-project, or ambiguous guide context | Upgrade fails; current active guide is never substituted. | -| Protected Task stamps present | Downgrade refuses with destructive-remediation guidance. | - -### Direct SQL constraints - -- Reject zero/negative activation sequence. -- Reject draft with sequence. -- Reject active/superseded without sequence. -- Reject duplicate project/sequence. -- Reject mutation or clearing of an allocated sequence. -- Preserve sequence across active -> superseded -> active. -- Reject partial Task guide triplets and mixed guide ID/version/sequence. - -### Concurrency - -- Two first-time activations for one project serialize on the Project row and - allocate distinct monotonically increasing sequences. -- Activations in different projects proceed independently. -- Reactivation racing with a new activation retains the old sequence and does - not allocate twice. -- Publication locks all generation rows in deterministic type/ID order and a - concurrent mutation of ProjectGuide, GuideSourceSnapshot, - GuideSufficiencyReport, ProjectSetupRun, SubmissionArtifactPolicy, - EffectiveProjectSubmissionArtifactPolicy, PreSubmitCheckerPolicy, - PostSubmitCheckerPolicy, ReviewPolicy, RevisionPolicy, or transitional - compensation-context row cannot create a mixed generation. - -### Service behavior - -- Draft creation allocates no sequence. -- First activation allocates once. -- Repeated activation of the sole active guide is a no-write idempotent return. -- Superseded-guide reactivation preserves original approval/effective - provenance and sequence, clears superseded time, supersedes the current guide, - and writes the reactivation audit with server-owned reason - `older_guide_reactivated`; the route accepts no new caller reason/body. -- Draft, active-repeat, superseded-reactivation, invalid-state, and both - competing-reactivation request/commit permutations have separate tests under - the one canonical lock order. -- Task screening copies one complete guide identity. -- No semantic or lexical version comparison is used. -- No external call occurs while publication locks are held. - -## 02B - Review Policy And Dormant Lifecycle - -### Migration fixtures - -| Case | Expected proof | -|---|---| -| Safe ReviewPolicy row | Approved duration defaults plus capacity 1, self-review false, close-task reject, optional evidence backfill. | -| `requires_second_review=true` | Upgrade refuses with guide/policy remediation. | -| Missing canonical decisions or finding fields | Upgrade refuses rather than broadening policy. | -| Existing RevisionPolicy with either legacy auto-reject value | Column is removed; no product row or lifecycle effect is created. | -| Existing normal Task/Assignment statuses | Values and timestamps are preserved. | -| Unknown or inconsistent historical status shape | Upgrade refuses with row IDs and remediation. | - -### Direct SQL constraints - -- Reject nonpositive preference/lease duration. -- Reject capacity other than one. -- Reject self-review true. -- Reject reject policy other than `close_task`. -- Reject unknown finding-evidence requirement. -- Reject malformed/duplicate/missing canonical decisions and finding fields. -- Reject `requires_second_review=true`. -- Reject activated ReviewPolicy and RevisionPolicy update or delete. -- Allow both draft-policy replacements before first activation. -- Reject unknown Task and TaskAssignment status values. -- Reject terminal Task without mapped reason/time and nonterminal Task with - terminal fields. -- Reject Assignment status/timestamp mismatch. - -### Service and lifecycle behavior - -- New guide policy validates the exact v0.1 values. -- Activated ReviewPolicy/RevisionPolicy upserts fail without modifying the row. -- Either changed policy is created only under a new draft guide version. -- Lifecycle constants include accepted/rejected/cancelled and - completed/blocked, but transition guards still reject attempts to enter them. -- Removal of `auto_reject_after_limit` creates no Review, finding, Task terminal - status, Assignment terminal status, contribution, award, audit, or outbox - effect. Executable limit/deadline block tests remain required in 09A. -- Checker paths cannot select `rejected` or `cancelled`. -- All three dormant cancellation reasons, including - `legacy_revision_context_unrecoverable`, satisfy storage constraints but no - 02B service transition can create them. - -## 02C - Submission Attribution And Lineage - -### Migration fixtures - -| Case | Expected proof | -|---|---| -| One assignment satisfying the exact inclusive temporal predicate | Submission receives that assignment ID. | -| No responsible assignment | Upgrade fails with submission/task IDs. | -| Multiple plausible assignments | Upgrade fails; current or latest assignment is not selected. | -| Assignment belongs to another task | Upgrade fails. | -| Submission contributor differs from assignment contributor | Upgrade fails. | -| Submission time equals assigned/accepted/released boundary | Inclusive predicate is applied exactly. | -| Missing acceptance, invalid interval, or overlapping reassignment intervals | Upgrade fails with responsible row IDs. | -| Same contributor assigned twice with non-overlapping intervals | The one interval containing submitted time is selected. | -| Timestamp tie yields two qualifying assignments | Upgrade fails as ambiguous. | -| Exact historical guide context | Guide ID/sequence backfill from locked version and task context. | -| Missing or inconsistent historical guide context | Upgrade fails; active guide is not substituted. | -| Valid N-1 chain | Upgrade succeeds and preserves every ID/version. | -| Cross-task, skipped, branched, or self-linked chain | Upgrade fails with chain remediation. | -| Protected lineage in use | Downgrade refuses. | - -### Direct SQL constraints and immutability - -- Reject assignment from another task. -- Reject contributor unequal to exact assignment contributor. -- Reject nonhuman contributor through the merged AUTH foundation. -- Reject version 1 with a predecessor. -- Reject version greater than one without predecessor. -- Reject predecessor whose task or version is not exact N-1. -- Reject a second successor for the same predecessor. -- Reject mutation/deletion of a finalized Submission's identity, attribution, - version, predecessor, context, packet, evidence, or attestation. -- Reject EvidenceItem insert, update, or delete when its parent - `Submission.locked_at` is non-null; `finalized_at` remains only the API alias. -- Permit only the separately owned set-once `artifact_hash` extension after - finalization when that ART amendment later exists; reject overwrite. - -### Concurrency and service behavior - -- Two concurrent creates for one task serialize on Task/current head; one - receives N and the other either receives N+1 under valid lifecycle state or - fails with the stable conflict. They never create duplicate N or branches. -- Concurrent reassignment cannot change the assignment selected for a - submission already being finalized. -- Release, authority revocation, and later reassignment preserve prior - attribution. -- Suspended/deactivated human and service ActorProfiles are denied by the - transaction-local AUTH revalidation. External subject, email, legacy typed - profile ID, and token role are rejected as contributor substitutes. -- Submission request input never supplies assignment ID, contributor ID, - version, predecessor, or guide context. -- TaskAssignment gains no guide/context field. -- No duplicate SubmissionVersion model/table/API appears. - -## Regression and negative-scope proof - -For every child: - -- existing project-guide, task claim/start, submission finalization, checker, - and legacy revision tests remain enabled; -- no assertion is weakened, skipped, or rewritten to accept unsafe lineage; -- no AUTH, ART, CON, compensation, contribution, reputation, adjudication, queue, - lease, Review, finding, or public review-route file changes; -- migration upgrade is tested against real PostgreSQL, not only metadata; -- unsafe upgrades leave no partial DDL/data effects; safe fixtures prove - upgrade/downgrade/upgrade, and protected-row fixtures prove downgrade refusal; -- full isolated suite remains at or above 78 percent repository coverage; -- each materially changed backend module remains at or above 90 percent; -- stale wording and Markdown-link checks pass. - -## Human decisions still required - -1. Exact positive v0.1 default for - `review_preference_window_seconds`. -2. Exact positive v0.1 default for `review_lease_duration_seconds`. - -These values are product policy. They are not inferred from the unrelated -`ReviewPolicy.sla_hours`, and no migration may start while either is unset. +Planning-only. No backend test/fixture/migration is implemented until the exact +child dependency and separate human-start gates are satisfied. + +## Dependency gate fixture + +Every runtime child records and asserts: + +- trusted-main SHA and one Alembic head; +- exact owner chunk IDs, merged PR/SHAs, migrations, typed contracts, and tests; +- canonical `contributor_id` on TaskAssignment/Submission with no retired + contributor storage names; +- database-backed canonical-human ActorProfile constraints; +- preserved task/submission/checker regressions, especially + `test_checker_caused_revision_resubmits_fixed_version_through_api`. + +Missing evidence stops before REV generates a migration. + +## 02A chronology and Task locking + +### Migration/data + +- Number active/superseded guides independently per project by effective time, + created time, then ID; drafts remain null. +- Fail on missing activation provenance, unknown/inconsistent status, duplicate + ordering/sequence facts, or ambiguous Task guide context with row-specific + remediation and no partial DDL/data effects. +- Backfill non-draft Task only from an exact same-project guide/version/sequence. +- Prove prior-head preflight, one head, upgrade, safe downgrade/re-upgrade, + protected-row downgrade refusal, and failure rollback on real PostgreSQL. + +### Direct SQL + +- Reject nonpositive/duplicate/mutable sequence. +- Enforce exact draft/active/superseded provenance shapes and canonical-human + approver. +- Reject partial, crossed, cross-project, or valid-to-valid changed Task guide + triplet. + +### Concurrency/service + +- Project-first publication and task screening run against activation, setup + mutation, and setup-job completion in both commit orders. +- First activations serialize and allocate distinct monotonic sequences. +- Draft activation succeeds; sole-active repeat is no-write idempotent; + superseded candidate remains denied in 02A. +- Screening audit contains complete triplet; audit fault rolls back stamp. +- No external I/O occurs while locks are held; timestamp is post-lock DB time. + +## 02A2 hidden reactivation + +- AUTH action remains unavailable while hidden behavior is built. +- Missing If-Match -> 428; stale/mismatched current active -> 412; no feature + mutation/audit. +- Valid reactivation preserves original approver/effective time/sequence, clears + only restored superseded time, supersedes expected current at DB time, and + appends exact shared audit. +- Exact retry, delayed retry, two reactivations, activation/reactivation, + authority loss, audit failure, and both commit orders leave one active guide. + +## 02B policy and dormant lifecycle + +- Approved positive preference/lease defaults are explicit and independent of + `sla_hours`. +- Enforce capacity one, no self-review, exact decisions, blocking/advisory + finding vocabulary, no second review, and immutable activated policy. +- Remove legacy auto-reject policy without creating Review/task terminal/ + assignment terminal/CON/audit/outbox effects. +- Add dormant accepted/rejected/cancelled and completed/blocked storage shapes + but no service transition or reject FK. +- Unknown/inconsistent historical policy/status fails preflight with no partial + migration. + +## 02C Submission lineage + +- Backfill exact responsible assignment using one inclusive historical interval; + zero or multiple candidates fail without choosing current/latest. +- Enforce exact assignment contributor, same task, canonical human actor, + immediate N-1 predecessor, one successor, and exact immutable guide context. +- Finalized identity/attribution/context/evidence is immutable. The only future + digest exception is the separately owned set-once server-derived + `artifact_hash`; overwrite/caller promotion fails. +- Concurrent initial creates yield exactly one v1; loser exact replay/conflict. + They never yield v2. +- Concurrent creates against one human preparation head yield exactly one N+1; + loser exact replay/conflict. Concurrent checker-remediation creates likewise + yield one N+1 from the exact current CheckerRun state. The winner persists the + server-derived `remediation_source_checker_run_id`; direct SQL cannot cross the + source run's task/immediate predecessor or reuse it for a second N+1. Neither + path yields N+2; that requires a later committed human Review/preparation or + final needs-revision CheckerRun. + +## Human Review preparation and distinct checker remediation + +### Human preparation constraints + +- Bind one root to the exact Review(needs_revision), project/task/prior + Submission/source assignment. +- Reject accept/reject Review, crossed/duplicate source, duplicate prior + Submission episode, mutable source, and service-as-human actor. +- A CheckerRun cannot be used as a RevisionContextPreparation root. +- Version 1 has neither source relation. After human prepared cutover, every N+1 + has exactly one of `revision_context_preparation_id` or + `remediation_source_checker_run_id`; null/null and both-set rows fail migration, + service creation, and direct SQL. + +### Atomic creation + +- Existing checker transaction remains CheckerRun -> Task needs_revision -> + audit/outbox -> one commit using unchanged task context. Fault rolls back its + state; no Review/finding/CON/preparation record exists. +- Human transaction in 10: immutable Review + reviewer CON operation -> initial + preparation -> Task needs_revision -> audit/outbox -> one commit. + Fault rolls back all review/contribution/revision effects. +- No contributor-readable human-review needs_revision state lacks a head; unsafe + context creates a blocked head. Exact CheckerRun lineage distinguishes the + separate checker path from rootless legacy human state. + +### Path-specific behavior + +- Human Review revision requires responses for unresolved blocking ReviewFindings, + response evidence where policy requires it, later resolutions, and preferred + prior-reviewer return. +- Checker remediation exposes only contributor-safe checker message/fix, keeps + existing guide/task context, consumes no human revision limit/deadline, requires + no fake ReviewFinding/response/resolution, and returns to open routing. + +### Limits and deadline + +- No test is locked until the human approves exact human Review round count, + deadline anchor, and inclusive/exclusive boundary. +- Approved semantics exclude checker retries and freeze/use database time. +- Limit/deadline blocked head cannot use repair; exact D6 close only. +- Context invalid/revoked head may append one authorized repair successor. + +### Legacy + +- Prove exact CheckerRun + Submission + matching durable audit lineage remains a + valid checker-remediation path and is never classified as legacy human state. +- Classify valid human Review root, valid checker remediation, ambiguous claimed + human source, and truly rootless human legacy separately. Never fabricate Review. + +## Release phase + +- Checker allow_review and checker needs_revision routing share the + allowed checker-completion phases through `revision_cutover_fenced`; both deny + from `admission_fenced`. +- Human preparation is inseparable from leased review.decision completion and + remains allowed only where that completion class is allowed. +- Phase tests prove static routes/AUTH memberships do not change, denied commands + fail at the database fence, scheduler suspension is operational, and crash + resume is forward-only. + +## Per-child proof + +Every child runs focused tests/Ruff, real-PostgreSQL isolated full suite at 78 +percent, 90 percent changed-subsystem coverage, stale contract scans, Markdown +links, agent gates including merge intent/internal review evidence, and +`git diff --check`. No test is skipped or weakened to accommodate new schema. diff --git a/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-02A-guide-activation-sequence.md b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-02A-guide-activation-sequence.md index 9690eb96e..7b27c8247 100644 --- a/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-02A-guide-activation-sequence.md +++ b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-02A-guide-activation-sequence.md @@ -1,146 +1,149 @@ # Chunk Contract: WS-REV-001-02A - Project Guide Activation Sequence And Publication Locking -## Parent initiative - -`WS-REV-001` - Review And Revision Lifecycle - ## Goal -Give every activated Project Guide an immutable per-project chronology and make -guide publication assemble and lock one internally consistent generation. - -## Why this chunk exists - -Revision rebase compares the prior Submission's stamped guide identity with the -currently active guide. Semantic or lexical version comparison cannot establish -chronology, and the current activation path can read policy rows from mixed -generations. This child establishes the chronology and Task-side lock before -Submission copies it in 02C. +Add immutable per-project guide chronology, make publication and task screening +share Project-first locking, and stamp one immutable guide triplet on each Task. +Do not add public superseded-guide reactivation under legacy authorization. ## Risk class -L1 schema, migration, and concurrency. - -## SLA - -P2. +L1 schema, migration, authorization preservation, and concurrency. ## Preconditions -- AUTH-09D-A and the separately reviewed AUTH-owned contributor-field - foundation are merged, even though this child does not edit contributor - fields; the user has declared that foundation a runtime gate for all REV-02 - implementation. -- Dependency refresh records exact merged PR/SHA evidence and the then-current - single Alembic head. REV does not reserve a migration number during planning. -- This contract receives a separate human start after parent 02 planning is - approved. +- AUTH-09D-A is merged through PR #148 at + `99ae4c963e53f317175dcb308b9e47c93ccf19ed`, with migration + `0026_actor_profile_lifecycle` and database-backed ActorProfile lifecycle + evidence. +- The separate AUTH-owned contributor/canonical-human foundation has a real + trusted-main chunk ID and is merged with exact PR/SHA, migration, constraints, + and regression evidence. An unmerged branch, worktree, proposed migration + number, or prose handoff does not satisfy this remaining gate. +- Current-main refresh records the single Alembic head. REV allocates only the + then-current next migration and does not reserve a number in planning. +- The user separately starts this child after `WS-REV-001-PLAN2` merges. ## Allowed files ```text -backend/app/modules/projects/{models,schemas,repository,service}.py +backend/app/modules/projects/{models,schemas,repository,service,router}.py +backend/app/workers/project_setup.py only if a direct setup writer must adopt the Project-first fence backend/app/modules/tasks/{models,schemas,repository,service}.py only for Task guide stamps backend/app/db/models.py backend/alembic/versions/_guide_activation_sequence.py backend/tests/test_{alembic,projects,tasks}.py +.github/workflows/backend.yml only to persist focused 90 percent coverage gates for changed project/task/setup-job modules docs/architecture_data_model.md docs/architecture_lifecycle_state_machine.md -docs/operations_operator_workflow.md only for migration/deployment/remediation +docs/spec_chunk_3_project_guide_foundation.md +docs/operations_operator_workflow.md .agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/** .agent-loop/merge-intents/WS-REV-001-02A.json ``` -## Not allowed changes +## Not allowed ```text +public or hidden superseded-guide reactivation behavior Submission attribution, lineage, or immutability -ReviewPolicy or RevisionPolicy field changes +ReviewPolicy or RevisionPolicy changes Task or TaskAssignment lifecycle state changes -AUTH-owned contributor or ActorProfile schema -review queue, lease, Review, finding, FinalAcceptance, or public review routes -ART, CON, compensation, contribution, adjudication, or synthetic reject behavior +AUTH-owned contributor/ActorProfile schema or authorization implementation +review queue, lease, Review, finding, FinalAcceptance, ART, CON, or adjudication behavior +weakening or removal of any CI, coverage, lint, type, migration, or test gate ``` ## Acceptance criteria - `ProjectGuide.activation_sequence` is a nullable positive bigint allocated - exactly once on first activation. -- Database checks require drafts to have null sequence and active/superseded - guides to have a non-null sequence; `(project_id, activation_sequence)` is - unique. -- A database guard rejects sequence mutation or clearing. Reactivating a - previously activated guide preserves its original sequence and allocates no - second value. -- Existing active/superseded guides are deterministically numbered per project - by `effective_at`, `created_at`, then `id`. Missing required activation - provenance, invalid status/sequence shape, or conflicting historical data - fails with an actionable remediation message. Drafts remain null. -- Activation takes a `FOR UPDATE` project row lock before allocating - `max(activation_sequence)+1`; concurrent first activations cannot duplicate or - invert allocation. -- Publication uses this exact lock order: Project; candidate/current - ProjectGuide rows; GuideSourceSnapshot; GuideSufficiencyReport; - ProjectSetupRun; SubmissionArtifactPolicy; - EffectiveProjectSubmissionArtifactPolicy; PreSubmitCheckerPolicy; - PostSubmitCheckerPolicy; ReviewPolicy; RevisionPolicy; then the transitional - compensation-context row if it still exists. Rows of one type lock by ascending - primary key. That retired row is consistency input only and is not copied into - the final guide/revision context. + exactly once on first activation. `(project_id, activation_sequence)` is + unique and a database guard rejects mutation or clearing. +- The exact status domain is `draft`, `active`, and `superseded`. Draft requires + null sequence/approver/effective/superseded times; active requires positive + sequence, canonical-human approver, effective time, and null superseded time; + superseded requires all activation provenance plus superseded time. Unknown or + inconsistent shapes fail migration and direct SQL. +- Existing active/superseded guides are numbered per project by `effective_at`, + `created_at`, then `id`. Missing provenance, duplicate ordering facts, invalid + status, or conflicting history fails with row-specific remediation. Drafts + remain null. +- Publication locks Project first, then candidate/current ProjectGuide rows, + GuideSourceSnapshot, GuideSufficiencyReport, ProjectSetupRun, + SubmissionArtifactPolicy, EffectiveProjectSubmissionArtifactPolicy, + PreSubmitCheckerPolicy, PostSubmitCheckerPolicy, ReviewPolicy, + RevisionPolicy, and the exact current `payment_policies` table row if it still + exists. Same-type rows lock by ascending ID. If CON removes it first, the + refresh removes that lock rather than adding an alias. +- Every service or setup-job mutation of a guide, source snapshot, sufficiency + report, setup run, or listed policy row first locks the same Project, then its + target rows in the publication type/ID order, and revalidates that the guide is + still draft before writing. Project-setup job entry points call those fenced + service methods and perform no direct database mutation. This shared prefix is required + for the claimed activation/setup/screening race safety. +- First activation reads database time after locks, allocates + `max(activation_sequence)+1`, and records the canonical approver/effective + time. Concurrent first activations serialize and cannot duplicate or invert + allocation. Publication performs no external I/O under locks. +- The existing public route continues to allow draft first activation and the + no-write idempotent repeat of the sole active candidate. A superseded + candidate remains denied. This chunk does not broaden legacy local role + authorization or expose backward reactivation. - `WorkstreamTask` stamps `locked_guide_id`, `locked_guide_version`, and - `locked_guide_activation_sequence` as one composite guide identity when it - leaves draft. Draft tasks keep the triplet null; non-draft tasks require it - complete and reference one guide row. -- Existing non-draft tasks backfill only from an exact same-project locked - guide version with a valid activation sequence. Missing or ambiguous context - fails migration rather than choosing the current guide. -- Publication cannot assemble policy rows from different guide/source/policy - generations and performs no external I/O while locks are held. -- First activation is allowed only from draft: it allocates sequence, records - `approved_by` and `effective_at=database_now`, and clears no historical - provenance. Repeating activation of the sole active candidate is idempotent - and changes no timestamp, provenance, sequence, or audit row. -- Reactivation is allowed only from superseded. It preserves original - `approved_by`, `effective_at`, and activation sequence; changes status to - active; clears `superseded_at`; supersedes the current active guide at - database time; and appends a reactivation audit event with server-owned reason - `older_guide_reactivated`, canonical actor, and replaced guide. The existing - route gains no caller-supplied reason or request body. No other status may - reactivate. -- Two competing activations/reactivations serialize under the Project lock. - Each valid request observes and supersedes the then-current guide; both lock - acquisition orders leave exactly one active guide and preserve every - previously allocated sequence. -- Downgrade refuses once Task rows stamp activation sequence unless the operator - uses the documented destructive remediation procedure. - -## Verification commands + `locked_guide_activation_sequence` as one triplet when leaving draft. Draft + tasks keep all three null; non-draft tasks require all three and one exact + same-project guide. A database guard rejects every valid-to-valid change or + clearing after allocation. +- Task screening locks Project first, then Task and the selected active guide + before context validation/stamping. Activation, setup mutation, setup-worker + completion, and screening races run with independent sessions in both commit + orders and cannot produce a mixed or no-longer-active generation stamp. +- Existing non-draft Task backfill uses only an exact same-project locked guide + version with a valid sequence. Missing/ambiguous context fails rather than + selecting the current guide. +- Screening audit includes the complete guide triplet. Audit failure rolls back + Task stamping. One post-lock database timestamp controls each mutation. +- Downgrade refuses after protected guide sequences or Task stamps exist unless + the documented destructive remediation is performed. +- Backend CI persistently executes the focused 90 percent coverage checks for + every materially changed project/task/setup-job module; the proof is not only + a one-time local command. Existing global 78 percent and all other gates remain + unchanged or stronger. + +## Verification ```text +cd backend && alembic heads cd backend && alembic upgrade head cd backend && pytest -q tests/test_alembic.py tests/test_projects.py tests/test_tasks.py -cd backend && ruff check app/modules/projects app/modules/tasks tests/test_alembic.py tests/test_projects.py tests/test_tasks.py -cd backend && docstr-coverage --config .docstr.yaml +cd backend && ruff check app/modules/projects app/modules/tasks app/workers/project_setup.py tests/test_alembic.py tests/test_projects.py tests/test_tasks.py python3 scripts/check_stale_workstream_wording.py python3 scripts/check_markdown_links.py +PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 backend/.venv/bin/python scripts/test_agent_gates.py +git diff --check +(metadata_dir="$(mktemp -d)" && trap 'rm -rf "$metadata_dir"' EXIT && cd backend && WORKSTREAM_TEST_ADMIN_DATABASE_URL=postgresql+asyncpg://workstream:workstream@localhost:5433/postgres .venv/bin/python scripts/run_isolated_tests.py --metadata-json "$metadata_dir/result.json" --timeout-seconds 12600 -- .venv/bin/python -m pytest -q --ignore=tests/test_isolated_database_runner.py --cov=app --cov-report=term-missing --cov-fail-under=78) +cd backend && coverage report --include='app/modules/projects/*' --precision=2 --fail-under=90 +cd backend && coverage report --include='app/modules/tasks/*' --precision=2 --fail-under=90 +cd backend && coverage report --include='app/workers/project_setup.py' --precision=2 --fail-under=90 ``` -The full isolated PostgreSQL suite must preserve the repository-wide 78 percent -floor. Every materially changed projects/tasks module must remain at or above -90 percent coverage. +Migration proof uses real PostgreSQL and covers prior-head preflight, upgrade, +safe downgrade/re-upgrade, protected-row downgrade refusal, failed-preflight +rollback/no partial DDL, direct-SQL constraints, and a single head. The isolated +full suite preserves the 78 percent floor; every materially changed project/task +module remains at or above 90 percent. ## Required reviewers -Senior engineering, QA/test, security/auth, product/ops, architecture, -reuse/dedup, docs, and test-delta. +Senior engineering, QA/test, security/auth, product/ops, architecture, docs, +reuse/dedup, test delta, and CI integrity if coverage workflow changes. ## Human review focus -Historical ordering, concurrent allocation, reactivation preservation, lock -order, task backfill refusal, and downgrade limits. +Historical ordering, Project-first races, Task triplet immutability, canonical +approver enforcement, unchanged public authorization, and downgrade limits. -## Stop conditions +## Stop condition -- Stop if contributor or ActorProfile schema must change. -- Stop if historical task/guide lineage is ambiguous. -- Merge, record automated memory, and stop. Do not start 02B automatically. +Stop if AUTH contributor/actor schema must change or historical lineage is +ambiguous. Merge, record automated memory, and stop. Do not start 02B. diff --git a/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-02A2-prepared-guide-reactivation.md b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-02A2-prepared-guide-reactivation.md new file mode 100644 index 000000000..50f74b153 --- /dev/null +++ b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-02A2-prepared-guide-reactivation.md @@ -0,0 +1,64 @@ +# Chunk Contract: WS-REV-001-02A2 - Prepared Superseded Guide Reactivation + +## Status + +Proposed. Do not implement until every precondition merges and the user gives a +separate explicit start. + +## Goal + +Add intentional backward guide reactivation through the bodyless activation +command without exposing it under legacy local-role authorization or allowing a +delayed retry to replace a newer guide. + +## Risk class + +L1 privileged mutation, immutable provenance, and concurrency. + +## Preconditions + +- 02A and 08 are merged with Project-first locking, immutable activation sequence, + pure decision/resource contracts, and + unchanged superseded-candidate denial. +- Exact merged AUTH-PREP/custody and an AUTH-12 contract amendment are recorded + by chunk ID, PR/SHA, typed action/resource contract, and tests. AUTH-12 runtime + evaluator/cutover/activation has not run; `project.guide.activate` remains + unavailable while this hidden behavior is built. +- A current-main contract refresh confirms route ownership and a separate human + start. + +## Acceptance boundary + +- The route remains bodyless and accepts no caller reason. +- Superseded reactivation requires `If-Match` for the exact current active-guide + ETag. Missing precondition is 428; stale/mismatched state is 412. Both leave + guide/audit/AUTH feature state unchanged except AUTH-owned bounded denial + evidence where its merged contract requires it. +- The command uses AUTH prepare/authority lock, then Project-first feature locks, + final-fact recomposition, AUTH consume/evaluate once, shared audit flush, and + one route-owned commit. +- Reactivation preserves the restored guide's original approver, effective time, + and activation sequence; clears only its superseded time; supersedes the exact + expected current guide at post-lock database time; and leaves exactly one + active guide. +- The shared AuditEvent records `project_guide_reactivated`, project/candidate, + canonical actor, replaced/restored IDs and activation sequences, + `older_guide_reactivated`, request/correlation IDs, AuthorizationDecision, + and database time. Audit failure rolls back all feature mutation. +- Active repeat remains no-write idempotent. Draft first activation remains 02A + behavior. Unknown/cross-project/wrong-state targets fail closed. +- Independent-session tests cover competing reactivations, new activation versus + reactivation, exact retry, delayed retry, current-guide change, authority loss, + audit failure, and both commit orders. + +## Required contract before start + +The start refresh must add exact allowed/not-allowed files, verification +commands including focused/full coverage, required reviewers, merge intent, and +stop condition from then-current main. This proposed record is not implementation +authorization. + +## Stop condition + +After its future PR merges, stop. Its manifest gates AUTH-12; do not start 09A1 +automatically. diff --git a/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-02B-review-policy-task-lifecycle.md b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-02B-review-policy-task-lifecycle.md index a4cc81595..68e5ab3a1 100644 --- a/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-02B-review-policy-task-lifecycle.md +++ b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-02B-review-policy-task-lifecycle.md @@ -132,16 +132,22 @@ synthetic reject from checker, revision limit, deadline, or administrative close ```text cd backend && alembic upgrade head +cd backend && alembic heads cd backend && pytest -q tests/test_alembic.py tests/test_projects.py tests/test_tasks.py cd backend && ruff check app/modules/projects app/modules/tasks tests/test_alembic.py tests/test_projects.py tests/test_tasks.py cd backend && docstr-coverage --config .docstr.yaml python3 scripts/check_stale_workstream_wording.py python3 scripts/check_markdown_links.py +PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 backend/.venv/bin/python scripts/test_agent_gates.py +git diff --check +(metadata_dir="$(mktemp -d)" && trap 'rm -rf "$metadata_dir"' EXIT && cd backend && WORKSTREAM_TEST_ADMIN_DATABASE_URL=postgresql+asyncpg://workstream:workstream@localhost:5433/postgres .venv/bin/python scripts/run_isolated_tests.py --metadata-json "$metadata_dir/result.json" --timeout-seconds 12600 -- .venv/bin/python -m pytest -q --ignore=tests/test_isolated_database_runner.py --cov=app --cov-report=term-missing --cov-fail-under=78) +cd backend && coverage report --include='app/modules/projects/*' --precision=2 --fail-under=90 +cd backend && coverage report --include='app/modules/tasks/*' --precision=2 --fail-under=90 ``` -The full isolated PostgreSQL suite must preserve the repository-wide 78 percent -floor. Every materially changed projects/tasks module must remain at or above -90 percent coverage. +Migration proof also covers prior-head preflight, safe downgrade/re-upgrade, +protected-row refusal, failed-preflight rollback/no partial DDL, direct SQL, and +a single head on real PostgreSQL. ## Required reviewers diff --git a/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-02C-submission-attribution-lineage.md b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-02C-submission-attribution-lineage.md index bb952d854..8a142636b 100644 --- a/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-02C-submission-attribution-lineage.md +++ b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-02C-submission-attribution-lineage.md @@ -8,14 +8,17 @@ Bind every existing versioned Submission to the exact TaskAssignment and canonical contributor that produced it, stamp the complete guide identity, and -enforce immutable immediate-predecessor lineage after finalization. +enforce immutable immediate-predecessor and checker-remediation source lineage +after finalization. ## Why this chunk exists Current Submission service logic allocates sequential versions, but direct SQL can create cross-task or skipped predecessor chains and prior attribution can be -misread after reassignment. The existing Submission must become durable review -lineage without introducing a competing SubmissionVersion table. +misread after reassignment. Checker-remediation N+1 currently has no immutable +causal relation to the needs-revision CheckerRun. The existing Submission must +become durable review lineage without introducing a competing SubmissionVersion +or lifecycle-root table. ## Risk class @@ -43,9 +46,12 @@ P2. ```text backend/app/modules/tasks/{models,schemas,repository,service}.py +backend/app/modules/checkers/{models,repository}.py only for the composite CheckerRun source key and lock/read support +backend/app/modules/checkers/service.py only if a CheckerRun supersession/retry path must adopt the shared Task-first source-lock prefix backend/app/db/models.py backend/alembic/versions/_submission_attribution_lineage.py -backend/tests/test_{alembic,tasks}.py +backend/tests/test_{alembic,tasks,checkers}.py +.github/workflows/backend.yml only for persistent 90 percent task/checker lineage coverage gates docs/architecture_data_model.md docs/architecture_lifecycle_state_machine.md docs/operations_revision_replay.md @@ -59,7 +65,7 @@ docs/operations_operator_workflow.md only for migration/deployment/remediation ```text new SubmissionVersion table or public submission route redesign AUTH-owned contributor field rename, compatibility alias, or ActorProfile schema -ProjectGuide activation allocation or ReviewPolicy shape +ProjectGuide activation allocation, ReviewPolicy shape, or checker routing/outcome semantics review queue, lease, Review, finding, response, preparation, or FinalAcceptance ART artifact_hash cutover or provider calls CON, compensation, contribution, reputation, adjudication, or synthetic reject @@ -93,17 +99,37 @@ CON, compensation, contribution, reputation, adjudication, or synthetic reject - `supersedes_submission_id` is null only for version 1. Version N greater than one points to version N-1 for the same task. Direct SQL rejects self-links, cross-task predecessors, skips, branches, and duplicate successors. +- Submission gains nullable, server-derived + `remediation_source_checker_run_id`. It is null for version 1. Before the + later human-preparation cutover, every version N greater than one references + the exact completed, `needs_revision`, current-at-selection CheckerRun for its + immediate predecessor Submission and same Task. A composite database relation + plus constraint trigger or equivalently reviewed PostgreSQL enforcement + rejects crossed task/predecessor/run facts, non-final or non-needs-revision + sources, direct-SQL fabrication, and source deletion/mutation. The nullable + source is unique, so one CheckerRun cannot admit two N+1 versions. +- Existing N greater than one rows backfill the checker source only when one + completed needs-revision CheckerRun for the immediate predecessor is proven by + matching task, predecessor, transition audit, and creation chronology. Zero or + multiple candidates fail with task/submission/run IDs and remediation; current + or latest-run inference is prohibited. - Draft/staged submission fields required by current finalization/checker flows remain mutable only until the existing finalization boundary. After physical `Submission.locked_at` is set (publicly serialized as `finalized_at`), - identity, task/assignment/contributor, version, - predecessor, locked context, packet, evidence, and attestation fields are + identity, task/assignment/contributor, version, predecessor, checker-remediation + source, locked context, packet, evidence, and attestation fields are update/delete protected. Later ART-owned server-derived `artifact_hash` publication remains an explicitly allowed set-once extension and is not implemented here. -- Version allocation and predecessor selection lock the Task plus current chain - head so concurrent submissions cannot allocate the same version or create two - successors. +- Version allocation and predecessor selection lock the Task, current Submission + chain head, then exact source CheckerRun. CheckerRun supersession/retry paths + that can change source currentness acquire that same Task-first prefix before + CheckerRun rows; same-type rows lock by ascending ID. Creation revalidates + completed/current/needs-revision facts after all locks. Concurrent initial + creates yield one v1 and an exact replay or stable conflict, never v2. + Concurrent creation against one exact final needs-revision CheckerRun yields + one N+1 and an exact replay or conflict, never N+2. A later CheckerRun retry + does not invalidate or rewrite the committed source relation. - TaskAssignment continues to store only task identity and contributor/freeze terms; it receives no guide or revision-preparation duplicate. - Submission creation revalidates that the canonical contributor ActorProfile @@ -112,6 +138,9 @@ CON, compensation, contribution, reputation, adjudication, or synthetic reject profile IDs, and token-role values cannot substitute. - No Review, queue entry, checker decision, contribution, or task terminal effect is created by migration or lineage enforcement. +- CI retains every existing gate and the repository-wide 78 percent baseline, + and persistently enforces at least 90 percent coverage for the task/checker + lineage files materially changed here. - Downgrade refuses after rows depend on the new assignment/guide lineage unless the documented destructive remediation procedure is used. @@ -119,21 +148,28 @@ CON, compensation, contribution, reputation, adjudication, or synthetic reject ```text cd backend && alembic upgrade head -cd backend && pytest -q tests/test_alembic.py tests/test_tasks.py -cd backend && ruff check app/modules/tasks tests/test_alembic.py tests/test_tasks.py +cd backend && alembic heads +cd backend && pytest -q tests/test_alembic.py tests/test_tasks.py tests/test_checkers.py +cd backend && ruff check app/modules/tasks app/modules/checkers/models.py app/modules/checkers/repository.py app/modules/checkers/service.py tests/test_alembic.py tests/test_tasks.py tests/test_checkers.py cd backend && docstr-coverage --config .docstr.yaml python3 scripts/check_stale_workstream_wording.py python3 scripts/check_markdown_links.py +PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 backend/.venv/bin/python scripts/test_agent_gates.py +git diff --check +(metadata_dir="$(mktemp -d)" && trap 'rm -rf "$metadata_dir"' EXIT && cd backend && WORKSTREAM_TEST_ADMIN_DATABASE_URL=postgresql+asyncpg://workstream:workstream@localhost:5433/postgres .venv/bin/python scripts/run_isolated_tests.py --metadata-json "$metadata_dir/result.json" --timeout-seconds 12600 -- .venv/bin/python -m pytest -q --ignore=tests/test_isolated_database_runner.py --cov=app --cov-report=term-missing --cov-fail-under=78) +cd backend && coverage report --include='app/modules/tasks/*,app/modules/checkers/models.py,app/modules/checkers/repository.py,app/modules/checkers/service.py' --precision=2 --fail-under=90 ``` -The full isolated PostgreSQL suite must preserve the repository-wide 78 percent -floor. Every materially changed tasks module must remain at or above 90 percent -coverage. +Migration proof also covers prior-head preflight, exact checker-source backfill, +safe downgrade/re-upgrade, protected-row refusal, failed-preflight rollback/no +partial DDL, direct SQL, crossed task/predecessor/run facts, duplicate source, +source immutability, both concurrency orders, and a single head on real +PostgreSQL. ## Required reviewers Senior engineering, QA/test, security/auth, product/ops, architecture, -reuse/dedup, docs, and test-delta. +reuse/dedup, docs, test-delta, and CI integrity. ## Human review focus @@ -146,4 +182,4 @@ downgrade refusal. - Stop if the AUTH foundation is incomplete or a retired contributor-identity storage name remains. - Stop if attribution or guide context cannot be proved for every migrated row. -- Merge, record automated memory, and stop. Do not start 03 automatically. +- Merge, record automated memory, and stop. Do not start 03A automatically. diff --git a/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-03-review-queue-lease-persistence.md b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-03-review-queue-lease-persistence.md index eb886db7a..69807154c 100644 --- a/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-03-review-queue-lease-persistence.md +++ b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-03-review-queue-lease-persistence.md @@ -1,106 +1,23 @@ -# Chunk Contract: WS-REV-001-03 +# Chunk Contract: WS-REV-001-03 - Review Queue And Lease Persistence -## Goal +## Status -Add review-owned queue and permanent lease-attempt persistence with complete -database invariants and repository tests, but no public claim behavior. +Non-executable split record. Do not implement or create a merge intent for this +parent. -Chunk start requires the WS-CON `ContributionPolicyVersion` persistence contract to be -merged with its exact lease-freeze FK/field types. This chunk owns those exact -immutable references on `ReviewLease`; it does not invent or implement WS-CON -policy. +## Children -## Risk class +- `WS-REV-001-03A` owns queue/lease base persistence and the exact merged + `WS-CON-001-03B` ContributionPolicyVersion FK. +- `WS-REV-001-03B` is the sole owner of the normalized immutable + ReviewPacketManifest/item models, schema, migration, repository contract, and + persistence tests. It starts only after ART merges an exact packet-membership + relation contract. JSON or opaque binding-ID sets are prohibited. Later claim + work consumes this canonical persistence contract and may not redefine it. -L1 schema and concurrency foundation. - -## Allowed files - -```text -backend/app/modules/reviews/{__init__,models,repository}.py -backend/app/modules/checkers/models.py only for CheckerRun composite identity -backend/app/db/models.py -backend/alembic/versions/_review_queue_lease.py -backend/tests/test_{alembic,reviews,checkers}.py -docs/operations_queue_policy.md only for deployment/backfill/rollback/remediation notes -.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/** -.agent-loop/merge-intents/WS-REV-001-03.json -``` - -## Not allowed - -```text -public routes or Celery workers -Review, finding, response, or resolution records -task status mutations -grant reads or authorization logic -artifact provider calls -WS-CON implementation -``` - -## Acceptance criteria - -- At most one queue entry per Submission version, and only an authoritatively - admitted version may receive one. -- Every queue entry stores an immutable `admitting_checker_run_id`. CheckerRun - exposes a composite `(id, submission_id)` identity so a composite FK binds the - run to the queue's same Submission. A deferred insert constraint requires that - run to be finalized, successful, current at that admission transaction, and - `allow_review`; immutable finalized outcome fields preserve the admission - fact. Later checker retry/supersession cannot rewrite the queue anchor. - Ambiguous historical rows remain unqueued for remediation. -- Queue state/routing/preference/active-lease/closure compatibility has database - check constraints. -- Lease state/close-reason compatibility has database check constraints. -- Partial unique indexes allow one active lease per queue and one globally per - reviewer. -- Preferred reviewer and lease reviewer FKs reference canonical human - `ActorProfile.id`; direct SQL cannot store external subjects, email, legacy - profile row IDs, or service/system actors as reviewers. -- This uses the plan's composite actor-kind constraint or reviewed deferred - trigger pattern; a plain ActorProfile FK does not satisfy the criterion. - Direct-SQL tests cover service ActorProfile, system principal, external - subject, legacy profile ID, and crossed human actor attempts. -- `first_queued_at` and permanent lease attempt history cannot be silently - overwritten or deleted. -- Frozen contribution-policy identifiers/versions required by the approved - WS-CON contract are persisted as exact immutable - `ContributionPolicyVersion` references on each lease attempt. They are not - part of the Submission guide/checker context and are never rebased with it. -- `ReviewPacketManifest` persistence is defined as an immutable lease-scoped - semantic projection. Its base schema can name the exact queue, lease, - Submission/version, admitting CheckerRun/results, locked guide/policy context - digest, response-evidence relation set, and ART binding ID set. It stores no - bytes, digest of artifact content, provider/scratch/receipt data, or AUTH - matrix facts. Chunk 06 creates manifests atomically with leases; 09A may add a - constrained revision-preparation reference without rewriting prior manifests. -- The schema migration performs no blanket historical queue backfill. Ambiguous - existing submissions remain unqueued; later admission/reconciliation is - limited by D13 and produces explicit audit/remediation evidence. -- Repository lock and deterministic ordering primitives are tested on Postgres. -- Deployment notes define ordering, no-backfill behavior, ambiguous-row - remediation, rollback limits, and proof queries. - -## Verification - -```text -cd backend && alembic upgrade head -cd backend && pytest -q tests/test_alembic.py tests/test_reviews.py tests/test_checkers.py -cd backend && ruff check app/modules/reviews app/modules/checkers/models.py tests/test_reviews.py tests/test_checkers.py tests/test_alembic.py -(metadata_dir="$(mktemp -d)" && trap 'rm -rf "$metadata_dir"' EXIT && (cd backend && WORKSTREAM_TEST_ADMIN_DATABASE_URL=postgresql+asyncpg://workstream:workstream@localhost:5433/postgres .venv/bin/python scripts/run_isolated_tests.py --metadata-json "$metadata_dir/result.json" --timeout-seconds 12600 -- .venv/bin/python -m pytest -q --ignore=tests/test_isolated_database_runner.py --cov=app --cov-report=term-missing --cov-fail-under=78)) -cd backend && for path in 'app/modules/reviews/*' app/modules/checkers/models.py; do coverage report --include="$path" --precision=2 --fail-under=90 || exit 1; done -``` - -## Required reviewers - -Senior engineering, QA/test, security/auth, product/ops, architecture, docs, -reuse/dedup, and test-delta. - -## Human review focus - -Partial uniqueness, state compatibility, immutable queue age, and migration -behavior under existing submissions. +Each child requires a current-main contract, architecture data-model update, +real-PostgreSQL migration proof, internal review, explicit start, and its own PR. ## Stop condition -Merge, record automated memory, and stop. Do not start 04. +Use `CHUNK_MAP.md`; do not execute this parent. diff --git a/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-04-review-chain-persistence.md b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-04-review-chain-persistence.md index 38269ddbb..1692d01fb 100644 --- a/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-04-review-chain-persistence.md +++ b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-04-review-chain-persistence.md @@ -1,126 +1,23 @@ -# Chunk Contract: WS-REV-001-04 +# Chunk Contract: WS-REV-001-04 - Review Chain Persistence -## Goal +## Status -Add persistence for immutable Review records, immutable submitted findings and -resolutions, and the immutable FinalAcceptance created only for an `accept` -Review, together with submitter responses, evidence relations, decision -idempotency, and projection requests. +Non-executable split record. Do not implement or create a merge intent for this +parent. -Chunk start requires the merged shared transactional-outbox contract. All -projection requests below use that shared foundation. +## Children -## Risk class +- `WS-REV-001-04A` owns immutable Review, ReviewFinding, + SubmissionFindingResponse, FindingResolution, immutable evidence attachment, + and ReviewDecisionRequest persistence primitives. +- `WS-REV-001-04B` owns immutable FinalAcceptance, the reject link to the exact + immutable `Submission.task_assignment_id`, and shared audit/outbox persistence + primitives after `WS-CON-001-02A` and `02C` merge. -L1 schema, audit, and evidence ownership. - -## Allowed files - -```text -backend/app/modules/reviews/{models,repository,schemas}.py -backend/app/modules/tasks/models.py only for relationships/FKs -backend/app/db/models.py -backend/alembic/versions/_review_chain.py -backend/tests/test_{alembic,audit,reviews}.py -docs/operations_reviewer_workflow.md only for deployment/rollback/immutability notes -.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/** -.agent-loop/merge-intents/WS-REV-001-04.json -``` - -## Not allowed - -```text -public routes, decision service, task effects, or background jobs -artifact provider implementation -grant or permission implementation -contribution/compensation models -mutable Review/finding/resolution rows -manual/public FinalAcceptance creation -review-private outbox or delivery queue -``` - -## Acceptance criteria - -- One Review per Submission and synchronized predecessor-chain constraints. -- Every Review is immutable regardless of whether its decision is `accept`, - `needs_revision`, or `reject`. Every submitted ReviewFinding and every later - FindingResolution is immutable. A later review round appends new rows and - never updates prior judgment or findings. -- `FinalAcceptance` is an immutable internal REV record with canonical - `submission_id` implementing the conceptual Submission-version identity, - `project_id`, `task_id`, `source_review_id`, `accepted_submitter_id`, - `accepted_at`, `recorded_by`, and `policy_context_ref` constrained to the - exact immutable ReviewPolicy row matching the reviewed Submission context. - `accepted_submitter_id` is the canonical human `ActorProfile.id` shared by the - reviewed Submission and its exact TaskAssignment. `recorded_by` is the - canonical human `ActorProfile.id` shared by the source Review and ReviewLease. -- PostgreSQL enforces `UNIQUE(task_id)`, `UNIQUE(source_review_id)`, and - `UNIQUE(submission_id)`, plus same-chain project/task/Submission/Review, - accepted-submitter and TaskAssignment lineage, recording-reviewer and - ReviewLease lineage, exact ReviewPolicy context, and canonical-human-actor - integrity. Direct-SQL tests cross each actor and lineage independently; none - may update or delete the record or create a crossed acceptance. -- This persistence chunk exposes no service, route, action, or background - command capable of creating FinalAcceptance. Only REV-10 may append it, and - only in the same transaction that appends a new Review whose decision is - `accept`, after the mandatory CON participant has merged. -- `ReviewEvidenceArtifact` is an immutable REV semantic relation over one - finalized ART binding. Before decision it is identified by exact lease, - operation kind, evidence slot, and idempotency identity; after decision it may - be linked set-once to the exact ReviewFinding or SubmissionFindingResponse. - Binding identity and scope never change. This is not artifact byte storage, - a provider reference, or a mutable ReviewAttempt. -- `Review.reviewer_id` is the exact canonical human `ActorProfile.id` on its - ReviewLease; a composite constraint rejects a crossed lease/reviewer and no - external subject, email, legacy profile ID, service actor, or system principal - may be persisted as the human reviewer. -- Database constraints require `Review(Sn).prior_review_id` to identify the - Review whose Submission is `Submission(Sn).supersedes_submission_id`; crossed - task, version, Submission, or Review predecessor chains fail under direct SQL. -- Immutable findings use only blocking/advisory severity. -- Finding responses and resolutions are immutable and uniquely scoped. -- Evidence relation rows reference canonical ArtifactBinding IDs and are unique. -- Decision idempotency completes only with one canonical Review and, for accept, - exactly one FinalAcceptance; it detects changed payload reuse. -- `ReviewDecisionRequest` reuses `canonical_json_hash`, shared request and - correlation identifiers, and the reserve/lock/complete transaction shape, - while keeping a review-specific operation/response matrix. No cloned JSON - canonicalizer or second generic idempotency framework is added. -- One canonical shared-outbox projection event commits with Review. Shared - outbox delivery state and ART receipts are reused; no review-private - projection request/status table exists. -- The reject-Review reference on TaskAssignment is added now that the Review - table exists and is constrained to a reject Review for the same task/current - assignment. -- Database triggers or equivalent guards prevent prohibited update/delete of - canonical review-chain records. -- Review events append through the merged shared AuditEvent participant in the - caller transaction. No `ReviewAuditEvent`, review-private audit repository, or - commit-owning audit writer exists. -- Deployment notes define ordering, historical-row handling, rollback limits - after immutable rows exist, and proof queries without synthetic backfill. - -## Verification - -```text -cd backend && alembic upgrade head -cd backend && pytest -q tests/test_alembic.py tests/test_audit.py tests/test_reviews.py -cd backend && ruff check app/modules/reviews app/modules/audit tests/test_reviews.py tests/test_audit.py tests/test_alembic.py -(metadata_dir="$(mktemp -d)" && trap 'rm -rf "$metadata_dir"' EXIT && (cd backend && WORKSTREAM_TEST_ADMIN_DATABASE_URL=postgresql+asyncpg://workstream:workstream@localhost:5433/postgres .venv/bin/python scripts/run_isolated_tests.py --metadata-json "$metadata_dir/result.json" --timeout-seconds 12600 -- .venv/bin/python -m pytest -q --ignore=tests/test_isolated_database_runner.py --cov=app --cov-report=term-missing --cov-fail-under=78)) -cd backend && for path in 'app/modules/reviews/*' app/modules/tasks/models.py; do coverage report --include="$path" --precision=2 --fail-under=90 || exit 1; done -``` - -## Required reviewers - -Senior engineering, QA/test, security/auth, product/ops, architecture, docs, -reuse/dedup, and test-delta. - -## Human review focus - -Immutability enforcement, FinalAcceptance uniqueness/cross-chain integrity, -predecessor integrity, evidence ownership, and idempotency atomicity. -Multi-version/takeover chain negatives receive explicit human attention. +Neither child exposes a creation service. Chunk 10 remains the first canonical +Review/FinalAcceptance transaction. Each child updates active data-model/state +docs and receives a separate contract, review, start, migration, and PR. ## Stop condition -Merge, record automated memory, and stop. Do not start 05. +Use `CHUNK_MAP.md`; do not execute this parent. diff --git a/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-05-checker-routing-queue-views.md b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-05-checker-routing-queue-views.md index 159787646..a5b443dbc 100644 --- a/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-05-checker-routing-queue-views.md +++ b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-05-checker-routing-queue-views.md @@ -1,124 +1,21 @@ -# Chunk Contract: WS-REV-001-05 +# Chunk Contract: WS-REV-001-05 - Checker Routing And Queue Views -## Goal +## Status -Create one review queue entry from authoritative checker admission and expose -authorized server-selected reviewer work plus administrative inspection. +Non-executable split record. -## Risk class +## Children -L1 authorization, routing, and intake integration. +- `WS-REV-001-05A` owns only online checker `allow_review` admission through a + typed checker-owned caller-transaction participant. Version-1 queue entries + enter open routing; eligible human-revision entries enter preferred routing. +- `WS-REV-001-05B` owns server-selected current work and bounded admin reads. -## Allowed files - -```text -backend/app/modules/reviews/{repository,schemas,service,router}.py -backend/app/modules/checkers/{ports,service,repository,router}.py -backend/app/modules/tasks/{models,lifecycle,service}.py only for atomic handoff/composition use -backend/app/modules/tasks/router.py only to use the explicit TaskService composition constructor -backend/app/workers/checkers.py only to use the explicit composition constructor -backend/app/composition/{__init__,review_lifecycle}.py -backend/tests/test_{reviews,checkers,tasks,app,authorization,artifacts,api_contract_e2e}.py -backend/scripts/api_contract_e2e.py -docs/operations_reviewer_workflow.md -.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/** -.agent-loop/merge-intents/WS-REV-001-05.json -``` - -## Not allowed - -```text -claim or decision mutations -full reviewer-visible backlog or queue depth -direct grant queries or provider imports -caller-supplied project/resource ownership -checker outcome stored as Review -production `/api/v1` review-router registration -``` - -## Acceptance criteria - -- `allow_review`, retained verified binding facts, task transition, queue entry, - and audit are idempotent and cannot orphan each other. -- The admission transaction writes the exact finalized successful - `allow_review` CheckerRun ID into the queue entry atomically. Retry, - supersession, reconciliation, or later checker execution never silently - changes that immutable packet anchor. -- The existing durable CheckerRun transaction invokes an injected review-owned - admission participant from `_apply_pre_review_gate_result`; reviews never - polls/recomputes `allow_review` or imports CheckerRepository. Review context - uses the checker-owned typed reader, not direct checker repository access. -- Every concrete CheckerService construction in checker routes, TaskService, - and checker execution processes is replaced by the single explicit composition assembly; - no optional participant, fallback constructor, or runtime service locator - exists. Import-boundary tests prohibit checker/review repository cycles. -- Every public task route replaces direct `TaskService(session)` construction - with the same explicit TaskService assembly; route tests prove there is no - constructor path that omits the checker admission participant. -- Version 1 routes open; later-admitted version routes preferred to the prior - needs-revision reviewer. -- Reviewer current endpoint returns active lease, one eligible preferred/open - offer, or none and reveals no alternative work. -- A reviewer with a global active lease in project A receives `none` when - requesting current work for project B. The response exposes neither the - project-A lease nor a project-B offer that global capacity makes unclaimable; - an independent cross-project test proves both suppression and concealment. -- Admin inspection is separately authorized and distinguishes open depth from - preferred backlog. -- Reviewer and administrative reads declare, respectively, - `review.queue.read` and `review.queue.inspect`, use canonical project resource - contexts, and call the centralized `AuthorizationService.require` boundary. -- Reviewer current requires the exact active independent project `reviewer` - grant. Submitter, adjudicator, and administrative grants cannot substitute; - no-self-review remains a separate lifecycle guard. -- This chunk supplies hidden read behavior, canonical resource composers, - guards, surface declarations, and a feature-manifest delta while both actions - remain planned and real-kernel requests return `action_unavailable`. - `WS-AUTH-001-REV-05` separately integrates evaluators and activates them after - merge; this chunk changes no activation custodian or availability. -- Merged AUTH-08 dependency tests prove successful teardown cannot commit an - uncommitted queue/checker/review mutation, decision evidence SQL failure - returns the stable retryable 503 with no partial state, and canonical actor - verification timestamps retain their AUTH-defined allowed-access behavior. - Missing or regressed proof on the chunk-start main SHA blocks this chunk. -- FIFO ordering is deterministic and preserves original age. -- Historical admission follows D13: only latest, finalized, current - `allow_review`, artifact-ready rows are reconciled; ambiguous rows receive an - auditable remediation state and are not queued. -- An idempotent deployment admission scan covers existing `review_pending` rows, reports - admitted/skipped/ambiguous counts in the admin view, and classifies legacy - revision chains lacking structured responses for explicit operator handling. -- Internal HTTP contract tests cover the routes while production OpenAPI proves - the lifecycle router is still absent. -- Independent-session PostgreSQL barriers race queue admission against checker - retry/supersession in both commit orders. Admission-first retains the exact - then-current successful `allow_review` anchor after later supersession. - Supersession-first makes stale admission fail/reselect and cannot queue an - incomplete, denied, or non-current run. Duplicate delivery still yields one - queue entry with one immutable anchor. -- Checker retry/supersession and review admission lock Submission, CheckerRun, - then ReviewQueueEntry in the canonical PLAN order; tests assert the checker - subsystem's owner order is reconciled to that shared sequence. - -## Verification - -```text -cd backend && pytest -q tests/test_reviews.py tests/test_checkers.py tests/test_tasks.py tests/test_app.py tests/test_authorization.py tests/test_artifacts.py tests/test_api_contract_e2e.py -cd backend && ruff check app/modules/reviews app/modules/checkers app/modules/tasks/router.py app/workers/checkers.py app/composition tests/test_reviews.py tests/test_checkers.py tests/test_tasks.py tests/test_app.py -(metadata_dir="$(mktemp -d)" && trap 'rm -rf "$metadata_dir"' EXIT && (cd backend && WORKSTREAM_TEST_ADMIN_DATABASE_URL=postgresql+asyncpg://workstream:workstream@localhost:5433/postgres .venv/bin/python scripts/run_isolated_tests.py --metadata-json "$metadata_dir/result.json" --timeout-seconds 12600 -- .venv/bin/python -m pytest -q --ignore=tests/test_isolated_database_runner.py --cov=app --cov-report=term-missing --cov-fail-under=78)) -cd backend && for path in 'app/modules/reviews/*' app/modules/checkers/ports.py app/modules/checkers/service.py app/modules/checkers/repository.py app/modules/checkers/router.py app/modules/tasks/models.py app/modules/tasks/lifecycle.py app/modules/tasks/service.py app/modules/tasks/router.py app/workers/checkers.py app/composition/__init__.py app/composition/review_lifecycle.py; do coverage report --include="$path" --precision=2 --fail-under=90 || exit 1; done -``` - -## Required reviewers - -Senior engineering, QA/test, security/auth, product/ops, architecture, docs, -reuse/dedup, and test-delta. - -## Human review focus - -Atomic checker handoff, no queue leakage, routing correctness, and artifact -readiness without provider coupling. +Historical admission scan/classification is not a deployment side effect here. +It belongs to 11C under exact `review.reconcile.run` fixed-service authority, +with bounded batches, stable cursor/resume state, database locks, audit/outbox, +counts, duplicate-safe retry, and explicit remediation reporting. ## Stop condition -Merge, record automated memory, and stop. Do not start 06. +Use `CHUNK_MAP.md`; do not execute this parent. diff --git a/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-06-claims-preference-timers.md b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-06-claims-preference-timers.md index b417b39d1..a6e565d0e 100644 --- a/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-06-claims-preference-timers.md +++ b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-06-claims-preference-timers.md @@ -1,138 +1,23 @@ -# Chunk Contract: WS-REV-001-06 +# Chunk Contract: WS-REV-001-06 - Claims, Preference, And Timers -## Goal +## Status -Implement atomic claim, reviewer release, preferred decline, preference expiry, -lease expiry, and lazy recovery with one global active reviewer lease. +Non-executable split record. -## Risk class +## Children -L1 authorization and concurrency. +- `WS-REV-001-06A`: atomic claim and ReviewLease, claim-time materialization + through 03B's canonical ReviewPacketManifest/item persistence contract, and + mandatory `WS-CON-001-06` reviewer policy freeze. It owns no packet-manifest + model, schema, migration, repository, or duplicate persistence abstraction. +- `WS-REV-001-06B`: reviewer-owned release/decline and preference transitions. +- `WS-REV-001-06C`: separate fixed-service preference and lease expiry plus + request-path lazy recovery. -## Allowed files - -```text -backend/app/modules/reviews/{repository,schemas,service,router}.py -backend/app/composition/review_lifecycle.py only to install the exact merged CON lease-freeze capability -backend/app/workers/{celery_app,reviews}.py -backend/app/core/config.py only for bounded timer settings -backend/tests/test_{reviews,authorization,artifacts,config}.py -docs/operations_queue_policy.md -docs/operations_reviewer_workflow.md only for timer/configuration rollout -.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/** -.agent-loop/merge-intents/WS-REV-001-06.json -``` - -## Not allowed - -```text -review decision or finding writes -admin override or force release -new authorization or artifact semantics -remote provider call while queue/lease rows are locked -reviewer capacity greater than one -production `/api/v1` review-router registration -``` - -## Acceptance criteria - -- A preliminary request-scoped authority and concealment gate precedes bounded - evidence preflight outside row locks. It exposes no packet or binding facts. - The final claim transaction then follows AUTH authority lock -> REV selected - queue and canonical packet-row locks -> final fact recomposition -> one AUTH - evaluation -> lease/manifest/participant flush -> one caller commit. It - revalidates the preflight identity without treating preflight as authority. -- Claim eligibility is re-evaluated inside the transaction before any private - context is disclosed: canonical active human actor, exact active independent - project `reviewer` grant, - required permissions, project match, no self-review against submitter, - creator, or current/prior task assignees, eligible queue state, and no global - active lease. Cross-project, suspended/revoked, self, creator, and assigned - reviewer negatives create no lease or artifact mutation. -- The claim transaction reselects and locks the reviewer's canonical - preferred-first/FIFO current offer and requires any submitted queue ID to - match it. Arbitrary, guessed, stale, lower-priority open, and concurrently - superseded IDs fail without disclosure or mutation. -- Concurrent claims create exactly one lease per entry and per reviewer. -- Lease `ContributionPolicyVersion` freeze required by WS-CON is present and is - resolved for the newly created lease through the merged WS-CON capability. - It is independent of decision outcome and any forward/backward Project Guide - rebase. A later lease may freeze a newer reviewer contribution-policy version, but a - prior lease is never rewritten. -- Claim creates one immutable `ReviewPacketManifest` atomically with the lease - from locked queue, Submission/version, admitting CheckerRun/results, locked - context, response-evidence relations, and ART binding IDs. Manifest creation - failure rolls back the lease and AuthorizationDecision. -- Release, decline, preference expiry, and lease expiry use distinct immutable - audit facts and preserve `first_queued_at`. -- Claim, release, decline, preference expiry, and lease expiry declare, - respectively, `review.claim`, `review.release`, - `review.decline_preference`, `review.preference_expiry.run`, and - `review.lease_expiry.run`. Every mutation uses AUTH's prepared protocol: - authority first; an opaque, non-Pydantic, single-use handle binds exact - session, ActionId, actor-reference kind and ID, idempotency key, and canonical - request digest; REV locks/recomposes final facts and calls AUTH; AUTH validates - every binding/current authority, consumes the handle once, evaluates once, and - stages evidence before the first feature mutation; then participants flush. - Wrong-session/action/actor/request binding, serialized, forged, or - caller-constructed attempts against an unconsumed handle stage no - AuthorizationDecision/evidence, preserve the legitimate handle, and permit its - later exact first use. Stale/already-consumed and concurrent duplicate attempts - remain invalid and stage no new evidence or feature state. Current-authority or policy denial after - valid consumption leaves no lease/routing or feature audit/outbox effect. The - request route or service command rolls back the dirty transaction; AUTH - restages the unchanged bounded denial evidence in a clean transaction; and the - request route or service command commits that evidence once. Evidence, - participant, cancellation, commit, or denial-restaging failure leaves no - partial feature state or authority evidence. -- Preference expiry runs only as fixed service - `workstream.review.preference_expiry`; lease expiry runs only as - `workstream.review.lease_expiry`. Each requires its exact static action row, - an AUTH-09A-compatible enum/constraint/matrix extension, AUTH-09B-provisioned - service ActorProfile/link, AUTH-09E admission, and cross-service/human-path - denial. Neither is one of AUTH-09A's seven ART identities or borrows Operator - or reviewer authority. -- Lease expiry clears stickiness and uses PostgreSQL time. -- Sweeps are idempotent and lazy recovery invokes the same transition service. -- Expected uniqueness races map to stable 409 codes, never 500. -- Claim, release, decline, preference expiry, and lease expiry follow the - canonical lock order; real-Postgres tests use independent sessions/barriers, - both operation permutations, and rollback fault injection. -- Services and internal route tests exist, but production OpenAPI remains free - of every lifecycle mutation through chunk 09B. -- All five actions remain planned while this chunk supplies hidden behavior, - composers, guards, static-service requirements, and a feature-manifest delta. - `WS-AUTH-001-REV-06` activates them only after the chunk merges; route exposure - still waits for REV-13. The exact preference-expiry and lease-expiry service - identity extensions build on AUTH-09A and are separately provisioned from the - published manifest through AUTH-09B/09E; generic admission creates no catch-all - review service. -- Operator docs enumerate every timer environment variable, bounded default, - Celery beat/execution command, lazy-recovery behavior, alert, and rollout rule. -- Timer jobs reuse `run_async_task`, the existing fresh engine/session disposal - pattern, stable Celery task IDs, and `sync_task_settings`; no second async - bridge, session factory helper, queue configuration, or fallback execution - path is introduced. - -## Verification - -```text -cd backend && pytest -q tests/test_reviews.py tests/test_authorization.py tests/test_artifacts.py tests/test_config.py -cd backend && ruff check app/modules/reviews app/workers/reviews.py tests/test_reviews.py -(metadata_dir="$(mktemp -d)" && trap 'rm -rf "$metadata_dir"' EXIT && (cd backend && WORKSTREAM_TEST_ADMIN_DATABASE_URL=postgresql+asyncpg://workstream:workstream@localhost:5433/postgres .venv/bin/python scripts/run_isolated_tests.py --metadata-json "$metadata_dir/result.json" --timeout-seconds 12600 -- .venv/bin/python -m pytest -q --ignore=tests/test_isolated_database_runner.py --cov=app --cov-report=term-missing --cov-fail-under=78)) -cd backend && for path in 'app/modules/reviews/*' app/composition/review_lifecycle.py app/workers/reviews.py app/workers/celery_app.py app/core/config.py; do coverage report --include="$path" --precision=2 --fail-under=90 || exit 1; done -``` - -## Required reviewers - -Senior engineering, QA/test, security/auth, product/ops, architecture, docs, -reuse/dedup, and test-delta. - -## Human review focus - -Database-time races, lock ordering, preflight freshness, compensation freeze, -and retry-safe job behavior. +Each command publishes its own AUTH-first lock order, database-time boundary, +idempotency, concealment, independent-session races, and rollback proof. No +child combines service identities or borrows human/Operator authority. ## Stop condition -Merge, record automated memory, and stop. Do not start 07. +Use `CHUNK_MAP.md`; do not execute this parent. diff --git a/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-07-review-context-finding-evidence.md b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-07-review-context-finding-evidence.md index 16f7c3fd6..452267431 100644 --- a/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-07-review-context-finding-evidence.md +++ b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-07-review-context-finding-evidence.md @@ -1,157 +1,19 @@ -# Chunk Contract: WS-REV-001-07 +# Chunk Contract: WS-REV-001-07 - Review Context And Finding Evidence -## Goal +## Status -Provide authorized Review Context retrieval and verified finding/finding-response -evidence intake through Workstream-owned artifact capabilities. +Non-executable split record. -## Risk class +## Children -L1 authorization, private data, and artifact integrity. +- `WS-REV-001-07A` owns active-exact-lease packet content and relationship- + scoped immutable chain metadata after ART merges packet-read ownership. +- `WS-REV-001-07B` owns reviewer finding-evidence candidate/finalize only after + ART merges the evidence port and AUTH merges the exact binding contracts. -## Allowed files - -```text -backend/app/modules/reviews/{repository,schemas,service,router}.py -backend/app/composition/review_lifecycle.py only to install exact merged ART packet-read and evidence ports -backend/tests/test_{reviews,artifacts,authorization,checkers,tasks,app}.py -docs/operations_reviewer_workflow.md -docs/template_review_packet.md -.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/** -.agent-loop/merge-intents/WS-REV-001-07.json -``` - -## Not allowed - -```text -decision commit -raw CID/path/URL/provider credential acceptance -human token forwarding to storage -provider-specific imports in review services -review-authoritative search state -production `/api/v1` review-router registration -``` - -## Acceptance criteria - -- Context read declares the `review.context.read` action mapped to - `submission.read_for_review`, then requires an active owned lease. The - separate review-chain endpoint declares `review.chain.read`; one endpoint - never declares two primary actions. -- `review.chain.read` additionally requires one server-resolved relationship: - the actor is the canonical contributor on the exact TaskAssignment associated - with a Submission in the requested chain; owns the active lease anchored to - the chain; authored a prior Review in the chain and still has the current - exact current project `reviewer` grant; or holds the explicit Project Manager/Operator inspection - permission. Arbitrary same-project reviewers, caller-selected unrelated - chains, cross-project actors, and revoked grants are denied. Prior - participation permits bounded metadata only, never content. -- Finding-evidence intake declares `review.finding_evidence.ingest` mapped to - `review.decision`; the active owned lease and exact server-derived evidence - scope are lifecycle/resource guards. Pre-intake denial creates no ART - candidate, binding, or receipt. -- Merged ART-02A2 supplies preparation and ART-02A3 supplies the byte-only v2 - LocalStorage clean cut; neither satisfies this chunk's review-facing ART gate. - REV imports no ART scratch/source or raw-store implementation. Chunk start - requires ART submission/checker cutovers, a separately approved and merged - ART-owner amendment for the currently unassigned narrow packet-read port, and a - separately approved/merged `WS-ART-001-REV-EVIDENCE` candidate/finalize - capability with canonical ART facts, guards, orphan retention, and tests. -- Binding finalization requires separately registered planned action - `artifact.review_evidence.binding.create`, mapped only to - `artifact.binding.create` and fixed identity `workstream.artifact.binding`. - It is not an alias of either human evidence-ingest action, generic artifact - retrieval, or Operator `artifact.binding.read`. AUTH activates it only after - the hidden ART capability merges. -- The exact locked guide/policy/submission/checker/prior-review chain is - disclosed as bounded history. Artifact bytes and complete binding metadata - are retrievable only for the canonical current review packet anchored to the - one Submission covered by the caller's active lease: that Submission's - bindings, the bindings attached to - `ReviewQueueEntry.admitting_checker_run_id`, its current - finding-response evidence, and required locked-context/source-snapshot - bindings. The server derives packet membership from canonical relations. -- Review service consumes the checker-owned context-reader port and task-owned - public relationships; it imports neither CheckerRepository nor TaskRepository. -- Unauthorized, cross-project/task, guessed, and nonexistent bindings are - concealment-equivalent and expose no binding existence or state. Distinct - stable availability and integrity errors plus bounded audit are permitted only - after exact in-scope authority and packet membership are established. -- Prior, later, sibling, and previously leased Submission artifacts fail closed - without an active lease for that exact Submission. An expired or consumed - lease grants no residual content authority; history remains metadata-only. -- Human tokens never enter artifact calls; service scope is least privilege. -- Finding evidence and response evidence enter the ART candidate port, become - verified bindings, and create immutable REV-owned `ReviewEvidenceArtifact` - relations referenced publicly only by ArtifactBinding ID. -- Reviewer finding evidence uses ART intake under the active lease before its - ArtifactBinding ID is attached to ReviewFinding. Raw bytes and provider - locations never enter the Review decision payload. -- Finding-evidence intake requires the active owned lease and exact finding - evidence operation; response-evidence intake is owned by chunk 09A under - `review.finding_response_evidence.ingest`, the contributor's owned active - assignment, and a prepared revision context. - Scope is derived server-side as exact project/task/submission/finding and - operation. Intake uses the merged ART-owned two-phase capability: request - preflight derives scope and ingests/verifies an unbound candidate outside - review locks; finalization uses AUTH authority lock -> REV lease/assignment, - Submission, evidence-slot and packet-lineage locks -> ART candidate/admission/ - binding locks -> final fact recomposition -> AUTH validation of exact bindings - and current authority, single consumption, evaluation, and decision-evidence staging -> binding plus - ReviewEvidenceArtifact flush. AUTH's opaque, non-Pydantic, single-use - handle is bound to the exact session, ActionId, actor-reference kind and ID, - idempotency key, and canonical request digest and is consumed by AUTH before the - first binding or REV mutation. Wrong-binding, serialized, forged, or - caller-constructed attempts against an unconsumed handle fail before canonical - mutation, stage no AuthorizationDecision/evidence, preserve the legitimate - handle, and permit its later exact first use. Stale/already-consumed and - concurrent duplicate attempts remain invalid and stage no new state. Current-authority - or policy denial after valid consumption follows AUTH's clean denial-evidence - protocol. A mid-intake stale - lease, revocation, assignment loss, preparation supersession, or cross-project - mismatch creates no canonical Workstream binding/relation or lifecycle effect; - an already uploaded unbound candidate remains only under ART retention and - orphan cleanup. Decision/resubmission revalidates the binding again. -- If the merged ART contract lacks candidate/finalize and orphan-retention - semantics, this chunk blocks for an ART-owned foundation change. Review code - adds no private upload/candidate table or provider cleanup path. -- Retrieval is bounded and logs contain no content, signed capabilities, paths, - credentials, or unrestricted finding text. -- LocalStorage and MinIO pass the same review-artifact contract tests. -- Production OpenAPI remains free of lifecycle routes; no private context is - exposed before the final product release. -- REV supplies hidden read/evidence behavior and feature-manifest deltas while - human actions remain planned. `WS-AUTH-001-REV-07` separately activates the - three REV actions only after this chunk, and - `WS-AUTH-001-ART-REV-EVIDENCE` activates the ART binding action only after its - hidden ART capability and exact service identity merge. -- Authorization tests cover submitter, active reviewer, prior participating - reviewer, takeover reviewer, Project Manager/Operator, arbitrary same-project - reviewer, cross-project actor, expired lease, and revoked grant. Independent - session/fault tests race lease expiry and grant revocation against reviewer - evidence intake in both orders and prove only an ART orphan candidate may - remain after failed finalization. - -## Verification - -```text -cd backend && pytest -q tests/test_reviews.py tests/test_artifacts.py tests/test_authorization.py tests/test_checkers.py tests/test_tasks.py tests/test_app.py -cd backend && ruff check app/modules/reviews app/modules/artifacts tests/test_reviews.py tests/test_artifacts.py tests/test_app.py -(metadata_dir="$(mktemp -d)" && trap 'rm -rf "$metadata_dir"' EXIT && (cd backend && WORKSTREAM_TEST_ADMIN_DATABASE_URL=postgresql+asyncpg://workstream:workstream@localhost:5433/postgres .venv/bin/python scripts/run_isolated_tests.py --metadata-json "$metadata_dir/result.json" --timeout-seconds 12600 -- .venv/bin/python -m pytest -q --ignore=tests/test_isolated_database_runner.py --cov=app --cov-report=term-missing --cov-fail-under=78)) -cd backend && for path in 'app/modules/reviews/*' app/composition/review_lifecycle.py; do coverage report --include="$path" --precision=2 --fail-under=90 || exit 1; done -``` - -## Required reviewers - -Senior engineering, QA/test, security/auth, product/ops, architecture, docs, -reuse/dedup, and test-delta. - -## Human review focus - -Current-review-packet isolation, history/content separation, canonical packet -membership, scope derivation, token isolation, evidence classification, -integrity quarantine, and provider equivalence. +Revision response evidence belongs only to 09A3. No 07 child receives raw +ArtifactStore/provider/repository access or makes history bytes readable. ## Stop condition -Merge, record automated memory, and stop. Do not start 08. +Use `CHUNK_MAP.md`; do not execute this parent. diff --git a/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-08-immutable-decision-kernel.md b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-08-immutable-decision-kernel.md index 0e27e74b9..47b1b8855 100644 --- a/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-08-immutable-decision-kernel.md +++ b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-08-immutable-decision-kernel.md @@ -1,140 +1,92 @@ -# Chunk Contract: WS-REV-001-08 +# Chunk Contract: WS-REV-001-08 - Pure Decision, Final Acceptance, And Task-Effect Contract ## Goal -Freeze the immutable review-decision request, pure validation, task-effect -participant, lock/fact contract, the FinalAcceptance consequence of `accept`, -and the two operation-specific CON participant inputs. Do not create a -canonical Review-committing service, including the additional FinalAcceptance -write for `accept`, before CON merges. +Freeze pure request schemas, canonical hashing/idempotency inputs, final-fact +validation, typed task effects, and the two ordered CON operation inputs. Add no +repository mutation, AUTH evidence staging, Review, FinalAcceptance, route, or +commit-capable orchestration. ## Risk class -L1 canonical judgment and transaction integrity. +L1 canonical judgment contract. -## Allowed files +## Preconditions -```text -backend/app/modules/reviews/{repository,schemas,service}.py -backend/app/modules/tasks/{models,review_participant}.py only for caller-transaction decision effects -backend/app/composition/review_lifecycle.py only to install the exact task participant -backend/tests/test_{reviews,tasks,authorization,artifacts,audit}.py -.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/** -.agent-loop/merge-intents/WS-REV-001-08.json -``` +07B merged; exact current Review/lease/packet/finding/evidence schema; exact +current task and CON participant protocols; separate human start and plan review. + +## Allowed scope + +Only pure review schemas/validators/hash inputs, task-owned typed effect input +protocols, CON operation input protocols/fakes, focused pure tests, initiative +artifacts, and this chunk's single merge intent. The current-main start contract +must enumerate exact files before implementation. ## Not allowed ```text -public decision route -production no-op WS-CON participant -any code path that commits a canonical Review, or an accept-path FinalAcceptance, -without the exact CON participant -remote storage calls inside the transaction -mutation of prior Submission, Review, ReviewFinding, or FindingResolution -reputation or fulfillment logic +AUTH prepare/evaluate/evidence calls +repository/model/migration/audit/outbox writes +Review, finding, resolution, FinalAcceptance, queue, lease, task, or assignment mutation +public/hidden route or service capable of committing a canonical decision +optional/no-op CON participant, ART call, contribution/award/reputation policy ``` ## Acceptance criteria -- The frozen transaction contract rechecks exact reviewer grant, lease ownership/ - expiry, no-self-review, queue state, idempotency, predecessor chain, packet - manifest, evidence relations, and stabilized binding facts using database time. -- The command declares planned `review.decision`. Mutation choreography is AUTH - prepare/authority lock -> opaque, non-Pydantic, single-use handle bound to the - exact session, ActionId, reviewer actor-reference kind and ID, idempotency key, - and canonical request digest -> REV locks and final fact recomposition -> AUTH - validates exact bindings/current authority, consumes once, evaluates once, and - stages evidence before the first feature mutation -> REV appends the Review, - findings, and resolutions -> CON - reviewer operation -> REV decision branch -> CON submitter operation only for - `accept` -> REV audit and outbox staging -> request route or service command - commits once. No plain mutation-time `require()` or serialized authorization - handle substitutes. Wrong-binding, forged, serialized, or caller-constructed - attempts against an unconsumed handle fail before mutation, stage no - AuthorizationDecision/evidence, preserve the legitimate handle, and permit its - later exact first use. Stale/already-consumed and concurrent duplicate attempts - remain invalid and stage no new state. Current-authority or policy denial after - valid consumption follows AUTH's clean denial-evidence protocol and leaves no - Review, lifecycle, CON, or feature/shared audit/outbox mutation. -- Decision, finding, evidence, and resolution rules match the canonical spec. -- Task effects use the task-owned `TaskReviewEffectsParticipant` with the - caller's AsyncSession. It flushes without commit, reuses TaskRepository and - lifecycle guards internally, and is the only path for review-driven task or - assignment effects; review code never imports TaskRepository. -- Common effects append one immutable Review and every submitted immutable - finding and resolution, consume the ReviewLease, close the ReviewQueueEntry, - and invoke the mandatory CON participant's reviewer operation. That operation - creates `completed_review` and evaluates the reviewer policy. Accept then - appends FinalAcceptance, targets the Task state `accepted`, completes the - TaskAssignment, and invokes the participant's submitter operation. Needs revision appends no - FinalAcceptance, keeps the assignment active, targets `needs_revision`, and - invokes no submitter operation. Human reject appends no FinalAcceptance, - blocks only that assignment, targets canonical `rejected` with reason, and - invokes no submitter operation. - Administrative closure is not a decision. -- Every decision appends one immutable Review and any submitted immutable - findings and resolutions before the reviewer contribution operation. The `accept` - branch later prepares one same-chain immutable FinalAcceptance; - `needs_revision` and `reject` prepare none and cannot invoke the submitter - operation. - No separate FinalAcceptance authorization action or public/manual creation - contract exists. -- One mandatory typed CON participant exposes two ordered flush-only operations - in the caller's AsyncSession. The reviewer operation always receives exact - Review and ReviewLease facts, creates the reviewer contribution, and evaluates - the reviewer policy. The submitter operation is called only after REV creates - FinalAcceptance for `accept`; it receives FinalAcceptance and TaskAssignment - facts, creates the submitter contribution, and evaluates the submitter policy. - Neither input uses nullable FinalAcceptance or combines both actors' frozen - policy contexts. Both operations return typed audit and outbox staging inputs - and never commit. -- Pure tests prove the future atomic write set: immutable Review and submitted - findings and resolutions for every decision, FinalAcceptance for `accept`, - ReviewEvidenceArtifact links, queue and lease state, Task and TaskAssignment - effects, CON contributions and awards, REV-staged audit records, and outbox - records. This chunk does not expose a service capable of committing that set. -- Exact replay contract returns the Review after REV-10; changed replay fails. -- Idempotency is bound to actor, operation, lease, submission, and canonical - payload. Replay reauthorizes disclosure for the same actor without requiring - a consumed lease to remain active; cross-actor, revoked-disclosure, or changed - payload replay fails without revealing the prior result. -- The decision actor is the active canonical human `ActorProfile.id` that owns - the exact ReviewLease. UUID shape alone is insufficient; a service actor, - system principal, legacy ID, or external subject cannot decide a Review. -- No hidden or production composition can commit a Review before the exact CON - participant is installed. The same rule covers the additional FinalAcceptance - write on the `accept` path. Absence of either ordered CON operation fails - construction; no optional or no-op path exists. -- This chunk proves command-specific lock planning and the task participant. Full - decision races, participant rollback, and canonical commits move to REV-10 - after CON merges. -- Audit, outbox, dead-letter, alerts, and error details contain only bounded - typed projections: no finding body, private artifact metadata, signed access, - provider path, or unrestricted identity value. -- Audit uses the shared caller-transaction participant with request/correlation - and AuthorizationDecision linkage; no review-private audit persistence exists. +- Decision values are exactly accept, needs_revision, reject. Findings use the + canonical blocking/advisory rules; later resolutions remain append-only. +- Canonical request hash/idempotency input binds actor-reference kind/ID, action, + lease, Submission, packet manifest, payload, and client key using the existing + `canonical_json_hash` convention. +- Pure final-fact validation accepts exact canonical human reviewer/lease, + reviewer grant, no-self-review, unexpired lease, open queue, task/assignment, + Submission, packet/evidence, predecessor, and immutable lineage facts. It + performs no database or external I/O. +- `TaskReviewEffectsInput` expresses exact branch effects against + `Submission.task_assignment_id`: accept completes it/task; needs_revision + retains it and carries typed human `RevisionOriginFacts`; reject blocks it and + rejects task. No moving current assignment is inferred. +- CON reviewer operation input contains exact future Review, ReviewLease, + reviewer, reviewer policy freeze, and stabilized lineage. CON submitter input + contains exact future FinalAcceptance, TaskAssignment, submitter, assignment + policy freeze, and the same lineage. Neither is nullable/omnibus. +- Pure choreography proves reviewer operation precedes every branch and + submitter operation exists only after accept produces FinalAcceptance. +- No interface allows FinalAcceptance manual creation or separate authorization. +- Chunk 10 remains the first caller of AUTH prepared mutation and the first code + capable of appending/committing Review, findings/resolutions, + FinalAcceptance, task effects, CON rows, audit, or outbox. ## Verification ```text -cd backend && pytest -q tests/test_reviews.py tests/test_tasks.py tests/test_authorization.py tests/test_artifacts.py tests/test_audit.py -cd backend && ruff check app/modules/reviews app/modules/tasks tests/test_reviews.py tests/test_tasks.py -(metadata_dir="$(mktemp -d)" && trap 'rm -rf "$metadata_dir"' EXIT && (cd backend && WORKSTREAM_TEST_ADMIN_DATABASE_URL=postgresql+asyncpg://workstream:workstream@localhost:5433/postgres .venv/bin/python scripts/run_isolated_tests.py --metadata-json "$metadata_dir/result.json" --timeout-seconds 12600 -- .venv/bin/python -m pytest -q --ignore=tests/test_isolated_database_runner.py --cov=app --cov-report=term-missing --cov-fail-under=78)) -cd backend && for path in 'app/modules/reviews/*' app/modules/tasks/models.py app/modules/tasks/review_participant.py app/composition/review_lifecycle.py; do coverage report --include="$path" --precision=2 --fail-under=90 || exit 1; done +cd backend && .venv/bin/python -m pytest -q tests/test_reviews.py tests/test_tasks.py tests/test_contributions.py +cd backend && .venv/bin/ruff check app/modules/reviews app/modules/tasks tests/test_reviews.py tests/test_tasks.py tests/test_contributions.py +cd backend && .venv/bin/docstr-coverage --config .docstr.yaml +(metadata_dir="$(mktemp -d)" && trap 'rm -rf "$metadata_dir"' EXIT && cd backend && WORKSTREAM_TEST_ADMIN_DATABASE_URL=postgresql+asyncpg://workstream:workstream@localhost:5433/postgres .venv/bin/python scripts/run_isolated_tests.py --metadata-json "$metadata_dir/result.json" --timeout-seconds 12600 -- .venv/bin/python -m pytest -q --ignore=tests/test_isolated_database_runner.py --cov=app --cov-report=term-missing --cov-fail-under=78) +cd backend && .venv/bin/coverage report --include='app/modules/reviews/*' --precision=2 --fail-under=90 +cd backend && .venv/bin/coverage report --include='app/modules/tasks/*' --precision=2 --fail-under=90 +python3 scripts/check_stale_workstream_wording.py +python3 scripts/check_stale_authorization_docs.py +python3 scripts/check_stale_artifact_contracts.py +python3 scripts/check_stale_review_contracts.py +python3 scripts/check_markdown_links.py +python3 scripts/check_internal_review_evidence.py +PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 backend/.venv/bin/python scripts/test_agent_gates.py +python3 scripts/update_post_merge_memory.py validate-merge-intent --base-ref origin/main +git diff --check ``` +The current-main start contract must preserve these gates and may only narrow +focused paths to the exact allowed-file manifest it approves. + ## Required reviewers Senior engineering, QA/test, security/auth, product/ops, architecture, -reuse/dedup, and test-delta. - -## Human review focus - -Complete decision contract and FinalAcceptance consequence, no premature -canonical commit, route absence, and no contribution or storage side-effect gap -hidden by tests. +reuse/dedup, docs, and test-delta. ## Stop condition -Merge, record automated memory, and stop. Do not start 09A. +Merge, record automated memory, and stop. Do not start 02A2 automatically. diff --git a/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-09A-revision-context-resubmission.md b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-09A-revision-context-resubmission.md index 378d58ccb..18a339a63 100644 --- a/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-09A-revision-context-resubmission.md +++ b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-09A-revision-context-resubmission.md @@ -1,282 +1,37 @@ -# Chunk Contract: WS-REV-001-09A - -## Goal - -Implement controlled revision-context preparation, immutable responses and -response evidence, and guarded version N+1 resubmission without replay -resolution or return routing. - -## Risk class - -L1 policy, immutable history, and contributor fairness. - -## Allowed files - -```text -backend/app/modules/reviews/{repository,schemas,service,router}.py -backend/app/modules/reviews/task_revision_participant.py -backend/app/modules/tasks/{models,repository,service,lifecycle,submission_participant}.py -backend/app/modules/projects/{models,repository,service}.py only for approved current guide/task-execution-policy resolution -backend/app/modules/checkers/models.py only for checker-to-submission context integrity -backend/app/composition/review_lifecycle.py only to install the revision participant -backend/app/db/models.py -backend/alembic/versions/_revision_context.py -backend/tests/test_{alembic,reviews,tasks,projects,checkers,artifacts,authorization,app}.py -docs/decision_0010_revision_context_rebase.md -docs/operations_revision_replay.md -docs/template_revision_replay.md -.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/** -.agent-loop/merge-intents/WS-REV-001-09A.json -``` - -## Not allowed - -```text -mutation of prior submission/review/finding -new submission.revise permission -parallel review-owned resubmission endpoint -contributor/reviewer-callable revision-preparation or repair route -out-of-band guidance as acceptance authority -automatic reject at limit/deadline -public decision route activation -finding resolution or preferred-return routing -production `/api/v1` review-router registration -``` - -## Acceptance criteria - -- Revision preparation compares the prior Submission's stamped guide identity - and activation sequence with the project's currently active Project Guide. - Exact identity/activation-sequence match records `kept`; any different active - identity or sequence records `rebased` plus `forward` or `backward` direction, - including a lower activation sequence. Missing, incomplete, or unsafe active - context records manager-repair block. No prior - task-attempt or Submission row is mutated. -- Immutable `RevisionContextPreparation` persists task, immutable - `reviewed_task_assignment_id`, current `target_task_assignment_id`, and prior- - Submission identity; `revision_episode_id` as an FK to the originating - `needs_revision` Review (not a separate episode entity); - target Submission version; preparation sequence/supersession identity; - kept/rebased/blocked - outcome; complete guide/source-snapshot and task-execution policy IDs, - versions, hashes, and locked bodies required by submission/checker execution; - context digest; - bounded change summary/reason; preparing actor/process; audit link; and - database timestamp. A partial unique root constraint permits exactly one root - per revision episode; `(task_id, revision_episode_id, preparation_sequence)` - is unique; `supersedes_preparation_id` is unique so one parent has at most one - child; and a deferred constraint trigger requires every edge to keep the same - task, reviewed assignment, prior Submission, target version, and episode while - incrementing the sequence by exactly one. Target assignment also remains the - same except for the exact authority-loss replacement transition below. - Manager repair appends a successor; - the row with no child is the sole head. -- A deferred database constraint validates the episode Review and root together: - `revision_episode_id` must reference a Review whose decision is - `needs_revision`, whose reviewed Submission is exactly `prior_submission_id`, - and whose project, task, and reviewed TaskAssignment match - `reviewed_task_assignment_id`; the target assignment must be for the same task - and exact active contributor authorized to fulfill the next attempt; - `target_submission_version` must be the prior Submission version plus one. - Successors retain that exact root lineage. -- Normal roots set target assignment equal to reviewed assignment. If AUTH-13 - closes that assignment for authority loss, the task retains an unassigned - revision obligation. A covered manager's later replacement-assignment command - invokes a typed review-owned transfer participant in the same caller session; - it appends exactly one successor whose reviewed assignment remains fixed and - whose target is the replacement, re-evaluates the authoritative current guide, - and commits or rolls back with assignment creation. Reactivation never restores - the old assignment. Concurrent replacement/repair/submission produces one - head or a stable stale-head conflict. -- Finding-response evidence intake declares - `review.finding_response_evidence.ingest` mapped to `submission.create`; it - uses request-scoped preflight before ART candidate intake. Finalization uses - AUTH prepare/authority lock and an opaque, non-Pydantic, single-use handle - bound to exact session, ActionId, actor-reference kind and ID, idempotency key, - and canonical request digest -> REV exact assignment, preparation head, prior - Submission, finding and evidence-slot locks -> ART candidate/admission/binding - locks -> final fact recomposition -> AUTH validation of exact bindings/current - authority, single consumption, evaluation, and evidence staging before the - first binding or REV mutation -> binding plus ReviewEvidenceArtifact flush. - Wrong-binding, serialized, forged, or caller-constructed attempts against an - unconsumed handle fail before canonical mutation, stage no - AuthorizationDecision/evidence, preserve the legitimate handle, and permit its - later exact first use. Stale/already-consumed and concurrent duplicate attempts - remain invalid and stage no new state. Current-authority - or policy denial after valid consumption follows AUTH's clean denial-evidence - protocol. Pre-intake denial creates no ART candidate, binding, or receipt. -- Contributor and later reviewer see old/new guide/task-execution-policy context - and change summary. ContributionPolicyVersion is not part of this context. -- While the task is `needs_revision`, the assigned submitter's Task Context API - returns the prepared next-attempt guide/policy context. Submission N+1 stamps - that same context; the reviewer later consumes it from Submission N+1 and - performs no separate guide rebase. -- Project Guide is the only guide identity. No ReviewGuide, reviewer guide lock, - or duplicate TaskAssignment guide-version field is introduced. -- Preparation freezes exact guide/source-snapshot and task-execution policy IDs, - versions, and hashes. It never copies, substitutes, or rebases - `ContributionPolicyVersion`; submitter policy remains frozen on the - immutable TaskAssignment and reviewer policy remains frozen on each - ReviewLease. Task Context returns the preparation and Submission N+1 must - match it exactly. A later guide activation causes no silent drift; a revoked, - corrupt, or invalid prepared context fails with an explicit re-preparation - requirement. -- The hidden `needs_revision` transaction synchronously appends the initial - preparation before the task becomes contributor-readable. Task Context is a - read-only deterministic resolver that selects the unsuperseded head and then - validates it; a blocked/revoked/corrupt/invalid head never falls back and the - read performs no lazy write. Revision submission supplies the head ID/digest as an - acknowledgment; Submission N+1, finding responses, audit, and enqueue intent - commit atomically against it. -- The migration removes Submission composite FKs that require every locked - context field to equal `WorkstreamTask.locked_*`. It replaces them with - direct same-project ProjectGuide/policy/source-snapshot integrity constraints, - requires version N+1 to reference the exact preparation/context digest, and - preserves the original task locks and every prior Submission unchanged. -- The same migration removes CheckerRun composite FKs that require guide/review/ - revision context to equal `WorkstreamTask.locked_*`. Any legacy checker or - Submission payment-context fields have already been removed by the exact - merged CON-owned retirement capability and are not replaced here. A CheckerRun for - Submission N is instead constrained to the exact immutable context stamped on - Submission N, including its post-submit policy and rebased guide/policy/source - facts. This permits checker execution for a valid rebased N+1 without allowing - mixed task, project, Submission, or context lineage. -- The existing `submission.create` operation creates version N+1 with immediate - predecessor and one immutable response per unresolved blocking finding. -- Revision preparation is a task-owned internal participant invoked by - `needs_revision`; submission only validates/acknowledges its frozen result. - Initial preparation has no separately callable route or ActionId. The - privileged manager repair command is deliberately deferred to chunk 11 and - may append a successor only; it cannot create the root. -- `POST /api/v1/tasks/{task_id}/submissions` remains the only submission route. - It declares the canonical AUTH-14 `submission.create` action for both initial - and revision submissions. - This chunk extracts its task-owned participant with caller AsyncSession and - reuses existing version allocation, locked policy, lifecycle, audit, and - post-commit enqueue rules without changing the registered route/schema or - legacy production behavior. The hidden review revision participant validates - preparation/responses and flushes response rows in the same test unit of - work; neither domain imports the other's repository. -- Required response evidence references verified same-project/task bindings. -- Checker gate does not admit a revision missing required responses/evidence. -- At the exact revision-round limit or revision deadline, preparation and N+1 - submission fail with stable policy errors. Task remains `needs_revision`, - TaskAssignment remains active, and no Review, finding, terminal Task or - Assignment status, CON record, award, feature audit, or outbox record is - created. Tests cover below/at/after each boundary, retry, and transaction - rollback. The explicit reason-bound cancellation command remains owned only by - REV-11; 09A never closes the obligation or fabricates reject. -- Response-evidence authorization uses - `review.finding_response_evidence.ingest` mapped to `submission.create`, plus - the owned active assignment, prepared revision context, and exact - server-derived project/task/submission/finding operation scope. A race lost to - revocation, assignment loss, or preparation supersession creates no canonical - binding/relation, Submission response, or lifecycle effect; any uploaded - unbound candidate is ART-owned and expires through ART retention. -- Response finalization depends on the same merged - `WS-ART-001-REV-EVIDENCE` port and AUTH-active - `artifact.review_evidence.binding.create` service action as REV-07; human - `submission.create` authority cannot execute that ART action. -- Revision preparation, evidence-intake, and structured response behavior remain - hidden and unavailable from production OpenAPI/composition in this chunk. - Existing first-submission and legacy revision behavior is unchanged until the - later amended AUTH-14 cutover installs the prepared branch and strict guard - behind unavailable `submission.create`; internal composition/tests prove the - new path before that owner cutover. -- This chunk changes no AUTH availability. It supplies hidden behavior and a - feature-manifest delta for later `WS-AUTH-001-REV-09A` activation; route - exposure waits for REV-13. -- Preparation-reference columns and conditional lineage constraints land here, - but the global rule requiring every newly written version greater than one to - reference a preparation does not. After REV-09A merges, amended AUTH-14 owns - the `NOT VALID` check and replaces the legacy submission branch in one reviewed - cutover while `submission.create` remains unavailable. REV-13 later verifies - and exposes that already merged cutover, so no deployment exposes an - `IntegrityError` or an accidental early public block. -- Import-boundary and rollback tests prohibit a parallel resubmission route, - commit-owning participant, repository cycle, or duplicate post-commit enqueue. -- Real-Postgres tests cover same-guide keep, forward changed-guide rebase, - backward changed-guide rebase, inconsistent/unsafe block, - repair/successor preparation, Task - Context before submission, preparation - acknowledgment mismatch, invalid preparation, constraint-safe N+1 stamping, - and immutable N/prior task locks. -- Forward and backward rebase tests prove the TaskAssignment submitter - ContributionPolicyVersion is unchanged. A later reviewer lease may - independently freeze the then-current reviewer ContributionPolicyVersion; no - Submission, CheckerRun, Task Context, or preparation field duplicates either - contribution-policy freeze. -- Independent-session barrier tests race guide activation against - `needs_revision` and prove one complete old/new context, canonical lock order, - and no mixed policy generation or deadlock. Head-selection tests prove no - fallback from blocked/invalid successors. -- Independent-session barriers exercise the repository/schema successor - primitive by racing two successor appends and a - successor append against N+1 submission on the formerly current head. Exactly - one unsuperseded head remains; submission either commits against its still- - current acknowledged head or fails `repreparation_required`, with no fallback, - partial response rows, or feature audit/enqueue intent. AUTH may retain only - its bounded clean denial evidence under the AUTH-owned rollback/restaging - protocol. -- A post-read activation test prepares and reads context, activates a newer - guide, then proves the still-valid frozen head stamps one complete old context - without drift. Separate revocation/corruption tests require re-preparation and - produce no Submission/response or feature audit/enqueue side effects. AUTH may - persist only its bounded clean denial evidence; evidence, participant, - cancellation, or commit failure leaves no partial authority evidence. -- Independent-session tests race grant revocation, assignment loss, and - preparation-head supersession against response-evidence candidate intake and - finalization in both orders. Submission creation revalidates the finalized - canonical binding and cannot consume an orphan candidate. -- Replacement-assignment tests prove authority-loss close, durable unassigned - obligation, atomic successor transfer, replacement Task Context/read and N+1 - submission, old-contributor denial, replay requirements, guide re-evaluation, - target-assignment contribution-policy source, and rollback/concurrent replacement. -- Fault injection during initial preparation rolls back the Review, - `needs_revision` task/assignment effect, lease consumption, audit, and outbox - so contributor access can never observe `needs_revision` without one head. -- Migration fixtures cover existing initial/revision rows, the non-forgeable - preparation-reference schema, preserved historical task-equal contexts, and - a prepared rebased N+1 whose context differs from the original task lock. - They prove unprepared legacy rows remain possible only until amended AUTH-14's - atomic route/schema cutover. Direct SQL rejects cross-project - guide/policy/source/preparation references, prior-Submission mismatch, and - preparation digest mismatch. Upgrade proof documents that rollback is blocked - once rebased rows depend on the new constraints. -- Migration/constraint tests also create a rebased N+1 CheckerRun and prove it - matches Submission N+1 rather than the original task lock. Direct SQL rejects - checker rows with crossed Submission, project, guide, source, or policy facts. - Existing `needs_revision` tasks that lack an originating Review and preparation - root are reported as incompatible and remain fail-closed for operator - remediation; migration and activation never fabricate a Review or root. -- Direct SQL root tests reject an accept/reject Review, a Review of another - Submission, crossed task/project/assignment lineage, a target version other - than prior version plus one, a second root, and a branched/skipped successor; - each failed transaction leaves no root or head. Migration proof also shows - historical unprepared revisions remain immutable/readable, names the - conditions for amended AUTH-14 enforcement/validation and later REV-13 - verification/exposure, and blocks migration downgrade once prepared rows exist. - -## Verification - -```text -cd backend && alembic upgrade head -cd backend && pytest -q tests/test_reviews.py tests/test_tasks.py tests/test_projects.py tests/test_checkers.py tests/test_artifacts.py tests/test_authorization.py tests/test_alembic.py tests/test_app.py -cd backend && ruff check app/modules/reviews app/modules/tasks app/modules/projects app/modules/checkers/models.py tests/test_reviews.py tests/test_tasks.py tests/test_checkers.py tests/test_app.py -(metadata_dir="$(mktemp -d)" && trap 'rm -rf "$metadata_dir"' EXIT && (cd backend && WORKSTREAM_TEST_ADMIN_DATABASE_URL=postgresql+asyncpg://workstream:workstream@localhost:5433/postgres .venv/bin/python scripts/run_isolated_tests.py --metadata-json "$metadata_dir/result.json" --timeout-seconds 12600 -- .venv/bin/python -m pytest -q --ignore=tests/test_isolated_database_runner.py --cov=app --cov-report=term-missing --cov-fail-under=78)) -cd backend && for path in 'app/modules/reviews/*' app/modules/tasks/models.py app/modules/tasks/repository.py app/modules/tasks/service.py app/modules/tasks/lifecycle.py app/modules/tasks/submission_participant.py app/modules/projects/models.py app/modules/projects/repository.py app/modules/projects/service.py app/modules/checkers/models.py app/composition/review_lifecycle.py; do coverage report --include="$path" --precision=2 --fail-under=90 || exit 1; done -``` - -## Required reviewers - -Senior engineering, QA/test, security/auth, product/ops, architecture, docs, -reuse/dedup, and test-delta. - -## Human review focus - -Fairness of rebase, complete response input, evidence authorization, and no -synthetic decision. +# Chunk Contract: WS-REV-001-09A - Revision Context Preparation And Resubmission + +## Status + +Non-executable split record. Controlled rebase remains rooted only in a human +`Review(needs_revision)`. Checker-caused remediation remains a distinct +CheckerRun-rooted path and is not treated as legacy. + +## Children + +- `WS-REV-001-09A1`: immutable Review-rooted, task-owned non-branching + RevisionContextPreparation persistence after human approval of exact round/ + deadline semantics. +- `WS-REV-001-09A2`: task-owned preparation participant and guide-context + resolver plus Task Context read. The participant uses 09A1 persistence and + flushes through the caller's session; decision transaction composition and + the single commit remain in chunk 10. +- `WS-REV-001-09A3`: human Review finding responses/evidence only. +- `WS-REV-001-09A4`: hidden prepared human N+1 task/checker participant. It adds + the server-selected Submission-to-preparation binding and replaces 02C's + checker-only N+1 guard with the exact version/source XOR: v1 has neither source; + human N+1 has only `revision_context_preparation_id`; checker-remediation N+1 + retains only 02C's immutable `remediation_source_checker_run_id`. Later AUTH-14 + owns public request acknowledgement, authorization cutover, and activation + after its contract amendment merges; it does not own these REV lifecycle + columns or constraints. +- `WS-REV-001-09A5`: hidden replacement-assignment preparation transfer; later + AUTH-13 owns public command/cutover/activation after its contract amendment. + +Checker remediation creates no Review/finding/reviewer contribution, performs no +guide rebase, consumes no human revision round/deadline, and returns to open +routing. Human Review revision requires blocking-finding responses and later +prefers the prior reviewer. ## Stop condition -Merge, record automated memory, and stop. Do not start 09B. +Use `CHUNK_MAP.md`; do not execute this parent. diff --git a/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-09B-finding-replay-resolution-routing.md b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-09B-finding-replay-resolution-routing.md index a71f5641e..9303bab58 100644 --- a/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-09B-finding-replay-resolution-routing.md +++ b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-09B-finding-replay-resolution-routing.md @@ -1,4 +1,4 @@ -# Chunk Contract: WS-REV-001-09B +# Chunk Contract: WS-REV-001-09B - Finding Replay, Resolution, And Preferred Return Routing ## Goal @@ -31,15 +31,18 @@ production `/api/v1` review-router registration ## Acceptance criteria -- Checker admission requires one immutable response and any policy-required - verified evidence for every unresolved blocking finding from the immediate - predecessor Review. +- Human-origin checker admission requires one immutable response and any + policy-required verified evidence for every unresolved blocking finding from + the immediate predecessor Review. Checker-origin remediation requires no fake + ReviewFinding response or resolution and instead revalidates its exact + contributor-safe CheckerRun failure lineage. - The review-owned admission participant established in chunk 05 extends its behavior inside the existing durable checker transaction; no checker/task repository import, polling path, or second admission service is added. -- Admission creates at most one queue entry preferred to the prior reviewer, +- Human-origin admission creates at most one queue entry preferred to the prior reviewer, preserves original queue age across preference expiry/decline/invalidation, - and preserves chain identity after takeover. + and preserves chain identity after takeover. Checker-origin admission creates + one ordinary open entry with no fabricated preferred reviewer. - A later Review records exactly one required immutable FindingResolution per prior blocking finding and cannot accept while any remains unresolved. - Missing/duplicate/cross-chain responses or resolutions, quarantined evidence, diff --git a/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-10-contribution-integration-hidden-composition.md b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-10-contribution-integration-hidden-composition.md index 08fc7e0e6..31173ea26 100644 --- a/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-10-contribution-integration-hidden-composition.md +++ b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-10-contribution-integration-hidden-composition.md @@ -1,4 +1,4 @@ -# Chunk Contract: WS-REV-001-10 +# Chunk Contract: WS-REV-001-10 - Canonical Review, Final Acceptance, And CON Atomic Integration ## Goal @@ -51,7 +51,10 @@ reputation scoring versioned Submission, predecessor Review, and packet/evidence facts; REV recomposes final context and calls AUTH; AUTH validates every binding/current authority, consumes once, evaluates once, and stages evidence before the first - feature mutation; REV appends + feature mutation. The exact order after AUTH authority is + ReviewDecisionRequest, review lifecycle fence, ReviewLease, + ReviewQueueEntry, Task, the exact Submission.task_assignment_id row, + Submission, and stable subordinate lineage rows. REV appends the immutable Review, findings, and resolutions; consumes the lease; closes the queue entry; and then calls the CON reviewer operation. That operation creates `completed_review` and evaluates the reviewer policy. REV then applies @@ -68,7 +71,7 @@ reputation scoring protocol and leaves no Review, lifecycle, CON, or feature/shared audit/outbox mutation. This hidden service has no public route or background-command entry point. - REV-12A later installs the mandatory lifecycle fence before REV-13 releases + REV-12A1 through 12A4 later install the mandatory lifecycle control before 13C releases any decision surface. - Every committed review decision creates exactly one reviewer `contribution_type=completed_review` directly from Review and ReviewLease. @@ -135,9 +138,14 @@ reputation scoring revocation, binding-state drift, and duplicate/changed replay in both orders. Fault injection after every REV, task, CON, audit, and outbox stage proves zero partial state and bounded database retry behavior. -- Initial revision-preparation failure on `needs_revision` rolls back Review, - Task and TaskAssignment, lease, preparation, reviewer contribution and award, - audit, and outbox state together. +- The needs-revision branch consumes the mandatory task-owned preparation + participant delivered by 09A2 and invokes it after the reviewer CON + operation. Chunk 10 adds no task-owned implementation file or second + participant path. The participant appends the exact Review-rooted initial + preparation through the caller's session before Task becomes + contributor-readable. Failure rolls + back Review, Task/Assignment, lease/queue, initial preparation, reviewer + contribution/award, audit, and outbox together. - Same-reviewer and takeover matrices prove v1 `needs_revision` then v2 accept/reject follows exact Submission/Review predecessors, attributes each reviewer record to the actual Review author. The v1 Review/findings remain @@ -182,4 +190,4 @@ contribution creation matrix, replay, rollback, and route absence. ## Stop condition -Merge, record automated memory, and stop. Do not start 11. +Merge, record automated memory, and stop. Do not start 11A. diff --git a/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-11-admin-revocation-reconciliation.md b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-11-admin-revocation-reconciliation.md index ad2da24c9..7e838918b 100644 --- a/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-11-admin-revocation-reconciliation.md +++ b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-11-admin-revocation-reconciliation.md @@ -1,239 +1,25 @@ -# Chunk Contract: WS-REV-001-11 +# Chunk Contract: WS-REV-001-11 - Administrative Recovery And Reconciliation -## Goal +## Status -Implement reason-bound administrative routing/lease operations, grant-revocation -recovery, and queue/lease/review reconciliation without rewriting history. +Non-executable split record. -## Risk class +## Children -L1 privileged operations and recovery. +- `WS-REV-001-11A`: privileged queue/lease override, correction, force release, + and close commands. +- `WS-REV-001-11B`: covered PM context repair and D6 exhaustion close. Repair + cannot bypass a frozen limit/deadline. +- `WS-REV-001-11C`: reconciliation persistence/generation, authority- + invalidation and general jobs, plus historical admission scan with exact + invocation, batching, stable resume cursor, locks, audit/counts, and reports. +- `WS-REV-001-11D`: Operator closure only for truly rootless/ambiguous legacy + obligations and narrow delegation to ART Operator recovery. -## Allowed files - -```text -backend/app/modules/reviews/{models,repository,schemas,service,router}.py -backend/app/modules/tasks/review_participant.py only for caller-transaction administrative closure effects -backend/app/composition/review_lifecycle.py only to install existing task/revision participants -backend/app/db/models.py -backend/alembic/versions/_review_reconciliation_admin_commands.py -backend/app/workers/{celery_app,reviews}.py -backend/tests/test_{alembic,reviews,authorization,artifacts,audit}.py -docs/operations_reviewer_workflow.md -docs/operations_operator_workflow.md -docs/operations_queue_policy.md -docs/operations_revision_replay.md -.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/** -.agent-loop/merge-intents/WS-REV-001-11.json -``` - -## Not allowed - -```text -admin decision authority without reviewer grant and lease -hard deletion or mutation of immutable review history -operator execution as artifact recovery lease owner -silent reconciliation repair -new adjudication or reject reopen flow -production `/api/v1` review-router registration -``` - -## Acceptance criteria - -- Force release, routing override, compensating routing correction, - administrative closure, and reconciliation declare, respectively, - `review.lease.force_release`, `review.queue.routing.override`, - `review.queue.routing.correct`, `review.queue.close`, and - `review.reconcile.run`. Human mutations use AUTH prepare/authority lock and an - opaque, non-Pydantic, single-use handle bound to exact session, ActionId, - actor-reference kind and ID, idempotency key, and canonical request digest; - REV canonical row locks and final fact recomposition; then AUTH validates every - binding/current authority, consumes once, evaluates once, and stages evidence - before first feature mutation; participant flush and one request-route/service- - command commit follow. They require exact covered scope and mandatory - reasons; queue closure, - correction, and force release remain Operator-only. -- `POST /api/v1/tasks/{task_id}/revision-obligation/close` declares the additive - AUTH-owned `review.revision_obligation.close` ActionId mapped to existing - `project.task.manage`. Only a covered Project Manager grant is a candidate. - The server-derived typed resource contains the exact project, task, current - assignment, originating `needs_revision` Review, current preparation head, - revision limit/deadline policy, and proof that the selected terminal cause is - currently reached. The request supplies only idempotency key, current head - ID/digest, bounded reason, and one of `revision_limit_reached` or - `revision_deadline_expired`; missing/not-yet-reached, stale/crossed, - cross-project, Operator-only, or arbitrary cause attempts fail closed. -- D6 closure locks/revalidates current authority and those exact rows, records - `ReviewAdministrativeCommandRequest`, AuthorizationDecision, audit, and outbox - evidence, and applies the terminal effects below in one caller transaction. - Exact replay returns the same closure; changed cause/head/reason/actor - conflicts. It creates no reconciliation finding and cannot reuse Operator - `review.queue.close` or legacy-close authority. -- `POST /api/v1/tasks/{task_id}/revision-context/repair` declares the additive - AUTH-owned `review.revision_context.repair` ActionId mapped to existing - `project.task.manage`. Its candidate authority is only a Project Manager grant - covering the canonical project. Its typed resource contains exact project, - task, assignment, prior Submission, revision episode, and current head facts, - and requires transaction revalidation. AUTH locks authority before REV locks - these feature rows. The command requires idempotency, a - bounded reason, and the - current preparation head ID/digest. Through the existing task-owned revision - participant it locks and revalidates authority, project/guide/policies, - task/assignment, prior Submission, revision episode, and head, then appends - exactly one validated successor. It cannot create a root, edit a preparation, - or act on a healthy submitted/terminal episode. -- Repair follows the canonical order through Submission then - RevisionContextPreparation. The originating episode Review is immutable and - is read/revalidated through its constrained FK lineage without taking an - earlier Review row lock; the command never reorders Review ahead of the - preparation head. -- Repair-versus-repair and repair-versus-submission barriers run both commit - orders. Exact replay returns the same successor; changed replay conflicts; - stale head returns a stable conflict/re-preparation response; one head remains - and no partial feature audit/outbox/lifecycle effect commits. AUTH denial - evidence follows the separate clean rollback/restaging protocol. -- Reconciliation classifies legacy `needs_revision` rows without an originating - Review/root as `legacy_revision_context_unrecoverable`. The exact - `POST /api/v1/admin/review-reconciliation/{finding_id}/legacy-revision-close` - endpoint declares additive AUTH-owned - `review.revision_context.legacy_close` mapped to existing - `operations.reconcile.run`; only an Operator AdminRoleGrant is a candidate. - Its typed resource contains the canonical unresolved finding, project, task, - assignment, queue, and no-Review/no-root facts and requires transaction - revalidation. The command is idempotent, requires the reconciliation finding - ID and reason, and closes the task with that - stable terminal reason by moving the task to canonical `cancelled`, releases/clears its assignment, closes any queue as - `admin_cancelled`, preserves immutable history/project grant, and creates no - Review, preparation root, CON/award/reputation record, or synthetic reject. -- Chunk 11 owns `ReviewReconciliationFinding` with immutable defect/evidence - facts and a set-once resolution pointer, plus one-to-one immutable - `ReviewReconciliationResolution` records for domain inconsistency evidence; - they are not audit or queue replacements. It also owns a bounded - `ReviewAdministrativeCommandRequest` idempotency aggregate keyed by actor, - ActionId, canonical resource, and client key, with canonical payload digest - and stable response snapshot. These reuse shared canonical hashing/request/ - correlation conventions and do not reuse AUTH decision persistence or the - lease/submission-specific `ReviewDecisionRequest`. -- Each reconciliation finding stores a canonical `identity_fingerprint` over - finding type plus canonical project/resource/lineage IDs, an immutable - `evidence_fingerprint` over the detected bounded facts, and a monotonically - allocated `generation` under the canonical resource lock. PostgreSQL enforces - unique `(identity_fingerprint, generation)` and a partial unique index allowing - at most one row with a null resolution pointer per identity. Duplicate or - concurrent scans use insert-on-conflict/reload and emit no duplicate alert or - outbox effect. -- Resolution atomically inserts the unique resolution row and sets the finding's - null pointer exactly once; a deferred trigger requires mutual one-to-one IDs, - the same administrative request/finding, and consistent actor/reason/auth/audit - facts. After resolution, a genuinely recurring defect may allocate generation - N+1 only after re-reading current resource facts under lock. It never reopens, - edits, or reuses generation N. -- Legacy closure loads the finding identity, then in canonical order locks the - administrative request, Project, task, assignment, queue if present, - reconciliation finding, and relevant Review/preparation absence facts. The - finding must remain unresolved/current, belong to that exact project/task, - and still prove the no-Review/no-root condition. Exact replay returns the - original closure; changed actor/resource/finding/reason payload conflicts. - Crossed/stale evidence, closure-versus-reconciliation, assignment/queue races, - duplicate delivery, and denial/fault rollback are covered in both orders. -- The successful legacy-close transaction atomically appends the one-to-one - `ReviewReconciliationResolution` linked to the exact finding and - `ReviewAdministrativeCommandRequest`, recording actor, bounded reason, - AuthorizationDecision, audit/outbox evidence, and terminal effects. Any fault - rolls back the resolution, command completion, task/assignment/queue effects, - audit, and outbox together, so the finding remains unresolved when closure did - not commit. -- Migration/direct-SQL tests reject duplicate unresolved identities, duplicate - identity/generation, a second or crossed resolution, and pointer/resolution - mismatch. Independent-session tests cover duplicate reconciliation scans, - reconciliation versus closure, post-resolution recurrence, job retry/ - restart, and fault rollback, proving one unresolved finding, at most one - resolution, stable alert/outbox effects, and no partial administrative request. -- D6 limit/deadline closure is explicit and idempotent: task moves from - `needs_revision` to `cancelled` with `revision_limit_reached` or - `revision_deadline_expired`, assignment atomically - becomes `released` with `released_at=database_now`, the task's active-assignee - projection clears, reclaim is denied because the task is terminal, queue closes - `admin_cancelled`, project grant is unchanged, and no - Review/CON/award/reputation record is created. -- D6 tests cover PM allow, non-PM and Operator denial, cross-project concealment, - not-yet-reached denial, both terminal causes, stale/crossed head, exact and - changed replay, closure versus submission/repair/reassignment, and fault - rollback after every state/audit/outbox participant. -- Exact reviewer-grant revocation, actor suspension/deactivation, corrected attribution that - creates self-review, and policy ineligibility immediately invalidate - preference/decision authority and revoke/requeue an active lease while - preserving queue age; missed recovery is detected idempotently. -- Reviewer-grant reconciliation changes only review preference, lease, and queue - state. It never revokes, replaces, or mutates submitter, adjudicator, or - AdminRoleGrant rows. Submitter revocation remains task-assignment owned; - adjudicator invalidation remains dormant until a separate lifecycle exists. -- Reconciliation detects every specified queue/lease/review inconsistency and - emits alerts/compensating events rather than silent edits. -- Reviewer-authority invalidation reconciliation runs only as fixed service - `workstream.review.authority_invalidation_reconciliation`; general queue, - lease, and history reconciliation runs only as - `workstream.review.reconciliation`. Both have their own exact static - `review.reconcile.run` row, an AUTH-09A-compatible identity/matrix extension, - AUTH-09B-provisioned ActorProfile/link, AUTH-09E admission, cross-service - denial, and later AUTH action activation. Neither borrows - Operator or reviewer identity; human Operator closure/force-release remains a - separate prepared path. Neither identity belongs to AUTH-09A's seven-identity - ART set. Generic AUTH-09E admission does not provision either identity; AUTH - adds each exact identity, constraint, static membership, and admission proof - only from this chunk's reviewed service manifest. -- Artifact verification recovery calls the existing ART-owned - `ArtifactOperatorRecoveryPort` with the registered - `artifact.verification_job.retry` action. The provisioned Artifact Storage - execution service runs under ART fencing; WS-REV owns neither another recovery - permission nor execution lease. -- Admin without reviewer grant still cannot claim or decide. -- Revocation/decision and override/claim races are deterministic. -- Release, decline, override, force-release, admin closure, recovery, and any - actor-attributed deferred commit use AUTH's prepared mutation protocol, - persist the AuthorizationDecision link, follow the command-specific lock order, and - reject wrong-binding, serialized, forged, or caller-constructed attempts - against an unconsumed handle before feature mutation. That rejection stages no - AuthorizationDecision/evidence, preserves the legitimate handle, and permits - its later exact first use. Stale/already-consumed and concurrent duplicate - attempts remain invalid and stage no new state. AUTH alone validates bindings, - consumes once, evaluates once, and stages evidence after REV recomposes final - facts. Current-authority - or policy denial after valid consumption leaves no REV/task/ART/CON mutation or - feature audit/outbox event. The request route or service command rolls back the - dirty transaction; AUTH restages the unchanged bounded denial in a clean - transaction; and that route or command commits the evidence once. Evidence, - participant, cancellation, commit, or restaging failure commits nothing. -- This chunk supplies hidden behavior/resource facts for its actions and changes - no ActionOwner or availability. `WS-AUTH-001-REV-11` activates the existing - action group after merge. `WS-AUTH-001-REV-LIFECYCLE` activates the three - additive chunk-11 actions only after all four additive manifests, including - REV-12A, merge. Product route release waits for REV-13. -- Production OpenAPI remains free of lifecycle routes. -- Recovery/reconciliation jobs reuse `run_async_task`, fresh execution - engine/session disposal, stable task IDs, and `sync_task_settings`; they do - not introduce another async bridge, session factory, or queue helper. - -## Verification - -```text -cd backend && alembic upgrade head -cd backend && pytest -q tests/test_alembic.py tests/test_reviews.py tests/test_authorization.py tests/test_artifacts.py tests/test_audit.py -cd backend && ruff check app/modules/reviews app/workers/reviews.py tests/test_reviews.py tests/test_alembic.py -(metadata_dir="$(mktemp -d)" && trap 'rm -rf "$metadata_dir"' EXIT && (cd backend && WORKSTREAM_TEST_ADMIN_DATABASE_URL=postgresql+asyncpg://workstream:workstream@localhost:5433/postgres .venv/bin/python scripts/run_isolated_tests.py --metadata-json "$metadata_dir/result.json" --timeout-seconds 12600 -- .venv/bin/python -m pytest -q --ignore=tests/test_isolated_database_runner.py --cov=app --cov-report=term-missing --cov-fail-under=78)) -cd backend && for path in 'app/modules/reviews/*' app/modules/tasks/review_participant.py app/composition/review_lifecycle.py app/workers/reviews.py app/workers/celery_app.py; do coverage report --include="$path" --precision=2 --fail-under=90 || exit 1; done -``` - -## Required reviewers - -Senior engineering, QA/test, security/auth, product/ops, architecture, -reuse/dedup, docs, and test-delta. - -## Human review focus - -Privilege separation, mandatory reasons, revocation race, recovery fencing, and -immutable history. +Recoverable checker-rooted history is not legacy-unrecoverable. Every child has +separate action/service identity, command lock order, schema/state docs, races, +and rollback evidence. ## Stop condition -Merge, record automated memory, and stop. Do not start 12. +Use `CHUNK_MAP.md`; do not execute this parent. diff --git a/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-12-projection-observability.md b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-12-projection-observability.md index 5c6f4f8e8..c328dde55 100644 --- a/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-12-projection-observability.md +++ b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-12-projection-observability.md @@ -1,126 +1,21 @@ -# Chunk Contract: WS-REV-001-12 +# Chunk Contract: WS-REV-001-12 - Projection And Observability -## Goal +## Status -Deliver deterministic review snapshot projection, notification events, -artifact-reference reconciliation, and bounded operational observability. +Non-executable split record. -## Risk class +## Children -L1 asynchronous delivery, privacy, and operations. +- `WS-REV-001-12P1`: deterministic shared-outbox projection handler and exact + merged dispatcher/handler-registry composition. +- `WS-REV-001-12P2`: separately authorized artifact-reference reconciliation + and projection rebuild jobs after ART owns the exact capability. +- `WS-REV-001-12P3`: bounded notifications/admin reads/metrics and + `ReviewLifecycleDrainObservationPort`. -## Allowed files - -```text -backend/app/modules/reviews/{ports,repository,schemas,service,projection}.py -backend/app/workers/{celery_app,reviews}.py -backend/app/core/config.py only for bounded job settings -backend/tests/test_{reviews,artifacts,audit,config}.py -docs/operations_reviewer_workflow.md -docs/operations_operator_workflow.md -docs/operations_queue_policy.md -.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/** -.agent-loop/merge-intents/WS-REV-001-12.json -``` - -## Not allowed - -```text -remote storage call in decision transaction -projection as canonical Review truth -unbounded reviewer IDs or finding text in public metric labels/logs -notification provider implementation beyond existing adapter convention -review decision changes on projection failure -production `/api/v1` review-router registration -``` - -## Acceptance criteria - -- Projection bytes are deterministic for Review ID and schema version. -- Every projection represents the immutable Review and submitted - finding and resolution history for its decision. An accept projection includes - bounded FinalAcceptance identity, source-Review identity, and acceptance time; - `needs_revision` and `reject` projections contain no inferred or synthetic - FinalAcceptance. Projection content never becomes the acceptance source. -- Same operation/bytes replay one logical receipt; changed bytes conflict. -- Projection-job retry/dead-letter/reconciliation changes only delivery status. -- The shared outbox dispatcher remains the sole event claimant and owner of - attempt, retry, dead-letter, and delivery status. Reviews registers only a - typed deterministic projection handler and relies on ART receipts; no review - polling loop, attempt table, or dead-letter ledger is created. -- Search/projection reads are reauthorized through Workstream. -- Artifact-reference reconciliation declares - `review.artifact_reference.reconcile`; an authorized projection rebuild - declares `review.projection.rebuild`. Artifact-reference reconciliation runs - only as `workstream.review.artifact_reference_reconciliation`; projection - rebuild runs only as `workstream.review.projection`. Each requires its exact - static ActionId row, an AUTH-09A-compatible identity/matrix extension, - AUTH-09B-provisioned ActorProfile/link, AUTH-09E admission, AUTH - prepare for the mutation and final REV facts, followed by AUTH-owned exact - binding/current-authority validation, single consumption, evaluation, and - evidence staging. The opaque, non-Pydantic, single-use handle binds exact - session, ActionId, service actor-reference kind and ID, idempotency key, and - canonical request digest. Wrong-binding, serialized, forged, or - caller-constructed attempts against an unconsumed handle fail before feature - mutation, stage no AuthorizationDecision/evidence, preserve the legitimate - handle, and permit its later exact first use. Stale/already-consumed and - concurrent duplicate attempts remain invalid and stage no new state. Current-authority - or policy denial after valid consumption follows AUTH's clean denial-evidence - protocol. Human Operator or reviewer authority cannot substitute. - AUTH-09A's seven-identity ART set contains neither identity. Generic AUTH-09E - admission creates neither identity; AUTH provisions each exact identity and - static membership only from this reviewed service manifest. -- Artifact relation reconciliation covers verification, project/task scope, - missing projection, receipt mismatch, uncertainty, and unavailable content - through ART-owned typed facts without importing ART repositories, invoking v1 - retain/release, or editing canonical history. -- Required queue, lease, decision, authorization, evidence, projection, and lag - metrics exist with bounded cardinality. -- Reviews exposes a typed, same-session `ReviewLifecycleDrainObservationPort` - that returns server-derived active-lease and review-maintenance counts under - canonical review locks. It is read-only, never commits, advances no lifecycle - phase, imports no lifecycle-control type, and is named in chunk 12 evidence so - 12A can consume it through composition. -- Administrative read models include open/preferred depth, oldest preferred - age, approaching-expiry leases, expired/released/invalidation counts, and - bounded turnaround distributions. -- Notification events explicitly cover preference nearing expiry, lease nearing - expiry, lease expired, preferred routing, decisions, and every authority - invalidation cause without coupling lifecycle to a delivery provider. -- Audit, shared outbox, dead-letter, alerts, errors, logs, and metrics retain - only bounded typed identifiers/reasons and never finding text, private - artifact metadata, signed access, provider paths, or secrets. -- Production OpenAPI remains free of lifecycle routes. -- Operator docs enumerate every projection/notification job variable, - bounded default, schedule/execution command, retry/dead-letter alert, rollout, - drain, and rollback behavior in the same chunk. -- Projection handlers reuse `run_async_task`, fresh execution engine/session - disposal, stable task IDs, and `sync_task_settings`; no second async bridge, - session factory, or queue helper is introduced. -- This chunk supplies hidden behavior, service resource facts, and feature- - manifest deltas while both review actions remain planned. AUTH separately - activates them through `WS-AUTH-001-REV-12` after merge; product release waits - for REV-13. - -## Verification - -```text -cd backend && pytest -q tests/test_reviews.py tests/test_artifacts.py tests/test_audit.py tests/test_config.py -cd backend && ruff check app/modules/reviews app/workers/reviews.py tests/test_reviews.py -(metadata_dir="$(mktemp -d)" && trap 'rm -rf "$metadata_dir"' EXIT && (cd backend && WORKSTREAM_TEST_ADMIN_DATABASE_URL=postgresql+asyncpg://workstream:workstream@localhost:5433/postgres .venv/bin/python scripts/run_isolated_tests.py --metadata-json "$metadata_dir/result.json" --timeout-seconds 12600 -- .venv/bin/python -m pytest -q --ignore=tests/test_isolated_database_runner.py --cov=app --cov-report=term-missing --cov-fail-under=78)) -cd backend && for path in 'app/modules/reviews/*' app/workers/reviews.py app/workers/celery_app.py app/core/config.py; do coverage report --include="$path" --precision=2 --fail-under=90 || exit 1; done -``` - -## Required reviewers - -Senior engineering, QA/test, security/auth, product/ops, architecture, docs, -reuse/dedup, and test-delta. - -## Human review focus - -Canonical/projection separation, deterministic bytes, privacy, dead-letter -operations, and metric usefulness. +No child creates a review-private poller, retry ledger, audit table, outbox, or +provider adapter. Each fixed service has its own AUTH identity/action/static row. ## Stop condition -Merge, record automated memory, and stop. Do not start 12A. +Use `CHUNK_MAP.md`; do not execute this parent. diff --git a/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-12A-joint-lifecycle-release-control.md b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-12A-joint-lifecycle-release-control.md index db7cdf7ac..f2be7b713 100644 --- a/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-12A-joint-lifecycle-release-control.md +++ b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-12A-joint-lifecycle-release-control.md @@ -1,344 +1,27 @@ -# Chunk Contract: WS-REV-001-12A +# Chunk Contract: WS-REV-001-12A - Joint Lifecycle Release Control -## Goal +## Status -Implement the hidden, persisted joint review/contribution release-control -aggregate and mandatory typed mutation fences required for safe product release, -shutdown, crash recovery, and forward reactivation. +Non-executable split record. This canonical parent ID is retained and may not be +reused for projection work. -## Risk class +## Children -L1 cross-domain release control, authorization, and operational safety. +- `WS-REV-001-12A1`: persisted controller/phase history/idempotency and typed + fence/drain ports. +- `WS-REV-001-12A2`: mandatory REV/task/checker command classification and + fence composition, including checker needs-revision routing. +- `WS-REV-001-12A3`: exact CON writer/dispatcher/callback/cutoff/drain fences. +- `WS-REV-001-12A4`: authorized Operator transition, bounded drain, + timeout/forward recovery, and crash resume. -## Allowed files - -```text -backend/app/modules/lifecycle_control/{__init__,models,repository,schemas,service,ports,router}.py -backend/app/composition/joint_lifecycle_control.py -backend/app/composition/review_lifecycle.py only to inject the mandatory fence into existing task/checker/review construction -backend/app/composition/compensation.py only to install the exact merged CON obligation-writer, dispatch, and callback fence hooks -backend/app/modules/reviews/service.py only to require the merged lifecycle fence on mutations -backend/app/modules/tasks/service.py only to require the merged lifecycle fence on submission/replacement commands -backend/app/modules/checkers/service.py only to require the merged lifecycle fence on review-queue admission -backend/app/workers/reviews.py only to inject the mandatory fence into existing review maintenance commands -backend/app/core/config.py only for bounded observation settings -backend/app/db/models.py -backend/alembic/versions/_joint_lifecycle_release_control.py -backend/tests/test_{alembic,lifecycle_control,reviews,tasks,checkers,compensation,outbox,audit,authorization,api_contract_e2e,config}.py -docs/operations_{reviewer_workflow,operator_workflow,payment_reputation}.md -.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/** -.agent-loop/merge-intents/WS-REV-001-12A.json -``` - -## Not allowed - -```text -production review/contribution/compensation/lifecycle-control router registration -review, contribution, award, compensation, or fulfillment policy changes -provider call in the control transaction -script-owned lifecycle truth or in-memory-only phase -optional/no-op production fence -schema/application downgrade after protected post-cutover rows exist -``` - -## Acceptance criteria - -- `JointLifecycleReleaseControl` is one PostgreSQL-canonical singleton with a - monotonically increasing generation, current phase, exact reviewed manifest - digest, database timestamps, latest successful transition, and the immutable - fulfillment-obligation cutoff captured for the current generation. Immutable - transition/attempt rows store expected generation/prior phase, target phase, - bounded reason, the server-derived cutoff when applicable, exact - `initiating_actor_id` referencing canonical human `ActorProfile.id`, - AuthorizationDecision, audit, and idempotency linkage. -- The only legal graph is - `pre_activation(N) -> revision_cutover_fenced(N) -> active(N) -> - admission_fenced(N) -> commands_draining(N) -> leases_released(N) -> - delivery_draining(N) -> disabled(N)`, followed only by - `disabled(N) -> pre_activation(N+1)` with a newly reviewed manifest digest. - Migration creates only `pre_activation(1)`. Compare-and-set plus database - constraints reject skipped, reversed, concurrent, crossed-generation, or - unknown edges and preserve every prior generation unchanged. -- Every lifecycle-control observe, transition, and crash-resume attempt is a - fresh authenticated Operator command declaring registered planned AUTH-owned - `review.lifecycle.activation.manage` mapped to existing - `operations.reconcile.run`. Only an Operator AdminRoleGrant is a candidate. - Its typed resource contains operation, singleton ID, expected generation and - phase, target phase when applicable, exact manifest digest, server-resolved - drain observations, bounded batch/deadline, and reason. It uses caller-owned - AsyncSession, revalidates authority, records one AuthorizationDecision/audit/ - outbox result, and exact replay returns the same result while changed replay - conflicts. There is no lifecycle-control background job, serialized human-authority - replay, or service actor that advances canonical phase; after a crash an - Operator reloads status and reissues the exact or next adjacent command. - Lease draining does not widen this action: each lease uses the existing - `review.lease.force_release` command with its own fresh Operator decision, - bounded reason, idempotency, audit, and review-owned effects. -- A shared typed `JointLifecycleMutationFence` is injected through one explicit - composition root into review mutations, every task submission, review-queue - admission, review maintenance commands, authority-loss replacement assignment, - every CON fulfillment-obligation root creation, requeue, successor, and repair - writer, and compensation fulfillment dispatch and callback handling. The CON - writer hooks must be approved and merged before 12A; this chunk installs them - through composition and does not edit CON-owned writer logic. There is no - fallback constructor, service locator, optional/no-op port, or concrete - cross-domain repository import. -- After AUTH prepares and locks current authority, it returns an opaque, - non-Pydantic, single-use handle bound to exact session, ActionId, - actor-reference kind and ID, idempotency key, and canonical request digest. - Every mutation locks its feature-owned operation-idempotency row, acquires the - shared PostgreSQL transaction advisory lock, reads the phase, locks its exact - product-domain rows, and recomposes the final typed facts. Only then does AUTH - validate and consume the exact handle, evaluate once, and stage decision - evidence. Feature mutation and participant flush follow that decision; the - request route or service command commits once. Phase transition follows the - same prefix with the matching exclusive advisory lock, so - it waits for prior mutation transactions and blocks new entrants without - reversing the global lock order. After commit, new commands acquire the shared - lock and fail or pass from the persisted phase. Independent-session tests prove - both orderings, AUTH/fence concurrency without deadlock, and that process-local - locks cannot substitute. Pre-consumption wrong-binding, serialization, forgery, - or caller construction fails before feature/shared audit/outbox mutation, - stages no AuthorizationDecision/evidence, and preserves the legitimate - unconsumed handle. Authority or policy denial after valid - consumption also leaves feature/shared audit/outbox state unchanged; its clean - AUTH evidence follows the denial protocol below. The phase snapshot remains - held for the transaction. -- Wrong-binding, serialized, forged, or caller-constructed attempts against an - unconsumed handle are protocol rejections: they stage no - AuthorizationDecision/evidence, preserve the legitimate handle, and permit its - later exact first use. Stale/already-consumed and concurrent duplicate attempts - remain invalid, stage no new evidence or feature state, and can never become - valid again; exactly one concurrent exact consumer may win. For current-authority or policy denial after - valid consumption, the - request route or service command rolls back the dirty caller transaction; AUTH - restages the unchanged bounded denial in a clean transaction; and that route - or command commits the evidence once. No phase, product, feature/shared - audit/outbox, or participant effect survives. Denial-evidence restaging failure - commits nothing. -- Submission fencing is two-stage. After acquiring the shared fence and phase, - the service loads canonical task, predecessor, assignment, and preparation - rows in normal order; derives initial, legacy-revision, or prepared-revision - class from those rows rather than request shape; then checks the derived class - against the captured phase before mutation. Crossed or forged preparation - claims fail without changing state. -- The closed phase/command matrix is: - -| Command class | Pre-activation N=1 | Pre-activation N>1 | Revision cutover fenced | Active | Admission fenced | Commands draining | Leases released | Delivery draining | Disabled | -|---|---:|---:|---:|---:|---:|---:|---:|---:|---:| -| initial submission | allow | allow | allow | allow | deny | deny | deny | deny | deny | -| legacy revision submission | allow | deny | deny | deny | deny | deny | deny | deny | deny | -| prepared revision submission | deny | deny | deny | allow | deny | deny | deny | deny | deny | -| review-queue admission | allow | allow | allow | allow | deny | deny | deny | deny | deny | -| new review claim/routing mutation | deny | deny | deny | allow | deny | deny | deny | deny | deny | -| leased review completion/owned release | deny | deny | deny | allow | allow | deny | deny | deny | deny | -| revision preparation/evidence/admin mutation | deny | deny | deny | allow | deny | deny | deny | deny | deny | -| review maintenance/projection or CON completion-only maintenance | deny | deny | deny | allow | allow | allow | allow | allow | deny | -| fulfillment-obligation creation, requeue, successor, or repair | deny | deny | deny | allow | allow | deny | deny | deny | deny | -| joint policy/configuration mutation | deny | deny | deny | allow | deny | deny | deny | deny | deny | -| legacy authority-loss replacement | allow | deny | deny | deny | deny | deny | deny | deny | deny | -| prepared authority-loss replacement | deny | deny | deny | allow | deny | deny | deny | deny | deny | -| authorized review recovery/lease release | deny | deny | deny | allow | allow | allow | deny | deny | deny | -| fulfillment dispatch | deny | deny | deny | allow | allow | allow | allow | pre-cutoff completion only | deny | -| authenticated fulfillment callback | allow | allow | allow | allow | allow | allow | allow | pre-cutoff completion only | deny | -| bounded canonical/control read | allow | allow | allow | allow | allow | allow | allow | allow | allow | -| lifecycle transition/status | allow | allow | allow | allow | allow | allow | allow | allow | allow | - - Bootstrap pre-activation therefore preserves the pre-cutover legacy pipeline - plus post-REV-05 hidden queue creation without exposing human review or CON - execution. Post-cutover generation N>1 pre-activation never re-enables legacy - revision or replacement writers. The exact activation manifest maps every - endpoint and async command to one matrix row; an unclassified command fails - closed. Recovery/lease release retains each - existing action and fixed service-actor or Operator authority; the matrix does - not merge those authorities into lifecycle control. -- This chunk implements hidden lifecycle-control behavior, typed resource facts, - guards, fence composition, and a feature-manifest delta while - `review.lifecycle.activation.manage` remains registered and planned after the - prerequisite `WS-AUTH-001-REV-REG`. `WS-AUTH-001-REV-LIFECYCLE` integrates its evaluator and - activates it only after this chunk and all other additive manifests merge. The - controller's `pre_activation` token is product state, not AUTH availability. -- The REV action/operation map is exact: - -| Action or internal operation | `JointLifecycleCommandClass` | -|---|---| -| `submission.create` | server-derived initial, legacy-revision, or prepared-revision submission | -| checker `allow_review` participant | review-queue admission | -| `review.queue.read`, `review.queue.inspect`, `review.context.read`, `review.chain.read` | bounded canonical/control read | -| `review.claim`, `review.decline_preference`, `review.preference_expiry.run`, `review.queue.routing.override`, `review.queue.routing.correct`, `review.queue.close` | new review claim/routing mutation | -| `review.release`, `review.finding_evidence.ingest`, `review.decision` | leased review completion/owned release | -| `review.finding_response_evidence.ingest`, `review.revision_context.repair`, `review.revision_obligation.close`, `review.revision_context.legacy_close` | revision preparation/evidence/admin mutation | -| `review.lease_expiry.run`, `review.lease.force_release` | authorized review recovery/lease release | -| `review.reconcile.run` queue/routing mode | new review claim/routing mutation | -| `review.reconcile.run` lease-only mode | authorized review recovery/lease release | -| `review.reconcile.run` evidence-only scan, `review.artifact_reference.reconcile`, `review.projection.rebuild` | review maintenance/projection or CON completion-only maintenance | -| shared-outbox review snapshot projection handler under fixed `outbox.dispatch` authority | review maintenance/projection or CON completion-only maintenance | -| AUTH-13 revision-obligation replacement operation | server-derived legacy or prepared authority-loss replacement | -| `review.lifecycle.activation.manage` transition/status | lifecycle transition/status | - - Reconciliation mode is derived from locked canonical facts, never a caller - label. The exact merged CON-owned joint-readiness manifest similarly maps every contribution, - compensation, fulfillment, callback, read, policy, and operations command to - the existing joint classes above. Missing, extra, ambiguous, or caller-chosen - mappings fail startup and preflight. A command that can create, requeue, - extend, or repair a fulfillment obligation cannot be classified as - completion-only. -- The replacement-assignment command has a required typed slot for the - preparation-transfer participant in prepared mode. REV-12A does not prescribe - whether its fence foundation or amended AUTH-13 merges first: it classifies and - fences the exact owner-installed legacy or prepared mode from the merged - manifest, never from a caller label. After REV-09A supplies the participant, - amended AUTH-13 atomically binds it, removes legacy replacement behavior, and - fails startup/command execution when the binding is absent. Active generation - and every generation N>1 require prepared mode and never re-enable the legacy - class. REV-13 only verifies the merged binding and exposes the already cut-over - command. No schema or release code infers or fabricates preparation. -- The composition root supplies the shared fence through the exact mandatory - CON dispatch and callback hooks. Under the shared fence, the shared outbox - dispatcher claims the event and passes an already-claimed command plus - generation to the CON-owned handler. The handler validates that claim through - a typed port and resolves the immutable root - `fulfillment_obligation_ordinal` from canonical CON lineage. During - `delivery_draining`, the captured generation must match and the root ordinal - must be at or below the persisted cutoff. The handler may then persist a - durable `in_flight` attempt under that existing root, commit, and release the - database transaction and advisory fence. Only then may it call the adapter, - with no lifecycle advisory lock or database transaction held; it finalizes - delivery success or retry state for the same root in a new fenced transaction. - It cannot create a new root, requeue a different root, or enqueue successor - work. Only the shared dispatcher changes outbox claim/retry/dead-letter state. - A lost pre-I/O race returns the same root event to retryable pending without - changing award or delivery truth. - After CON-owned signature verification plus AUTH/idempotency locking, - the callback transaction acquires the shared fence, reads the captured phase, - resolves the callback's canonical root obligation and ordinal, and holds the - fence through idempotent receipt commit. In `delivery_draining`, the callback - must target the captured generation and a root at or below the cutoff. It may - only finalize that root; it cannot create a successor event, retry root, - delivery obligation, award, or other follow-on work. It fails closed before - provider or successor I/O on crossed, missing, or post-cutoff lineage, fails - closed after `disabled`, and cannot race the exclusive disable transition. - REV edits neither CON handler nor outbox policy. -- Typed readiness/drain ports provide only server-resolved observations. Merged - chunk 12 supplies same-session `ReviewLifecycleDrainObservationPort` for - active-lease plus pending/in-flight review-maintenance counts. The exact - merged CON-owned capabilities supply - same-session `FulfillmentLifecycleDrainObservationPort` for pending/claimed/ - retryable fulfillment events, in-flight dispatch, and nonterminal delivery/ - callback obligations through the shared-outbox capability. The same port - returns the current maximum immutable, monotonically increasing - `fulfillment_obligation_ordinal`, allocated by CON only after the shared fence - is acquired. The lifecycle transition persists that server-derived value as - the generation's cutoff; zero is valid when no obligation exists. Exact - writer/composition/migration readiness is also typed. Each port uses the - caller's AsyncSession, is read-only, never commits or calls a provider, and is - named in the readiness manifest. Caller-supplied timestamps, ordinals, event - IDs, or generation claims cannot substitute. Lifecycle control imports no - review, CON, or outbox repository. -- The CON readiness manifest enumerates every obligation-root writer and proves - that each writer acquires the shared fence before allocating its ordinal or - locking CON-owned obligation rows. Missing, optional, or differently ordered - writer hooks fail composition and preflight. Independent-session tests race - every creation, requeue, successor, and repair writer against - `admission_fenced -> commands_draining` in both orders. The writer either - commits under an ordinal included by the cutoff or observes - `commands_draining` and fails without allocating or mutating an obligation. -- ART-backed review maintenance/projection uses the same fenced handoff: claim - and persist durable `in_flight` under the shared fence, commit/release, perform - provider I/O outside every database transaction and lifecycle advisory lock, - then finalize through a new fenced transaction. Pending work may survive - shutdown; persisted in-flight work blocks disable until completion or - canonical crash recovery returns it to retryable state. -- Edge guards are exact: cutover entry verifies the reviewed manifest; product activation - requires zero old writers plus strict migration/composition readiness; - `admission_fenced -> commands_draining` takes the exclusive lock and therefore - waits for admitted completion commands, reads the CON-owned ordinal through - the same-session port, and atomically stores the generation's immutable drain - cutoff; `commands_draining -> leases_released` requires zero active leases - after fresh Operator force-release calls; - `leases_released -> delivery_draining` begins the bounded drain of fulfillment - work that was committed before completion commands were fenced. Fulfillment - dispatch and authenticated callbacks remain allowed in `delivery_draining` - only for roots at or below the stored cutoff. Every command that can create, - requeue, extend, or repair an obligation is denied, including maintenance, - reconciliation, callback successor work, and post-cutoff events. The - `delivery_draining -> disabled` guard requires zero dispatchable, retryable, - claimed, or in-flight fulfillment events; zero nonterminal delivery or - callback obligations; and zero in-flight review maintenance after the - exclusive lock drains concurrent finalization and callback transactions. - Pending retryable review projection work may remain durable for forward - reactivation, but no remote operation may remain in flight. No provider I/O - occurs while any lifecycle advisory fence or database transaction is held. - New-generation pre-activation requires prior `disabled`, a new manifest, and - no schema downgrade. -- Bounded settings use database time and reject invalid/unbounded values. A - timeout appends an immutable failed attempt with captured observations while - leaving phase and product truth unchanged. Fresh Operator retry resumes - forward; it never fabricates completion, drops pending work, disables callbacks - early, replays serialized human authority, or attempts schema downgrade. -- Lifecycle control reuses `canonical_json_hash`, shared request/correlation - identifiers, the established reserve/lock/complete idempotency shape, and the - shared caller-transaction audit/outbox participants. It creates no private - canonicalizer, audit ledger, outbox, dispatcher, or retry framework. -- Operator transition route/service and every joint product router remain absent - from production OpenAPI. Internal service, affected-execution integration, - migration, and composition tests prove the foundation is present and fail - closed if any mandatory fence binding is missing. -- REV-13 release keeps only the already-AUTH-active authenticated lifecycle- - control transition and status surface available in `disabled`; product - routes, product background jobs, and their fixed service identity mappings remain disabled. This - retained control surface is the sole way to request `pre_activation(N+1)`. -- Migration/direct-SQL and independent-session tests cover singleton uniqueness, - every legal/illegal edge and full generation-aware command matrix, N-to-N+1 - reactivation without legacy writer revival, - compare-and-set/generation races, two-stage forged/crossed classification, - actor/action linkage with the same composite/trigger human-kind enforcement - used by review records, direct-SQL rejection of service/system/external/legacy - actor IDs, AUTH/fence ordering, cutoff capture after prior completion - transactions, every obligation writer versus cutoff capture in both orders, - missing-writer-hook composition failure, callback-versus-disable, pre-cutoff - dispatch before adapter I/O, post-cutoff/crossed-generation denial before - adapter I/O, maintenance and callback-successor denial, canonical same-root - claim recovery, bounded denial audit, and downgrade refusal once protected - history exists. - Failure injection after reservation, observation, history append, control CAS, - audit, and outbox flush proves rollback; crash after commit plus exact replay, - timeout-without-advance, bounded lease release, and forward retry are explicit. - Review snapshot projection tests directly cover allowed phases, disabled - denial, pending-versus-in-flight observation, blocked transition attempts, - fresh retry, crash/retry, and unchanged canonical Review truth under its fixed - `outbox.dispatch` actor. - Independent-session tests run maintenance/projection versus disable in both - orderings, prove durable in-flight state exists before fence release, deny - disable advancement until finalization/recovery, prove the blocked attempt - releases its exclusive lock and leaves phase unchanged, and instrument the - adapter to prove provider I/O executes with no lifecycle advisory lock or DB - transaction held. -- New/materially changed code is at least 90 percent covered and the repository - remains at or above the 78 percent global floor. - -## Verification - -```text -cd backend && alembic upgrade head -cd backend && pytest -q tests/test_alembic.py tests/test_lifecycle_control.py tests/test_reviews.py tests/test_tasks.py tests/test_checkers.py tests/test_compensation.py tests/test_outbox.py tests/test_audit.py tests/test_authorization.py tests/test_api_contract_e2e.py tests/test_config.py -cd backend && ruff check app/modules/lifecycle_control app/modules/reviews app/modules/tasks app/modules/checkers app/workers/reviews.py app/composition/joint_lifecycle_control.py app/composition/review_lifecycle.py app/composition/compensation.py tests/test_lifecycle_control.py -(metadata_dir="$(mktemp -d)" && trap 'rm -rf "$metadata_dir"' EXIT && (cd backend && WORKSTREAM_TEST_ADMIN_DATABASE_URL=postgresql+asyncpg://workstream:workstream@localhost:5433/postgres .venv/bin/python scripts/run_isolated_tests.py --metadata-json "$metadata_dir/result.json" --timeout-seconds 12600 -- .venv/bin/python -m pytest -q --ignore=tests/test_isolated_database_runner.py --cov=app --cov-report=term-missing --cov-fail-under=78)) -cd backend && coverage report --include='app/modules/lifecycle_control/*' --precision=2 --fail-under=90 -cd backend && for path in app/modules/reviews/service.py app/modules/tasks/service.py app/modules/checkers/service.py app/workers/reviews.py app/core/config.py app/composition/joint_lifecycle_control.py app/composition/review_lifecycle.py app/composition/compensation.py; do coverage report --include="$path" --precision=2 --fail-under=90 || exit 1; done -``` - -## Required reviewers - -Senior engineering, QA/test, security/auth, product/ops, architecture, docs, -reuse/dedup, test-delta, and CI integrity if proof tooling changes. - -## Human review focus - -Cross-domain fence ownership, advisory-lock behavior, Operator authority, -timeout/forward-recovery semantics, immutable fulfillment cutoff, completion-only -drain authority, callback preservation, and no public surface. +Persisted phase denies execution; it does not unregister FastAPI routes, change +AUTH action availability/static membership, or substitute for operational +scheduler suspension. Checker needs-revision routing is allowed wherever initial/ +revision checker completion is allowed through `revision_cutover_fenced`, then +denied from `admission_fenced`; human Review preparation remains an internal +consequence of leased `review.decision` completion. ## Stop condition -Merge, record automated memory, and stop. Do not start 13. +Use `CHUNK_MAP.md`; do not execute this parent. diff --git a/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-13-live-drill-docs-release.md b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-13-live-drill-docs-release.md index adf39c073..a5ceb19b9 100644 --- a/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-13-live-drill-docs-release.md +++ b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-13-live-drill-docs-release.md @@ -1,345 +1,24 @@ -# Chunk Contract: WS-REV-001-13 +# Chunk Contract: WS-REV-001-13 - Coherent Product Release And Proof -## Goal +## Status -Perform fail-closed public lifecycle release of already-AUTH-active actions, run privacy-safe HTTP-visible -conformance drills, close active documentation, and prove the complete backend -review/revision lifecycle. +Non-executable split record. -## Risk class +## Children -L1 release proof and documentation closure. +- `WS-REV-001-13A`: exact merged-SHA dependency/feature manifests, + fail-closed preflight, and reusable live-drill harness while product routes + remain absent. +- `WS-REV-001-13B`: planned/pre-release documentation and generated-artifact + preparation only; it may not claim routes are live. +- `WS-REV-001-13C`: sole product router registration, active documentation and + generated derivative update, final real-HTTP drill, evidence, and initiative + closure. -## Allowed files - -```text -backend/scripts/review_lifecycle_{stack_preflight,live_drill,validate_evidence}.py -backend/tests/test_{reviews,contributions,compensation,authorization,api_contract_e2e,review_lifecycle_live_drill}.py only for final integration conformance gaps -backend/app/api/router.py only for review and lifecycle-control registration after owner readiness -backend/app/modules/reviews/router.py only for final product-release conformance -backend/app/modules/lifecycle_control/router.py only for final Operator control product-release conformance -backend/app/modules/tasks/{schemas,service,router}.py only for Task Context and final product-release conformance over the already merged AUTH-14 cutover -backend/app/composition/review_lifecycle.py only for final fail-closed participant composition -backend/app/composition/joint_lifecycle_control.py only for final active command-class/binding product release -docs/architecture_*.md -docs/architecture_brief/** -docs/diagrams/** -docs/operations_*.md -docs/product_brief.md -docs/product_principles.md -docs/principles.md -docs/product_first_user_flows.md -docs/glossary.md -docs/roles_permissions.md -docs/template_review_packet.md -docs/template_revision_replay.md -docs/template_prior_feedback_checklist.md -docs/template_task_status.md -docs/template_project_guide.md -docs/template_task.md -docs/current_system_data_flow.html -README.md -.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/** -.agent-loop/merge-intents/WS-REV-001-13.json -``` - -## Not allowed - -```text -new lifecycle behavior hidden inside proof scripts -frontend implementation -real secrets, private artifact content, local absolute paths, or personal IDs -provider or authorization bypass for the drill -reputation formula or deferred product scope -CON router, policy, contribution, award, outbox, fulfillment, callback, or projection ownership -AUTH action registration, ActionOwner/evaluator edit, or availability change -AUTH-13/14 command, participant-binding, task-submission behavior, or migration ownership -``` - -## Acceptance criteria - -- HTTP drill proves first submission, needs revision, revision preparation, - response evidence, preferred return, preference expiry/takeover, and accept - with a new immutable Review and exactly one immutable FinalAcceptance. It - proves the earlier needs_revision Review and findings remain unchanged. -- Separate drills prove reject, lease expiry, grant revocation during lease, - finding evidence, artifact unavailable/integrity failure/recovery, projection - retry, and WS-CON atomicity. -- API plus database evidence proves the complete three-decision matrix. Each - `accept`, `needs_revision`, and `reject` has exactly one immutable Review and - one `completed_review` whose `source_review_id` and - `source_review_lease_id` identify that Review and lease and whose - `source_final_acceptance_id` and `source_task_assignment_id` are null. - `needs_revision` and `reject` each have zero FinalAcceptance and zero - `accepted_submission`. `accept` has exactly one FinalAcceptance and one - `accepted_submission` whose - `source_final_acceptance_id` and `source_task_assignment_id` identify that - acceptance and assignment and whose direct Review and ReviewLease source - fields are null. -- The same proof asserts exact lifecycle effects: accept sets Task `accepted` - and TaskAssignment `completed`; needs_revision sets Task `needs_revision` and - keeps its assignment active; reject sets Task `rejected`, blocks that - assignment, and changes no other task or project grant. Lease consumption and - queue closure occur for every decision. -- Separate drills prove reason-bound preparation repair after guide correction, - stale-head/concurrent repair behavior, and audited legacy unrecoverable closure - without a fabricated Review or contribution. -- Reconciliation proof runs duplicate/concurrent scans, closure, and a controlled - post-resolution recurrence and verifies one unresolved fingerprint generation, - one resolution, stable alert/outbox effects, and generation N+1 only after the - prior finding is resolved. -- Database and API audit evidence agree; no direct database mutation creates - the claimed lifecycle result. -- Before product registration, stack preflight proves merged AUTH/ART/CON, shared - outbox, runtime jobs/schedules, MinIO protocol, migrations, and reconciliation are - live. Production composition fails closed when any mandatory participant is - absent. -- The exact merged WS-REV-12A release-control schema, phase history, advisory - lock, command-class matrix, Operator action, and mandatory fence bindings are - preflight inputs. REV-13 registers and exercises that foundation; it does not - implement an alternate controller or store phase in a proof script. -- Preflight consumes the CON-owned joint-readiness capability's exact merged - SHA, migration head, ActionId and fixed service identity mapping, ART capability, - outbox/dispatch-job, and handler manifest. - Missing, extra, stale, or mismatched entries block startup and product release. -- A REV-owned feature/release manifest covers every human endpoint and - asynchronous command with exact ActionId, PermissionId mapping, resource - composer owner, allowed principal kind, exact fixed service ActorProfile - assignment, transaction-revalidation rule, exact - `JointLifecycleCommandClass`, and generation-aware phase policy. Internal - checker admission, AUTH-13 replacement, and every operation-specific - `review.reconcile.run` mode are manifest entries even when they share an - ActionId. The shared-outbox review snapshot projection handler is a separate - manifest entry under fixed `outbox.dispatch` authority. It includes at least - `review.preference_expiry.run`, `review.lease_expiry.run`, the separately - assigned authority-invalidation and general `review.reconcile.run` modes, - `review.artifact_reference.reconcile`, and `review.projection.rebuild`; - missing, extra, ambiguous, caller-selected, stale, or mismatched mappings fail - preflight and startup. The exact merged CON-owned manifest supplies the same fields for every - joint contribution/compensation command. -- The six protected review jobs map exactly to - `workstream.review.preference_expiry`, `workstream.review.lease_expiry`, - `workstream.review.authority_invalidation_reconciliation`, - `workstream.review.reconciliation`, - `workstream.review.artifact_reference_reconciliation`, and - `workstream.review.projection`. AUTH-09E admission, exact static rows, - provisioning, cross-service denial, and human/Operator isolation are live. - Evidence binding separately proves `workstream.artifact.binding` plus - `artifact.review_evidence.binding.create`. -- A separate AUTH availability manifest proves every required action was - registered, transferred by `WS-AUTH-001-REV-CUSTODY` to an exact AUTH activation - custodian, paired with merged hidden behavior/evaluator, and activated through - AUTH-14 for `submission.create`, `WS-AUTH-001-REV-05/06/07/08/09A/11/12`, or - `WS-AUTH-001-REV-LIFECYCLE` before release. It - derives exact counts and SHAs from current trusted main, separately inventories - the four additive REV actions and - `artifact.review_evidence.binding.create`, and rejects missing/extra or early - activation. Historical 57/9/48, 65/9/56, and AUTH-09B 65/10/55 plus - current-main AUTH-09C 65/12/53 are snapshots, not fixed expected totals for - this later release gate. - AUTH-14 proof specifically covers one `submission.create` action for initial - and prepared revision submission, the merged REV-09A preparation/replay - participant, final locked-fact recomposition, misuse/denial behavior, and no - legacy revision bypass. -- AUTH preflight proves its reusable dependency has no generic success - auto-commit, every request route or service command owns its explicit - transaction boundary and only commit, - authorization-evidence SQL failures produce a retryable 503 without partial - state, and successful existing-actor GET/PATCH access matches AUTH's repaired, - documented verification-timestamp semantics. -- Live mutation proof rejects wrong-binding, serialized, forged, and - caller-constructed `PreparedAuthorizationHandle` attempts against an - unconsumed legitimate handle before any REV/task/ART/CON mutation. Each such - attempt stages no AuthorizationDecision/evidence, preserves that handle, and a - subsequent exact first use succeeds. Separate stale/already-consumed and - concurrent duplicate-use tests prove no new evidence or feature state, no - resurrection, and exactly one winner for concurrent exact use. Separate - current-authority and policy denials after valid consumption prove dirty - caller-transaction rollback, unchanged bounded AUTH evidence restaging in a - clean transaction, one request-route/service-command evidence commit, and no - feature/shared audit/outbox effect. Evidence, participant, cancellation, - commit, or denial-restaging failure leaves no partial authority evidence. -- Final product registration exposes coherent current-work, claim, release, decline, - context, decision, revision preparation/evidence, chain, and authorized admin - operations alongside the existing canonical task resubmission endpoint. - Shutdown advances the persisted 12A controller through every adjacent phase: - `admission_fenced` blocks new submissions, queue admission, claims, and - replacement while leased completion may finish; `commands_draining` blocks - new completion commands and fresh Operator calls release remaining leases; - `leases_released -> delivery_draining` begins the bounded drain of fulfillment - work committed before completion commands were fenced. During - `delivery_draining`, fulfillment dispatch and authenticated callbacks remain - allowed only for canonical obligation roots at or below the immutable cutoff - stored when `commands_draining` began. Decisions, policy changes, - maintenance, reconciliation, callback successor work, and post-cutoff events - cannot create, requeue, extend, or repair an obligation. - The transition to `disabled` requires zero dispatchable, retryable, claimed, - or in-flight fulfillment events and zero nonterminal delivery or callback - obligations. Routes, background jobs, and fixed service identity mappings are - then disabled in manifest order without deleting pending immutable work. The - authenticated lifecycle-control transition/status route and its AUTH mapping - remain available while disabled; all product routes, product background jobs, - and product fixed service identity mappings remain off. Queued review work remains durable - for forward reactivation. REV-13 does not invent a second coordinator or - attempt schema downgrade after protected rows exist. -- CON-owned readiness proves its binding/policy operations, contribution/award - reads, callback, and bounded Finance/Operator operations are composed by CON - under `/api/v1`. REV-13 neither edits nor registers those routers. Missing CON - readiness blocks joint release; noncanonical API aliases and optional participants remain - prohibited. -- API proof includes the exact Project Manager D6 obligation-close and repair - routes plus Operator legacy-close, their registered AUTH mappings/resource - composers, PM cross-project/not-reached denial, Operator D6 denial, - non-Operator legacy-close denial, stale/crossed head or finding denial, exact - replay, and changed-replay conflict. -- Product release registers only the review-owned evidence-intake routes and - exposes the already merged AUTH-14 canonical task submission command behind - the joint lifecycle controller. The amended AUTH-14 cutover already installed - frozen-preparation acknowledgment, the prepared structured-response branch, - removal of the legacy direct-revision path, and the strict revision database - guard while the surface remained unavailable. REV-13 verifies those exact - contracts and changes neither task-owned command nor migration. It adds no - contributor/reviewer preparation route or second review resubmission route; - the only preparation mutation route is the privileged chunk-11 successor- - repair command. First submissions remain behaviorally unchanged. -- Preflight verifies the already merged amended AUTH-13 replacement-assignment - command requires the typed review preparation-transfer participant whenever a - Review-rooted revision obligation exists. AUTH-13 owns the non-optional - binding, startup/command fail-closed behavior, and atomic assignment plus - preparation-successor transaction. REV-13 changes no AUTH-owned command. Live - proof covers absent binding, injected failure after each participant, replay, - stale head, concurrent replacement/repair/submission, and rollback that never - removes the participant while the command is available. -- Preflight also verifies the amended AUTH-14 cutover's named PostgreSQL - `NOT VALID` check requiring version 1 or a non-null preparation reference. - Existing version>1 rows remain immutable/readable, while every new or updated - post-cutover row is checked. The service maps missing/stale preparation to a - stable domain error; no `IntegrityError` escapes. Existing AUTH-14 migration/API - evidence plus the REV live drill prove new unprepared revisions fail, prepared - revisions succeed, direct SQL cannot forge a legacy exemption, and downgrade - is refused once post-cutover rows depend on the rule. -- Deployment does not pretend Alembic and process replacement are simultaneous. - The Operator advances `pre_activation -> revision_cutover_fenced`, whose exact - matrix allows initial submissions and checker admission but denies legacy and - prepared revisions plus both replacement classes. The runbook drains and - verifies no old writer remains, verifies the already applied AUTH-13/14 - migration and prepared/replacement bindings, then advances to `active` to open - prepared revision/replacement admission. A live ordering test holds an old - writer at the fence and proves it cannot cross the product-release boundary or - leak an IntegrityError. -- Existing Task Context responses expose the frozen current preparation ID, - digest, guide/policy versions, and change summary during `needs_revision`. - The canonical submission request acknowledges preparation ID/digest; neither - request mutates preparation state. -- Full conformance suite, lint, docs, coverage, stale scans, and link checks pass. -- The live drill calls the authenticated Operator lifecycle-control route for - every legal edge, proves every illegal/skipped edge, full phase/command matrix, - N-to-N+1 reactivation with a new manifest and proof that no retired legacy - revision/replacement writer revives, exact and changed replay, and crash - after each durable-write boundary. It also proves timeout leaves phase - unchanged, fresh retry, bounded lease release, dispatch denial before adapter - I/O, callback in flight during delivery drain, and disable denial while any - delivery/callback obligation remains. -- In `delivery_draining`, the drill runs fulfillment dispatch, authenticated - callbacks, and ART-backed review projection against the transition to - `disabled` in both orderings. Durable in-flight state precedes fence release; - a disable attempt observes it, returns blocked with phase unchanged, and - releases the exclusive lock. Provider I/O observes no lifecycle advisory lock - or database transaction; crash returns work to retryable state; fenced - finalization or callback completion clears the observation; and a fresh - Operator command advances without changing canonical Review or award truth. -- The same drill proves the cutoff is captured under the exclusive fence after - all admitted completion transactions finish. CON allocates every immutable - fulfillment-obligation ordinal only after acquiring the shared fence. A - pre-cutoff root may create and finalize only attempts under that root; - post-cutoff, crossed-generation, caller-supplied-ordinal, requeue, maintenance, - reconciliation, and callback-successor cases fail before adapter or successor - I/O. They preserve phase, obligation-root, award, delivery, and callback truth; - append bounded denial audit evidence; create no successor outbox event; and - permit only the shared dispatcher's canonical claim-to-retryable recovery for - the same root event. The drill proves that recovery transition is idempotent, - cannot change provider or award truth, and does not strand a claimed event. -- Preflight enumerates every CON obligation creation, requeue, successor, and - repair writer and requires its exact merged shared-fence hook. Barrier tests - race each writer against cutoff capture in both orders: the writer either - commits under an ordinal included by the cutoff or observes - `commands_draining` and fails before allocating an ordinal or changing an - obligation. -- The joint drill also proves contribution-policy/binding setup, TaskAssignment - and ReviewLease ContributionPolicyVersion freezes, reviewer contribution for - all three decisions, immutable Review, findings, and resolutions for every round, - FinalAcceptance and its sole submitter contribution only when the decision is - `accept`, mutually exclusive source lineage, a second revision Review, paid and - explicit-unpaid awards, outbound delivery/callback ordering, suspended or - retired binding behavior, core contribution/award privacy, - Finance-versus-Operator denials, atomic rollback, adapter/storage outage, - replay, and reconciliation. -- Barrier and fault evidence proves the exact write order: immutable Review, - findings, and resolutions; lease consumption and queue closure; reviewer - contribution and rule evaluation; decision branch; for `accept` only, - FinalAcceptance followed by the submitter contribution and rule evaluation; - REV-staged audit and outbox rows; then one commit. Failure after the reviewer - operation or any later branch stage leaves none of those writes committed. -- Forward and backward Project Guide rebase leave the TaskAssignment - ContributionPolicyVersion unchanged; each new ReviewLease freezes reviewer terms - independently and decision-neutral reviewer awards agree across - `accept`/`needs_revision`/`reject` for the same frozen terms. -- Active docs use blocking/advisory findings, server-selected offer semantics, - controlled rebase, canonical decisions, `Review(accept) -> FinalAcceptance -> - accepted_submission`, REV-owned atomic audit and outbox staging, WS-CON - contribution/award boundaries, AWS S3/MinIO, and deferred reputation - consistently. -- Optional contribution-evidence projection is outside core release readiness. - Its absence or ART outage cannot block Review, ContributionRecord, awards, - fulfillment, or core reads. -- Evidence report contains only placeholder paths/IDs and approved bounded - excerpts. -- A terminology/retirement matrix covers every review object and removes active - high/medium/low, full-backlog, direct payment/reputation, and checker-as-human- - decision wording. PlantUML, architecture brief PDF, and linked generated - derivatives are regenerated and diff-verified. -- Initiative status, risks, decisions, review evidence, and trust bundle record - what is proven and any explicitly deferred residual work. - -## Verification - -```text -cd backend && alembic upgrade head -cd backend && pytest -q tests/test_alembic.py tests/test_lifecycle_control.py tests/test_tasks.py tests/test_checkers.py tests/test_reviews.py tests/test_contributions.py tests/test_compensation.py tests/test_authorization.py tests/test_outbox.py tests/test_audit.py tests/test_config.py tests/test_api_contract_e2e.py tests/test_review_lifecycle_live_drill.py -cd backend && ruff check app tests scripts -cd backend && docstr-coverage --config .docstr.yaml -docker compose up -d --wait postgres redis minio -cd backend && python scripts/review_lifecycle_live_drill.py --start-api-worker-beat --run-live-preflight --require-postgres --require-workers --require-minio --require-auth --require-con --require-outbox --base-url http://127.0.0.1:8000 --require-real-http --artifact-backend s3_compatible --evidence-out ../.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/evidence/live-drill.json -cd backend && python scripts/review_lifecycle_validate_evidence.py ../.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/evidence/live-drill.json -(metadata_dir="$(mktemp -d)" && trap 'rm -rf "$metadata_dir"' EXIT && (cd backend && WORKSTREAM_TEST_ADMIN_DATABASE_URL=postgresql+asyncpg://workstream:workstream@localhost:5433/postgres .venv/bin/python scripts/run_isolated_tests.py --metadata-json "$metadata_dir/result.json" --timeout-seconds 12600 -- .venv/bin/python -m pytest -q --ignore=tests/test_isolated_database_runner.py --cov=app --cov-report=term-missing --cov-fail-under=78)) -cd backend && coverage report --include='app/modules/reviews/*,app/workers/reviews.py' --precision=2 --fail-under=90 -cd backend && for path in app/api/router.py app/modules/contributions/router.py app/modules/compensation/router.py 'app/modules/lifecycle_control/*' app/modules/tasks/schemas.py app/modules/tasks/service.py app/modules/tasks/router.py app/composition/review_lifecycle.py app/composition/joint_lifecycle_control.py; do coverage report --include="$path" --precision=2 --fail-under=90 || exit 1; done -./docs/diagrams/render_plantuml.sh -./docs/architecture_brief/render_pdf.sh -git diff --exit-code -- docs/diagrams docs/architecture_brief -sha256sum -c docs/reference_specs/SHA256SUMS -git check-attr diff merge text -- docs/reference_specs/*.pdf | awk '$3 != "unset" {bad=1} END {exit bad}' -python3 scripts/check_internal_review_evidence.py -python3 scripts/check_markdown_links.py -python3 scripts/check_stale_workstream_wording.py -python3 scripts/check_stale_review_contracts.py -python3 scripts/check_stale_artifact_contracts.py -python3 scripts/check_stale_authorization_docs.py -git diff --check -``` - -## Required reviewers - -Senior engineering, QA/test, security/auth, product/ops, architecture, docs, -reuse/dedup, test-delta, and CI integrity if proof or coverage tooling changes. - -## Human review focus - -Evidence authenticity, no bypass, complete failure coverage, privacy scrub, and -clear distinction between proven lifecycle and deferred frontend/reputation. +AUTH action/service activation remains AUTH-owned. Persisted lifecycle phase +controls execution after static registration. Every behavior child adds its +scenario before 13C so release is proof aggregation, not first-time testing. ## Stop condition -After merge and automated memory, mark the initiative complete only if every -definition-of-done item is proven. Do not start a frontend successor -automatically. +Use `CHUNK_MAP.md`; do not execute this parent. diff --git a/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-PLAN2-runtime-readiness-plan-refresh.md b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-PLAN2-runtime-readiness-plan-refresh.md new file mode 100644 index 000000000..ffae7bb31 --- /dev/null +++ b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/chunks/WS-REV-001-PLAN2-runtime-readiness-plan-refresh.md @@ -0,0 +1,106 @@ +# Chunk Contract: WS-REV-001-PLAN2 - REV-02A Runtime Readiness Plan Refresh + +## Parent initiative + +`WS-REV-001` - Review And Revision Lifecycle + +## Goal + +Reconcile the complete REV initiative against trusted main, current owner plans, +and internal review before any REV-02 runtime or migration work begins. + +## Risk class + +L1 planning and cross-initiative contract integrity. + +## Preconditions + +- `WS-REV-001-02` is merged through PR #147 on trusted main. +- AUTH-09D-A is merged through PR #148 at + `99ae4c963e53f317175dcb308b9e47c93ccf19ed`; its profile-lifecycle behavior and + migration `0026` are trusted, while the separate contributor foundation is not. +- The user explicitly authorized planning and read-only preparation while the + remaining AUTH contributor-foundation runtime dependency remains unmerged. +- No AUTH, ART, CON, backend runtime, migration, or persistence test is edited. + +## Allowed files + +```text +.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/** +.agent-loop/merge-intents/WS-REV-001-PLAN2.json +docs/spec_review_lifecycle.md +docs/architecture_data_model.md +docs/architecture_lifecycle_state_machine.md +docs/operations_revision_replay.md +``` + +## Not allowed changes + +```text +backend runtime, migrations, schemas, models, repositories, services, routes, or tests +frozen `docs/reference_specs/` source specifications, archival inputs, or cross-initiative owner artifacts +AUTH, ART, or CON action availability, ownership, runtime, or planning contracts +implementation or activation of any review, revision, adjudication, or release behavior +completion of WS-REV-001-02A or automatic start of WS-REV-001-02B +``` + +## Acceptance criteria + +- Trusted merged authority is separated from unmerged worktree evidence and + human-approved prospective dependencies. Every runtime gate requires its + eventual exact owner chunk ID, merged PR/SHA, migration head, constraints, and + test evidence before implementation. +- The 02A guide-activation contract defines Project-first publication and + Task-screening locking, immutable Task guide identity, exact status/provenance + invariants, database time, unchanged superseded-candidate denial, and complete + allowed-file/test scope. Proposed 02A2 owns prepared-authorized stale-retry + protection before AUTH-12 activation. +- The initiative uses one explicit command-specific lock order for the review + decision transaction and identifies every cross-domain owner prerequisite. +- Pure decision-contract work is separated from the first canonical + Review/FinalAcceptance transaction. Oversized L1 chunks are split into + independently reviewable same-initiative successors before implementation. +- ART packet-read, review-evidence, stabilized artifact-digest, CON persistence/ + participant, AUTH identity/action, and release-control dependencies are + fail-closed owner gates. REV does not invent or start owner chunks. +- Every executable chunk has a canonical title, explicit allowed/not-allowed + scope, acceptance criteria, verification commands, required reviewer tracks, + and a stop condition. Migration numbers remain unreserved until each chunk + starts from the then-current single head. +- v0.1 remains limited to immutable Review/finding/resolution history, + `accept -> FinalAcceptance -> accepted_submission`, revision rebase, and + terminal reject. Adjudication remains disabled and unimplemented. +- The merge intent returns to `WS-REV-001-02A` and requires a new explicit start + after all runtime gates merge. This planning chunk activates no successor. + +## Verification commands + +```text +git diff --check +python3 scripts/check_stale_workstream_wording.py +python3 scripts/check_markdown_links.py +PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 backend/.venv/bin/python scripts/test_agent_gates.py +``` + +Run the initiative-specific AUTH/ART/CON dependency scans. Verify that the only +active product documents changed are the four enumerated allowed files, +including `docs/spec_review_lifecycle.md`, and that the diff contains no +backend, migration, frozen `docs/reference_specs/` or archival specification, +cross-initiative handoff, or owner-plan files. + +## Required reviewers + +Senior engineering, QA/test, security/auth, product/ops, architecture, docs, +reuse/dedup, test delta, and CI integrity. + +## Human review focus + +Dependency authority, chunk boundaries, transaction and locking ownership, +future-compatible but dormant adjudication boundary, and absence of runtime +changes. + +## Stop condition + +Merge, allow automated memory to record this planning chunk, and stop. +`WS-REV-001-02A` requires its exact external dependencies and a separate human +start; do not implement it or begin 02B automatically. diff --git a/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/reviews/WS-REV-001-PLAN2-external-review-response.md b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/reviews/WS-REV-001-PLAN2-external-review-response.md new file mode 100644 index 000000000..dcf22fc63 --- /dev/null +++ b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/reviews/WS-REV-001-PLAN2-external-review-response.md @@ -0,0 +1,58 @@ +# External Review Response: WS-REV-001-PLAN2 + +## Review source + +- Pull request: #150 +- Reviewer: CodeRabbit +- Reviewed head: `e311709a29367d298442ee9a28e2192f6d4d704b` +- Internally reviewed repaired head: `a5d6b2ced4aef4e5df316af65246e10dcdc524d1` +- Actionable threads: 6 + +## Comments addressed + +1. Made 03B the sole normalized ReviewPacketManifest/item model, schema, + migration, repository-contract, and persistence-test owner. 06A now consumes + that canonical contract for claim-time materialization and owns no duplicate + persistence definition. +2. Added concrete focused pytest, Ruff, docstring, isolated 78 percent suite, + focused 90 percent coverage, stale-scan, link, evidence, agent-gate, + merge-intent, and diff commands to executable chunk 08. +3. Assigned the task-owned flush-only preparation participant to 09A2. Chunk 10 + consumes it through the caller's session and adds no task-owned implementation + file or second participant path. +4. Restricted legacy revision closure to state with neither an unambiguous human + Review root nor an exact final `needs_revision` CheckerRun. Valid checker + remediation is never legacy. +5. Classified `docs/spec_review_lifecycle.md` as one of PLAN2's four active + product documents and reserved the unchanged claim for frozen + `docs/reference_specs/` sources. +6. Preserved 12A as a non-executable split record and assigned controller + implementation to 12A1 through 12A4. + +## Comments deferred + +None. + +## Human decisions needed + +None for these repairs. The PR still requires the user's explicit merge +approval, and merging PLAN2 does not start 02A. + +## Commands rerun + +- `git diff --check 99ae4c963e53f317175dcb308b9e47c93ccf19ed..HEAD`: PASS. +- Four stale-contract scanners: PASS. +- `python3 scripts/check_markdown_links.py`: PASS for 36 Markdown files. +- Agent gates: 87 passed. +- `alembic heads`: one head, `0026_actor_profile_lifecycle`. +- Schema-v2 PLAN2 merge-intent validation: PASS. +- Pinned Ruff, docstring-coverage, and coverage executables: present; pinned + docstring command: PASS. +- `python3 scripts/check_internal_review_evidence.py`: PASS after exact-SHA + evidence rebind. + +## Remaining risks + +The AUTH contributor-field foundation remains unmerged, so REV runtime and 02A +implementation remain stopped. GitHub CI and CodeRabbit re-review must pass on +the repaired PR head. diff --git a/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/reviews/WS-REV-001-PLAN2-internal-review-evidence.md b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/reviews/WS-REV-001-PLAN2-internal-review-evidence.md new file mode 100644 index 000000000..16179ebb8 --- /dev/null +++ b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/reviews/WS-REV-001-PLAN2-internal-review-evidence.md @@ -0,0 +1,109 @@ +# Internal Review Evidence: WS-REV-001-PLAN2 + +## Candidate + +- Trusted base: `99ae4c963e53f317175dcb308b9e47c93ccf19ed` +- Reviewed planning candidate: `a5d6b2ced4aef4e5df316af65246e10dcdc524d1` +- Scope: complete REV initiative/runtime-readiness reconciliation, four active + product documents including `docs/spec_review_lifecycle.md`, and one schema-v2 + merge intent +- Runtime status: blocked; no backend runtime, migration, model, service, route, + test, workflow, frozen `docs/reference_specs/` source specification, or cross-owner + plan changed + +Open sub-agent sessions: none + +Valid findings addressed: yes + +## Reviewed revision + +Reviewed code SHA: a5d6b2ced4aef4e5df316af65246e10dcdc524d1 + +Reviewed at: 2026-07-18T20:14:06Z + +Reviewer run IDs: /root/rev01_senior_arch_reuse@a5d6b2ced4aef4e5df316af65246e10dcdc524d1; /root/rev01_qa_product_test@a5d6b2ced4aef4e5df316af65246e10dcdc524d1; /root/rev01_security_docs_ci@a5d6b2ced4aef4e5df316af65246e10dcdc524d1 + +## Circuit breaker + +PASS with a documented planning-only size exception. The full authorized +initiative refresh changes 37 files and contracts substantially more than the +default review guideline, but 3,884 lines are contraction/removal, no runtime or +schema is implemented, oversized runtime parents are non-executable split +records, only PLAN2 is active, and every successor requires a separate start. + +## Reviewer results + +| Reviewer | Result | Blocking findings | Notes | +|---|---:|---|---| +| Senior engineering | PASS | None | Runtime ownership, lock ordering, child boundaries, AUTH-09D-A reconciliation, and stop gates are explicit. | +| QA/test | PASS | None | Backfill refusal, direct SQL, races, rollback, immutable history, checker/human separation, and release proof are covered. | +| Security/auth | PASS | None | AUTH owns contributor clean cut; REV owns lifecycle lineage; all 24 REV action dependencies remain unavailable. | +| Product/ops | PASS | None | Accept, needs-revision, reject, FinalAcceptance, contribution, checker remediation, and human revision flows are unambiguous. | +| Architecture | PASS | None | Submission persists exact checker-remediation cause; 09A4 owns final source XOR; AUTH-14 owns public request acknowledgement, authorization cutover, and activation. | +| CI integrity | PASS | None | Merge intent is unique; global 78 percent and independent focused 90 percent future coverage gates are preserved; no CI file changed. | +| Docs | PASS | None | Active authority is current through AUTH-09D-A PR #148; `docs/reference_specs/` remains frozen; historical catalogue snapshots remain historical. | +| Reuse/dedup | PASS | None | Canonical Submission, CheckerRun, ActorProfile, RevisionContextPreparation, ART capabilities, and CON participants are reused. | +| Test delta | PASS | None | No executable test changed, was removed, skipped, weakened, or rewritten. | + +No Critical, High, or Medium finding remains. + +The reviewed commit includes the initiative review log, external-review repair, +and initial response/evidence/trust artifacts. The follow-up changes only +recognized review evidence to bind this exact-SHA result and record final gates. + +## Findings repaired + +- Split oversized runtime parents into unique proposed child ownership records. +- Separated pure decision contracts from the first canonical + Review/FinalAcceptance/CON transaction. +- Made human Review revision preparation distinct from checker remediation in + every active contract and operational proof. +- Added immutable server-derived `remediation_source_checker_run_id`, exact + fail-closed backfill, database constraints, Task-first retry locking, and later + 09A4 source-XOR ownership. +- Preserved legacy public denial in 02A and moved prepared superseded-guide + reactivation to hidden 02A2 before AUTH-12 activation. +- Corrected successor IDs, merge-intent identity, exact policy-row locking, + persistent focused-coverage scope, and CI-integrity reviewer requirements. +- Rebased onto AUTH-09D-A PR #148, adopted migration + `0026_actor_profile_lifecycle`, and retained the separate contributor-field + foundation as 02A's only unmerged AUTH runtime dependency. +- Updated live AUTH catalogue truth to 74 PermissionIds and 65 ActionIds split + into 15 active and 50 planned while preserving historical snapshots. +- Made 03B the sole packet-manifest persistence owner, made 06A its consumer, + and made chunk 10 consume the task participant delivered by 09A2. +- Added pinned executable chunk 08 commands with independent reviews/tasks 90 + percent floors; excluded exact CheckerRun remediation from legacy closure. +- Corrected active-spec versus frozen `docs/reference_specs/` scope and assigned + release-control implementation exclusively to 12A1 through 12A4. + +## Deterministic evidence + +- `git diff --check`: PASS. +- Workstream, authorization, artifact, and review stale-contract scanners: PASS. +- Markdown links: PASS for 36 changed Markdown files. +- Agent gates: 87 passed. +- `alembic heads`: one head, `0026_actor_profile_lifecycle`. +- Schema-v2 merge intent: PASS for `WS-REV-001-PLAN2 -> WS-REV-001-02A`, + explicit start required. +- Runtime catalogue arithmetic: 74 PermissionIds; 65 ActionIds; 15 active; 50 + planned. +- Changed-scope scan: only the REV initiative, PLAN2 merge intent, and the four + allowed active product documents. + +The full backend suite was not run because this chunk changes no runtime, +migration, dependency, workflow, or executable test. Repository process gates +and exact source-of-truth checks cover the documentation-only delta. + +## Remaining gates + +- AUTH must merge the separately reviewed contributor/canonical-human field + foundation from the then-current migration head. +- 02A requires a separate explicit human start and current-main contract refresh. +- Later ART, CON, AUTH custody/prepared/cutover, duration, round/deadline, and + release dependencies remain gated by their exact child contracts. +- Adjudication remains disabled and unimplemented in v0.1. + +## Disposition + +PASS for PLAN2 publication. Runtime implementation remains prohibited. diff --git a/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/reviews/WS-REV-001-PLAN2-pr-trust-bundle.md b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/reviews/WS-REV-001-PLAN2-pr-trust-bundle.md new file mode 100644 index 000000000..f68a35bd3 --- /dev/null +++ b/.agent-loop/initiatives/WS-REV-001-review-revision-lifecycle/reviews/WS-REV-001-PLAN2-pr-trust-bundle.md @@ -0,0 +1,131 @@ +# PR Trust Bundle: WS-REV-001-PLAN2 + +## Chunk + +`WS-REV-001-PLAN2` - REV-02A Runtime Readiness Plan Refresh. + +## Goal + +Make the complete review/revision initiative implementation-ready against +trusted main without starting REV runtime or coding against the still-retired +task contributor fields. + +## Human-approved intent + +Preserve one Project Guide task pipeline, immutable Review/finding/resolution +history, exact leased Submission review, accept-only FinalAcceptance, separate +checker remediation, Review-rooted human revision rebase, and no v0.1 +adjudication implementation. + +## What changed + +- Reconciled the full initiative, active lifecycle/data/replay documents, risks, + decisions, conformance, test design, and executable/proposed chunk boundaries. +- Converted oversized future parents into non-executable split records. +- Added exact checker-remediation causal lineage and final human/checker source + XOR ownership to future 02C/09A4 contracts. +- Reconciled merged AUTH-09D-A PR #148, migration `0026`, and the live AUTH + catalogue while preserving the separate contributor foundation gate. +- Added exactly one merge intent for PLAN2 with explicit successor start. + +## Why it changed + +Merged AUTH, ART, CON, and cross-initiative contracts invalidated older planning +assumptions. The prior plan also combined runtime boundaries, mixed human and +checker revision rules, and lacked database-enforceable checker-remediation +causal lineage. + +## Design chosen + +REV owns immutable review/revision lifecycle facts and orchestration. Task owns +guide context and Submission lineage. Checker remediation reuses CheckerRun and +stores `remediation_source_checker_run_id`; human revision uses +RevisionContextPreparation. CON participates flush-only in the REV-owned commit, +ART stays behind typed capability ports, and AUTH owns authorization plus the +separate contributor clean cut. + +## Alternatives rejected + +- No synthetic Review or shared origin-neutral revision-obligation entity for + checker remediation. +- No separate reviewer guide or reviewer-side rebase. +- No direct Review-decision inference for submitter contribution; it consumes + FinalAcceptance. +- No AUTH ownership of REV source columns/constraints. +- No adjudication states, queues, actions, policy, or runtime in v0.1. + +## Scope control + +Only the REV initiative, four allowed active product documents including +`docs/spec_review_lifecycle.md`, and one PLAN2 merge intent changed. No backend, +migration, test, workflow, dependency, frozen `docs/reference_specs/` source +specification, AUTH/ART/CON owner plan, or handoff file changed. + +## Product behavior + +This PR activates no product behavior. Planned v0.1 decisions remain `accept`, +`needs_revision`, and `reject`; every committed decision/finding/resolution is +immutable, accept alone creates FinalAcceptance, and checker remediation remains +distinct from Review-rooted human revision. + +## Acceptance criteria proof + +The plan names exact dependencies, lock orders, transaction ownership, +database constraints, migration/backfill refusal, race tests, contribution and +artifact boundaries, child ownership, required reviewers, and explicit stops. +AUTH-09D-A is treated as merged; the contributor foundation remains fail-closed. + +## Tests/checks run + +Diff integrity, four stale-contract scanners, Markdown links, 87 agent-gate +tests, one-head Alembic verification, merge-intent validation, catalogue +arithmetic, and changed-scope scans all pass. + +## Test delta + +No executable test or runtime file changed. No assertion, skip, coverage floor, +or CI gate was weakened. + +## CI integrity + +Current global 78 percent coverage remains unchanged. Future materially changed +task/checker/project areas require persistent focused 90 percent gates in their +own implementation chunks. PLAN2's schema-v2 merge intent validates uniquely. + +## Reviewer results + +Senior engineering, QA/test, security/auth, product/ops, architecture, docs, +reuse/dedup, test delta, and CI integrity all pass on repaired reviewed SHA +`a5d6b2ced4aef4e5df316af65246e10dcdc524d1`. + +## External review + +CodeRabbit reported six planning/scope findings on PR #150. All six are +addressed in the external-review repair: packet-manifest ownership, chunk 08 +verification commands, task-participant ownership, legacy-checker exclusion, +active-spec scope classification, and 12A child ownership. Final GitHub CI and +CodeRabbit re-review are pending; human review remains required. + +## Remaining risks + +The contributor-field foundation has not merged, ART/CON runtime participants +remain future owner work, two duration defaults and human revision exhaustion +semantics require explicit approval, and later migration heads must be refreshed +from current main. + +## Follow-up work + +After PLAN2 merges, automated memory names 02A but does not start it. AUTH must +merge the contributor foundation, then a human must explicitly start a refreshed +02A contract. Every later child follows its own gate. + +## Human review focus + +Review the AUTH/REV ownership boundary, checker versus human revision lineage, +02A/02A2 sequencing, transaction/lock ownership, dormant adjudication boundary, +and absence of runtime changes. + +## Human merge ownership + +Only the user may approve and merge this PR. Merge does not authorize 02A +implementation. diff --git a/.agent-loop/merge-intents/WS-REV-001-PLAN2.json b/.agent-loop/merge-intents/WS-REV-001-PLAN2.json new file mode 100644 index 000000000..5104c6290 --- /dev/null +++ b/.agent-loop/merge-intents/WS-REV-001-PLAN2.json @@ -0,0 +1,9 @@ +{ + "chunk_id": "WS-REV-001-PLAN2", + "chunk_title": "REV-02A Runtime Readiness Plan Refresh", + "initiative_id": "WS-REV-001", + "next_chunk_id": "WS-REV-001-02A", + "next_chunk_title": "Project Guide Activation Sequence And Publication Locking", + "next_requires_explicit_start": true, + "schema_version": 2 +} diff --git a/docs/architecture_data_model.md b/docs/architecture_data_model.md index d79832be1..f2bae7ed6 100644 --- a/docs/architecture_data_model.md +++ b/docs/architecture_data_model.md @@ -202,6 +202,7 @@ Fields: - `project_id` - `version` - `status` +- `activation_sequence` (nullable only while draft; immutable after allocation) - `content_markdown` - `change_summary` - `approved_by` @@ -218,6 +219,13 @@ instructions, reviewer guidance, or other project-specific source material. `approved_by` and `effective_at` are server-written activation provenance, not request-body fields and not contributor-facing guide content. +Guide status is exactly `draft | active | superseded`. Draft rows have null +activation sequence/approval/effective/superseded provenance. Active and +superseded rows retain one positive per-project activation sequence plus original +approval/effective provenance; superseded rows additionally retain +`superseded_at`. The planned 02A migration enforces this shape and immutable +chronology before Task stamping consumes it. + Runtime enforcement uses machine-readable policies attached to the guide version. Workstream does not parse guide prose at submission time to decide which artifact checks to run. Project owners provide open-ended setup material and business terms. Workstream @@ -1060,7 +1068,9 @@ Fields: - `id` - `project_id` +- `locked_guide_id` - `locked_guide_version` +- `locked_guide_activation_sequence` - `locked_guide_source_snapshot_id` - `locked_guide_source_snapshot_hash` - `locked_effective_project_submission_artifact_policy_id` @@ -1116,8 +1126,9 @@ Source type: External origin adapters are later work. When added, they normalize into this task shape instead of creating a separate task lifecycle. -The task id points to the locked task contract. That contract includes the guide -version, guide source snapshot id/hash, effective project submission artifact +The task id points to the locked task contract. That contract includes the exact +same-project guide ID/version/activation-sequence triplet, guide source snapshot +id/hash, effective project submission artifact policy id/hash, generated project pre-submit checker policy id/bundle hash, post-submit checker policy id/version/hash, review policy version, revision policy version, acceptance criteria, derived display summaries, and skill tags. @@ -1177,7 +1188,8 @@ Fields: - `submitted_at` - `locked_at` - `supersedes_submission_id` -- `revision_context_preparation_id` (revision submissions only) +- `remediation_source_checker_run_id` (checker-remediation submissions only) +- `revision_context_preparation_id` (human-Review revision submissions only) The contributor submission packet supplies the task id, summary, outputs, artifact hashes, evidence references, and contributor attestation. Workstream assigns the @@ -1192,6 +1204,16 @@ revision policy versions. Submitter award eligibility remains governed by the immutable TaskAssignment-frozen `ContributionPolicyVersion` and is not restated on the submission. +Version 1 has neither revision-source field. Every later version has exactly one: +a checker-remediation version stores the server-derived +`remediation_source_checker_run_id`, while a human-Review revision stores the +server-selected `revision_context_preparation_id`. The checker source must be the +completed, needs-revision, current-at-selection CheckerRun for the immediate +predecessor Submission and same Task. PostgreSQL enforces same-task/immediate- +predecessor lineage, one successor per source CheckerRun, source-field XOR, and +post-finalization immutability. A later CheckerRun retry cannot rewrite committed +Submission lineage. Contributor requests supply neither authoritative source ID. + Implementation note: submissions stamp explicit post-submit checker provenance from the task. Durable `CheckerRun` creation uses those `locked_post_submit_checker_policy_*` fields and fails closed when they are @@ -1496,8 +1518,9 @@ Fields: Purpose: -This immutable Review-rooted record is created before a contributor resumes a -human-review revision. Exact prior Submission guide identity/activation-sequence +This immutable Review-rooted record is created atomically before a contributor +can observe human-review-caused revision. Checker remediation retains the Task's +locked context and creates no preparation. Exact prior Submission guide identity/activation-sequence match with the currently active guide keeps context. Any different valid active pair rebases forward or backward. Missing, inconsistent, revoked, or unsafe context blocks for manager repair. Task Context returns the validated chain diff --git a/docs/architecture_lifecycle_state_machine.md b/docs/architecture_lifecycle_state_machine.md index 4598a3ae5..20e2ad22f 100644 --- a/docs/architecture_lifecycle_state_machine.md +++ b/docs/architecture_lifecycle_state_machine.md @@ -161,13 +161,17 @@ Required before entering: - from `REVIEW_PENDING`: the same TaskAssignment remains `active`, with no FinalAcceptance or submitter contribution -Before the contributor resumes from a human Review, Workstream appends an -immutable RevisionContextPreparation. Exact prior Submission guide -identity/activation-sequence match with the currently active guide keeps -context. Any different valid active pair rebases forward or backward. Missing, -inconsistent, revoked, or unsafe context blocks for Project Manager repair. -Checker-caused remediation remains CheckerResult-rooted and creates no Review -episode. +Before the contributor resumes from a human Review, Workstream appends one +immutable Review-rooted RevisionContextPreparation in the same transaction that +enters `needs_revision`. Exact prior Submission guide identity/activation- +sequence match with the currently active guide keeps context. Any different +valid active pair rebases forward or backward. Missing, inconsistent, revoked, +or unsafe context blocks for Project Manager repair. Checker-caused remediation +remains a distinct CheckerRun-rooted path, keeps the Task's locked context, and +creates no Review, ReviewFinding, preparation, reviewer contribution, or +synthetic human actor. Its corrected Submission persists the unique immutable +`remediation_source_checker_run_id` for the exact predecessor CheckerRun; a +later retry cannot rewrite that causal lineage. A revision context rebase never mutates the prior submitted attempt. It only stamps the next submission attempt. The contributor and reviewer must see the prior version, the next version, and the guide or policy change summary. diff --git a/docs/operations_revision_replay.md b/docs/operations_revision_replay.md index 8c1962286..9378a21cd 100644 --- a/docs/operations_revision_replay.md +++ b/docs/operations_revision_replay.md @@ -3,7 +3,7 @@ ## Status And Purpose This is the planned v0.1 operating contract. Revision behavior remains -unavailable until its owning REV chunks, exact AUTH activation, and REV-13 joint +unavailable until its owning REV chunks, exact AUTH activation, and REV-13C joint release complete. Revision replay preserves an immutable answer to three questions: what the @@ -13,8 +13,10 @@ resolution. ## Review-Rooted Preparation -Human revision begins only from an immutable `Review(needs_revision)`. Checker -remediation remains CheckerResult-rooted and does not fabricate a Review episode. +Controlled revision replay begins only from one immutable +`Review(needs_revision)`. Checker remediation remains a separate CheckerRun- +rooted resubmission path using the Task's existing locked context; it does not +fabricate a Review, finding, preparation, reviewer contribution, or human actor. Before contributor access, Workstream appends a RevisionContextPreparation. It compares the prior Submission's stamped Project Guide identity and activation @@ -46,16 +48,21 @@ immutable SubmissionFindingResponse containing: Advisory findings may be answered but do not block resubmission unless the locked policy explicitly requires a response. Vague aggregate “fixed all” text cannot -replace per-finding responses. +replace per-finding responses. The distinct checker-remediation path uses only +contributor-safe checker messages/fixes and requires no fabricated +ReviewFinding response or resolution. ## Resubmission And Checks -Submission N+1 acknowledges the exact preparation head/digest, links its -immediate predecessor, and stamps the frozen context. The normal finalization -and checker spine reruns. Only a current successful `allow_review` may create a -new queue entry. +A human-Review Submission N+1 acknowledges the exact preparation head/digest, +links its immediate predecessor, and stamps the frozen context. A checker- +remediation Submission N+1 instead binds the exact final needs-revision +CheckerRun and the Task's existing locked context; it carries no preparation or +ReviewFinding response. Both paths rerun the normal finalization and checker +spine. Only a current successful `allow_review` may create a new queue entry. -The queue initially prefers the reviewer who requested revision. Expiry, +Human Review return initially prefers the reviewer who requested revision. The +distinct corrected checker path enters open routing. Expiry, decline, or invalidation opens the entry without resetting queue age. ## Reviewer Resolution @@ -72,21 +79,33 @@ new ReviewFinding on the later Review. ## Limits And Recovery -A reached revision limit or deadline blocks further preparation and +Exact human Review round counting, deadline anchor, and boundary require human +approval before implementation and exclude checker retries. Approved values use +database time and freeze on the Review-rooted episode. A reached revision limit +or deadline blocks further preparation and `submission.create`; it does not automatically reject or cancel the task. The task remains `needs_revision` until a covered Project Manager explicitly invokes -the planned reason-bound obligation-close command. That administrative closure -uses task `cancelled`, releases the assignment, and creates no synthetic Review -or contribution. +the planned reason-bound `review.revision_obligation.close` command. That +administrative closure uses task `cancelled`, releases the assignment, and +creates no synthetic Review or contribution. -A blocked or invalid Review-rooted preparation can be repaired only by appending -one successor through the planned covered-manager repair command. Legacy -`needs_revision` state with no Review/root requires an Operator evidence-linked -legacy close and cannot enter normal revision replay. +A blocked or invalid context preparation can be repaired only by appending one +successor through the planned covered-manager repair command. Repair cannot +bypass limit/deadline exhaustion. Exact durable CheckerRun remediation is not +legacy; only ambiguous or truly rootless claimed human Review state uses +Operator evidence-linked close. ## Required Proof -A revision cannot return to human review unless every unresolved blocking -finding has one response, the exact preparation is still current, Submission -lineage is immediate and same-task, evidence bindings are finalized, and the -new CheckerRun is current for that Submission. +A human-Review revision cannot return to human review unless every unresolved +blocking finding has one response, the exact preparation is still current, +Submission lineage is immediate and same-task, evidence bindings are finalized, +and the new `allow_review` CheckerRun is current for that Submission. + +A checker-remediation submission cannot enter human review unless it binds the +exact final needs-revision CheckerRun that caused remediation through immutable +`remediation_source_checker_run_id`, preserves the Task's existing locked +context, has immediate same-task Submission lineage, and has a new current +`allow_review` CheckerRun. The source relation is server-derived, unique, and +cannot be rewritten by a later retry. It has no preparation or ReviewFinding +response requirement. diff --git a/docs/spec_review_lifecycle.md b/docs/spec_review_lifecycle.md index dc6c157eb..ebd2d7f28 100644 --- a/docs/spec_review_lifecycle.md +++ b/docs/spec_review_lifecycle.md @@ -6,7 +6,7 @@ This document is the active normative implementation contract for the planned Workstream v0.1 human review and revision lifecycle. The lifecycle described here is not yet available in the production API. Each owning REV chunk must merge hidden behavior, AUTH must activate the exact registered actions, and -`WS-REV-001-13` must pass the joint release gate before any surface is exposed. +`WS-REV-001-13C` must pass the joint release gate before any surface is exposed. The implementation sequence is defined by `WS-REV-001-review-revision-lifecycle/CHUNK_MAP.md` under `.agent-loop`. This @@ -90,7 +90,7 @@ availability. All of these endpoints remain planned and unavailable until the owning REV chunks provide hidden behavior, AUTH registers and activates their dependencies, -and REV-13 releases the product surface. +and REV-13C releases the product surface. `GET /api/v1/reviews/current` is a concealed read, not a claim: @@ -208,12 +208,13 @@ may admit the exact immutable Submission to human review. Admission records the exact CheckerRun ID and verified binding facts. A retry, supersession, or different Submission cannot silently replace that anchor. -Checker routing is not human judgment. A checker may route contributor-fixable -problems to the user-facing task state `needs_revision`, but it creates no -Review, ReviewFinding, reviewer contribution, or Review-rooted revision episode. -Checker remediation follows its checker-result lineage and must pass the normal -submission/checker spine before human review. Human revision preparation below -is rooted only in an immutable `Review(decision=needs_revision)`. +Checker routing is not human judgment. A final needs-revision CheckerRun moves +the Task to contributor-readable `needs_revision` in the existing checker +transaction while retaining the Task's locked context. It creates no Review, +ReviewFinding, RevisionContextPreparation, reviewer contribution, or synthetic +human actor, consumes no human revision round/deadline, and does not use D6 +closure. Checker remediation follows that exact CheckerRun lineage and must pass +the normal submission/checker spine before human review. Queue schema migration performs no blanket historical backfill. A later audited reconciliation may admit only an unambiguous latest finalized Submission with a @@ -315,7 +316,8 @@ freshly verify the Flow token -> AUTH PREP review.decision with exact request bindings -> lock review idempotency -> lock the review lifecycle fence --> lock ReviewQueueEntry, ReviewLease, task, TaskAssignment, Submission, +-> lock ReviewLease, ReviewQueueEntry, task, the exact + Submission.task_assignment_id row, Submission, predecessor Review, finding/resolution lineage, and stabilized binding facts -> recompose canonical final facts -> AUTH validates all prepared-handle bindings, consumes the handle once, @@ -352,6 +354,7 @@ Review(accept) ```text Review(needs_revision) -> reviewer completed_review already created +-> append Review-rooted initial RevisionContextPreparation -> Task.status = needs_revision -> TaskAssignment remains active -> no FinalAcceptance @@ -452,9 +455,12 @@ lock. Each Submission stamps the exact guide ID, version, immutable per-project activation sequence, source snapshot, and task-execution policy IDs, versions, and hashes used for that attempt. -After a human `needs_revision` Review, revision preparation compares only the -prior Submission's stamped guide identity and activation sequence with the -project's currently active Project Guide pair: +Controlled revision preparation applies only after an immutable human +`Review(needs_revision)`. Checker-caused remediation remains the distinct +CheckerRun-rooted path above and performs no guide rebase or human finding replay. + +Revision preparation compares the prior Submission's stamped guide identity and +activation sequence with the project's currently active Project Guide pair: - exact identity and activation-sequence match: `kept`; - any different internally consistent active pair: `rebased`, recording @@ -473,7 +479,7 @@ TaskAssignment, preparation sequence, preparing actor/process, and audit link. It does not contain or rebase a ContributionPolicyVersion. Each episode forms one non-branching preparation chain: one root per Review, -one child per preparation, same task/review/source lineage across an edge, and +one child per preparation, same task/Review/source lineage across an edge, and sequence increasing by exactly one. The head is the row with no successor. Task Context selects that head and then validates it; it never falls back to an older preparation when the head is blocked, corrupt, revoked, or stale. @@ -491,15 +497,24 @@ and change summary. ## Finding Replay And Resubmission -For every unresolved blocking ReviewFinding, the assigned submitter creates one -immutable `SubmissionFindingResponse` with response text and optional finalized +For a human-review origin, every unresolved blocking ReviewFinding requires one +immutable `SubmissionFindingResponse` from the assigned submitter, with response +text and optional finalized evidence binding. Responses to advisory findings are optional unless the locked -policy explicitly requires them. - -Submission N+1 links its immediate predecessor, exact preparation head, -responses, evidence relations, and target TaskAssignment. The existing -finalization and checker spine reruns. A new current `allow_review` creates a -queue entry preferred to the reviewer who issued the prior revision request. +policy explicitly requires them. The checker-remediation path instead exposes +only bounded contributor-safe CheckerResult messages/suggested fixes, requires +no fabricated ReviewFinding/response/resolution, and returns to open routing +after corrected checker admission. + +A human-Review Submission N+1 links its immediate predecessor, exact preparation +head, required responses, evidence relations, and target TaskAssignment. A +checker-remediation Submission N+1 instead binds the exact final needs-revision +CheckerRun through its server-derived immutable +`remediation_source_checker_run_id` and retains the Task's existing locked +context; it has no preparation or ReviewFinding response. Both paths rerun the +existing finalization and checker spine. A new current `allow_review` creates a +queue entry preferred to the reviewer who issued the prior human revision +request. Corrected checker work enters ordinary open routing. The later Review appends one immutable `FindingResolution` for each required prior finding with the canonical result `resolved`, `unresolved`, or @@ -508,12 +523,17 @@ or submitter response. Normal revision returns to the same assigned contributor. If that contributor loses authority, the source Submission and TaskAssignment remain immutable. A -covered manager may assign a replacement against the durable revision -obligation and append one preparation successor whose target TaskAssignment is -the replacement. The old contributor cannot submit. +covered manager may assign a replacement against the durable human revision +episode and append one preparation successor whose target TaskAssignment is the +replacement. The old contributor cannot submit. ## Revision Limits, Repair, And Legacy Recovery +Exact human Review revision-round counting, deadline anchor, and boundary require +separate human approval before implementation. They are not inferred from +checker retries, task SLA, current time, or archival examples. Approved values +freeze on the Review-rooted episode and use database time. + Reaching a revision limit or deadline blocks new revision preparation and `submission.create` with a stable policy error. It does not automatically reject or close the task. The task remains `needs_revision` and its assignment remains @@ -527,13 +547,16 @@ queue entry as administratively cancelled. It creates no Review, FinalAcceptance, ContributionRecord, award, fulfillment instruction, or reputation effect. -Blocked/revoked/invalid Review-rooted preparation is repaired only through the +Blocked/revoked/invalid context preparation is repaired only through the planned `review.revision_context.repair` command. A covered Project Manager acknowledges the exact current head ID/digest and reason; the command appends one validated successor after project setup correction. It cannot edit history, -branch the chain, or create an episode root. +branch the chain, create an episode root, or bypass a frozen limit/deadline. -A legacy task in `needs_revision` with no originating Review/root cannot use +A historical checker-rooted task is proven by exact durable CheckerRun, +Submission, and matching audit lineage; it is not legacy solely because no +Review exists. A task that claims human Review revision but has no unambiguous +Review/root cannot use normal repair. Reconciliation records the defect. An Operator may use the planned evidence-linked `review.revision_context.legacy_close` command to set the task `cancelled`, release the assignment, and close any queue with terminal @@ -543,14 +566,14 @@ or CON record. ## Action Inventory And Activation Custody Merged AUTH-08 is historical provenance: 74 PermissionIds and 57 ActionIds, -with 9 active and 48 planned. Trusted main after merged AUTH-09C contains 74 -PermissionIds and 65 ActionIds, with 12 active and 53 planned. AUTH-09A added +with 9 active and 48 planned. Trusted main after merged AUTH-09D-A contains 74 +PermissionIds and 65 ActionIds, with 15 active and 50 planned. AUTH-09A added the common fixed-service schema and seven ART identities with eleven -memberships. AUTH-09B activates `actor.service.provision` for identities -already in AUTH's closed registry. AUTH-09C activates only -`actor.profile.read` and `actor.identity_link.read`. Neither admits a -service token, activates a review action, or contains any of REV's six future -service identities. +memberships. AUTH-09B activates `actor.service.provision` for identities already +in AUTH's closed registry. AUTH-09C activates `actor.profile.read` and +`actor.identity_link.read`; AUTH-09D-A activates `actor.profile.suspend`, +`actor.profile.reactivate`, and `actor.profile.deactivate`. These merges do not +activate a review action or contain any of REV's six future service identities. The review lifecycle currently depends on 24 unavailable actions: @@ -569,7 +592,7 @@ The exact delivery order is: AUTH planned registration and activation custody -> required ART/CON capability plus REV hidden behavior and canonical facts -> AUTH evaluator integration and exact action activation --> REV-13 joint product-surface release +-> REV-13C joint product-surface release ``` `WS-AUTH-001-REV-CUSTODY` transfers the 19 registered planned review rows to @@ -578,7 +601,7 @@ availability. `WS-AUTH-001-PREP` supplies the prepared mutation protocol. `WS-AUTH-001-REV-REG` registers the four additions below as planned. `WS-AUTH-001-REV-05/06/07/08/09A/11/12` integrate and activate only their exact merged hidden features. `WS-AUTH-001-REV-LIFECYCLE` activates the four additions -only after the REV-11 and REV-12A hidden manifests are complete. REV-13 alone +only after the REV-11A-D and REV-12A1-A4 hidden manifests are complete. REV-13C alone exposes the already-active coherent product surface. ## Four-Action Registration Manifest @@ -603,7 +626,7 @@ revalidation. - Transaction revalidation: authority, project, task, assignments, prior Submission, Review, episode, head, and current guide/policies under canonical locks. -- Hidden behavior dependency: `WS-REV-001-11` and the task-owned revision +- Hidden behavior dependency: `WS-REV-001-11B` and the task-owned revision participant. ### `review.revision_context.legacy_close` @@ -614,12 +637,13 @@ revalidation. `POST /api/v1/admin/review-reconciliation/{finding_id}/legacy-revision-close`. - Resource facts: exact unresolved `legacy_revision_context_unrecoverable` finding, project, task, assignment, - optional queue, and server-proven absence of Review/root. + optional queue, absence of a recoverable human Review/root, and proof that the + state is not exact CheckerRun remediation. - Guards: exact unresolved current finding, legacy task still - `needs_revision`, no healthy Review-rooted obligation, exact replay only. + `needs_revision`, no healthy/recoverable Review root, exact replay only. - Effects: task cancelled, assignment released, queue administratively closed; no synthetic Review, FinalAcceptance, or CON record. -- Hidden behavior dependency: `WS-REV-001-11`. +- Hidden behavior dependency: `WS-REV-001-11D`. ### `review.revision_obligation.close` @@ -628,20 +652,21 @@ revalidation. not substitute. - Planned surface: `POST /api/v1/tasks/{task_id}/revision-obligation/close`. -- Resource facts: exact project, task, assignment, originating - `needs_revision` Review, current preparation head, frozen limit/deadline, and - server proof of the selected reached cause. +- Resource facts: exact project, task, assignment, originating human + `needs_revision` Review, current preparation head, approved frozen + limit/deadline facts, and server proof of the selected reached cause. +- CheckerRun-rooted remediation is not an eligible resource for this command. - Guards: exact current head/cause, task still `needs_revision`, and terminal reason exactly `revision_limit_reached` or `revision_deadline_expired`; missing, not-reached, stale, arbitrary, crossed, or cross-project input denies. -- Hidden behavior dependency: `WS-REV-001-11`. +- Hidden behavior dependency: `WS-REV-001-11B`. ### `review.lifecycle.activation.manage` - Permission: existing `operations.reconcile.run`. - Candidate: Operator AdminRoleGrant only; no service actor or background replay. - Planned surface: authenticated lifecycle-control status and adjacent-phase - transition commands; REV-12A/13 lock the exact URI before exposure. + transition commands; REV-12A1-A4/13C lock the exact URI before exposure. - Resource facts: operation, singleton ID, expected generation/current phase, target phase, reviewed manifest digest, server-derived drain observations, bounded batch/deadline, and reason. @@ -650,7 +675,7 @@ revalidation. conflict. Lease force release keeps its own action. - Transaction revalidation: prepared authority, shared/exclusive advisory fence, row locks, final observations, one caller commit. -- Hidden behavior dependency: `WS-REV-001-12A`. +- Hidden behavior dependency: `WS-REV-001-12A1` through `WS-REV-001-12A4`. ## Fixed Service Identity Manifests @@ -677,7 +702,7 @@ by the caller. ## Planned API Surface -All routes remain unavailable until REV-13. The final coherent `/api/v1` +All routes remain unavailable until REV-13C. The final coherent `/api/v1` surface includes separate capabilities for: - reviewer current work; @@ -687,7 +712,8 @@ surface includes separate capabilities for: - finding and response evidence intake; - review decision; - Task Context revision preparation read; -- revision submission with responses; +- human-Review revision submission with responses and distinct checker- + remediation resubmission; - administrative queue inspection, routing correction, force release, reconciliation, revision repair/closure, and lifecycle control. @@ -716,8 +742,9 @@ authority. ## Joint Release Control -REV-12A adds one hidden PostgreSQL-canonical -`JointLifecycleReleaseControl`. It uses compare-and-set phase history, +REV-12A is a non-executable split record. REV-12A1 through REV-12A4 collectively +add one hidden PostgreSQL-canonical `JointLifecycleReleaseControl`. It uses +compare-and-set phase history, PostgreSQL advisory-lock fences, mandatory typed fence ports, and bounded drain observations across review mutations, task submissions, queue admission, authority-loss replacement, CON fulfillment-obligation writers, dispatch, and @@ -730,9 +757,10 @@ same-generation pre-cutoff completion work, then disables. Timeout leaves the phase unchanged for forward retry. No background job replays human Operator authority or advances a phase. Reactivation requires a newly reviewed manifest. -This controller is product release state, not AUTH action availability. REV-12A -exposes no public route; AUTH activates the exact management action only after -the hidden manifests merge, and REV-13 exposes and drills it. +This controller is product release state, not AUTH action availability. The +12A1 through 12A4 implementation exposes no public route; AUTH activates the +exact management action only after all four hidden manifests merge, and REV-13C +exposes and drills it. ## Error, Concurrency, And Idempotency Rules @@ -761,7 +789,7 @@ The lifecycle is delivered one explicitly approved PR-sized chunk at a time: 05-07 admission, routing, leases, context, and artifact evidence 08-10 decision/revision kernels and atomic FinalAcceptance/CON composition 11-12 recovery, reconciliation, projection, and observability -12A hidden joint release control and cross-domain fences +12A1-12A4 hidden joint release control and cross-domain fences 13 AUTH-active coherent API exposure and live proof ```