From 02ccc0af505f9fc1e983e5e1085c68968efdb366 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sat, 10 Oct 2026 14:59:16 +0100 Subject: [PATCH 001/283] docs: bound atomic JSON-to-DRAFT task import --- .../pilot02-atomic-json-draft-import.md | 156 ++++++++++++++++++ 1 file changed, 156 insertions(+) create mode 100644 .commitrail/changes/pilot02-atomic-json-draft-import.md diff --git a/.commitrail/changes/pilot02-atomic-json-draft-import.md b/.commitrail/changes/pilot02-atomic-json-draft-import.md new file mode 100644 index 000000000..8fdfb1d76 --- /dev/null +++ b/.commitrail/changes/pilot02-atomic-json-draft-import.md @@ -0,0 +1,156 @@ +# PILOT-02B — Import one verified JSON source into DRAFT Tasks atomically + +- Initiative: `None` +- Durable disposition: `Planned` +- Intended merge outcome: A covered Project Manager imports one verified project-bound JSON source into one immutable batch and its DRAFT Tasks, with exact replay and complete rollback. + +## Intent + +Issue [489](https://github.com/Flow-Research/workstream/issues/489) requires a +real 200-row file to produce 200 DRAFT Tasks before separate screen and release. +PILOT-02A provides exact source custody but creates no Tasks. This chunk supplies +that missing JSON-to-DRAFT operation and a covered-manager batch-status read. +Issue #489 remains open after this chunk; batch transitions and CLI remain. + +## Current behavior + +The inspected integration is `7a3551e7caf2c07af51701db06d011207b44e106`, +based on main `a51cf06ccb5ab85f2c41528855f537d4362ec26b`. PR520 remains +the separate source prerequisite. Its parser in `tasks/api/task_import.py` +accepts one strict UTF-8 JSON document with 1..500 rows, required case-sensitive +external IDs, indexed duplicate errors and an 8 MiB ceiling. ART's +`api/task_import_source.py` and `task_import_sources.py` own project-bound +declaration, admission, fresh authority, verified reads and provider recovery. + +`tasks/authorized_commands.py` owns canonical create/screen/release and their +per-task AUTH/audit; each public command opens its own root transaction. +`command_replay.py` reserves one Task's actor/action/key namespace and requires +fresh authority before recovery. Its receipt cannot represent a whole batch. +`WorkstreamTask` has source fields, but no batch record or project/external-ID +unique constraint. Its existing `import_batch_id` is nullable string metadata; +it is not an authoritative native-UUID batch relationship. + +## Bounded change + +### Allowed + +- TASK: `api/task_import.py`, a cohesive `task_import_batches.py`, + `authorized_commands.py`, `command_replay.py`, `models.py`, `schemas.py`, + `repository.py` and `router.py`: typed import/status contracts, immutable batch + receipt and row membership, server provenance and reuse of canonical creation. +- ART: `api/task_import_source.py` and `task_import_sources.py`: the smallest + typed preparation/binding port over the existing verified source. No second + provider path, storage lifecycle or inspector. +- Composition: existing `adapters/tasks/__init__.py`, + `adapters/artifacts/__init__.py`, `adapters/auth/__init__.py` and + `api/deps/authorization.py`: explicit owner ports and one transaction root. +- AUTH: exact batch import/status resource facts, preparation and closed + action/permission/resource classifications in the existing TASK authority + owner; reuse covered Project Manager grant evaluation and canonical denials. +- Focused TASK/ART/AUTH public-contract and native PostgreSQL/MinIO tests; + affected ownership/lane/inventory expectations; current TASK/ART/AUTH specs, + README and roadmap claims for this chunk only. +- One coordinated successor migration and its graph/reset/fingerprint consumers, + authored solely by the delegated migration owner after final schema handoff. + This planning work authors no migration and reserves no ordinal in advance. + +### Not allowed + +- PR520 source branch edits, batch screen/release, Task release/assignment, + contributor task creation, CLI/frontend, CSV ingestion, external adapters or + checker/runtime changes; no dependency on PILOT-04 execution. +- Changes to the normal screen/release guide locks, policy validation, + compensation selection, hidden completion/routing or false-guide readiness. +- Route-to-route calls, per-row commits/savepoint success, copied TASK transition + rules, direct product filesystem/provider access or invented byte receipts. +- Retained-row deletion, automatic repair/backfill of conflicts, unrestricted + AUTH strings, threshold/skip/runner weakening, deployment, merge or issue closure. + +## Design and decisions + +1. Public import selects a project and verified source with exactly one UUID + idempotency key; input supplies no Task state, creator, locked lineage or + server provenance. ART verifies and bounds bytes before the TASK write root. + Its typed prepared facts bind source/project, exact SHA/count and actual + verification ancestry. Inside the write root, the ART participant validates + the immutable reference again without provider I/O or a separate commit. +2. TASK owns a UUIDv7 batch record, exact received-file commitment and ordered + row-to-Task membership. Project plus received-file identity governs exact-file + recovery; actor/action/key receipts distinguish retries from changed requests. + TASK row IDs use `new_record_id()` and are recovered from stored facts. + A source supplied by another covered manager conveys no inherited authority. +3. One root reserves the batch, acquires deterministic TASK/custody locks before + AUTH, and composes flush-only canonical create participants. Every new row + retains its own exact CREATE decision and normal `TaskCreated` audit. Batch, + all DRAFT Tasks, source binding, related receipts and successful evidence + commit together. Any row failure removes all these effects; canonical denied + evidence is retained through the correct AUTH owner after rollback. +4. Enforce case-sensitive `(project_id, external_task_id)` uniqueness in + PostgreSQL, including concurrent imports. Same external ID in another project + is allowed; an existing conflicting ID rejects the complete new batch with + indexed errors. Preserve exact source bytes rather than hashing reserialized + rows as the file identity. Imported provenance is server-stamped JSON custody; + a converted CSV is never described as original server-retained CSV. +5. Exact replay returns the original ordered Task IDs and immutable creation + facts with fresh covered-manager authority and no additional creation effects. + It cannot mutate Tasks that subsequently advanced. Existing single-Task + command replay/state-conflict behavior remains unchanged. Status reads are + project-scoped and conceal foreign or revoked access without source coordinates. +6. Before the schema handoff, explicitly settle the native relationship for the + existing string `import_batch_id` and preflight retained non-UUID/duplicate + provenance. Unsafe retained facts must stop the migration with a diagnostic; + they cannot be rewritten or discarded. Review also freezes exact batch replay + AUTH facts and lock order before application coding. + +## Acceptance criteria + +- [ ] One real 200-row verified JSON source creates exactly 200 DRAFT Tasks under + one batch; every row has the correct source hash/reference, external ID, actor, + per-task AUTH decision and creation event. No locked screen/release lineage, + assignment or release effects are invented. +- [ ] Invalid or unverified input, one conflicting row, duplicate ID, foreign + source/project, missing authority and 501 rows yield indexed closed errors and + zero batch/Task creation effects. Existing separately committed source/read or + canonical denial evidence is distinguished from successful TASK effects. +- [ ] Exact same-key and exact-file retries recover original IDs with fresh + authority; changed bytes/key reuse conflicts; revoked replay fails. Source, + actor, receipt and row-membership substitutions fail closed. +- [ ] Native PostgreSQL proves identical concurrent import recovery, overlapping + external-ID conflicts, deterministic intermediate lock waits and complete + rollback after an injected late-row/audit/binding failure. +- [ ] Direct SQL rejects partial batch closure, foreign source/verification/Task + membership, changed original receipts and NULL/changed custody. Upgrade/reset + preserves every retained main and source fact on the sole linear schema. + +## Risk and review routing + +- Risk class: `L0` (multi-owner authority, immutable custody and atomic creation). +- Required reviewers: architecture/reuse for owner composition and native parity; + security for current actor/project/source/replay custody; QA/test delta for + observable rollback and discriminating native controls. The lead owns common + CI/collection/cleanup validation and independent SQL review. +- Human review focus: batch/file identity, retained provenance preflight, fresh + replay authority, per-task evidence, root atomicity and the SOURCE/TASK/AUTH + lock graph. Source storage is a prerequisite, not the import result. + +## Evidence + +| Claim | Command or proof | Result | Remaining uncertainty | +|---|---|---|---| +| Current owners and concrete gap | Inspect source port/parser, TASK create/replay/models and Issue 489 | Scope preparation only; no product code or import operation implemented | Exact schema and replay facts require affected review | +| Public import and atomic effects | Planned isolated runner: `pytest -q tests/tasks/test_task_import_batches.py` with real PostgreSQL 16/MinIO | Not run; tests not authored | All positive/negative/concurrency cases above must pass | +| Schema, guards and complete integration | Sole-author native graph/reset/UUID proof, affected guards, complete hosted lanes and aggregate | Not run for this chunk | Exact frozen candidate, actual merge tree and cleanup required | + +## Review findings + +No implementation review is claimed. Scope preparation identifies the existing +per-command transaction and unbound string provenance as explicit handoff issues. + +## Reconciliation + +- Current-source reconciliation: source PR520 stays frozen at `7a3551e7`; + this separate preparation branch includes main's delivered hidden B8 owners. +- Next usable boundary: explicit atomic batch screen/release, then the CLI's + project/source/batch commands and client CSV conversion against public contracts. +- Remaining risks: source prerequisite and current required CI/actual external + review remain separate; no deployed import capability or whole Issue 489 claim. From 7f43d109656c9cd8d5685b25b160a9d13d383296 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sat, 10 Oct 2026 15:12:14 +0100 Subject: [PATCH 002/283] docs: prepare native batch custody and replay handoff --- .../pilot02-atomic-json-draft-import.md | 41 ++++++++++++++++--- 1 file changed, 36 insertions(+), 5 deletions(-) diff --git a/.commitrail/changes/pilot02-atomic-json-draft-import.md b/.commitrail/changes/pilot02-atomic-json-draft-import.md index 8fdfb1d76..bd847b281 100644 --- a/.commitrail/changes/pilot02-atomic-json-draft-import.md +++ b/.commitrail/changes/pilot02-atomic-json-draft-import.md @@ -96,11 +96,42 @@ it is not an authoritative native-UUID batch relationship. It cannot mutate Tasks that subsequently advanced. Existing single-Task command replay/state-conflict behavior remains unchanged. Status reads are project-scoped and conceal foreign or revoked access without source coordinates. -6. Before the schema handoff, explicitly settle the native relationship for the - existing string `import_batch_id` and preflight retained non-UUID/duplicate - provenance. Unsafe retained facts must stop the migration with a diagnostic; - they cannot be rewritten or discarded. Review also freezes exact batch replay - AUTH facts and lock order before application coding. +6. The inspected string `import_batch_id` is genuinely caller-supplied metadata: + retained public fixtures use `private-import-batch` and `ready-private-import`, + and the Go management contract accepts `batch`. It cannot be cast to an owned + UUID reference. The proposed handoff preserves that metadata unchanged and + gives the new ordered membership table the authoritative native batch/Task + relationship. Batch APIs select the new UUID owner, never arbitrary metadata. + Existing management/contributor projection and concealment stay unchanged. + A duplicate project/external-ID preflight must stop with a diagnostic, without + deleting or rewriting retained Tasks. Affected review freezes this mapping, + exact replay AUTH facts and lock order before application coding. + +### Proposed schema and replay handoff for affected review + +- Batch: UUIDv7 ID, project UUID, original source UUID, exact SHA/count, + verified ART ancestry, row count, original actor/link and immutable creation + receipt/result. Unique received-file identity is project plus SHA/count. +- Ordered membership: native batch and Task UUIDs, project, zero-based row index, + external ID, normalized row digest and exact CREATE decision. Composite custody + binds each member to its batch/project and Task/project. Each Task has one + import membership; batch row indexes and project/external IDs are unique. +- Retry receipt: actor/action/UUID key namespace, exact project/source selector + request digest, original batch ID and immutable ordered result. A changed + selector under the same key conflicts even when the alternative source has + identical bytes. A new key for the same exact project/file recovers the + original batch after current authority and actual original custody checks. +- Fresh replay authorization binds the current caller to the stored batch/source + and manifest digest. It does not borrow the original actor, issue new CREATE + effects or pretend an advanced Task is DRAFT. Status can show current row + states separately from immutable creation facts. Existing single-Task command + state-conflict semantics remain intact. +- The ART binding participant validates actual immutable source/verification + rows in the caller's root; an application-created DTO supplies no authority. + Direct SQL must reject foreign ancestry, partial closure and changed tuples. + Native FK representations follow each existing owner, including string-mapped + actor/audit UUIDs. The sole migration author receives the reviewed field/lock + contract against then-current main before allocating a linear successor. ## Acceptance criteria From ac9c5d443bb56c78d9f441eff5128fa92f007a73 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sat, 10 Oct 2026 16:56:59 +0100 Subject: [PATCH 003/283] Freeze import membership and replay scope decisions --- .../pilot02-atomic-json-draft-import.md | 70 ++++++++++++++++++- 1 file changed, 69 insertions(+), 1 deletion(-) diff --git a/.commitrail/changes/pilot02-atomic-json-draft-import.md b/.commitrail/changes/pilot02-atomic-json-draft-import.md index bd847b281..96c083d6b 100644 --- a/.commitrail/changes/pilot02-atomic-json-draft-import.md +++ b/.commitrail/changes/pilot02-atomic-json-draft-import.md @@ -101,7 +101,9 @@ it is not an authoritative native-UUID batch relationship. and the Go management contract accepts `batch`. It cannot be cast to an owned UUID reference. The proposed handoff preserves that metadata unchanged and gives the new ordered membership table the authoritative native batch/Task - relationship. Batch APIs select the new UUID owner, never arbitrary metadata. + relationship. Newly imported rows may expose the native batch UUID spelling + through that string metadata field. Batch APIs select the new UUID owner, + never arbitrary metadata; a manually supplied spelling creates no membership. Existing management/contributor projection and concealment stay unchanged. A duplicate project/external-ID preflight must stop with a diagnostic, without deleting or rewriting retained Tasks. Affected review freezes this mapping, @@ -133,6 +135,72 @@ it is not an authoritative native-UUID batch relationship. actor/audit UUIDs. The sole migration author receives the reviewed field/lock contract against then-current main before allocating a linear successor. +### Scope decisions and transaction preparation + +The lead confirmed the following issue489 boundaries during preparation: + +- Preserve all retained/manual `import_batch_id` strings. New imports may stamp + their native batch UUID spelling into metadata; native immutable membership + alone selects and authorizes the batch. Add a public control showing that a + manually supplied matching string never appears in the batch status response. +- Exact project/SHA/byte-count file replay returns original IDs and creation + facts after fresh batch/source Project Manager authority, even if Tasks have + advanced. Reused actor/action/key with a changed source selector conflicts; + a new key for the same exact file recovers the original batch. Actual verified + source ancestry and parser/schema identity are bound, not a client digest alone. +- Case-sensitive project/external-ID uniqueness covers every non-NULL Task + external ID, including normal create. Native preflight reports retained + duplicates without changing their data. NULL remains available for normal + Tasks without an external ID; arbitrary batch-label metadata gains no authority. + +The existing Task composite `(id, project_id)` uniqueness can bind native row +membership without rewriting Task IDs or their string-mapped UUID model type. +The new membership must bind the original external ID, row index, normalized +row digest, original CREATE decision and immutable creation response separately +from mutable current Task status. A batch closure invariant rejects committed +success with a missing, foreign or duplicated row. No committed pending batch +or partially created row set is an accepted intermediate product state. + +The creation refactor stays in the existing TASK owner: extract the current +create operation into one explicitly caller-owned participant, with the current +single-create public method remaining its transaction-owning wrapper. Batch +imports compose that participant; they do not invoke the public command in a +loop. Reserve all needed per-row replay identities before current AUTH locks, +then retain each row's real CREATE decision and `TaskCreated` evidence. Successful +batch closure and all row effects use one root; denial restaging follows the +specific AUTH instance that captured the original decision. Late-row failure +must remove every earlier successful creation effect in that root. + +The proposed lock graph requires affected review before code or DDL: + +1. Finish bounded ART provider verification and JSON parsing before the TASK + write root. Source read evidence belongs to that earlier read operation; + no provider stream, scratch cleanup or I/O occurs while TASK write locks wait. +2. Within the root, reserve TASK batch/file and retry identities. Acquire a + TASK-owned external-ID creation fence shared by normal create and imports, + then existing Task/member custody where replay needs it, in deterministic + order. Actor and ART source foreign keys on reservations must not implicitly + take conflicting owner locks before their proper phase. +3. Validate actual ART source/verification custody through its typed participant + after TASK custody and before fresh AUTH consumption. Read immutable tuples + with the weakest required lock; do not lock a mutable put attempt merely to + trust an application DTO. Preserve the existing TASK-before-CHECKERS/ART order. +4. Consume fresh current batch/source authority, then the exact per-row CREATE + authority through the shared owner. Stage Tasks, immutable memberships and + evidence; close the batch and flush once before the caller commits. + +One concrete lock hazard still needs a reviewed choice: the current normal +create inserts its Task after AUTH. Adding a unique external-ID reservation +before AUTH only for imports can deadlock with a normal create that holds AUTH +and waits on that reservation. Both entry points must share the same pre-AUTH +creation fence; an import-only lock does not solve this. Candidate fences are a +single project-scoped transaction advisory lock, or sorted project/external-ID +transaction advisory locks. Native uniqueness remains the correctness boundary +for direct SQL; the fence controls owner lock order and is not authority. +Review must freeze the chosen key/order and native intermediate-wait regression, +including normal create versus overlapping import and revoked-authority races. +No fence, source participant, model or migration is implemented by this record. + ## Acceptance criteria - [ ] One real 200-row verified JSON source creates exactly 200 DRAFT Tasks under From b3e303eeb807bd8c6bc8f3e306181803f86113fc Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sat, 10 Oct 2026 16:59:02 +0100 Subject: [PATCH 004/283] Record import difficulty native parity decision --- .../changes/pilot02-atomic-json-draft-import.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/.commitrail/changes/pilot02-atomic-json-draft-import.md b/.commitrail/changes/pilot02-atomic-json-draft-import.md index 96c083d6b..5c12c3c7e 100644 --- a/.commitrail/changes/pilot02-atomic-json-draft-import.md +++ b/.commitrail/changes/pilot02-atomic-json-draft-import.md @@ -201,6 +201,19 @@ Review must freeze the chosen key/order and native intermediate-wait regression, including normal create versus overlapping import and revoked-authority races. No fence, source participant, model or migration is implemented by this record. +Field mapping also has one concrete pending native-parity decision: +`TaskImportRow.difficulty` publishes an 80-character limit, whereas the current +`WorkstreamTask.difficulty` column is `varchar(50)` and `TaskCreate` has no length +validator. A valid retained source must not fail as an unexplained late database +error. Proposed handoff expands that TASK display column to 80 in the sole-author +successor migration, preserving existing values and the published source shape; +the alternative is an explicitly reviewed parser-contract narrowing to 50. +Native 51/80-character controls and an indexed 81-character rejection must +discriminate the chosen boundary. No schema choice or alteration is claimed here. +The batch retains the actual `workstream.task_import.v1` document identity and +an explicit row-mapping/parser commitment, alongside verified bytes, so replay +never silently reinterprets retained rows under a later mapping. + ## Acceptance criteria - [ ] One real 200-row verified JSON source creates exactly 200 DRAFT Tasks under From 59b4bd223f67050fcdb850f92d116b31eab8e453 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 07:40:16 +0100 Subject: [PATCH 005/283] Prepare canonical AUTH ordering and preserve source difficulty --- .../pilot02-atomic-json-draft-import.md | 33 ++++++++++++++++--- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/.commitrail/changes/pilot02-atomic-json-draft-import.md b/.commitrail/changes/pilot02-atomic-json-draft-import.md index 5c12c3c7e..ec9762fb1 100644 --- a/.commitrail/changes/pilot02-atomic-json-draft-import.md +++ b/.commitrail/changes/pilot02-atomic-json-draft-import.md @@ -201,19 +201,42 @@ Review must freeze the chosen key/order and native intermediate-wait regression, including normal create versus overlapping import and revoked-authority races. No fence, source participant, model or migration is implemented by this record. -Field mapping also has one concrete pending native-parity decision: +Field mapping has one confirmed native-parity decision: `TaskImportRow.difficulty` publishes an 80-character limit, whereas the current `WorkstreamTask.difficulty` column is `varchar(50)` and `TaskCreate` has no length validator. A valid retained source must not fail as an unexplained late database -error. Proposed handoff expands that TASK display column to 80 in the sole-author -successor migration, preserving existing values and the published source shape; -the alternative is an explicitly reviewed parser-contract narrowing to 50. +error. The lead confirmed expanding that TASK display column to 80 in the +sole-author successor migration, preserving existing values and the published +source shape. Source intake is not narrowed and retained values are not rewritten. Native 51/80-character controls and an indexed 81-character rejection must -discriminate the chosen boundary. No schema choice or alteration is claimed here. +discriminate the chosen boundary. No alteration is authored by this record. The batch retains the actual `workstream.task_import.v1` document identity and an explicit row-mapping/parser commitment, alongside verified bytes, so replay never silently reinterprets retained rows under a later mapping. +Further owner tracing identifies a smaller proposed lock solution for review: +the current normal create already consumes fresh AUTH before inserting its Task +(`authorized_commands.py` lines 152..165). The PM kernel locks the current +actor/profile/link and effective PM grant (`kernel.py` lines 499..527); it does +not acquire a shared project-global creation lock. Imports can reserve their +TASK batch/row retry identities first, validate ART custody, consume fresh AUTH, +then insert external-ID-bearing Tasks in deterministic project/UTF-8 external-ID +order. They must reserve every per-row identity before the first AUTH lock and +retain document row indexes independently from the insertion order. + +The bad schedule is an import's pre-AUTH external-ID write, a normal create's +actor lock, the normal create waiting on that external-ID write, then the import +waiting on the actor. With both entries consuming AUTH before uniqueness writes, +the same actor's contender waits on AUTH before owning that external key. +Different actors keep independent AUTH locks, so overlapping multi-row imports +must insert external IDs in the same order to avoid crossed-key index waits; +normal create has only one such key. This proposed common ordering avoids a new +advisory fence or custody table. Native intermediate-wait controls must include +same-actor create/import and different-actor reversed-document-order imports. +Review must settle this ordering and all implicit FK locks before replacing the +earlier fence proposal or authoring implementation/DDL. No concurrency PASS is +claimed from this source analysis. + ## Acceptance criteria - [ ] One real 200-row verified JSON source creates exactly 200 DRAFT Tasks under From 1bafa149604a39dc0e5411edf78acf785090162f Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 09:08:23 +0100 Subject: [PATCH 006/283] plan(pilot02): freeze common authority and sorted import writes --- .../pilot02-atomic-json-draft-import.md | 88 ++++++++----------- 1 file changed, 37 insertions(+), 51 deletions(-) diff --git a/.commitrail/changes/pilot02-atomic-json-draft-import.md b/.commitrail/changes/pilot02-atomic-json-draft-import.md index ec9762fb1..2cd203397 100644 --- a/.commitrail/changes/pilot02-atomic-json-draft-import.md +++ b/.commitrail/changes/pilot02-atomic-json-draft-import.md @@ -14,8 +14,8 @@ Issue #489 remains open after this chunk; batch transitions and CLI remain. ## Current behavior -The inspected integration is `7a3551e7caf2c07af51701db06d011207b44e106`, -based on main `a51cf06ccb5ab85f2c41528855f537d4362ec26b`. PR520 remains +The inspected integration is `aa784c9c31490c018d35f4a3cc306fa7c16c630a`, +based on main `251bc29bc5661934b2b70cde4ceecd52dbfa9687`. PR520 remains the separate source prerequisite. Its parser in `tasks/api/task_import.py` accepts one strict UTF-8 JSON document with 1..500 rows, required case-sensitive external IDs, indexed duplicate errors and an 8 MiB ceiling. ART's @@ -171,35 +171,39 @@ batch closure and all row effects use one root; denial restaging follows the specific AUTH instance that captured the original decision. Late-row failure must remove every earlier successful creation effect in that root. -The proposed lock graph requires affected review before code or DDL: +The lead approved common AUTH-before-uniqueness ordering with sorted writes; +no additional global advisory fence or custody table is introduced. The exact +owner preparation and implicit-FK schedule still require affected schema review +and native discriminating proofs before any concurrency PASS: 1. Finish bounded ART provider verification and JSON parsing before the TASK write root. Source read evidence belongs to that earlier read operation; no provider stream, scratch cleanup or I/O occurs while TASK write locks wait. -2. Within the root, reserve TASK batch/file and retry identities. Acquire a - TASK-owned external-ID creation fence shared by normal create and imports, - then existing Task/member custody where replay needs it, in deterministic - order. Actor and ART source foreign keys on reservations must not implicitly - take conflicting owner locks before their proper phase. +2. Within the root, reserve the batch/file retry identity and every per-row TASK + retry identity. Acquire existing Task/member custody needed by replay in + deterministic order before the first AUTH lock. Proposed new batch/row tuples + must not introduce foreign owner locks through premature FK writes. 3. Validate actual ART source/verification custody through its typed participant after TASK custody and before fresh AUTH consumption. Read immutable tuples with the weakest required lock; do not lock a mutable put attempt merely to - trust an application DTO. Preserve the existing TASK-before-CHECKERS/ART order. -4. Consume fresh current batch/source authority, then the exact per-row CREATE - authority through the shared owner. Stage Tasks, immutable memberships and - evidence; close the batch and flush once before the caller commits. - -One concrete lock hazard still needs a reviewed choice: the current normal -create inserts its Task after AUTH. Adding a unique external-ID reservation -before AUTH only for imports can deadlock with a normal create that holds AUTH -and waits on that reservation. Both entry points must share the same pre-AUTH -creation fence; an import-only lock does not solve this. Candidate fences are a -single project-scoped transaction advisory lock, or sorted project/external-ID -transaction advisory locks. Native uniqueness remains the correctness boundary -for direct SQL; the fence controls owner lock order and is not authority. -Review must freeze the chosen key/order and native intermediate-wait regression, -including normal create versus overlapping import and revoked-authority races. -No fence, source participant, model or migration is implemented by this record. + trust an application DTO. Preserve existing TASK-before-CHECKERS/ART order. +4. Consume fresh current batch/source authority and exact per-row CREATE + authority through the shared TASK owner. After AUTH, insert external-ID-bearing + Tasks in deterministic project/UTF-8 external-ID order. Retain document row + indexes and immutable responses independently from insertion order. Stage + membership and evidence, close the batch and flush within the caller root. + No per-row TASK reservation or additional ART custody acquisition follows AUTH. + +Normal create already consumes fresh AUTH before inserting its Task. An import +that wrote the unique external key before AUTH could hold that key while a +normal create held the same actor's AUTH lock: the normal create would wait on +uniqueness while the import waited on AUTH. Shared AUTH-before-write ordering +prevents that inversion. Distinct actors retain independent AUTH custody; +deterministic multi-row writes prevent crossed-key index waits. Native controls +must observe intermediate waits for same-actor create/import and distinct-actor +imports whose documents list overlapping external IDs in reverse order, alongside +revocation and late-failure rollback. Native uniqueness also protects direct SQL; +AUTH custody and file replay do not depend on an invented global creation fence. Field mapping has one confirmed native-parity decision: `TaskImportRow.difficulty` publishes an 80-character limit, whereas the current @@ -214,29 +218,6 @@ The batch retains the actual `workstream.task_import.v1` document identity and an explicit row-mapping/parser commitment, alongside verified bytes, so replay never silently reinterprets retained rows under a later mapping. -Further owner tracing identifies a smaller proposed lock solution for review: -the current normal create already consumes fresh AUTH before inserting its Task -(`authorized_commands.py` lines 152..165). The PM kernel locks the current -actor/profile/link and effective PM grant (`kernel.py` lines 499..527); it does -not acquire a shared project-global creation lock. Imports can reserve their -TASK batch/row retry identities first, validate ART custody, consume fresh AUTH, -then insert external-ID-bearing Tasks in deterministic project/UTF-8 external-ID -order. They must reserve every per-row identity before the first AUTH lock and -retain document row indexes independently from the insertion order. - -The bad schedule is an import's pre-AUTH external-ID write, a normal create's -actor lock, the normal create waiting on that external-ID write, then the import -waiting on the actor. With both entries consuming AUTH before uniqueness writes, -the same actor's contender waits on AUTH before owning that external key. -Different actors keep independent AUTH locks, so overlapping multi-row imports -must insert external IDs in the same order to avoid crossed-key index waits; -normal create has only one such key. This proposed common ordering avoids a new -advisory fence or custody table. Native intermediate-wait controls must include -same-actor create/import and different-actor reversed-document-order imports. -Review must settle this ordering and all implicit FK locks before replacing the -earlier fence proposal or authoring implementation/DDL. No concurrency PASS is -claimed from this source analysis. - ## Acceptance criteria - [ ] One real 200-row verified JSON source creates exactly 200 DRAFT Tasks under @@ -283,9 +264,14 @@ per-command transaction and unbound string provenance as explicit handoff issues ## Reconciliation -- Current-source reconciliation: source PR520 stays frozen at `7a3551e7`; - this separate preparation branch includes main's delivered hidden B8 owners. -- Next usable boundary: explicit atomic batch screen/release, then the CLI's - project/source/batch commands and client CSV conversion against public contracts. +- Current-source reconciliation: this preparation branch incorporates source + prerequisite `aa784c9c31490c018d35f4a3cc306fa7c16c630a` and main `251bc29b`, + retaining its ten-lane CI, hidden materialization/completion/failure/feedback + owners and CLI approval contracts. Only this planning record differs from the + source candidate; no atomic-import product code, test or DDL is authored. +- Next usable boundary: review the exact batch/membership/receipt schema and + owner preparation/replay graph, then coordinate the sole-author migration and + implement atomic JSON-to-DRAFT import. Explicit batch screen/release and CLI + project/source/batch commands with client CSV conversion remain later chunks. - Remaining risks: source prerequisite and current required CI/actual external review remain separate; no deployed import capability or whole Issue 489 claim. From b6e8cfa8fa987ede4564174bd4ce89764239af1f Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 09:14:08 +0100 Subject: [PATCH 007/283] plan(pilot02): preserve deferred reservation foreign-key custody --- .commitrail/changes/pilot02-atomic-json-draft-import.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.commitrail/changes/pilot02-atomic-json-draft-import.md b/.commitrail/changes/pilot02-atomic-json-draft-import.md index 2cd203397..99bf4a893 100644 --- a/.commitrail/changes/pilot02-atomic-json-draft-import.md +++ b/.commitrail/changes/pilot02-atomic-json-draft-import.md @@ -183,6 +183,13 @@ and native discriminating proofs before any concurrency PASS: retry identity. Acquire existing Task/member custody needed by replay in deterministic order before the first AUTH lock. Proposed new batch/row tuples must not introduce foreign owner locks through premature FK writes. + The existing TaskCommandReceipt defers both actor and Task FKs until commit; + new pre-AUTH reservation rows must follow that owner pattern for actor, + project, source and not-yet-inserted Task references. An immediate actor FK + would let two same-actor imports retain KEY SHARE and deadlock while upgrading + to AUTH's actor FOR UPDATE. An immediate source FK before remaining TASK + reservations would silently invert TASK-before-ART custody. Native controls + must distinguish both implicit-FK hazards without weakening final custody. 3. Validate actual ART source/verification custody through its typed participant after TASK custody and before fresh AUTH consumption. Read immutable tuples with the weakest required lock; do not lock a mutable put attempt merely to From 3a2574145b52ea029b36b79b51b70fa2de5d85cf Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 09:18:07 +0100 Subject: [PATCH 008/283] plan(pilot02): acquire immutable source custody before authority --- .commitrail/changes/pilot02-atomic-json-draft-import.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.commitrail/changes/pilot02-atomic-json-draft-import.md b/.commitrail/changes/pilot02-atomic-json-draft-import.md index 99bf4a893..1c5f474d0 100644 --- a/.commitrail/changes/pilot02-atomic-json-draft-import.md +++ b/.commitrail/changes/pilot02-atomic-json-draft-import.md @@ -193,7 +193,12 @@ and native discriminating proofs before any concurrency PASS: 3. Validate actual ART source/verification custody through its typed participant after TASK custody and before fresh AUTH consumption. Read immutable tuples with the weakest required lock; do not lock a mutable put attempt merely to - trust an application DTO. Preserve existing TASK-before-CHECKERS/ART order. + trust an application DTO. The source row is acquired FOR KEY SHARE here and + retained through commit: its existing upload/replay operation uses FOR UPDATE, + so postponing source FK custody until after AUTH could invert SOURCE/AUTH. + This compatible immutable-parent lock also satisfies deferred final custody + without reacquiring a conflicting source lock after actor authority. + Preserve existing TASK-before-CHECKERS/ART order. 4. Consume fresh current batch/source authority and exact per-row CREATE authority through the shared TASK owner. After AUTH, insert external-ID-bearing Tasks in deterministic project/UTF-8 external-ID order. Retain document row From e2303a2b51dd51ed40c3e498f0efda129f6a4d23 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 09:49:43 +0100 Subject: [PATCH 009/283] plan(pilot02): bind durable import replay to verified native ancestry --- .../pilot02-atomic-json-draft-import.md | 28 +++++++++++++++---- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/.commitrail/changes/pilot02-atomic-json-draft-import.md b/.commitrail/changes/pilot02-atomic-json-draft-import.md index 1c5f474d0..4a65ce4b0 100644 --- a/.commitrail/changes/pilot02-atomic-json-draft-import.md +++ b/.commitrail/changes/pilot02-atomic-json-draft-import.md @@ -70,8 +70,13 @@ it is not an authoritative native-UUID batch relationship. 1. Public import selects a project and verified source with exactly one UUID idempotency key; input supplies no Task state, creator, locked lineage or - server provenance. ART verifies and bounds bytes before the TASK write root. - Its typed prepared facts bind source/project, exact SHA/count and actual + server provenance. First import verifies actual provider bytes and parses + them before the TASK write root. Committed exact-file replay instead recovers + immutable IDs/facts from verified native original-source/receipt ancestry, + with fresh batch/source authority and no provider read or reinterpretation. + A different selected source needs its own actual verified receipt and the same + exact original byte identity/count; a client-claimed digest is insufficient. + Typed prepared facts bind source/project, exact SHA/count and actual verification ancestry. Inside the write root, the ART participant validates the immutable reference again without provider I/O or a separate commit. 2. TASK owns a UUIDv7 batch record, exact received-file commitment and ordered @@ -176,9 +181,14 @@ no additional global advisory fence or custody table is introduced. The exact owner preparation and implicit-FK schedule still require affected schema review and native discriminating proofs before any concurrency PASS: -1. Finish bounded ART provider verification and JSON parsing before the TASK - write root. Source read evidence belongs to that earlier read operation; - no provider stream, scratch cleanup or I/O occurs while TASK write locks wait. +1. For first import, finish bounded ART provider verification and JSON parsing + before the TASK write root. Source read evidence belongs to that earlier + operation; no provider stream, scratch cleanup or I/O occurs while TASK + write locks wait. For committed exact-file replay, use stored immutable + batch/member results and actual native verified-source/receipt ancestry. + Do not depend on provider availability or parse old bytes again. If the + requested selector differs, validate its own completed verified receipt and + exact original SHA/count before recovering the original batch. 2. Within the root, reserve the batch/file retry identity and every per-row TASK retry identity. Acquire existing Task/member custody needed by replay in deterministic order before the first AUTH lock. Proposed new batch/row tuples @@ -243,6 +253,14 @@ never silently reinterprets retained rows under a later mapping. - [ ] Exact same-key and exact-file retries recover original IDs with fresh authority; changed bytes/key reuse conflicts; revoked replay fails. Source, actor, receipt and row-membership substitutions fail closed. +- [ ] After successful import and Task advancement, provider unavailability + cannot prevent same-key or new-key exact-file recovery of original IDs/facts; + replay performs zero provider reads and emits no additional Task creation. + Revoked current authority still denies that recovery. A different verified + source with identical actual SHA/count recovers under a new key; a declaration + with only the claimed digest, foreign/missing receipt or different bytes never + recovers. Changing the selected source under the original key conflicts even + when both verified sources contain identical bytes. - [ ] Native PostgreSQL proves identical concurrent import recovery, overlapping external-ID conflicts, deterministic intermediate lock waits and complete rollback after an injected late-row/audit/binding failure. From a55ebf6fb474306970ac1c5ea7a2fa5c30a83cc1 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 09:54:38 +0100 Subject: [PATCH 010/283] plan(pilot02): name immutable ART ancestry for batch recovery --- .../changes/pilot02-atomic-json-draft-import.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.commitrail/changes/pilot02-atomic-json-draft-import.md b/.commitrail/changes/pilot02-atomic-json-draft-import.md index 4a65ce4b0..a722e0842 100644 --- a/.commitrail/changes/pilot02-atomic-json-draft-import.md +++ b/.commitrail/changes/pilot02-atomic-json-draft-import.md @@ -135,6 +135,18 @@ it is not an authoritative native-UUID batch relationship. state-conflict semantics remain intact. - The ART binding participant validates actual immutable source/verification rows in the caller's root; an application-created DTO supplies no authority. + The reviewed handoff must name the original source ID/operation identity, + put-attempt ID, artifact content/replica IDs, verification job ID/generation + and append-only verification receipt with its observed SHA/count. Exactly one + existing operation acknowledgement or confirmed observation receipt must bind + that same attempt and stored object ancestry. Reuse ART's existing native + admission/receipt custody pattern; do not copy it into TASK or accept a DTO as + proof. Initial import still uses the existing actual verified-byte read. + Committed recovery validates retained immutable ancestry through an ART-owned + participant and must not depend on the source read helper's current replica + availability/integrity flags, active namespace or provider access. Native + substitutions must fail without treating changed operational health as a new + import or reinterpreting original rows. Direct SQL must reject foreign ancestry, partial closure and changed tuples. Native FK representations follow each existing owner, including string-mapped actor/audit UUIDs. The sole migration author receives the reviewed field/lock From a4189b6925b9405a050f7b5145bfd1a7b45f13c5 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 10:17:08 +0100 Subject: [PATCH 011/283] plan(pilot02): name atomic batch schema and canonical creation phases --- .../pilot02-atomic-json-draft-import.md | 53 +++++++++++++++++-- 1 file changed, 49 insertions(+), 4 deletions(-) diff --git a/.commitrail/changes/pilot02-atomic-json-draft-import.md b/.commitrail/changes/pilot02-atomic-json-draft-import.md index a722e0842..40c43f45b 100644 --- a/.commitrail/changes/pilot02-atomic-json-draft-import.md +++ b/.commitrail/changes/pilot02-atomic-json-draft-import.md @@ -14,8 +14,8 @@ Issue #489 remains open after this chunk; batch transitions and CLI remain. ## Current behavior -The inspected integration is `aa784c9c31490c018d35f4a3cc306fa7c16c630a`, -based on main `251bc29bc5661934b2b70cde4ceecd52dbfa9687`. PR520 remains +The inspected integration is `f831fda0fc8373910a71bcc0726e2a342898e890`, +based on main `7e499849ab871f445012cf9e343ff97fbb95d62d`. PR520 remains the separate source prerequisite. Its parser in `tasks/api/task_import.py` accepts one strict UTF-8 JSON document with 1..500 rows, required case-sensitive external IDs, indexed duplicate errors and an 8 MiB ceiling. ART's @@ -152,6 +152,51 @@ it is not an authoritative native-UUID batch relationship. actor/audit UUIDs. The sole migration author receives the reviewed field/lock contract against then-current main before allocating a linear successor. +### Concrete owner and schema preparation for review + +The next reviewed application boundary separates canonical Task creation into +three caller-root phases: prepare all retry/Task identities, consume the same +exact CREATE authority facts, then stage the existing Task/create event/receipt. +Normal public create remains the root-owning wrapper over those phases, with +its current advanced-state replay rejection unchanged. Batch replay recovers +its immutable creation responses and never routes through single-Task recovery. +No public route or per-row command transaction is invoked from the batch owner. + +The proposed native tables are `task_import_batches`, +`task_import_batch_members` and `task_import_batch_command_receipts`: + +- Batch reservation has UUIDv7 ID, project UUID, original source UUID and its + operation identity, exact source SHA/count, document schema and parser/mapping + identity, row count, original actor/link, current batch creation decision and + original immutable ordered result. Project/SHA/count identifies one original + batch. A reservation may be incomplete only inside its caller root; a deferred + closure check rejects any committed pending header, missing or extra member, + incorrect row count or incomplete ordered result. +- Native ART ancestry stores source/attempt/content/replica IDs, verification + job/generation/receipt and exactly one operation/observation acknowledgement. + FKs plus owner validation bind each tuple to the same project/source bytes; + mutable replica health is not an original creation fact. +- Member has batch/project/Task IDs, bounded original row index, exact external + ID, normalized row digest, server-generated CREATE key, original Task command + receipt/decision IDs and closed original Task creation response. Task/project + and batch/project composite FKs close custody; unique Task membership, + batch/index and project/external-ID identities reject substitutions. Existing + arbitrary `import_batch_id` metadata never supplies these relationships. +- Batch command receipt has UUIDv7 ID, actor, closed import action, UUID key, + exact request digest over project/selected-source IDs, selected verified + ancestry, original batch ID and closed immutable ordered result. Actor/action/ + key is unique. A changed selector conflicts after fresh authority; new-key + exact-file recovery creates only the current retry receipt/evidence. + +String-mapped owner UUID FKs use `Uuid(as_uuid=False)`; native UUID-typed receipt +IDs keep their existing representation. Reservation actor/project/source/Task +FK checks are deferred where they would otherwise acquire implicit locks before +explicit TASK/ART/AUTH preparation. SOURCE KEY SHARE is acquired explicitly +before AUTH and retained through commit. All member/receipt mutation and deletion +are refused after committed closure. The sole migration author reviews native +constraints, deferred closure and exact owner representations before DDL work; +these proposed names/columns are planning, not installed schema. + ### Scope decisions and transaction preparation The lead confirmed the following issue489 boundaries during preparation: @@ -307,9 +352,9 @@ per-command transaction and unbound string provenance as explicit handoff issues ## Reconciliation - Current-source reconciliation: this preparation branch incorporates source - prerequisite `aa784c9c31490c018d35f4a3cc306fa7c16c630a` and main `251bc29b`, + prerequisite `f831fda0fc8373910a71bcc0726e2a342898e890` and main `7e499849`, retaining its ten-lane CI, hidden materialization/completion/failure/feedback - owners and CLI approval contracts. Only this planning record differs from the + owners and CLI approval/correction contracts. Only this planning record differs from the source candidate; no atomic-import product code, test or DDL is authored. - Next usable boundary: review the exact batch/membership/receipt schema and owner preparation/replay graph, then coordinate the sole-author migration and From 3e30775044f7c1062eeb0e536f8c9055a1e12244 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 10:18:44 +0100 Subject: [PATCH 012/283] plan(pilot02): map public atomic import onto canonical Task fields --- .../pilot02-atomic-json-draft-import.md | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/.commitrail/changes/pilot02-atomic-json-draft-import.md b/.commitrail/changes/pilot02-atomic-json-draft-import.md index 40c43f45b..19f9b46a7 100644 --- a/.commitrail/changes/pilot02-atomic-json-draft-import.md +++ b/.commitrail/changes/pilot02-atomic-json-draft-import.md @@ -152,6 +152,29 @@ it is not an authoritative native-UUID batch relationship. actor/audit UUIDs. The sole migration author receives the reviewed field/lock contract against then-current main before allocating a linear successor. +### Proposed public and row-mapping contract + +- POST `/projects/{project_id}/task-import-batches` accepts a closed + `{source_id: UUID}` body and the shared UUID idempotency header. Its import + action is `project.task.import`; proposed native resource facts use the + bounded `task_import_batch` classification with project/source identity. +- GET `/projects/{project_id}/task-import-batches/{batch_id}` uses + `project.task.import_batch.read`, returns only native membership, and separates + immutable original creation facts from current Task states. All responses are + bounded by the retained maximum 500 rows and keep document row order. +- The validated source's instruction fields map directly to canonical TaskCreate + fields. Server metadata stamps additive source type `json_import`, + `source_ref=task-import-source:`, the actual verified + `source_payload_hash`, and native batch UUID spelling in `import_batch_id`. + These labels add no authority; a manually stamped matching label remains + outside native membership. The server does not infer deadline, assignment, + guide locks, contribution terms or release state. +- Parser/mapping identity captures this exact field mapping and the published + `workstream.task_import.v1` document version. Source metadata labels are retained + as display values, never used as replay, project or authorization selectors. + Actual provider bytes are parsed only on first import; stored creation facts + and verified native receipts govern committed replay. + ### Concrete owner and schema preparation for review The next reviewed application boundary separates canonical Task creation into From 602451467ee674b21fde276ce0b65170ae9531eb Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 10:20:44 +0100 Subject: [PATCH 013/283] plan(pilot02): close JSON audit and batch mutation guard requirements --- .../pilot02-atomic-json-draft-import.md | 28 ++++++++++++++++--- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/.commitrail/changes/pilot02-atomic-json-draft-import.md b/.commitrail/changes/pilot02-atomic-json-draft-import.md index 19f9b46a7..bb4da421d 100644 --- a/.commitrail/changes/pilot02-atomic-json-draft-import.md +++ b/.commitrail/changes/pilot02-atomic-json-draft-import.md @@ -34,7 +34,7 @@ it is not an authoritative native-UUID batch relationship. ### Allowed -- TASK: `api/task_import.py`, a cohesive `task_import_batches.py`, +- TASK: `api/task_import.py`, `api/transition_audit.py`, a cohesive `task_import_batches.py`, `authorized_commands.py`, `command_replay.py`, `models.py`, `schemas.py`, `repository.py` and `router.py`: typed import/status contracts, immutable batch receipt and row membership, server provenance and reuse of canonical creation. @@ -50,6 +50,8 @@ it is not an authoritative native-UUID batch relationship. - Focused TASK/ART/AUTH public-contract and native PostgreSQL/MinIO tests; affected ownership/lane/inventory expectations; current TASK/ART/AUTH specs, README and roadmap claims for this chunk only. +- AUDIT: the existing closed TaskCreated payload source-type classification in + `audit/schemas.py`; preserve every existing type and canonical event owner. - One coordinated successor migration and its graph/reset/fingerprint consumers, authored solely by the delegated migration owner after final schema handoff. This planning work authors no migration and reserves no ordinal in advance. @@ -166,6 +168,11 @@ it is not an authoritative native-UUID batch relationship. fields. Server metadata stamps additive source type `json_import`, `source_ref=task-import-source:`, the actual verified `source_payload_hash`, and native batch UUID spelling in `import_batch_id`. + Select exactly `json_import` across TaskCreate, TaskTransitionFacts and the + closed TaskCreated payload. The sole-author successor updates the current + lifecycle SQL custody validator to admit that same exact token; historical + baseline files stay unchanged. Normal manual/markdown/CSV entries remain. + Caller input cannot choose or relabel these atomic-import server stamps. These labels add no authority; a manually stamped matching label remains outside native membership. The server does not infer deadline, assignment, guide locks, contribution terms or release state. @@ -215,8 +222,12 @@ String-mapped owner UUID FKs use `Uuid(as_uuid=False)`; native UUID-typed receip IDs keep their existing representation. Reservation actor/project/source/Task FK checks are deferred where they would otherwise acquire implicit locks before explicit TASK/ART/AUTH preparation. SOURCE KEY SHARE is acquired explicitly -before AUTH and retained through commit. All member/receipt mutation and deletion -are refused after committed closure. The sole migration author reviews native +before AUTH and retained through commit. All three tables reject UPDATE/DELETE after committed +closure and reject statement-level TRUNCATE. Only the exact pending-to-committed +header/receipt completion may change staged fields; immutable identity and +ancestry never change. Members are append-only and committed headers cannot be +reopened or deleted. Native reset restores these guards through the canonical +owned reset helper, without leaving them disabled for product writes. The sole migration author reviews native constraints, deferred closure and exact owner representations before DDL work; these proposed names/columns are planning, not installed schema. @@ -345,7 +356,11 @@ never silently reinterprets retained rows under a later mapping. external-ID conflicts, deterministic intermediate lock waits and complete rollback after an injected late-row/audit/binding failure. - [ ] Direct SQL rejects partial batch closure, foreign source/verification/Task - membership, changed original receipts and NULL/changed custody. Upgrade/reset + membership, changed original receipts and NULL/changed custody. For each of + batch/member/receipt tables, native direct-SQL UPDATE, DELETE and TRUNCATE + negatives retain all original facts. TaskCreated evidence uses the exact + `json_import` token and server provenance; malformed/caller-relabelled stamps + cannot produce a committed batch. Upgrade/reset preserves every retained main and source fact on the sole linear schema. ## Risk and review routing @@ -371,6 +386,11 @@ never silently reinterprets retained rows under a later mapping. No implementation review is claimed. Scope preparation identifies the existing per-command transaction and unbound string provenance as explicit handoff issues. +Affected independent planning review found two concrete missing integration +requirements: the closed TaskCreated JSON source token and complete batch/header/ +TRUNCATE immutability. This record now names all typed/audit/native token owners +and all-three-table UPDATE/DELETE/TRUNCATE controls. Product/native proof is +still unimplemented; these are recorded schema contracts, not runtime findings. ## Reconciliation From 59d47a6c621bf423406c489666516799ab8b712d Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 11:00:39 +0100 Subject: [PATCH 014/283] refactor(tasks): share caller-owned canonical creation phases --- .../pilot02-atomic-json-draft-import.md | 17 ++- .../app/modules/tasks/authorized_commands.py | 113 +++++++++++++----- backend/app/modules/tasks/schemas.py | 7 ++ 3 files changed, 100 insertions(+), 37 deletions(-) diff --git a/.commitrail/changes/pilot02-atomic-json-draft-import.md b/.commitrail/changes/pilot02-atomic-json-draft-import.md index bb4da421d..7e991ba95 100644 --- a/.commitrail/changes/pilot02-atomic-json-draft-import.md +++ b/.commitrail/changes/pilot02-atomic-json-draft-import.md @@ -14,7 +14,7 @@ Issue #489 remains open after this chunk; batch transitions and CLI remain. ## Current behavior -The inspected integration is `f831fda0fc8373910a71bcc0726e2a342898e890`, +The inspected integration is `0524e56b6aa7576f748d645f672d42ce069141af`, based on main `7e499849ab871f445012cf9e343ff97fbb95d62d`. PR520 remains the separate source prerequisite. Its parser in `tasks/api/task_import.py` accepts one strict UTF-8 JSON document with 1..500 rows, required case-sensitive @@ -168,8 +168,10 @@ it is not an authoritative native-UUID batch relationship. fields. Server metadata stamps additive source type `json_import`, `source_ref=task-import-source:`, the actual verified `source_payload_hash`, and native batch UUID spelling in `import_batch_id`. - Select exactly `json_import` across TaskCreate, TaskTransitionFacts and the - closed TaskCreated payload. The sole-author successor updates the current + Select exactly `json_import` in the server-only ImportedTaskCreate subtype, + TaskTransitionFacts and the closed TaskCreated payload. Public manual-create + TaskCreate keeps its existing three source types; callers cannot select the + server-only import value through that route. The sole-author successor updates the current lifecycle SQL custody validator to admit that same exact token; historical baseline files stay unchanged. Normal manual/markdown/CSV entries remain. Caller input cannot choose or relabel these atomic-import server stamps. @@ -378,7 +380,7 @@ never silently reinterprets retained rows under a later mapping. | Claim | Command or proof | Result | Remaining uncertainty | |---|---|---|---| -| Current owners and concrete gap | Inspect source port/parser, TASK create/replay/models and Issue 489 | Scope preparation only; no product code or import operation implemented | Exact schema and replay facts require affected review | +| Current owners and concrete gap | Inspect source port/parser, TASK create/replay/models and Issue 489 | Canonical create now has caller-root prepare/AUTH/stage phases; atomic import operation remains unimplemented | Exact schema and replay facts require affected review | | Public import and atomic effects | Planned isolated runner: `pytest -q tests/tasks/test_task_import_batches.py` with real PostgreSQL 16/MinIO | Not run; tests not authored | All positive/negative/concurrency cases above must pass | | Schema, guards and complete integration | Sole-author native graph/reset/UUID proof, affected guards, complete hosted lanes and aggregate | Not run for this chunk | Exact frozen candidate, actual merge tree and cleanup required | @@ -395,10 +397,13 @@ still unimplemented; these are recorded schema contracts, not runtime findings. ## Reconciliation - Current-source reconciliation: this preparation branch incorporates source - prerequisite `f831fda0fc8373910a71bcc0726e2a342898e890` and main `7e499849`, + prerequisite `0524e56b6aa7576f748d645f672d42ce069141af` and main `7e499849`, retaining its ten-lane CI, hidden materialization/completion/failure/feedback owners and CLI approval/correction contracts. Only this planning record differs from the - source candidate; no atomic-import product code, test or DDL is authored. + source candidate before implementation. Canonical Task creation now shares + caller-root phases with its normal public wrapper; atomic batch creation and + all new native schema are not yet implemented or proven. No migration is + authored in this worktree. - Next usable boundary: review the exact batch/membership/receipt schema and owner preparation/replay graph, then coordinate the sole-author migration and implement atomic JSON-to-DRAFT import. Explicit batch screen/release and CLI diff --git a/backend/app/modules/tasks/authorized_commands.py b/backend/app/modules/tasks/authorized_commands.py index 7ae1680c6..620d05437 100644 --- a/backend/app/modules/tasks/authorized_commands.py +++ b/backend/app/modules/tasks/authorized_commands.py @@ -3,7 +3,7 @@ import json from collections.abc import AsyncIterator from contextlib import AsyncExitStack, asynccontextmanager -from dataclasses import replace +from dataclasses import dataclass, replace from datetime import UTC, datetime from uuid import UUID from app.core.identifiers import new_record_id @@ -40,6 +40,7 @@ ManagementTaskLockedContext, OperationalTaskLockedContext, AuditTaskLockedContext, AssignmentResponse, TaskCreate, + ImportedTaskCreate, TaskResponse, TaskWithAssignmentResponse, ) @@ -55,6 +56,20 @@ ) +@dataclass(frozen=True, slots=True) +class TaskCreationPreparation: + """Caller-root reservation and immutable values prepared before AUTH locks.""" + + project_id: UUID + task_id: UUID + payload_json: str + receipt: TaskCommandReceipt + request_digest: str + reserved: bool + current: WorkstreamTask | None + facts: TaskAuthorityFacts + + class AuthorizedTaskCommands: """TASK owns state and assignment; AUTH owns permission and current grants.""" @@ -136,37 +151,73 @@ async def _locked_task( self._authorization.close(handle) async def create_task(self, project_id: UUID, payload: TaskCreate, *, idempotency_key: UUID) -> TaskResponse: - """Authorize the exact proposed task before creating it in the same transaction.""" - operation = TaskAuthorityOperation.CREATE + """Own the single-create root over the same preparation/AUTH/staging phases.""" async with self._session.begin(): - receipt, digest, reserved = await self._replay.reserve( - self._actor_id, operation, idempotency_key, new_record_id(), None, - request_value={"project_id": str(project_id), "payload": payload.model_dump(mode="json")}, - ) - # A duplicate may address an existing task: keep TASK before AUTH. - current = await self._repo.get_task(receipt.task_id, for_update=True) if not reserved else None - proposed = WorkstreamTask(id=receipt.task_id, project_id=str(project_id), status="draft", - created_by=str(self._actor_id), **payload.model_dump()) - facts = replace(self._facts(proposed, None, operation, None, idempotency_key), - request_digest=digest, replay_command_id=self._replay.manager_replay(receipt, operation, UUID(proposed.id), self._actor_id, idempotency_key)) - handle = await self._authorization.prepare(facts) - try: - decision_id = await self._authorization.consume(handle, facts) - finally: - self._authorization.close(handle) - project = await self._contexts._project_contexts.read_project_display(project_id) - if project is None or project.id != project_id: - raise TaskProjectNotReady("project not found") - task = current if current is not None else proposed - replayed = self._replay.recover(receipt, digest, self._facts(task, None, operation, None), - task, None, reserved=reserved) - if replayed is not None: - return replayed - task = await self._repo.add_task(task) - await self._record_management(task, operation, decision_id, None, None) - response = self._contexts.task_response_for_authority(task, can_manage=True) - self._replay.complete(receipt, None, self._facts(task, None, operation, None), response) - await self._session.flush() + prepared = await self.prepare_creation(project_id, payload, idempotency_key=idempotency_key) + decision = await self.authorize_creation(prepared) + return await self.stage_creation(prepared, decision) + + async def prepare_creation( + self, project_id: UUID, payload: TaskCreate | ImportedTaskCreate, *, idempotency_key: UUID, + ) -> TaskCreationPreparation: + """Reserve and acquire any existing TASK custody before the caller takes AUTH.""" + if not self._session.in_transaction(): + raise RuntimeError("task creation preparation requires the caller transaction") + operation = TaskAuthorityOperation.CREATE + receipt, digest, reserved = await self._replay.reserve( + self._actor_id, operation, idempotency_key, new_record_id(), None, + request_value={"project_id": str(project_id), "payload": payload.model_dump(mode="json")}, + ) + current = await self._repo.get_task(receipt.task_id, for_update=True) if not reserved else None + proposed = WorkstreamTask(id=receipt.task_id, project_id=str(project_id), status="draft", + created_by=str(self._actor_id), **payload.model_dump()) + facts = replace( + self._facts(proposed, None, operation, None, idempotency_key), request_digest=digest, + replay_command_id=self._replay.manager_replay( + receipt, operation, UUID(proposed.id), self._actor_id, idempotency_key, + ), + ) + return TaskCreationPreparation(project_id, UUID(proposed.id), payload.model_dump_json(), + receipt, digest, reserved, current, facts) + + async def authorize_creation(self, prepared: TaskCreationPreparation) -> TaskAuthorityDecision: + """Consume exact current per-Task authority after all caller preparation locks.""" + if not self._session.in_transaction() or prepared.facts.actor_profile_id != self._actor_id: + raise RuntimeError("task creation authority requires its original caller transaction") + handle = await self._authorization.prepare(prepared.facts) + try: + return await self._authorization.consume(handle, prepared.facts) + finally: + self._authorization.close(handle) + + async def stage_creation( + self, prepared: TaskCreationPreparation, decision: TaskAuthorityDecision, + ) -> TaskResponse: + """Stage canonical creation/evidence/receipt without opening or committing a root.""" + if not self._session.in_transaction() or prepared.facts.actor_profile_id != self._actor_id: + raise RuntimeError("task creation staging requires its original caller transaction") + payload = TypeAdapter(TaskCreate | ImportedTaskCreate).validate_json(prepared.payload_json) + digest = canonical_json_hash({"project_id": str(prepared.project_id), "payload": payload.model_dump(mode="json")}) + if digest != prepared.request_digest or prepared.receipt.task_id != str(prepared.task_id): + raise TaskValidationError("task creation preparation changed") + project = await self._contexts._project_contexts.read_project_display(prepared.project_id) + if project is None or project.id != prepared.project_id: + raise TaskProjectNotReady("project not found") + task = prepared.current if prepared.current is not None else WorkstreamTask( + id=str(prepared.task_id), project_id=str(prepared.project_id), status="draft", + created_by=str(self._actor_id), **payload.model_dump(), + ) + facts = self._facts(task, None, TaskAuthorityOperation.CREATE, None) + replayed = self._replay.recover( + prepared.receipt, prepared.request_digest, facts, task, None, reserved=prepared.reserved, + ) + if replayed is not None: + return replayed + task = await self._repo.add_task(task) + await self._record_management(task, TaskAuthorityOperation.CREATE, decision, None, None) + response = self._contexts.task_response_for_authority(task, can_manage=True) + self._replay.complete(prepared.receipt, None, self._facts(task, None, TaskAuthorityOperation.CREATE, None), response) + await self._session.flush() return response async def screen(self, task_id: UUID, reason: str | None, *, idempotency_key: UUID) -> TaskResponse: diff --git a/backend/app/modules/tasks/schemas.py b/backend/app/modules/tasks/schemas.py index 97141aac3..26b93796c 100644 --- a/backend/app/modules/tasks/schemas.py +++ b/backend/app/modules/tasks/schemas.py @@ -153,6 +153,13 @@ class TaskCreate(BaseModel): deadline_at: datetime | None = None +class ImportedTaskCreate(TaskCreate): + """Server-stamped JSON creation values; not a public manual-create request.""" + + model_config = ConfigDict(extra="forbid", frozen=True) + source_type: Literal["json_import"] = "json_import" + + class TaskTransitionRequest(BaseModel): """Optional request body for task lifecycle transitions.""" From 3111322bfe045f45da7c7871374a39def2995007 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 11:15:35 +0100 Subject: [PATCH 015/283] feat(tasks): prepare native batch contracts and verified source bindings --- .../pilot02-atomic-json-draft-import.md | 15 +- .../artifacts/api/task_import_source.py | 44 ++++- .../modules/artifacts/task_import_sources.py | 90 ++++++++-- backend/app/modules/audit/schemas.py | 2 +- backend/app/modules/tasks/api/task_import.py | 45 ++++- .../app/modules/tasks/api/transition_audit.py | 2 +- backend/app/modules/tasks/models.py | 162 +++++++++++++++++- backend/app/modules/tasks/schemas.py | 69 ++++++++ .../tasks/test_task_import_batch_bindings.py | 68 ++++++++ 9 files changed, 471 insertions(+), 26 deletions(-) create mode 100644 backend/tests/tasks/test_task_import_batch_bindings.py diff --git a/.commitrail/changes/pilot02-atomic-json-draft-import.md b/.commitrail/changes/pilot02-atomic-json-draft-import.md index 7e991ba95..01949a939 100644 --- a/.commitrail/changes/pilot02-atomic-json-draft-import.md +++ b/.commitrail/changes/pilot02-atomic-json-draft-import.md @@ -380,7 +380,8 @@ never silently reinterprets retained rows under a later mapping. | Claim | Command or proof | Result | Remaining uncertainty | |---|---|---|---| -| Current owners and concrete gap | Inspect source port/parser, TASK create/replay/models and Issue 489 | Canonical create now has caller-root prepare/AUTH/stage phases; atomic import operation remains unimplemented | Exact schema and replay facts require affected review | +| Canonical creation participant | Exact `59d47a6c` isolated native execution of five retained CREATE, denial, rollback and receipt controls | 5 passed in 69.02 seconds; schema `0031_task_import_source`; owned database/role/MinIO cleanup complete | Proves preservation of normal creation; no atomic batch success claim | +| Current owners and concrete gap | Inspect source port/parser, TASK create/replay/models and Issue 489 | Canonical caller-root phases, closed batch DTOs, model representations and ART immutable-binding participant are implemented; batch operation remains unassembled | New table constraints and guards require sole-author DDL and native proof | | Public import and atomic effects | Planned isolated runner: `pytest -q tests/tasks/test_task_import_batches.py` with real PostgreSQL 16/MinIO | Not run; tests not authored | All positive/negative/concurrency cases above must pass | | Schema, guards and complete integration | Sole-author native graph/reset/UUID proof, affected guards, complete hosted lanes and aggregate | Not run for this chunk | Exact frozen candidate, actual merge tree and cleanup required | @@ -391,18 +392,20 @@ per-command transaction and unbound string provenance as explicit handoff issues Affected independent planning review found two concrete missing integration requirements: the closed TaskCreated JSON source token and complete batch/header/ TRUNCATE immutability. This record now names all typed/audit/native token owners -and all-three-table UPDATE/DELETE/TRUNCATE controls. Product/native proof is -still unimplemented; these are recorded schema contracts, not runtime findings. +and all-three-table UPDATE/DELETE/TRUNCATE controls. Complete batch/native proof remains unimplemented; schema contracts alone do +not prove installed custody or a public import result. ## Reconciliation - Current-source reconciliation: this preparation branch incorporates source prerequisite `0524e56b6aa7576f748d645f672d42ce069141af` and main `7e499849`, retaining its ten-lane CI, hidden materialization/completion/failure/feedback - owners and CLI approval/correction contracts. Only this planning record differs from the - source candidate before implementation. Canonical Task creation now shares + owners and CLI approval/correction contracts. Before implementation, only + this planning record differed from the source candidate. Canonical Task creation now shares caller-root phases with its normal public wrapper; atomic batch creation and - all new native schema are not yet implemented or proven. No migration is + the installed native schema are not yet implemented or proven. Model/API + representations and provider-free ART binding validation are in progress; + no batch route is exposed. No migration is authored in this worktree. - Next usable boundary: review the exact batch/membership/receipt schema and owner preparation/replay graph, then coordinate the sole-author migration and diff --git a/backend/app/modules/artifacts/api/task_import_source.py b/backend/app/modules/artifacts/api/task_import_source.py index 44be16689..32d1929a6 100644 --- a/backend/app/modules/artifacts/api/task_import_source.py +++ b/backend/app/modules/artifacts/api/task_import_source.py @@ -8,7 +8,7 @@ from typing import Literal, Protocol from uuid import UUID -from pydantic import BaseModel, ConfigDict, Field +from pydantic import BaseModel, ConfigDict, Field, model_validator class TaskImportSourceError(RuntimeError): """A closed source outcome mapped to a concealed or explicit HTTP response.""" @@ -87,6 +87,48 @@ class VerifiedTaskImportSourceRead: stream: AsyncIterator[bytes] +class VerifiedTaskImportSourceBinding(BaseModel): + """Immutable native byte ancestry; the ART participant revalidates every reference.""" + + model_config = ConfigDict(extra="forbid", strict=True, frozen=True) + + source_id: UUID + project_id: UUID + sha256: str = Field(pattern=r"^sha256:[0-9a-f]{64}$") + byte_count: int = Field(ge=1, le=8388608) + operation_identity: str = Field(pattern=r"^sha256:[0-9a-f]{64}$") + put_attempt_id: UUID + content_id: UUID + replica_id: UUID + verification_job_id: UUID + verification_generation: int = Field(ge=1) + verification_receipt_id: UUID + operation_receipt_id: UUID | None + observation_receipt_id: UUID | None + + @model_validator(mode="after") + def exact_acknowledgement(self): + """Require precisely one retained operation or observation acknowledgement.""" + if (self.operation_receipt_id is None) == (self.observation_receipt_id is None): + raise ValueError("verified source requires exactly one acknowledgement") + return self + + +class TaskImportSourceBindingPort(Protocol): + """Prepare immutable source custody before caller-root AUTH and authorize it freshly.""" + + async def prepare_binding( + self, project_id: UUID, source_id: UUID, + expected: VerifiedTaskImportSourceBinding | None = None, + ) -> VerifiedTaskImportSourceBinding: + """Retain SOURCE KEY SHARE and validate actual receipts without provider access.""" + ... + + async def authorize_binding(self, binding: VerifiedTaskImportSourceBinding) -> UUID: + """Revalidate prepared custody and consume the current caller's exact source READ.""" + ... + + class TaskImportSourceCommandPort(Protocol): """Manage source custody only; these operations never create or transition Tasks.""" diff --git a/backend/app/modules/artifacts/task_import_sources.py b/backend/app/modules/artifacts/task_import_sources.py index 77c1ea88e..4066fcd77 100644 --- a/backend/app/modules/artifacts/task_import_sources.py +++ b/backend/app/modules/artifacts/task_import_sources.py @@ -16,7 +16,7 @@ TaskImportSourceError, TaskImportSourceAction, TaskImportSourceAuthorityDenied, TaskImportSourceAuthorityFacts, TaskImportSourceAuthorizationPort, TaskImportSourceDeclare, TaskImportSourceResponse, - VerifiedTaskImportSourceRead, + VerifiedTaskImportSourceRead, VerifiedTaskImportSourceBinding, ) from app.modules.artifacts.models import ( ArtifactContent, ArtifactOperationReceipt, ArtifactPutAttempt, ArtifactPutObservationReceipt, @@ -196,48 +196,108 @@ async def upload(self, project_id: UUID, source_id: UUID, byte_source: AsyncIter await prepared.close() return await self.status(project_id, source_id) - async def _verified_replica(self, source: ArtifactTaskImportSource) -> ArtifactReplica: - row = (await self._session.execute(select( + async def _verified_ancestry( + self, source: ArtifactTaskImportSource, + expected: VerifiedTaskImportSourceBinding | None = None, + ) -> tuple[VerifiedTaskImportSourceBinding, ArtifactReplica]: + """Validate append-only byte receipts independently of current provider health.""" + query = (select( ArtifactPutAttempt, ArtifactReplica, ArtifactContent, ArtifactVerificationJob, ArtifactVerificationReceipt, ).join(ArtifactReplica, ArtifactReplica.id == ArtifactPutAttempt.replica_id) .join(ArtifactContent, ArtifactContent.id == ArtifactReplica.content_id) .join(ArtifactVerificationJob, ArtifactVerificationJob.originating_put_attempt_id == ArtifactPutAttempt.id) - .join(ArtifactVerificationReceipt, (ArtifactVerificationReceipt.verification_job_id == ArtifactVerificationJob.id) - & (ArtifactVerificationReceipt.execution_generation == ArtifactVerificationJob.execution_generation)) - .where(ArtifactPutAttempt.task_import_source_id == source.id, ArtifactVerificationJob.status == "verified") - .order_by(ArtifactVerificationJob.created_at.desc(), ArtifactVerificationJob.id.desc()).limit(1))).one_or_none() + .join(ArtifactVerificationReceipt, ArtifactVerificationReceipt.verification_job_id == ArtifactVerificationJob.id) + .where(ArtifactPutAttempt.task_import_source_id == source.id, ArtifactVerificationReceipt.outcome == "verified")) + if expected is None: + query = query.where( + ArtifactVerificationJob.status == "verified", + ArtifactVerificationReceipt.execution_generation == ArtifactVerificationJob.execution_generation, + ).order_by(ArtifactVerificationJob.created_at.desc(), ArtifactVerificationJob.id.desc()).limit(1) + else: + query = query.where(ArtifactVerificationReceipt.id == str(expected.verification_receipt_id)) + row = (await self._session.execute(query)).one_or_none() if row is None: raise TaskImportSourceError("task_import_source_unverified", 409) attempt, replica, content, job, receipt = row if (attempt.producer_request_type != "task_import_source" or attempt.project_id != source.project_id - or attempt.logical_role != "task_import_source" or attempt.status != "object_confirmed" + or (expected is None and attempt.status != "object_confirmed") + or attempt.logical_role != "task_import_source" or (attempt.sha256, attempt.byte_count, attempt.media_type) != (source.sha256, source.byte_count, source.media_type) or (content.sha256, content.byte_count) != (source.sha256, source.byte_count) - or job.replica_id != replica.id or job.execution_generation != receipt.execution_generation + or job.replica_id != replica.id or receipt.verification_job_id != job.id or receipt.outcome != "verified" or (receipt.observed_sha256, receipt.observed_byte_count) != (source.sha256, source.byte_count) - or (replica.verification_state, replica.availability_state, replica.integrity_state) != ("verified", "available", "valid") or (replica.storage_namespace_id, replica.namespace_fingerprint) != (attempt.storage_namespace_id, attempt.namespace_fingerprint)): raise TaskImportSourceError("task_import_source_custody_invalid", 409) - if attempt.receipt_id is not None: + operation_id = attempt.receipt_id if expected is None else ( + str(expected.operation_receipt_id) if expected.operation_receipt_id is not None else None + ) + observation_id = None + if operation_id is not None: acknowledged = await self._session.scalar(select(ArtifactOperationReceipt.id).where( - ArtifactOperationReceipt.id == attempt.receipt_id, ArtifactOperationReceipt.put_attempt_id == attempt.id, + ArtifactOperationReceipt.id == operation_id, ArtifactOperationReceipt.put_attempt_id == attempt.id, ArtifactOperationReceipt.replica_id == replica.id, ArtifactOperationReceipt.request_digest == attempt.request_digest, ArtifactOperationReceipt.provider_object_ref == replica.provider_object_ref, ArtifactOperationReceipt.logical_role == "task_import_source", ArtifactOperationReceipt.outcome == "stored_pending_verification", )) else: - acknowledged = await self._session.scalar(select(ArtifactPutObservationReceipt.id).where( + query = select(ArtifactPutObservationReceipt.id).where( ArtifactPutObservationReceipt.put_attempt_id == attempt.id, - ArtifactPutObservationReceipt.execution_generation == attempt.execution_generation, ArtifactPutObservationReceipt.outcome == "observed_confirmed", ArtifactPutObservationReceipt.observed_sha256 == source.sha256, ArtifactPutObservationReceipt.expected_sha256 == source.sha256, ArtifactPutObservationReceipt.observed_byte_count == source.byte_count, ArtifactPutObservationReceipt.expected_byte_count == source.byte_count, - )) + ) + if expected is None: + query = query.where(ArtifactPutObservationReceipt.execution_generation == attempt.execution_generation) + else: + query = query.where(ArtifactPutObservationReceipt.id == str(expected.observation_receipt_id)) + acknowledged = await self._session.scalar(query) + observation_id = acknowledged if acknowledged is None: raise TaskImportSourceError("task_import_source_custody_invalid", 409) + binding = VerifiedTaskImportSourceBinding( + source_id=UUID(source.id), project_id=UUID(source.project_id), sha256=source.sha256, + byte_count=source.byte_count, operation_identity=source.operation_identity, + put_attempt_id=UUID(attempt.id), content_id=UUID(content.id), replica_id=UUID(replica.id), + verification_job_id=UUID(job.id), verification_generation=receipt.execution_generation, + verification_receipt_id=UUID(receipt.id), + operation_receipt_id=UUID(operation_id) if operation_id is not None else None, + observation_receipt_id=UUID(observation_id) if observation_id is not None else None, + ) + if expected is not None and binding != expected: + raise TaskImportSourceError("task_import_source_custody_invalid", 409) + return binding, replica + + async def prepare_binding( + self, project_id: UUID, source_id: UUID, + expected: VerifiedTaskImportSourceBinding | None = None, + ) -> VerifiedTaskImportSourceBinding: + """Retain SOURCE KEY SHARE before AUTH in the caller-owned transaction.""" + if not self._session.in_transaction(): + raise RuntimeError("source binding requires a caller transaction") + source = await self._session.scalar(select(ArtifactTaskImportSource).where( + ArtifactTaskImportSource.id == str(source_id), ArtifactTaskImportSource.project_id == str(project_id), + ).with_for_update(read=True, key_share=True).execution_options(populate_existing=True)) + if source is None: + raise TaskImportSourceError("task_import_source_not_found", 404) + binding, _ = await self._verified_ancestry(source, expected) + return binding + + async def authorize_binding(self, binding: VerifiedTaskImportSourceBinding) -> UUID: + """Revalidate prepared ancestry and consume fresh current-actor source READ.""" + await self.prepare_binding(binding.project_id, binding.source_id, binding) + source = await self._session.get(ArtifactTaskImportSource, str(binding.source_id)) + return await self._authorization.authorize(TaskImportSourceAction.READ, self._facts(source)) + + async def _verified_replica(self, source: ArtifactTaskImportSource) -> ArtifactReplica: + """Apply current operational health checks only to an actual provider read.""" + _, replica = await self._verified_ancestry(source) + if (replica.verification_state, replica.availability_state, replica.integrity_state) != ( + "verified", "available", "valid", + ): + raise TaskImportSourceError("task_import_source_custody_invalid", 409) return replica @asynccontextmanager diff --git a/backend/app/modules/audit/schemas.py b/backend/app/modules/audit/schemas.py index f33925ecf..a35a15784 100644 --- a/backend/app/modules/audit/schemas.py +++ b/backend/app/modules/audit/schemas.py @@ -367,7 +367,7 @@ class LifecycleAuditEventInput(BaseModel): event_type: LifecycleAuditEventType actor_id: UUID reason: LifecycleAuditReason - source_type: Literal["manual", "markdown_import", "csv_import"] | None = None + source_type: Literal["manual", "markdown_import", "csv_import", "json_import"] | None = None locked_lineage: dict[str, object] | None = None task_reason: Annotated[str, Field(min_length=1, max_length=1000)] | None = None from_status: Annotated[str, Field(pattern=r"^[a-z][a-z0-9_]{0,29}$")] | None = None diff --git a/backend/app/modules/tasks/api/task_import.py b/backend/app/modules/tasks/api/task_import.py index e74c44c51..0abe85038 100644 --- a/backend/app/modules/tasks/api/task_import.py +++ b/backend/app/modules/tasks/api/task_import.py @@ -4,13 +4,56 @@ import json import unicodedata from dataclasses import dataclass -from typing import Annotated, Literal +from enum import StrEnum +from typing import Annotated, Literal, Protocol +from uuid import UUID from pydantic import BaseModel, ConfigDict, Field, ValidationError, field_validator from pydantic_core import PydanticCustomError TASK_IMPORT_MAXIMUM_BYTES = 8 * 1024 * 1024 +TASK_IMPORT_MAPPING_VERSION = "workstream.task_import.draft_mapping.v1" + + +class TaskImportBatchAction(StrEnum): + """Covered-manager import and membership status, separate from Task transitions.""" + + IMPORT = "project.task.import" + READ = "project.task.import_batch.read" + + +class TaskImportBatchAuthorityDenied(RuntimeError): + """The exact native batch operation lacks current covered-manager authority.""" + + +@dataclass(frozen=True, slots=True) +class TaskImportBatchAuthorityFacts: + """Caller and exact native file/result identities consumed by the AUTH owner.""" + + batch_id: UUID + project_id: UUID + source_id: UUID + actor_profile_id: UUID + sha256: str + byte_count: int + row_count: int + manifest_digest: str + source_binding_digest: str + idempotency_key: UUID + request_digest: str + + +class TaskImportBatchAuthorizationPort(Protocol): + """Consume exact prepared authority and retain its original denial after rollback.""" + + async def authorize(self, action: TaskImportBatchAction, facts: TaskImportBatchAuthorityFacts) -> UUID: + """Return the fresh canonical decision for the current batch caller.""" + ... + + async def restage_denial(self, error: TaskImportBatchAuthorityDenied) -> None: + """Commit canonical denied evidence only through the instance that captured it.""" + ... class TaskImportRow(BaseModel): diff --git a/backend/app/modules/tasks/api/transition_audit.py b/backend/app/modules/tasks/api/transition_audit.py index a6ab5ac6e..4380f68a0 100644 --- a/backend/app/modules/tasks/api/transition_audit.py +++ b/backend/app/modules/tasks/api/transition_audit.py @@ -44,7 +44,7 @@ class TaskTransitionFacts: from_status: str | None to_status: str reason: str | None - source_type: Literal["manual", "markdown_import", "csv_import"] | None = None + source_type: Literal["manual", "markdown_import", "csv_import", "json_import"] | None = None locked_lineage: TaskPolicyLineage | None = None authority: TaskAuthorityDecision | None = None diff --git a/backend/app/modules/tasks/models.py b/backend/app/modules/tasks/models.py index 32c550229..e8c277137 100644 --- a/backend/app/modules/tasks/models.py +++ b/backend/app/modules/tasks/models.py @@ -7,6 +7,7 @@ from sqlalchemy import ( Boolean, + BigInteger, CheckConstraint, DateTime, ForeignKey, @@ -200,6 +201,7 @@ class WorkstreamTask(Base): ), UniqueConstraint("id", "locked_guide_version", name="uq_workstream_tasks_id_locked_guide"), UniqueConstraint("id", "project_id", name="uq_workstream_tasks_id_project"), + UniqueConstraint("project_id", "external_task_id", name="uq_workstream_tasks_project_external_id"), UniqueConstraint( "id", "locked_post_submit_checker_policy_id", @@ -303,7 +305,7 @@ class WorkstreamTask(Base): title: Mapped[str] = mapped_column(String(300), nullable=False) description: Mapped[str] = mapped_column(Text, nullable=False) task_type: Mapped[str | None] = mapped_column(String(100)) - difficulty: Mapped[str | None] = mapped_column(String(50)) + difficulty: Mapped[str | None] = mapped_column(String(80)) skill_tags: Mapped[list[str]] = mapped_column(JSON, nullable=False, default=list) estimated_time_minutes: Mapped[int | None] = mapped_column(Integer) status: Mapped[str] = mapped_column(String(30), nullable=False, default="draft", index=True) @@ -759,3 +761,161 @@ def result(self): name: UUID(str(getattr(self, name))) if name.endswith("_id") else getattr(self, name) for name in SubmissionCreationResult.__dataclass_fields__ }) + + +class TaskImportBatch(Base): + """One exact received JSON file and its immutable ordered creation result.""" + + __tablename__ = "task_import_batches" + __table_args__ = ( + CheckConstraint("(get_byte(uuid_send(id), 6) >> 4) = 7 and (get_byte(uuid_send(id), 8) & 192) = 128", name="id_uuid7"), + UniqueConstraint("project_id", "sha256", "byte_count", name="uq_task_import_batch_file"), + UniqueConstraint("id", "project_id", name="uq_task_import_batch_project"), + ForeignKeyConstraint( + ["source_id", "project_id", "sha256", "byte_count", "media_type"], + ["artifact_task_import_sources.id", "artifact_task_import_sources.project_id", + "artifact_task_import_sources.sha256", "artifact_task_import_sources.byte_count", + "artifact_task_import_sources.media_type"], + name="fk_task_import_batch_source", ondelete="RESTRICT", deferrable=True, initially="DEFERRED", + ), + ForeignKeyConstraint( + ["identity_link_id", "actor_profile_id"], + ["actor_identity_links.id", "actor_identity_links.actor_profile_id"], + name="fk_task_import_batch_actor_link", ondelete="RESTRICT", deferrable=True, initially="DEFERRED", + ), + CheckConstraint("sha256 ~ '^sha256:[0-9a-f]{64}$'", name="source_hash"), + CheckConstraint("source_operation_identity ~ '^sha256:[0-9a-f]{64}$'", name="source_operation"), + CheckConstraint("manifest_digest ~ '^sha256:[0-9a-f]{64}$'", name="manifest_hash"), + CheckConstraint("byte_count between 1 and 8388608 and row_count between 1 and 500", name="bounds"), + CheckConstraint("media_type='application/json' and schema_version='workstream.task_import.v1' " + "and mapping_version='workstream.task_import.draft_mapping.v1'", name="format"), + CheckConstraint( + "(status='pending' and response is null and authorization_decision_id is null and committed_at is null) or " + "(status='committed' and response is not null and jsonb_typeof(response)='object' " + "and authorization_decision_id is not null and committed_at is not null " + "and put_attempt_id is not null and content_id is not null and replica_id is not null " + "and verification_job_id is not null and verification_generation is not null " + "and verification_generation>0 and verification_receipt_id is not null " + "and ((operation_receipt_id is not null and observation_receipt_id is null) " + "or (operation_receipt_id is null and observation_receipt_id is not null)))", name="state_shape", + ), + ) + + id: Mapped[str] = mapped_column(Uuid(as_uuid=False), primary_key=True) + project_id: Mapped[str] = mapped_column(ForeignKey("projects.id", ondelete="RESTRICT", deferrable=True, initially="DEFERRED")) + source_id: Mapped[str] = mapped_column(Uuid(as_uuid=False)) + sha256: Mapped[str] = mapped_column(String(71)) + byte_count: Mapped[int] = mapped_column(BigInteger) + media_type: Mapped[str] = mapped_column(String(255), default="application/json") + schema_version: Mapped[str] = mapped_column(String(80)) + mapping_version: Mapped[str] = mapped_column(String(80)) + manifest_digest: Mapped[str] = mapped_column(String(71)) + row_count: Mapped[int] = mapped_column(Integer) + actor_profile_id: Mapped[str] = mapped_column(ForeignKey("actor_profiles.id", ondelete="RESTRICT", deferrable=True, initially="DEFERRED")) + identity_link_id: Mapped[str] = mapped_column(Uuid(as_uuid=False)) + authorization_decision_id: Mapped[str | None] = mapped_column(ForeignKey("audit_events.id", ondelete="RESTRICT", deferrable=True, initially="DEFERRED")) + status: Mapped[str] = mapped_column(String(16), default="pending") + response: Mapped[dict | None] = mapped_column(JSONB(none_as_null=True)) + created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now()) + committed_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True)) + source_operation_identity: Mapped[str] = mapped_column(String(71)) + put_attempt_id: Mapped[str | None] = mapped_column(ForeignKey("artifact_put_attempts.id", ondelete="RESTRICT", deferrable=True, initially="DEFERRED")) + content_id: Mapped[str | None] = mapped_column(ForeignKey("artifact_contents.id", ondelete="RESTRICT", deferrable=True, initially="DEFERRED")) + replica_id: Mapped[str | None] = mapped_column(ForeignKey("artifact_replicas.id", ondelete="RESTRICT", deferrable=True, initially="DEFERRED")) + verification_job_id: Mapped[str | None] = mapped_column(ForeignKey("artifact_verification_jobs.id", ondelete="RESTRICT", deferrable=True, initially="DEFERRED")) + verification_generation: Mapped[int | None] = mapped_column(BigInteger) + verification_receipt_id: Mapped[str | None] = mapped_column(ForeignKey("artifact_verification_receipts.id", ondelete="RESTRICT", deferrable=True, initially="DEFERRED")) + operation_receipt_id: Mapped[str | None] = mapped_column(ForeignKey("artifact_operation_receipts.id", ondelete="RESTRICT", deferrable=True, initially="DEFERRED")) + observation_receipt_id: Mapped[str | None] = mapped_column(ForeignKey("artifact_put_observation_receipts.id", ondelete="RESTRICT", deferrable=True, initially="DEFERRED")) + + +class TaskImportBatchMember(Base): + """Append-only document row bound to its canonical Task creation receipt.""" + + __tablename__ = "task_import_batch_members" + __table_args__ = ( + CheckConstraint("(get_byte(uuid_send(id), 6) >> 4) = 7 and (get_byte(uuid_send(id), 8) & 192) = 128", name="id_uuid7"), + UniqueConstraint("task_id", name="uq_task_import_member_task"), + UniqueConstraint("batch_id", "row_index", name="uq_task_import_member_row"), + UniqueConstraint("project_id", "external_task_id", name="uq_task_import_member_external_id"), + UniqueConstraint("task_command_receipt_id", name="uq_task_import_member_creation"), + ForeignKeyConstraint(["batch_id", "project_id"], ["task_import_batches.id", "task_import_batches.project_id"], + name="fk_task_import_member_batch", ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), + ForeignKeyConstraint(["task_id", "project_id"], ["workstream_tasks.id", "workstream_tasks.project_id"], + name="fk_task_import_member_task", ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), + CheckConstraint("row_index between 0 and 499", name="row_index"), + CheckConstraint("row_digest ~ '^sha256:[0-9a-f]{64}$'", name="row_hash"), + CheckConstraint("jsonb_typeof(response)='object'", name="response_shape"), + ) + + id: Mapped[str] = mapped_column(Uuid(as_uuid=False), primary_key=True) + batch_id: Mapped[str] = mapped_column(Uuid(as_uuid=False)) + project_id: Mapped[str] = mapped_column(Uuid(as_uuid=False)) + task_id: Mapped[str] = mapped_column(Uuid(as_uuid=False)) + row_index: Mapped[int] = mapped_column(Integer) + external_task_id: Mapped[str] = mapped_column(String(200)) + row_digest: Mapped[str] = mapped_column(String(71)) + create_idempotency_key: Mapped[UUID] = mapped_column(Uuid()) + task_command_receipt_id: Mapped[UUID] = mapped_column(ForeignKey("task_command_receipts.id", ondelete="RESTRICT", deferrable=True, initially="DEFERRED")) + authorization_decision_id: Mapped[str] = mapped_column(ForeignKey("audit_events.id", ondelete="RESTRICT", deferrable=True, initially="DEFERRED")) + response: Mapped[dict] = mapped_column(JSONB) + created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now()) + + +class TaskImportBatchCommandReceipt(Base): + """Actor/action/key retry custody with independently verified selected-source ancestry.""" + + __tablename__ = "task_import_batch_command_receipts" + __table_args__ = ( + CheckConstraint("(get_byte(uuid_send(id), 6) >> 4) = 7 and (get_byte(uuid_send(id), 8) & 192) = 128", name="id_uuid7"), + UniqueConstraint("actor_profile_id", "action_id", "idempotency_key", name="uq_task_import_command_namespace"), + ForeignKeyConstraint(["batch_id", "project_id"], ["task_import_batches.id", "task_import_batches.project_id"], + name="fk_task_import_command_batch", ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), + ForeignKeyConstraint( + ["source_id", "project_id", "sha256", "byte_count", "media_type"], + ["artifact_task_import_sources.id", "artifact_task_import_sources.project_id", + "artifact_task_import_sources.sha256", "artifact_task_import_sources.byte_count", + "artifact_task_import_sources.media_type"], + name="fk_task_import_command_source", ondelete="RESTRICT", deferrable=True, initially="DEFERRED", + ), + CheckConstraint("action_id='project.task.import'", name="action"), + CheckConstraint("request_digest ~ '^sha256:[0-9a-f]{64}$'", name="request_hash"), + CheckConstraint("sha256 ~ '^sha256:[0-9a-f]{64}$' and source_operation_identity ~ '^sha256:[0-9a-f]{64}$'", name="source_hash"), + CheckConstraint("byte_count between 1 and 8388608 and media_type='application/json'", name="bounds"), + CheckConstraint( + "(status='pending' and response is null and authorization_decision_id is null and committed_at is null) or " + "(status='committed' and batch_id is not null and response is not null and jsonb_typeof(response)='object' " + "and authorization_decision_id is not null and committed_at is not null " + "and put_attempt_id is not null and content_id is not null and replica_id is not null " + "and verification_job_id is not null and verification_generation is not null " + "and verification_generation>0 and verification_receipt_id is not null " + "and ((operation_receipt_id is not null and observation_receipt_id is null) " + "or (operation_receipt_id is null and observation_receipt_id is not null)))", name="state_shape", + ), + ) + + id: Mapped[str] = mapped_column(Uuid(as_uuid=False), primary_key=True) + actor_profile_id: Mapped[str] = mapped_column(ForeignKey("actor_profiles.id", ondelete="RESTRICT", deferrable=True, initially="DEFERRED")) + action_id: Mapped[str] = mapped_column(String(160)) + idempotency_key: Mapped[UUID] = mapped_column(Uuid()) + request_digest: Mapped[str] = mapped_column(String(71)) + project_id: Mapped[str] = mapped_column(ForeignKey("projects.id", ondelete="RESTRICT", deferrable=True, initially="DEFERRED")) + source_id: Mapped[str] = mapped_column(Uuid(as_uuid=False)) + sha256: Mapped[str] = mapped_column(String(71)) + byte_count: Mapped[int] = mapped_column(BigInteger) + media_type: Mapped[str] = mapped_column(String(255), default="application/json") + batch_id: Mapped[str | None] = mapped_column(Uuid(as_uuid=False)) + authorization_decision_id: Mapped[str | None] = mapped_column(ForeignKey("audit_events.id", ondelete="RESTRICT", deferrable=True, initially="DEFERRED")) + status: Mapped[str] = mapped_column(String(16), default="pending") + response: Mapped[dict | None] = mapped_column(JSONB(none_as_null=True)) + created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now()) + committed_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True)) + source_operation_identity: Mapped[str] = mapped_column(String(71)) + put_attempt_id: Mapped[str | None] = mapped_column(ForeignKey("artifact_put_attempts.id", ondelete="RESTRICT", deferrable=True, initially="DEFERRED")) + content_id: Mapped[str | None] = mapped_column(ForeignKey("artifact_contents.id", ondelete="RESTRICT", deferrable=True, initially="DEFERRED")) + replica_id: Mapped[str | None] = mapped_column(ForeignKey("artifact_replicas.id", ondelete="RESTRICT", deferrable=True, initially="DEFERRED")) + verification_job_id: Mapped[str | None] = mapped_column(ForeignKey("artifact_verification_jobs.id", ondelete="RESTRICT", deferrable=True, initially="DEFERRED")) + verification_generation: Mapped[int | None] = mapped_column(BigInteger) + verification_receipt_id: Mapped[str | None] = mapped_column(ForeignKey("artifact_verification_receipts.id", ondelete="RESTRICT", deferrable=True, initially="DEFERRED")) + operation_receipt_id: Mapped[str | None] = mapped_column(ForeignKey("artifact_operation_receipts.id", ondelete="RESTRICT", deferrable=True, initially="DEFERRED")) + observation_receipt_id: Mapped[str | None] = mapped_column(ForeignKey("artifact_put_observation_receipts.id", ondelete="RESTRICT", deferrable=True, initially="DEFERRED")) diff --git a/backend/app/modules/tasks/schemas.py b/backend/app/modules/tasks/schemas.py index 26b93796c..cd0c44870 100644 --- a/backend/app/modules/tasks/schemas.py +++ b/backend/app/modules/tasks/schemas.py @@ -259,6 +259,75 @@ class TaskResponse(BaseModel): updated_at: datetime +class TaskImportBatchRequest(BaseModel): + """Select one native verified source; all Task provenance is server-stamped.""" + + model_config = ConfigDict(extra="forbid", frozen=True) + + source_id: UUID + + +class TaskImportBatchResponse(BaseModel): + """Immutable original ordered creation facts, also returned after Tasks advance.""" + + model_config = ConfigDict(extra="forbid", frozen=True) + + batch_id: UUID + project_id: UUID + source_id: UUID + sha256: str = Field(pattern=r"^sha256:[0-9a-f]{64}$") + byte_count: int = Field(ge=1, le=8388608) + schema_version: Literal["workstream.task_import.v1"] + mapping_version: Literal["workstream.task_import.draft_mapping.v1"] + row_count: int = Field(ge=1, le=500) + created_at: datetime + tasks: tuple[TaskResponse, ...] = Field(min_length=1, max_length=500) + + @model_validator(mode="after") + def original_creation_custody(self): + """Reject foreign, duplicate or relabelled original Task creation responses.""" + if len(self.tasks) != self.row_count or len({task.id for task in self.tasks}) != self.row_count: + raise ValueError("batch creation result has invalid membership") + external_ids = {task.external_task_id for task in self.tasks} + if None in external_ids or len(external_ids) != self.row_count: + raise ValueError("batch creation result has invalid external IDs") + for task in self.tasks: + if (task.project_id != str(self.project_id) or task.status != "draft" + or task.source_type != "json_import" + or task.source_ref != f"task-import-source:{self.source_id}" + or task.source_payload_hash != self.sha256 or task.import_batch_id != str(self.batch_id)): + raise ValueError("batch creation result differs from original custody") + return self + + +class TaskImportBatchCurrentTask(BaseModel): + """Current lifecycle state selected solely by immutable native membership.""" + + model_config = ConfigDict(extra="forbid", frozen=True) + + task_id: UUID + row_index: int = Field(ge=0, le=499) + status: str = Field(pattern=r"^[a-z][a-z0-9_]{0,29}$") + + +class TaskImportBatchStatus(BaseModel): + """Separate original creation facts from the current member lifecycle states.""" + + model_config = ConfigDict(extra="forbid", frozen=True) + + creation: TaskImportBatchResponse + current_tasks: tuple[TaskImportBatchCurrentTask, ...] = Field(min_length=1, max_length=500) + + @model_validator(mode="after") + def exact_current_membership(self): + """Keep the current projection in the same original document row order.""" + if (len(self.current_tasks) != self.creation.row_count + or any(row.row_index != index or str(row.task_id) != self.creation.tasks[index].id + for index, row in enumerate(self.current_tasks))): + raise ValueError("current Task projection differs from native membership") + return self + + class RequiredArtifactRequirement(BaseModel): """Contributor-facing required artifact rule from the locked effective policy.""" diff --git a/backend/tests/tasks/test_task_import_batch_bindings.py b/backend/tests/tasks/test_task_import_batch_bindings.py new file mode 100644 index 000000000..36c720b1b --- /dev/null +++ b/backend/tests/tasks/test_task_import_batch_bindings.py @@ -0,0 +1,68 @@ +"""Native immutable source ancestry used by atomic import and provider-free replay.""" + +import json +from uuid import UUID, uuid4 + +import pytest +from sqlalchemy import select + +from app.db import session as db_session +from app.modules.actors.models import ActorIdentityLink, ActorProfile +from app.modules.artifacts.api.task_import_source import TaskImportSourceError +from app.modules.artifacts.models import ArtifactReplica +from app.modules.artifacts.task_import_sources import ArtifactTaskImportSourceCommands +from app.modules.authorization.runtime import ( + ActorKind, ActorStatus, HumanAuthorizationContext, IdentityLinkStatus, +) +from app.modules.authorization.task_import_sources import PreparedTaskImportSourceAuthorization +from tests.test_task_import_sources import ( + import_source_client as import_source_client, _declare, _path, _project, +) +from tests.test_tasks import auth_headers, task_database_env as task_database_env +from tests.tasks.test_task_import_contract import document + + +def _unexpected_runtime(): + raise AssertionError("immutable source replay must never acquire provider runtime") + + +async def test_native_binding_survives_operational_health_and_rejects_substitutions(import_source_client): + """Current health may change; the exact verified native byte ancestry may not.""" + client = import_source_client + project = await _project(client) + raw = json.dumps(document()).encode() + source = await _declare(client, project, raw) + uploaded = await client.put(_path(project, source) + "/content", + headers=auth_headers() | {"Content-Type": "application/json"}, content=raw) + assert uploaded.status_code == 200 and uploaded.json()["status"] == "verified", uploaded.text + async with db_session.get_session_factory()() as session: + async with session.begin(): + link = (await session.scalars(select(ActorIdentityLink).join( + ActorProfile, ActorProfile.id == ActorIdentityLink.actor_profile_id, + ).where(ActorIdentityLink.subject == "project-manager-subject"))).one() + context = HumanAuthorizationContext( + actor_profile_id=UUID(link.actor_profile_id), identity_link_id=UUID(link.id), + actor_kind=ActorKind.HUMAN, actor_status=ActorStatus.ACTIVE, + identity_link_status=IdentityLinkStatus.ACTIVE, request_id=uuid4(), correlation_id=uuid4(), + ) + commands = ArtifactTaskImportSourceCommands( + session, actor_profile_id=context.actor_profile_id, identity_link_id=context.identity_link_id, + authorization=PreparedTaskImportSourceAuthorization(session, context), runtime=_unexpected_runtime, + ) + binding = await commands.prepare_binding(UUID(project), UUID(source["source_id"])) + assert await commands.authorize_binding(binding) + async with session.begin(): + replica = await session.get(ArtifactReplica, str(binding.replica_id)) + replica.availability_state = "unavailable" + async with session.begin(): + assert await commands.prepare_binding(UUID(project), binding.source_id, binding) == binding + assert await commands.authorize_binding(binding) + for replacement in ( + {"verification_receipt_id": uuid4()}, {"sha256": "sha256:" + "a" * 64}, + {"put_attempt_id": uuid4()}, {"project_id": uuid4()}, + {"operation_receipt_id": None, "observation_receipt_id": uuid4()}, + ): + changed = binding.model_copy(update=replacement) + async with session.begin(): + with pytest.raises(TaskImportSourceError): + await commands.prepare_binding(UUID(project), binding.source_id, changed) From bea4af29689b4350bbe90770332436bb25002592 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 11:27:18 +0100 Subject: [PATCH 016/283] feat(tasks): compose atomic import root and exact batch authority --- .../artifacts/api/task_import_source.py | 12 + .../modules/artifacts/task_import_sources.py | 41 ++- backend/app/modules/audit/schemas.py | 3 +- .../artifact_project_authority.py | 14 +- .../app/modules/authorization/catalogue.py | 8 +- .../authorization/domain/action_groups.py | 3 + .../app/modules/authorization/domain/audit.py | 2 + .../authorization/domain/task_authority.py | 28 +- backend/app/modules/authorization/prepared.py | 9 +- backend/app/modules/authorization/runtime.py | 3 + .../authorization/task_authorization.py | 37 +- .../app/modules/tasks/authorized_commands.py | 9 +- .../app/modules/tasks/task_import_batches.py | 319 ++++++++++++++++++ .../tasks/test_task_import_batch_contract.py | 71 ++++ 14 files changed, 536 insertions(+), 23 deletions(-) create mode 100644 backend/app/modules/tasks/task_import_batches.py create mode 100644 backend/tests/tasks/test_task_import_batch_contract.py diff --git a/backend/app/modules/artifacts/api/task_import_source.py b/backend/app/modules/artifacts/api/task_import_source.py index 32d1929a6..eb4e87608 100644 --- a/backend/app/modules/artifacts/api/task_import_source.py +++ b/backend/app/modules/artifacts/api/task_import_source.py @@ -117,6 +117,14 @@ def exact_acknowledgement(self): class TaskImportSourceBindingPort(Protocol): """Prepare immutable source custody before caller-root AUTH and authorize it freshly.""" + async def source_commitment(self, project_id: UUID, source_id: UUID) -> TaskImportSourceAuthorityFacts: + """Read native immutable declaration facts without claiming or granting authority.""" + ... + + async def authorize_commitment(self, facts: TaskImportSourceAuthorityFacts) -> UUID: + """Freshly authorize actual source facts before exposing preparation outcomes.""" + ... + async def prepare_binding( self, project_id: UUID, source_id: UUID, expected: VerifiedTaskImportSourceBinding | None = None, @@ -128,6 +136,10 @@ async def authorize_binding(self, binding: VerifiedTaskImportSourceBinding) -> U """Revalidate prepared custody and consume the current caller's exact source READ.""" ... + async def restage_denial(self, error: TaskImportSourceAuthorityDenied) -> None: + """Retain a caller-root denial through the actual issuing source authority.""" + ... + class TaskImportSourceCommandPort(Protocol): """Manage source custody only; these operations never create or transition Tasks.""" diff --git a/backend/app/modules/artifacts/task_import_sources.py b/backend/app/modules/artifacts/task_import_sources.py index 4066fcd77..ab87e7e30 100644 --- a/backend/app/modules/artifacts/task_import_sources.py +++ b/backend/app/modules/artifacts/task_import_sources.py @@ -199,6 +199,7 @@ async def upload(self, project_id: UUID, source_id: UUID, byte_source: AsyncIter async def _verified_ancestry( self, source: ArtifactTaskImportSource, expected: VerifiedTaskImportSourceBinding | None = None, + *, require_operational: bool = False, ) -> tuple[VerifiedTaskImportSourceBinding, ArtifactReplica]: """Validate append-only byte receipts independently of current provider health.""" query = (select( @@ -208,19 +209,21 @@ async def _verified_ancestry( .join(ArtifactVerificationJob, ArtifactVerificationJob.originating_put_attempt_id == ArtifactPutAttempt.id) .join(ArtifactVerificationReceipt, ArtifactVerificationReceipt.verification_job_id == ArtifactVerificationJob.id) .where(ArtifactPutAttempt.task_import_source_id == source.id, ArtifactVerificationReceipt.outcome == "verified")) - if expected is None: + if require_operational: query = query.where( ArtifactVerificationJob.status == "verified", ArtifactVerificationReceipt.execution_generation == ArtifactVerificationJob.execution_generation, ).order_by(ArtifactVerificationJob.created_at.desc(), ArtifactVerificationJob.id.desc()).limit(1) - else: + elif expected is not None: query = query.where(ArtifactVerificationReceipt.id == str(expected.verification_receipt_id)) + else: + query = query.order_by(ArtifactVerificationReceipt.created_at.desc(), ArtifactVerificationReceipt.id.desc()).limit(1) row = (await self._session.execute(query)).one_or_none() if row is None: raise TaskImportSourceError("task_import_source_unverified", 409) attempt, replica, content, job, receipt = row if (attempt.producer_request_type != "task_import_source" or attempt.project_id != source.project_id - or (expected is None and attempt.status != "object_confirmed") + or (require_operational and attempt.status != "object_confirmed") or attempt.logical_role != "task_import_source" or (attempt.sha256, attempt.byte_count, attempt.media_type) != (source.sha256, source.byte_count, source.media_type) or (content.sha256, content.byte_count) != (source.sha256, source.byte_count) @@ -270,6 +273,32 @@ async def _verified_ancestry( raise TaskImportSourceError("task_import_source_custody_invalid", 409) return binding, replica + async def source_commitment(self, project_id: UUID, source_id: UUID) -> TaskImportSourceAuthorityFacts: + """Read the actual declaration for preparation; this supplies no authority.""" + if not self._session.in_transaction(): + raise RuntimeError("source commitment requires a caller transaction") + source = await self._session.scalar(select(ArtifactTaskImportSource).where( + ArtifactTaskImportSource.id == str(source_id), ArtifactTaskImportSource.project_id == str(project_id), + ).execution_options(populate_existing=True)) + if source is None: + raise TaskImportSourceError("task_import_source_not_found", 404) + return self._facts(source) + + async def authorize_commitment(self, facts: TaskImportSourceAuthorityFacts) -> UUID: + """Fence the actual declaration and authorize a provider-free preparation read.""" + if not self._session.in_transaction(): + raise RuntimeError("source authorization requires a caller transaction") + source = await self._session.scalar(select(ArtifactTaskImportSource).where( + ArtifactTaskImportSource.id == str(facts.source_id), + ArtifactTaskImportSource.project_id == str(facts.project_id), + ).with_for_update(read=True, key_share=True).execution_options(populate_existing=True)) + if source is None: + raise TaskImportSourceError("task_import_source_not_found", 404) + current = self._facts(source) + if current != facts: + raise TaskImportSourceError("task_import_source_custody_invalid", 409) + return await self._authorization.authorize(TaskImportSourceAction.READ, current) + async def prepare_binding( self, project_id: UUID, source_id: UUID, expected: VerifiedTaskImportSourceBinding | None = None, @@ -291,9 +320,13 @@ async def authorize_binding(self, binding: VerifiedTaskImportSourceBinding) -> U source = await self._session.get(ArtifactTaskImportSource, str(binding.source_id)) return await self._authorization.authorize(TaskImportSourceAction.READ, self._facts(source)) + async def restage_denial(self, error: TaskImportSourceAuthorityDenied) -> None: + """Delegate caller-root denial custody to the source instance that captured it.""" + await self._authorization.restage_denial(error) + async def _verified_replica(self, source: ArtifactTaskImportSource) -> ArtifactReplica: """Apply current operational health checks only to an actual provider read.""" - _, replica = await self._verified_ancestry(source) + _, replica = await self._verified_ancestry(source, require_operational=True) if (replica.verification_state, replica.availability_state, replica.integrity_state) != ( "verified", "available", "valid", ): diff --git a/backend/app/modules/audit/schemas.py b/backend/app/modules/audit/schemas.py index a35a15784..5e3449a4c 100644 --- a/backend/app/modules/audit/schemas.py +++ b/backend/app/modules/audit/schemas.py @@ -41,7 +41,7 @@ project_guide_compilation_attempt project_guide_sufficiency_projection project_submission_artifact_policy_projection project_guide_setup_finalization project_guide_compilation_review_package project_guide_compilation_correction - project_post_submit_checker_policy_mutation external_checker_registry_entry task_import_source""".split() + project_post_submit_checker_policy_mutation external_checker_registry_entry task_import_source task_import_batch""".split() ) _UUID_TARGET_KINDS = frozenset( { @@ -53,6 +53,7 @@ "project_role_grant", "external_checker_registry_entry", "task_import_source", + "task_import_batch", } ) _TARGET_REF_KINDS = _UUID_TARGET_KINDS | {"project"} diff --git a/backend/app/modules/authorization/artifact_project_authority.py b/backend/app/modules/authorization/artifact_project_authority.py index a120d2c85..e3f67199d 100644 --- a/backend/app/modules/authorization/artifact_project_authority.py +++ b/backend/app/modules/authorization/artifact_project_authority.py @@ -7,7 +7,7 @@ from app.modules.authorization.catalogue import ActionAvailability, ActionId from app.modules.authorization.schemas import AdminRole from app.modules.authorization.domain.task_authority import ( - TASK_ACTIONS, TASK_PROJECT_ROLE_READ_ACTIONS, TASK_SUBMITTER_ACTIONS, + TASK_ACTIONS, TASK_IMPORT_BATCH_ACTIONS, TASK_PROJECT_ROLE_READ_ACTIONS, TASK_SUBMITTER_ACTIONS, evaluate_task_authority, ) from app.modules.authorization.runtime import ( @@ -24,7 +24,7 @@ PROJECT_SUBMITTER_ACTIONS = TASK_SUBMITTER_ACTIONS | { ActionId.ARTIFACT_SUBMISSION_BUNDLE_PREPARE, ActionId.SUBMISSION_CREATE, } -PROJECT_AUTHORITY_ACTIONS = TASK_ACTIONS | PROJECT_SUBMITTER_ACTIONS | { +PROJECT_AUTHORITY_ACTIONS = TASK_ACTIONS | TASK_IMPORT_BATCH_ACTIONS | PROJECT_SUBMITTER_ACTIONS | { ActionId.ARTIFACT_GUIDE_SOURCE_INGEST, ActionId.ARTIFACT_TASK_IMPORT_SOURCE_DECLARE, ActionId.ARTIFACT_TASK_IMPORT_SOURCE_UPLOAD, @@ -52,7 +52,7 @@ async def lock_project_authority(repository, context, scope, action, locked_cont ActionId.OPERATIONS_TASK_START_OVERRIDE, ActionId.OPERATIONS_TASK_LOCKED_CONTEXT_READ, }, allowed_roles={ - **{action: frozenset({AdminRole.PROJECT_MANAGER}) for action in TASK_IMPORT_SOURCE_ACTIONS}, + **{action: frozenset({AdminRole.PROJECT_MANAGER}) for action in TASK_IMPORT_SOURCE_ACTIONS | TASK_IMPORT_BATCH_ACTIONS}, ActionId.PROJECT_TASK_LOCKED_CONTEXT_READ: frozenset({AdminRole.PROJECT_MANAGER}), ActionId.OPERATIONS_TASK_LOCKED_CONTEXT_READ: frozenset({AdminRole.OPERATOR}), ActionId.AUDIT_TASK_LOCKED_CONTEXT_READ: frozenset({AdminRole.AUDIT_AUTHORITY}), @@ -90,13 +90,15 @@ def evaluate_project_authority(action, context, authority, resource, lifecycle_d """Keep each resource guard distinct while sharing the closed dispatch boundary.""" if action.action_id in TASK_ACTIONS: return evaluate_task_authority(action, context, authority, resource, lifecycle_denial) - if action.action_id in TASK_IMPORT_SOURCE_ACTIONS: - from app.modules.authorization.runtime import TaskImportSourceResourceContext + if action.action_id in TASK_IMPORT_SOURCE_ACTIONS | TASK_IMPORT_BATCH_ACTIONS: + from app.modules.authorization.runtime import TaskImportSourceResourceContext, TaskImportBatchResourceContext + expected_resource = (TaskImportBatchResourceContext if action.action_id in TASK_IMPORT_BATCH_ACTIONS + else TaskImportSourceResourceContext) denial = lifecycle_denial if denial is None and action.availability is not ActionAvailability.ACTIVE: denial = AuthorizationDenialCode.ACTION_UNAVAILABLE if denial is None and ( - type(resource) is not TaskImportSourceResourceContext + type(resource) is not expected_resource or resource.scope_project_id != authority.scope_project_id or resource.actor_profile_id != context.actor_profile_id or resource.identity_link_id != context.identity_link_id diff --git a/backend/app/modules/authorization/catalogue.py b/backend/app/modules/authorization/catalogue.py index aad5b829b..0450a0efa 100644 --- a/backend/app/modules/authorization/catalogue.py +++ b/backend/app/modules/authorization/catalogue.py @@ -109,6 +109,8 @@ class ActionId(StrEnum): PROJECT_TASK_QUEUE_READ = "project.task.queue.read" OPERATIONS_TASK_QUEUE_READ = "operations.task.queue.read" PROJECT_TASK_CREATE = "project.task.create" + PROJECT_TASK_IMPORT = "project.task.import" + PROJECT_TASK_IMPORT_BATCH_READ = "project.task.import_batch.read" PROJECT_TASK_SCREEN = "project.task.screen" PROJECT_TASK_RELEASE = "project.task.release" TASK_CLAIM = "task.claim" @@ -289,6 +291,7 @@ class ActionOwner(StrEnum): TASK_PROJECT_GRANT = "task-project-grant-authorization" PILOT_13 = "PILOT-13" PILOT_02A = "PILOT-02A" + PILOT_02B = "PILOT-02B" PILOT_04 = "PILOT-04" AUTH_07B = "WS-AUTH-001-07B" @@ -558,6 +561,8 @@ def _active( _active(ActionId.PROJECT_TASK_QUEUE_READ, PermissionId.PROJECT_TASK_MANAGE, ActionOwner.ARCH_03C4), _active(ActionId.OPERATIONS_TASK_QUEUE_READ, PermissionId.OPERATIONS_STATUS_READ, ActionOwner.ARCH_03C4), _active(ActionId.PROJECT_TASK_CREATE, PermissionId.PROJECT_TASK_MANAGE, ActionOwner.ARCH_03C3), + _active(ActionId.PROJECT_TASK_IMPORT, PermissionId.PROJECT_TASK_MANAGE, ActionOwner.PILOT_02B), + _active(ActionId.PROJECT_TASK_IMPORT_BATCH_READ, PermissionId.PROJECT_TASK_MANAGE, ActionOwner.PILOT_02B), _active(ActionId.ARTIFACT_TASK_IMPORT_SOURCE_DECLARE, PermissionId.PROJECT_TASK_MANAGE, ActionOwner.PILOT_02A), _active(ActionId.ARTIFACT_TASK_IMPORT_SOURCE_UPLOAD, PermissionId.PROJECT_TASK_MANAGE, ActionOwner.PILOT_02A), _active(ActionId.ARTIFACT_TASK_IMPORT_SOURCE_READ, PermissionId.PROJECT_TASK_MANAGE, ActionOwner.PILOT_02A), @@ -767,7 +772,7 @@ def _active( def _require_catalogue_counts() -> None: """Keep the closed action inventory and permission boundary exact.""" - if len(PERMISSION_IDS) != 78 or len(ACTION_IDS) != 148: + if len(PERMISSION_IDS) != 78 or len(ACTION_IDS) != 150: raise RuntimeError("authorization catalogue count mismatch") if len(HISTORICAL_PERMISSION_IDS) != 49 or len(NEW_PERMISSION_IDS) != 29: raise RuntimeError("authorization permission boundary mismatch") @@ -906,6 +911,7 @@ def _index_actions(definitions: tuple[ActionDefinition, ...]) -> MappingProxyTyp ActionId.TASK_GUIDE_READ, ActionId.PROJECT_TASK_WORK_CONTEXT_READ, ActionId.OPERATIONS_TASK_START_OVERRIDE, ActionId.PROJECT_TASK_CREATE, ActionId.PROJECT_TASK_SCREEN, ActionId.PROJECT_TASK_RELEASE, + ActionId.PROJECT_TASK_IMPORT, ActionId.PROJECT_TASK_IMPORT_BATCH_READ, ActionId.ARTIFACT_TASK_IMPORT_SOURCE_DECLARE, ActionId.ARTIFACT_TASK_IMPORT_SOURCE_UPLOAD, ActionId.ARTIFACT_TASK_IMPORT_SOURCE_READ, ActionId.TASK_QUEUE_READ, ActionId.PROJECT_TASK_QUEUE_READ, ActionId.OPERATIONS_TASK_QUEUE_READ, diff --git a/backend/app/modules/authorization/domain/action_groups.py b/backend/app/modules/authorization/domain/action_groups.py index 4c39192fd..dac79ff30 100644 --- a/backend/app/modules/authorization/domain/action_groups.py +++ b/backend/app/modules/authorization/domain/action_groups.py @@ -1,6 +1,7 @@ """Exact shared kernel action classifications; these sets grant no authority.""" from app.modules.authorization.catalogue import GUIDE_PROPOSAL_ACTION_IDS, POST_POLICY_HUMAN_ACTION_IDS, POST_POLICY_MUTATION_ACTION_IDS +from app.modules.authorization.domain.task_authority import TASK_IMPORT_BATCH_ACTIONS, TaskImportBatchResourceContext from app.modules.authorization.catalogue import ActionId from app.modules.authorization.domain import adapter_bindings, contribution_policies from app.modules.authorization.runtime import PROJECT_SUBMISSION_POLICY_TARGET_KIND_BY_ACTION @@ -39,6 +40,7 @@ CONTEXT_DIGEST_ACTIONS = frozenset( { ActionId.ARTIFACT_GUIDE_SOURCE_INGEST, + *TASK_IMPORT_BATCH_ACTIONS, ActionId.ARTIFACT_TASK_IMPORT_SOURCE_DECLARE, ActionId.ARTIFACT_TASK_IMPORT_SOURCE_UPLOAD, ActionId.ARTIFACT_TASK_IMPORT_SOURCE_READ, @@ -70,6 +72,7 @@ def supports_prepared_denial(action_id: ActionId, resource_context: object) -> b ) or (action_id in TASK_ACTIONS and isinstance(resource_context, TaskAuthorityResourceContext)) + or (action_id in TASK_IMPORT_BATCH_ACTIONS and type(resource_context) is TaskImportBatchResourceContext) or ( action_id in {ActionId.ARTIFACT_TASK_IMPORT_SOURCE_DECLARE, ActionId.ARTIFACT_TASK_IMPORT_SOURCE_UPLOAD, ActionId.ARTIFACT_TASK_IMPORT_SOURCE_READ} diff --git a/backend/app/modules/authorization/domain/audit.py b/backend/app/modules/authorization/domain/audit.py index 369d46a04..eacfdfeef 100644 --- a/backend/app/modules/authorization/domain/audit.py +++ b/backend/app/modules/authorization/domain/audit.py @@ -43,6 +43,7 @@ "contribution_policy", "external_checker_registry_entry", "task_import_source", + "task_import_batch", ) @@ -106,6 +107,7 @@ "contribution_policy", "external_checker_registry_entry", "task_import_source", + "task_import_batch", ] diff --git a/backend/app/modules/authorization/domain/task_authority.py b/backend/app/modules/authorization/domain/task_authority.py index a1c81e4fb..58fefc80f 100644 --- a/backend/app/modules/authorization/domain/task_authority.py +++ b/backend/app/modules/authorization/domain/task_authority.py @@ -33,6 +33,7 @@ TASK_MANAGER_ACTIONS = frozenset({ ActionId.PROJECT_TASK_CREATE, ActionId.PROJECT_TASK_SCREEN, ActionId.PROJECT_TASK_RELEASE, }) +TASK_IMPORT_BATCH_ACTIONS = frozenset({ActionId.PROJECT_TASK_IMPORT, ActionId.PROJECT_TASK_IMPORT_BATCH_READ}) TASK_ACTIONS = TASK_PROJECT_ROLE_ACTIONS | TASK_MANAGER_ACTIONS | TASK_MANAGER_READ_ACTIONS | TASK_LOCKED_CONTEXT_READ_ACTIONS | { ActionId.OPERATIONS_TASK_START_OVERRIDE, ActionId.AUDIT_TASK_EVIDENCE_READ, @@ -60,15 +61,36 @@ class TaskAuthorityResourceContext(BaseModel): replay_command_id: UUID | None = None +class TaskImportBatchResourceContext(BaseModel): + """Exact native batch, selected byte ancestry and original manifest under fresh PM authority.""" + + model_config = ConfigDict(extra="forbid", frozen=True, strict=True) + + resource_type: Literal["task_import_batch"] = "task_import_batch" + resource_id: UUID + scope_project_id: UUID + source_id: UUID + actor_profile_id: UUID + identity_link_id: UUID + sha256: str = Field(pattern=r"^sha256:[0-9a-f]{64}$") + byte_count: int = Field(ge=1, le=8388608) + row_count: int = Field(ge=1, le=500) + manifest_digest: str = Field(pattern=r"^sha256:[0-9a-f]{64}$") + source_binding_digest: str = Field(pattern=r"^sha256:[0-9a-f]{64}$") + idempotency_key: UUID + request_digest: str = Field(pattern=r"^sha256:[0-9a-f]{64}$") + + def parse_task_authority_binding( action: ActionId, request: Mapping[str, object], invalid_error: type[Exception], idempotency_key: UUID, -) -> TaskAuthorityResourceContext | None: +) -> TaskAuthorityResourceContext | TaskImportBatchResourceContext | None: """Keep the complete task commitment typed and immutable through consumption.""" - if action not in TASK_ACTIONS: + if action not in TASK_ACTIONS | TASK_IMPORT_BATCH_ACTIONS: return None try: - resource = TaskAuthorityResourceContext.model_validate_json(json.dumps(dict(request))) + model = TaskImportBatchResourceContext if action in TASK_IMPORT_BATCH_ACTIONS else TaskAuthorityResourceContext + resource = model.model_validate_json(json.dumps(dict(request))) if resource.idempotency_key is not None and resource.idempotency_key != idempotency_key: raise ValueError("task key differs from prepared binding") return resource diff --git a/backend/app/modules/authorization/prepared.py b/backend/app/modules/authorization/prepared.py index 4b3b69096..ee3a2db91 100644 --- a/backend/app/modules/authorization/prepared.py +++ b/backend/app/modules/authorization/prepared.py @@ -120,7 +120,7 @@ SubmissionBundlePreparationResourceContext, ) from app.modules.authorization.domain.task_authority import ( - TASK_ACTIONS, TaskAuthorityResourceContext, parse_task_authority_binding, + TASK_ACTIONS, TASK_IMPORT_BATCH_ACTIONS, TaskAuthorityResourceContext, TaskImportBatchResourceContext, parse_task_authority_binding, ) from app.modules.authorization.domain.post_submit_routing import ( ROUTE, PostSubmitRoutingResourceContext, post_submit_routing_prepare_matches, @@ -197,7 +197,7 @@ class _PreparedAuthorizationBinding: outbox_dispatch_digest: str | None = None post_submit_prepare_context: dict | None = None routing_request: TaskRoutingRequestFacts | None = None - task_authority_context: TaskAuthorityResourceContext | None = None + task_authority_context: TaskAuthorityResourceContext | TaskImportBatchResourceContext | None = None lifecycle_command: LifecycleTransitionCommand | None = None project_create_operation_id: UUID | None = None project_create_project_id: UUID | None = None @@ -652,8 +652,8 @@ async def consume( """Consume one exact capability before evaluating and evidencing final facts.""" issuance = self._live_issuance(handle) self._validate_consumption(issuance, expected_action_id, caller_input, final_resource_context) - if expected_action_id in TASK_ACTIONS and ( - not isinstance(final_resource_context, TaskAuthorityResourceContext) + if expected_action_id in TASK_ACTIONS | TASK_IMPORT_BATCH_ACTIONS and ( + not isinstance(final_resource_context, (TaskAuthorityResourceContext, TaskImportBatchResourceContext)) or issuance.binding.task_authority_context != final_resource_context ): raise PreparedAuthorizationHandleInvalid("invalid prepared authorization handle") @@ -962,6 +962,7 @@ def _scope_from_resource( or GUIDE_PROPOSAL_RESOURCE_BY_ACTION.get(action_id) or COMPILATION_RESOURCE_BY_ACTION.get(action_id) or (TaskAuthorityResourceContext if action_id in TASK_ACTIONS else None) + or (TaskImportBatchResourceContext if action_id in TASK_IMPORT_BATCH_ACTIONS else None) or (TaskImportSourceResourceContext if action_id in TASK_IMPORT_SOURCE_ACTIONS else None) ) if action_id in CONTRIBUTION_POLICY_MUTATION_ACTIONS and isinstance(resource, ContributionPolicyMutationResourceContext): diff --git a/backend/app/modules/authorization/runtime.py b/backend/app/modules/authorization/runtime.py index 2b808b53e..62bd45fe6 100644 --- a/backend/app/modules/authorization/runtime.py +++ b/backend/app/modules/authorization/runtime.py @@ -48,6 +48,8 @@ from app.modules.authorization.schemas import AdminRole, AdminScope, ProjectRole from app.modules.authorization.submission_preparation import SubmissionBundlePreparationPreflightResourceContext, SubmissionBundlePreparationResourceContext from app.modules.authorization.submission_consumption import SubmissionBindingResourceContext, SubmissionCreationResourceContext +from app.modules.authorization.domain.task_authority import TaskImportBatchResourceContext as TaskImportBatchResourceContext + _STRICT_FROZEN = ConfigDict(extra="forbid", frozen=True, strict=True) PROJECT_DIAGNOSTIC_TARGET_KIND_BY_ACTION = { ActionId.PROJECT_SETUP_RUN_READ: "setup_run", @@ -1090,6 +1092,7 @@ class PreSubmitCheckerInputResourceContext(PreSubmitCheckerInputPreparationConte | ProjectRoleGrantRevokeResourceContext | GuideSourceIngestResourceContext | TaskImportSourceResourceContext + | TaskImportBatchResourceContext | ArtifactPutAttemptResourceContext | ArtifactVerificationJobResourceContext | ArtifactPendingWorkResourceContext diff --git a/backend/app/modules/authorization/task_authorization.py b/backend/app/modules/authorization/task_authorization.py index 26d5d2121..e98db703e 100644 --- a/backend/app/modules/authorization/task_authorization.py +++ b/backend/app/modules/authorization/task_authorization.py @@ -1,11 +1,16 @@ """AUTH-owned adapter for exact prepared task operations.""" +from uuid import UUID + from sqlalchemy.ext.asyncio import AsyncSession from app.modules.tasks.api import TaskAuthorityDenied, TaskAuthorityFacts from app.modules.tasks.api.authorization import TaskAuthorityDecision +from app.modules.tasks.api.task_import import ( + TaskImportBatchAction, TaskImportBatchAuthorityDenied, TaskImportBatchAuthorityFacts, +) from app.modules.authorization.catalogue import ActionId -from app.modules.authorization.domain.task_authority import TaskAuthorityResourceContext +from app.modules.authorization.domain.task_authority import TaskAuthorityResourceContext, TaskImportBatchResourceContext from app.modules.authorization.kernel import AuthorizationService from app.modules.authorization.prepared import PreparedAuthorizationHandle, PreparedAuthorizationService from app.modules.authorization.repository import AdminAuthorizationRepository @@ -116,7 +121,35 @@ def close(self, handle: object) -> None: if isinstance(handle, _TaskPrepared): handle.service.close() - async def restage_denial(self, error: TaskAuthorityDenied) -> bool: + async def authorize(self, action: TaskImportBatchAction, facts: TaskImportBatchAuthorityFacts) -> UUID: + """Bind the native batch/file result to current covered-manager authority.""" + if type(facts) is not TaskImportBatchAuthorityFacts or facts.actor_profile_id != self._context.actor_profile_id: + raise TaskImportBatchAuthorityDenied("task import authority denied") + resource = TaskImportBatchResourceContext( + resource_id=facts.batch_id, scope_project_id=facts.project_id, source_id=facts.source_id, + actor_profile_id=facts.actor_profile_id, identity_link_id=self._context.identity_link_id, + sha256=facts.sha256, byte_count=facts.byte_count, row_count=facts.row_count, + manifest_digest=facts.manifest_digest, source_binding_digest=facts.source_binding_digest, + idempotency_key=facts.idempotency_key, request_digest=facts.request_digest, + ) + service = PreparedAuthorizationService(self._session, self._context, self._kernel, self._repository) + caller_input = PreparedAuthorizationInput(idempotency_key=facts.idempotency_key, + request_value=resource.model_dump(mode="json")) + try: + try: + handle = await service.prepare(ActionId(action.value), caller_input, PreparedAuthorityScope( + kind=PreparedAuthorityScopeKind.PROJECT, project_id=facts.project_id, + )) + except PreparedAuthorizationUnsupported as exc: + await service.deny_unsupported(ActionId(action.value), caller_input, resource, exc) + raise + return (await service.consume(handle, ActionId(action.value), caller_input, resource)).decision_id + except AuthorizationDenied as exc: + raise TaskImportBatchAuthorityDenied("task import authority denied") from exc + finally: + service.close() + + async def restage_denial(self, error: TaskAuthorityDenied | TaskImportBatchAuthorityDenied) -> bool: """Reuse the issuing kernel's exact pending evidence after rollback.""" if isinstance(error.__cause__, AuthorizationDenied): await self._kernel.restage_denial(error.__cause__.decision) diff --git a/backend/app/modules/tasks/authorized_commands.py b/backend/app/modules/tasks/authorized_commands.py index 620d05437..7be57ec73 100644 --- a/backend/app/modules/tasks/authorized_commands.py +++ b/backend/app/modules/tasks/authorized_commands.py @@ -32,7 +32,7 @@ from app.modules.tasks.api.transition_audit import TaskPolicyLineage, TaskTransitionAuditPort, TaskTransitionFacts from app.modules.tasks.api.audit_evidence import AuditTaskEvidenceRequest, AuditTaskEvidencePage, TaskEvidenceInvalid from app.modules.tasks.models import TaskAssignment, TaskCommandReceipt, WorkstreamTask -from app.modules.tasks.command_replay import TaskCommandReplay +from app.modules.tasks.command_replay import TaskCommandReplay, TaskReplayConflict from app.modules.tasks.repository import TaskRepository from app.modules.tasks.schemas import ( ContributorTaskLifecycle, ContributorTaskWorkContext, ManagementTaskWorkContext, @@ -213,7 +213,12 @@ async def stage_creation( ) if replayed is not None: return replayed - task = await self._repo.add_task(task) + try: + task = await self._repo.add_task(task) + except IntegrityError as exc: + if integrity_constraint_name(exc) == "uq_workstream_tasks_project_external_id": + raise TaskReplayConflict("external_task_id_conflict") from exc + raise await self._record_management(task, TaskAuthorityOperation.CREATE, decision, None, None) response = self._contexts.task_response_for_authority(task, can_manage=True) self._replay.complete(prepared.receipt, None, self._facts(task, None, TaskAuthorityOperation.CREATE, None), response) diff --git a/backend/app/modules/tasks/task_import_batches.py b/backend/app/modules/tasks/task_import_batches.py new file mode 100644 index 000000000..4a781152b --- /dev/null +++ b/backend/app/modules/tasks/task_import_batches.py @@ -0,0 +1,319 @@ +"""One caller-root JSON import using canonical Task creation and ART byte custody.""" + +from datetime import UTC, datetime +from uuid import UUID, uuid4 + +from sqlalchemy import select +from sqlalchemy.dialects.postgresql import insert +from sqlalchemy.ext.asyncio import AsyncSession + +from app.core.hashing import canonical_json_hash +from app.core.identifiers import new_record_id +from app.modules.artifacts.api.task_import_source import ( + TaskImportSourceAuthorityFacts, TaskImportSourceBindingPort, + TaskImportSourceCommandPort, VerifiedTaskImportSourceBinding, +) +from app.modules.tasks.api.task_import import ( + ParsedTaskImport, TASK_IMPORT_MAPPING_VERSION, TASK_IMPORT_MAXIMUM_BYTES, + TaskImportBatchAction, TaskImportBatchAuthorityFacts, TaskImportBatchAuthorizationPort, + TaskImportRow, parse_task_import, +) +from app.modules.tasks.authorized_commands import AuthorizedTaskCommands, TaskCreationPreparation +from app.modules.tasks.command_replay import TaskReplayConflict +from app.modules.tasks.models import ( + TaskCommandReceipt, TaskImportBatch, TaskImportBatchCommandReceipt, TaskImportBatchMember, WorkstreamTask, +) +from app.modules.tasks.schemas import ( + ImportedTaskCreate, TaskImportBatchResponse, TaskImportBatchCurrentTask, TaskImportBatchStatus, +) + + +class TaskImportBatchError(RuntimeError): + """A controlled batch outcome with bounded document-row diagnostics.""" + + def __init__(self, code: str, status_code: int, row_indexes: tuple[int, ...] = ()): + self.code, self.status_code, self.row_indexes = code, status_code, row_indexes + super().__init__(code) + + +def imported_task_payload(row: TaskImportRow, source: TaskImportSourceAuthorityFacts, batch_id: UUID) -> ImportedTaskCreate: + """Map instructions directly and stamp provenance solely from actual native custody.""" + return ImportedTaskCreate( + **row.model_dump(), source_type="json_import", source_ref=f"task-import-source:{source.source_id}", + source_payload_hash=source.sha256, import_batch_id=str(batch_id), + ) + + +def _binding(row: TaskImportBatch | TaskImportBatchCommandReceipt) -> VerifiedTaskImportSourceBinding: + """Recover a closed native ancestry tuple without operational provider fields.""" + return VerifiedTaskImportSourceBinding( + source_id=UUID(row.source_id), project_id=UUID(row.project_id), sha256=row.sha256, byte_count=row.byte_count, + operation_identity=row.source_operation_identity, put_attempt_id=UUID(row.put_attempt_id), + content_id=UUID(row.content_id), replica_id=UUID(row.replica_id), verification_job_id=UUID(row.verification_job_id), + verification_generation=row.verification_generation, verification_receipt_id=UUID(row.verification_receipt_id), + operation_receipt_id=UUID(row.operation_receipt_id) if row.operation_receipt_id is not None else None, + observation_receipt_id=UUID(row.observation_receipt_id) if row.observation_receipt_id is not None else None, + ) + + +def _stage_binding(row: TaskImportBatch | TaskImportBatchCommandReceipt, binding: VerifiedTaskImportSourceBinding) -> None: + """Stage only the concrete native ancestry columns validated by the ART owner.""" + row.source_operation_identity = binding.operation_identity + row.verification_generation = binding.verification_generation + for field in ("put_attempt_id", "content_id", "replica_id", "verification_job_id", + "verification_receipt_id", "operation_receipt_id", "observation_receipt_id"): + value = getattr(binding, field) + setattr(row, field, str(value) if value is not None else None) + + +class TaskImportBatchCommands: + """Own the batch transaction; its Task and ART participants never commit it.""" + + def __init__( + self, session: AsyncSession, *, actor_profile_id: UUID, identity_link_id: UUID, + authorization: TaskImportBatchAuthorizationPort, tasks: AuthorizedTaskCommands, + source_reader: TaskImportSourceCommandPort, source_binding: TaskImportSourceBindingPort, + ) -> None: + self._session, self._actor_id, self._link_id = session, actor_profile_id, identity_link_id + self._authorization, self._tasks = authorization, tasks + self._source_reader, self._source_binding = source_reader, source_binding + + @staticmethod + def _request_digest(project_id: UUID, source_id: UUID) -> str: + return canonical_json_hash({"project_id": str(project_id), "source_id": str(source_id)}) + + async def _command(self, key: UUID, *, lock: bool = False) -> TaskImportBatchCommandReceipt | None: + query = select(TaskImportBatchCommandReceipt).where( + TaskImportBatchCommandReceipt.actor_profile_id == str(self._actor_id), + TaskImportBatchCommandReceipt.action_id == TaskImportBatchAction.IMPORT.value, + TaskImportBatchCommandReceipt.idempotency_key == key, + ).execution_options(populate_existing=True) + return await self._session.scalar(query.with_for_update() if lock else query) + + async def _file_batch(self, facts: TaskImportSourceAuthorityFacts, *, lock: bool = False) -> TaskImportBatch | None: + query = select(TaskImportBatch).where( + TaskImportBatch.project_id == str(facts.project_id), TaskImportBatch.sha256 == facts.sha256, + TaskImportBatch.byte_count == facts.byte_count, + ).execution_options(populate_existing=True) + return await self._session.scalar(query.with_for_update() if lock else query) + + async def _preflight(self, project_id: UUID, source_id: UUID, key: UUID) -> tuple[TaskImportSourceAuthorityFacts, bool]: + """Determine whether immutable recovery exists without reading provider bytes.""" + async with self._session.begin(): + command = await self._command(key) + if command is not None: + facts = await self._source_binding.source_commitment(UUID(command.project_id), UUID(command.source_id)) + await self._source_binding.authorize_commitment(facts) + return facts, True + facts = await self._source_binding.source_commitment(project_id, source_id) + await self._source_binding.authorize_commitment(facts) + batch = await self._file_batch(facts) + return facts, batch is not None + + async def _read_first_import(self, facts: TaskImportSourceAuthorityFacts) -> ParsedTaskImport: + """Finish bounded actual provider verification and parsing before TASK locks.""" + raw = bytearray() + async with self._source_reader.open(facts.project_id, facts.source_id) as opened: + async for chunk in opened.stream: + raw.extend(chunk) + if len(raw) > TASK_IMPORT_MAXIMUM_BYTES: + raise TaskImportBatchError("task_import_source_limit_exceeded", 413) + parsed = parse_task_import(bytes(raw)) + if (parsed.sha256, parsed.byte_count) != (facts.sha256, facts.byte_count): + raise TaskImportBatchError("task_import_source_custody_invalid", 409) + return parsed + + async def _reserve_command( + self, facts: TaskImportSourceAuthorityFacts, key: UUID, request_digest: str, + ) -> TaskImportBatchCommandReceipt: + """Reserve the exact actor/action/key before batch, ART or AUTH locks.""" + await self._session.execute(insert(TaskImportBatchCommandReceipt).values( + id=str(new_record_id()), actor_profile_id=str(self._actor_id), action_id=TaskImportBatchAction.IMPORT.value, + idempotency_key=key, request_digest=request_digest, project_id=str(facts.project_id), + source_id=str(facts.source_id), sha256=facts.sha256, byte_count=facts.byte_count, + media_type="application/json", source_operation_identity=facts.operation_identity, status="pending", + ).on_conflict_do_nothing(constraint="uq_task_import_command_namespace")) + return await self._command(key, lock=True) + + async def _reserve_batch(self, facts: TaskImportSourceAuthorityFacts, parsed: ParsedTaskImport | None) -> TaskImportBatch: + """Serialize only the exact project/file identity; native FKs remain deferred.""" + if parsed is not None: + await self._session.execute(insert(TaskImportBatch).values( + id=str(new_record_id()), project_id=str(facts.project_id), source_id=str(facts.source_id), + sha256=facts.sha256, byte_count=facts.byte_count, media_type="application/json", + schema_version=parsed.document.schema_version, mapping_version=TASK_IMPORT_MAPPING_VERSION, + manifest_digest=canonical_json_hash(parsed.document.model_dump(mode="json")), + row_count=len(parsed.document.tasks), actor_profile_id=str(self._actor_id), identity_link_id=str(self._link_id), + source_operation_identity=facts.operation_identity, status="pending", + ).on_conflict_do_nothing(constraint="uq_task_import_batch_file")) + batch = await self._file_batch(facts, lock=True) + if batch is None: + raise TaskImportBatchError("task_import_batch_custody_invalid", 409) + return batch + + def _facts( + self, batch: TaskImportBatch, selected: VerifiedTaskImportSourceBinding, key: UUID, request_digest: str, + ) -> TaskImportBatchAuthorityFacts: + return TaskImportBatchAuthorityFacts( + UUID(batch.id), UUID(batch.project_id), selected.source_id, self._actor_id, batch.sha256, + batch.byte_count, batch.row_count, batch.manifest_digest, + canonical_json_hash(selected.model_dump(mode="json")), key, request_digest, + ) + + async def _prepare_rows( + self, batch: TaskImportBatch, facts: TaskImportSourceAuthorityFacts, parsed: ParsedTaskImport, + ) -> list[tuple[int, TaskCreationPreparation]]: + """Prepare every canonical Task retry identity before any ART/AUTH lock.""" + prepared = [] + rows = sorted(enumerate(parsed.document.tasks), key=lambda item: item[1].external_task_id.encode("utf-8")) + for index, row in rows: + values = imported_task_payload(row, facts, UUID(batch.id)) + prepared.append((index, await self._tasks.prepare_creation( + UUID(batch.project_id), values, idempotency_key=uuid4(), + ))) + return prepared + + async def _prepare_sources( + self, batch: TaskImportBatch, command: TaskImportBatchCommandReceipt, + ) -> VerifiedTaskImportSourceBinding: + """Acquire all selected/original SOURCE custody before current AUTH.""" + expected = {} + if batch.status == "committed": + expected[batch.source_id] = _binding(batch) + if command.status == "committed": + expected[command.source_id] = _binding(command) + expected.setdefault(command.source_id, None) + prepared = {} + for source_id in sorted(expected): + prepared[source_id] = await self._source_binding.prepare_binding( + UUID(batch.project_id), UUID(source_id), expected[source_id], + ) + selected = prepared[command.source_id] + if (selected.sha256, selected.byte_count) != (batch.sha256, batch.byte_count): + raise TaskImportBatchError("task_import_source_custody_invalid", 409) + return selected + + async def _original_response(self, batch: TaskImportBatch) -> TaskImportBatchResponse: + """Recover immutable creation facts; mutable Task state is not replay input.""" + response = TaskImportBatchResponse.model_validate(batch.response) + if (str(response.batch_id), str(response.project_id), str(response.source_id), response.sha256, + response.byte_count, response.row_count, response.schema_version, response.mapping_version) != ( + batch.id, batch.project_id, batch.source_id, batch.sha256, batch.byte_count, batch.row_count, + batch.schema_version, batch.mapping_version, + ): + raise TaskImportBatchError("task_import_batch_custody_invalid", 409) + rows = (await self._session.execute(select(TaskImportBatchMember, TaskCommandReceipt).join( + TaskCommandReceipt, TaskCommandReceipt.id == TaskImportBatchMember.task_command_receipt_id, + ).where(TaskImportBatchMember.batch_id == batch.id).order_by(TaskImportBatchMember.row_index))).all() + if len(rows) != batch.row_count: + raise TaskImportBatchError("task_import_batch_custody_invalid", 409) + for index, (member, receipt) in enumerate(rows): + original = response.tasks[index] + instructions = {field: getattr(original, field) for field in TaskImportRow.model_fields} + if (member.row_index != index or member.project_id != batch.project_id or member.task_id != original.id + or member.external_task_id != original.external_task_id + or member.row_digest != canonical_json_hash(instructions) + or member.response != original.model_dump(mode="json") + or receipt.response != member.response or receipt.status != "committed" + or receipt.action_id != "project.task.create" or receipt.task_id != member.task_id + or receipt.actor_profile_id != batch.actor_profile_id + or receipt.idempotency_key != member.create_idempotency_key + or original.created_by != batch.actor_profile_id): + raise TaskImportBatchError("task_import_batch_custody_invalid", 409) + return response + + async def _stage_rows( + self, batch: TaskImportBatch, parsed: ParsedTaskImport, + prepared: list[tuple[int, TaskCreationPreparation]], + ) -> TaskImportBatchResponse: + """Authorize every CREATE then stage sorted writes in the same caller root.""" + decisions = [(index, creation, await self._tasks.authorize_creation(creation)) for index, creation in prepared] + existing = set(await self._session.scalars(select(WorkstreamTask.external_task_id).where( + WorkstreamTask.project_id == batch.project_id, + WorkstreamTask.external_task_id.in_([row.external_task_id for row in parsed.document.tasks]), + ))) + conflicts = tuple(index for index, row in enumerate(parsed.document.tasks) if row.external_task_id in existing) + if conflicts: + raise TaskImportBatchError("task_import_external_id_conflict", 409, conflicts) + originals = {} + for index, creation, decision in decisions: + try: + original = await self._tasks.stage_creation(creation, decision) + except TaskReplayConflict as exc: + if exc.code == "external_task_id_conflict": + raise TaskImportBatchError("task_import_external_id_conflict", 409, (index,)) from exc + raise + originals[index] = original + self._session.add(TaskImportBatchMember( + id=str(new_record_id()), batch_id=batch.id, project_id=batch.project_id, task_id=original.id, + row_index=index, external_task_id=original.external_task_id, + row_digest=canonical_json_hash(parsed.document.tasks[index].model_dump(mode="json")), + create_idempotency_key=creation.facts.idempotency_key, task_command_receipt_id=creation.receipt.id, + authorization_decision_id=str(decision.decision_id), response=original.model_dump(mode="json"), + )) + return TaskImportBatchResponse( + batch_id=UUID(batch.id), project_id=UUID(batch.project_id), source_id=UUID(batch.source_id), + sha256=batch.sha256, byte_count=batch.byte_count, schema_version=batch.schema_version, + mapping_version=batch.mapping_version, row_count=batch.row_count, created_at=batch.created_at, + tasks=tuple(originals[index] for index in range(batch.row_count)), + ) + + async def import_source(self, project_id: UUID, source_id: UUID, *, idempotency_key: UUID) -> TaskImportBatchResponse: + """Create all rows atomically or freshly authorize immutable exact-file recovery.""" + facts, recoverable = await self._preflight(project_id, source_id, idempotency_key) + parsed = None if recoverable else await self._read_first_import(facts) + digest = self._request_digest(project_id, source_id) + async with self._session.begin(): + command = await self._reserve_command(facts, idempotency_key, digest) + # Namespace custody may now point at the original selector from a competing commit. + facts = await self._source_binding.source_commitment(UUID(command.project_id), UUID(command.source_id)) + batch = await self._reserve_batch(facts, parsed) + prepared = (await self._prepare_rows(batch, facts, parsed)) if batch.status == "pending" else [] + selected = await self._prepare_sources(batch, command) + await self._source_binding.authorize_binding(selected) + decision_id = await self._authorization.authorize( + TaskImportBatchAction.IMPORT, self._facts(batch, selected, idempotency_key, digest), + ) + if command.request_digest != digest: + raise TaskImportBatchError("task_import_idempotency_mismatch", 409) + if command.status == "committed": + original = await self._original_response(batch) + if command.batch_id != batch.id or command.response != original.model_dump(mode="json"): + raise TaskImportBatchError("task_import_batch_custody_invalid", 409) + return original + if batch.status == "committed": + original = await self._original_response(batch) + else: + original = await self._stage_rows(batch, parsed, prepared) + _stage_binding(batch, selected) + batch.authorization_decision_id, batch.status = str(decision_id), "committed" + batch.response, batch.committed_at = original.model_dump(mode="json"), datetime.now(UTC) + _stage_binding(command, selected) + command.batch_id, command.authorization_decision_id, command.status = batch.id, str(decision_id), "committed" + command.response, command.committed_at = original.model_dump(mode="json"), datetime.now(UTC) + await self._session.flush() + return original + + async def status(self, project_id: UUID, batch_id: UUID, *, request_id: UUID) -> TaskImportBatchStatus: + """Read only native ordered members, preserving original and current states separately.""" + async with self._session.begin(): + batch = await self._session.scalar(select(TaskImportBatch).where( + TaskImportBatch.id == str(batch_id), TaskImportBatch.project_id == str(project_id), + TaskImportBatch.status == "committed", + ).execution_options(populate_existing=True)) + if batch is None: + raise TaskImportBatchError("task_import_batch_not_found", 404) + binding = await self._source_binding.prepare_binding(project_id, UUID(batch.source_id), _binding(batch)) + await self._source_binding.authorize_binding(binding) + await self._authorization.authorize(TaskImportBatchAction.READ, self._facts( + batch, binding, request_id, canonical_json_hash({"project_id": str(project_id), "batch_id": str(batch_id)}), + )) + original = await self._original_response(batch) + rows = (await self._session.execute(select(TaskImportBatchMember.row_index, WorkstreamTask.id, WorkstreamTask.status) + .join(WorkstreamTask, (WorkstreamTask.id == TaskImportBatchMember.task_id) + & (WorkstreamTask.project_id == TaskImportBatchMember.project_id)) + .where(TaskImportBatchMember.batch_id == batch.id).order_by(TaskImportBatchMember.row_index))).all() + return TaskImportBatchStatus(creation=original, current_tasks=tuple( + TaskImportBatchCurrentTask(row_index=index, task_id=UUID(task_id), status=status) + for index, task_id, status in rows + )) diff --git a/backend/tests/tasks/test_task_import_batch_contract.py b/backend/tests/tasks/test_task_import_batch_contract.py new file mode 100644 index 000000000..808dbfc5c --- /dev/null +++ b/backend/tests/tasks/test_task_import_batch_contract.py @@ -0,0 +1,71 @@ +"""Instruction mapping and closed original/current batch projections.""" + +from datetime import UTC, datetime +from uuid import uuid4 + +import pytest +from pydantic import ValidationError + +from app.core.identifiers import new_record_id +from app.modules.artifacts.api.task_import_source import TaskImportSourceAuthorityFacts +from app.modules.tasks.api.task_import import TaskImportRow +from app.modules.tasks.schemas import ( + TaskCreate, TaskImportBatchCurrentTask, TaskImportBatchRequest, TaskImportBatchResponse, + TaskImportBatchStatus, TaskResponse, +) +from app.modules.tasks.task_import_batches import imported_task_payload + + +def _source(): + return TaskImportSourceAuthorityFacts(new_record_id(), new_record_id(), new_record_id(), + "sha256:" + "a" * 64, 100, "sha256:" + "b" * 64, uuid4()) + + +def _original(source, batch_id, external_id): + values = {field: None for field in TaskResponse.model_fields} + values.update(imported_task_payload( + TaskImportRow(external_task_id=external_id, title="Instructions", description="Actual work"), source, batch_id, + ).model_dump()) + values.update(id=str(new_record_id()), project_id=str(source.project_id), status="draft", + created_by=str(source.actor_profile_id), created_at=datetime.now(UTC), updated_at=datetime.now(UTC)) + return TaskResponse.model_validate(values) + + +def test_mapping_preserves_instructions_and_stamps_server_only_json_custody(): + source, batch_id = _source(), new_record_id() + row = TaskImportRow(external_task_id="Case-Sensitive", title="Instructions", description="Exact work", + difficulty="x" * 80, skill_tags=["python"], estimated_time_minutes=30) + mapped = imported_task_payload(row, source, batch_id) + assert {field: getattr(mapped, field) for field in TaskImportRow.model_fields} == row.model_dump() + assert (mapped.source_type, mapped.source_ref, mapped.source_payload_hash, mapped.import_batch_id) == ( + "json_import", f"task-import-source:{source.source_id}", source.sha256, str(batch_id), + ) + assert mapped.deadline_at is None + with pytest.raises(ValidationError): + TaskCreate.model_validate(mapped.model_dump()) + with pytest.raises(ValidationError): + TaskImportBatchRequest.model_validate({"source_id": source.source_id, "source_type": "manual"}) + with pytest.raises(ValidationError): + TaskImportRow.model_validate(row.model_dump() | {"import_batch_id": str(batch_id)}) + + +def test_projection_separates_immutable_creation_from_current_member_states(): + source, batch_id = _source(), new_record_id() + originals = (_original(source, batch_id, "one"), _original(source, batch_id, "two")) + creation = TaskImportBatchResponse( + batch_id=batch_id, project_id=source.project_id, source_id=source.source_id, + sha256=source.sha256, byte_count=source.byte_count, row_count=2, created_at=datetime.now(UTC), + schema_version="workstream.task_import.v1", mapping_version="workstream.task_import.draft_mapping.v1", + tasks=originals, + ) + current = tuple(TaskImportBatchCurrentTask(task_id=original.id, row_index=index, status="ready") + for index, original in enumerate(originals)) + status = TaskImportBatchStatus(creation=creation, current_tasks=current) + assert [row.status for row in status.current_tasks] == ["ready", "ready"] + assert [row.status for row in status.creation.tasks] == ["draft", "draft"] + with pytest.raises(ValidationError): + TaskImportBatchStatus(creation=creation, current_tasks=tuple(reversed(current))) + with pytest.raises(ValidationError): + TaskImportBatchResponse.model_validate(creation.model_dump() | {"project_id": new_record_id()}) + with pytest.raises(ValidationError): + TaskImportBatchResponse.model_validate(creation.model_dump() | {"tasks": (originals[0], originals[0])}) From 37d8705d0129189be7d076262f43417f693626b4 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 11:53:02 +0100 Subject: [PATCH 017/283] feat(tasks): wire atomic import composition and native schema handoff --- .../pilot02-atomic-json-draft-import.md | 96 +++++++++++++++---- backend/app/adapters/artifacts/__init__.py | 14 +-- backend/app/adapters/tasks/__init__.py | 15 +++ backend/app/api/deps/authorization.py | 62 ++++++++++++ .../artifacts/api/task_import_source.py | 56 +---------- .../modules/artifacts/task_import_sources.py | 28 ++++-- .../authorization/domain/audit_targets.py | 5 +- backend/app/modules/tasks/api/task_import.py | 76 ++++++++++++++- .../app/modules/tasks/authorized_commands.py | 11 ++- backend/app/modules/tasks/models.py | 9 ++ backend/app/modules/tasks/router.py | 56 ++++++++++- backend/app/modules/tasks/schemas.py | 1 + .../app/modules/tasks/task_import_batches.py | 58 ++++++----- .../tests/authorization/catalogue_fixtures.py | 4 + .../task_authority/test_audit_contract.py | 13 ++- .../tasks/test_task_import_batch_contract.py | 10 +- .../authorization_activation_custody.md | 9 ++ docs/spec_authorization_service.md | 9 ++ docs/spec_chunk_4_task_queue_assignment.md | 43 +++++++-- .../contracts/authorization_context_get.json | 6 +- 20 files changed, 445 insertions(+), 136 deletions(-) diff --git a/.commitrail/changes/pilot02-atomic-json-draft-import.md b/.commitrail/changes/pilot02-atomic-json-draft-import.md index 01949a939..3d1ce703a 100644 --- a/.commitrail/changes/pilot02-atomic-json-draft-import.md +++ b/.commitrail/changes/pilot02-atomic-json-draft-import.md @@ -14,9 +14,8 @@ Issue #489 remains open after this chunk; batch transitions and CLI remain. ## Current behavior -The inspected integration is `0524e56b6aa7576f748d645f672d42ce069141af`, -based on main `7e499849ab871f445012cf9e343ff97fbb95d62d`. PR520 remains -the separate source prerequisite. Its parser in `tasks/api/task_import.py` +The implementation incorporates merged source prerequisite PR520 on main +`d3c50e1500beffea684fe881cd0a2b3431e6ccb9`. Its parser in `tasks/api/task_import.py` accepts one strict UTF-8 JSON document with 1..500 rows, required case-sensitive external IDs, indexed duplicate errors and an 8 MiB ceiling. ART's `api/task_import_source.py` and `task_import_sources.py` own project-bound @@ -38,9 +37,12 @@ it is not an authoritative native-UUID batch relationship. `authorized_commands.py`, `command_replay.py`, `models.py`, `schemas.py`, `repository.py` and `router.py`: typed import/status contracts, immutable batch receipt and row membership, server provenance and reuse of canonical creation. -- ART: `api/task_import_source.py` and `task_import_sources.py`: the smallest - typed preparation/binding port over the existing verified source. No second - provider path, storage lifecycle or inspector. +- ART: `task_import_sources.py` implements TASK’s bounded source-consumer + preparation/binding port over the existing verified source. ART already + depends on TASK’s canonical parser; the consumer contract remains in TASK + `api/task_import.py` to preserve the acyclic owner graph. Existing ART public + source/AUTH contracts remain intact. No second provider path, storage lifecycle + or inspector. - Composition: existing `adapters/tasks/__init__.py`, `adapters/artifacts/__init__.py`, `adapters/auth/__init__.py` and `api/deps/authorization.py`: explicit owner ports and one transaction root. @@ -48,7 +50,8 @@ it is not an authoritative native-UUID batch relationship. action/permission/resource classifications in the existing TASK authority owner; reuse covered Project Manager grant evaluation and canonical denials. - Focused TASK/ART/AUTH public-contract and native PostgreSQL/MinIO tests; - affected ownership/lane/inventory expectations; current TASK/ART/AUTH specs, + affected ownership/lane/inventory expectations and the selected MCP + `authorization_context_get` snapshot for additive ActionId parity; current TASK/ART/AUTH specs, README and roadmap claims for this chunk only. - AUDIT: the existing closed TaskCreated payload source-type classification in `audit/schemas.py`; preserve every existing type and canonical event owner. @@ -197,9 +200,10 @@ No public route or per-row command transaction is invoked from the batch owner. The proposed native tables are `task_import_batches`, `task_import_batch_members` and `task_import_batch_command_receipts`: -- Batch reservation has UUIDv7 ID, project UUID, original source UUID and its +- Batch reservation has UUIDv7 ID, project UUID, original command receipt UUID + (deferred circular closure), original source UUID and its operation identity, exact source SHA/count, document schema and parser/mapping - identity, row count, original actor/link, current batch creation decision and + identity, row count, retained optional metadata label, original actor/link, current batch creation decision and original immutable ordered result. Project/SHA/count identifies one original batch. A reservation may be incomplete only inside its caller root; a deferred closure check rejects any committed pending header, missing or extra member, @@ -214,7 +218,7 @@ The proposed native tables are `task_import_batches`, and batch/project composite FKs close custody; unique Task membership, batch/index and project/external-ID identities reject substitutions. Existing arbitrary `import_batch_id` metadata never supplies these relationships. -- Batch command receipt has UUIDv7 ID, actor, closed import action, UUID key, +- Batch command receipt has UUIDv7 ID, current actor/link, closed import action, UUID key, exact request digest over project/selected-source IDs, selected verified ancestry, original batch ID and closed immutable ordered result. Actor/action/ key is unique. A changed selector conflicts after fresh authority; new-key @@ -233,6 +237,66 @@ owned reset helper, without leaving them disabled for product writes. The sole m constraints, deferred closure and exact owner representations before DDL work; these proposed names/columns are planning, not installed schema. +### Concrete non-DDL schema handoff + +The ORM representations now declare these exact owner relationships for the +sole migration author’s affected review. They do not install any table or guard: + +- `task_import_batches`: native string-mapped UUIDv7 `id`, project and original + source UUIDs, unique original `creation_command_receipt_id`, exact SHA/count/ + JSON media, document/mapping versions, normalized-document `manifest_digest`, + retained nullable `metadata_label`, row count, original actor/link, original + batch ALLOW decision, pending/committed shape, original response and timestamps. + Project/SHA/count and ID/project are unique. The original command receipt FK + is deferred, closing the intentional header/receipt cycle at root commit. +- Both batch and retry receipt store native put-attempt/content/replica IDs, + verification job/generation/receipt, original source operation identity and + exactly one operation/observation acknowledgement UUID. Pending ancestry may + be NULL only inside the creating root; committed generation is explicitly + non-NULL and positive. Source/project/SHA/count/media uses the existing ART + composite custody FK, deferred until commit. Every other ART UUID FK uses its + owner’s string-mapped native UUID representation and is deferred. +- `task_import_batch_members`: native UUIDv7 ID, batch/project/Task UUIDs, + original index/external ID/normalized row digest, server-generated CREATE key, + original `TaskCommandReceipt` UUID (its existing Python UUID representation), + actual CREATE decision UUID, exact original Task response and timestamp. + Unique Task, batch/index, project/external-ID and CREATE receipt prevent + duplicated or substituted membership; Task/project and batch/project FKs + are deferred and bind actual native owners. +- `task_import_batch_command_receipts`: native UUIDv7 ID, current actor/link, + exact action `project.task.import`, UUID key, immutable selector request digest, + selected source/project/SHA/count/media and complete ART ancestry, original + batch ID, this invocation’s batch ALLOW decision, pending/committed result and + timestamps. Actor/action/key is unique; batch/project and actor/link custody + is deferred. New-key exact-file recovery creates only this receipt and fresh + authority evidence, with the original header/members/result unchanged. +- The header’s complete normalized-document digest is reconstructible from its + retained metadata label and ordered original Task instruction fields. It must + equal the original parsed document; native closure must also prove the exact + member count/indexes, original CREATE receipt/decision/action/actor/key/result, + truthful `json_import`/source-ref/hash/batch metadata and all ART ancestry. + Retry closure binds its fresh actor/link/decision and selected native source + while returning the original immutable ordered result. A pending header or + receipt cannot survive commit. All three tables reject DELETE/TRUNCATE and + committed UPDATE; only exact staged completion is admitted. +- Native TASK changes remain the approved global case-sensitive project/non-NULL + external-ID uniqueness with retained duplicate diagnostic preflight, difficulty + width 80 preserving values, and additive current lifecycle `json_import` + evidence. Current sensitive-audit constraints/guards must admit only the exact + batch resource/actions. Historical baseline SQL remains unchanged. Canonical + reset and graph/fingerprint/UUID inventories must retain every merged owner. + +Reservation order is retry namespace, exact-file header, all canonical Task +CREATE reservations, explicit sorted SOURCE KEY SHARE, then fresh batch/source/ +row AUTH and sorted external-ID writes. New batch FKs are deferred to avoid +implicit actor/source locks before this preparation. A separate provider-free +source read preflight authorizes before preparation outcomes are observable; +it commits no Task or batch effect. Each creation preparation is bound to its +original active SQLAlchemy root, preventing reuse after rollback/commit. The +sole author allocates a successor only after the lead names the actual merged +predecessor; source `0031` is merged, PR534 is reconciling to `0032`, and this +chunk reserves no ordinal. + ### Scope decisions and transaction preparation The lead confirmed the following issue489 boundaries during preparation: @@ -381,7 +445,7 @@ never silently reinterprets retained rows under a later mapping. | Claim | Command or proof | Result | Remaining uncertainty | |---|---|---|---| | Canonical creation participant | Exact `59d47a6c` isolated native execution of five retained CREATE, denial, rollback and receipt controls | 5 passed in 69.02 seconds; schema `0031_task_import_source`; owned database/role/MinIO cleanup complete | Proves preservation of normal creation; no atomic batch success claim | -| Current owners and concrete gap | Inspect source port/parser, TASK create/replay/models and Issue 489 | Canonical caller-root phases, closed batch DTOs, model representations and ART immutable-binding participant are implemented; batch operation remains unassembled | New table constraints and guards require sole-author DDL and native proof | +| Current owners and concrete gap | Inspect source port/parser, TASK create/replay/models and Issue 489 | Canonical caller-root phases, closed batch DTOs, model representations, ART immutable-binding participant and batch/root/AUTH composition are implemented | New table constraints and guards require sole-author DDL and native proof | | Public import and atomic effects | Planned isolated runner: `pytest -q tests/tasks/test_task_import_batches.py` with real PostgreSQL 16/MinIO | Not run; tests not authored | All positive/negative/concurrency cases above must pass | | Schema, guards and complete integration | Sole-author native graph/reset/UUID proof, affected guards, complete hosted lanes and aggregate | Not run for this chunk | Exact frozen candidate, actual merge tree and cleanup required | @@ -398,14 +462,14 @@ not prove installed custody or a public import result. ## Reconciliation - Current-source reconciliation: this preparation branch incorporates source - prerequisite `0524e56b6aa7576f748d645f672d42ce069141af` and main `7e499849`, + prerequisite PR520 and merged main `d3c50e15`, retaining its ten-lane CI, hidden materialization/completion/failure/feedback owners and CLI approval/correction contracts. Before implementation, only this planning record differed from the source candidate. Canonical Task creation now shares - caller-root phases with its normal public wrapper; atomic batch creation and - the installed native schema are not yet implemented or proven. Model/API - representations and provider-free ART binding validation are in progress; - no batch route is exposed. No migration is + caller-root phases with its normal public wrapper; atomic batch creation + still lacks installed schema/native proof. Model/API representations, + provider-free ART binding validation and public route composition are coded + on this isolated branch; no delivered import capability is claimed. No migration is authored in this worktree. - Next usable boundary: review the exact batch/membership/receipt schema and owner preparation/replay graph, then coordinate the sole-author migration and diff --git a/backend/app/adapters/artifacts/__init__.py b/backend/app/adapters/artifacts/__init__.py index f12ed22b6..aa5634be5 100644 --- a/backend/app/adapters/artifacts/__init__.py +++ b/backend/app/adapters/artifacts/__init__.py @@ -624,18 +624,20 @@ async def get_task_import_source_commands( session: Annotated[AsyncSession, Depends(get_db_session)], context: Annotated[object, Depends(get_artifact_authorization_context)], ) -> TaskImportSourceCommandPort: - """Compose exact source commands in ART's registered owner root.""" + """Capture actor facts, then compose the same source owner for public commands.""" + await session.rollback() + return task_import_source_commands(session, settings=request.app.state.settings, context=context) + + +def task_import_source_commands(session: AsyncSession, *, settings, context): + """Compose source reads/bindings and lazy provider runtime through one owner path.""" from app.adapters.auth import task_import_source_authorization from app.modules.artifacts.service import ( ArtifactAdmissionService, ArtifactStorageOrchestrator, artifact_storage_namespace_spec, ) from app.modules.artifacts.task_import_sources import ArtifactTaskImportSourceCommands, TaskImportSourceRuntime - settings = request.app.state.settings - request_id, correlation_id = (UUID(value) for value in request_ids(request)) - # Identity provisioning is committed by its owner. As in TASK commands, - # discard the resolver's read-only refresh before ART owns each root. - await session.rollback() + request_id, correlation_id = context.request_id, context.correlation_id @asynccontextmanager async def runtime(): diff --git a/backend/app/adapters/tasks/__init__.py b/backend/app/adapters/tasks/__init__.py index 02e65750a..119c23581 100644 --- a/backend/app/adapters/tasks/__init__.py +++ b/backend/app/adapters/tasks/__init__.py @@ -103,6 +103,21 @@ def task_commands( ) +def task_import_batch_commands( + session: AsyncSession, *, authorization, audit: TaskTransitionAuditPort, + actor_profile_id: UUID, identity_link_id: UUID, settings: Settings, source, +): + """Compose the batch root from canonical TASK commands and one ART source owner.""" + from app.modules.tasks.task_import_batches import TaskImportBatchCommands + return TaskImportBatchCommands( + session, actor_profile_id=actor_profile_id, identity_link_id=identity_link_id, + authorization=authorization, + tasks=task_commands(session, authorization=authorization, audit=audit, + actor_profile_id=actor_profile_id, settings=settings), + source=source, + ) + + def contributor_task_repository(session: AsyncSession) -> TaskRepository: """Compose contributor reads with CON's bounded locked-terms public port.""" from app.adapters.contributions import locked_compensation_terms_port diff --git a/backend/app/api/deps/authorization.py b/backend/app/api/deps/authorization.py index 36eee14ad..9fd13e374 100644 --- a/backend/app/api/deps/authorization.py +++ b/backend/app/api/deps/authorization.py @@ -114,6 +114,68 @@ async def get_authorization_actor( return await resolve_authorization_actor(request, result, session, rate_control) +async def get_task_import_batch_commands( + request: Request, + resolved: Annotated[ResolvedActor, Depends(get_authorization_actor)], + session: Annotated[AsyncSession, Depends(get_db_session)], +) -> AsyncIterator[object]: + """Compose one root and restage denials only through their actual issuing owner.""" + from app.adapters.artifacts import task_import_source_commands + from app.adapters.audit import task_transition_audit + from app.adapters.auth import task_authorization + from app.adapters.tasks import task_import_batch_commands + from app.modules.artifacts.api.task_import_source import TaskImportSourceAuthorityDenied, TaskImportSourceError + from app.modules.tasks.api import TaskAuthorityDenied + from app.modules.tasks.api.task_import import TaskImportBatchAuthorityDenied + + request_id, correlation_id = (UUID(value) for value in request_ids(request)) + context = _authorization_context(resolved, request_id, correlation_id) + await session.rollback() + authority = task_authorization(session, context) + source = task_import_source_commands(session, settings=request.app.state.settings, context=context) + try: + yield task_import_batch_commands( + session, settings=request.app.state.settings, authorization=authority, + audit=task_transition_audit(session), actor_profile_id=context.actor_profile_id, + identity_link_id=context.identity_link_id, source=source, + ) + except (TaskAuthorityDenied, TaskImportBatchAuthorityDenied, TaskImportSourceAuthorityDenied) as exc: + await session.rollback() + try: + if isinstance(exc, TaskImportSourceAuthorityDenied): + await source.restage_denial(exc) + else: + await authority.restage_denial(exc) + await session.commit() + except (AuthorizationEvidenceUnavailable, SQLAlchemyError) as evidence_error: + await session.rollback() + raise StructuredHTTPException( + status_code=503, detail="Task import authority unavailable", error_code="task_import_authority_unavailable", + error_message="Task import authority unavailable", retryable=True, + ) from evidence_error + concealed = request.method == "GET" + raise StructuredHTTPException( + status_code=404 if concealed else 403, + detail="Task import batch not found" if concealed else "Task import authority denied", + error_code="task_import_batch_not_found" if concealed else "permission_not_granted", + error_message="Task import batch not found" if concealed else "Task import authority denied", + ) from exc + except TaskImportSourceError as exc: + raise StructuredHTTPException( + status_code=exc.status_code, detail=exc.code, error_code=exc.code, + error_message=exc.code.replace("_", " "), retryable=exc.status_code == 503, + ) from exc + except (AuthorizationEvidenceUnavailable, SQLAlchemyError) as exc: + await session.rollback() + raise StructuredHTTPException( + status_code=503, detail="Task import authority unavailable", error_code="task_import_authority_unavailable", + error_message="Task import authority unavailable", retryable=True, + ) from exc + finally: + if session.in_transaction(): + await session.rollback() + + async def get_task_commands( request: Request, resolved: Annotated[ResolvedActor, Depends(get_authorization_actor)], diff --git a/backend/app/modules/artifacts/api/task_import_source.py b/backend/app/modules/artifacts/api/task_import_source.py index eb4e87608..44be16689 100644 --- a/backend/app/modules/artifacts/api/task_import_source.py +++ b/backend/app/modules/artifacts/api/task_import_source.py @@ -8,7 +8,7 @@ from typing import Literal, Protocol from uuid import UUID -from pydantic import BaseModel, ConfigDict, Field, model_validator +from pydantic import BaseModel, ConfigDict, Field class TaskImportSourceError(RuntimeError): """A closed source outcome mapped to a concealed or explicit HTTP response.""" @@ -87,60 +87,6 @@ class VerifiedTaskImportSourceRead: stream: AsyncIterator[bytes] -class VerifiedTaskImportSourceBinding(BaseModel): - """Immutable native byte ancestry; the ART participant revalidates every reference.""" - - model_config = ConfigDict(extra="forbid", strict=True, frozen=True) - - source_id: UUID - project_id: UUID - sha256: str = Field(pattern=r"^sha256:[0-9a-f]{64}$") - byte_count: int = Field(ge=1, le=8388608) - operation_identity: str = Field(pattern=r"^sha256:[0-9a-f]{64}$") - put_attempt_id: UUID - content_id: UUID - replica_id: UUID - verification_job_id: UUID - verification_generation: int = Field(ge=1) - verification_receipt_id: UUID - operation_receipt_id: UUID | None - observation_receipt_id: UUID | None - - @model_validator(mode="after") - def exact_acknowledgement(self): - """Require precisely one retained operation or observation acknowledgement.""" - if (self.operation_receipt_id is None) == (self.observation_receipt_id is None): - raise ValueError("verified source requires exactly one acknowledgement") - return self - - -class TaskImportSourceBindingPort(Protocol): - """Prepare immutable source custody before caller-root AUTH and authorize it freshly.""" - - async def source_commitment(self, project_id: UUID, source_id: UUID) -> TaskImportSourceAuthorityFacts: - """Read native immutable declaration facts without claiming or granting authority.""" - ... - - async def authorize_commitment(self, facts: TaskImportSourceAuthorityFacts) -> UUID: - """Freshly authorize actual source facts before exposing preparation outcomes.""" - ... - - async def prepare_binding( - self, project_id: UUID, source_id: UUID, - expected: VerifiedTaskImportSourceBinding | None = None, - ) -> VerifiedTaskImportSourceBinding: - """Retain SOURCE KEY SHARE and validate actual receipts without provider access.""" - ... - - async def authorize_binding(self, binding: VerifiedTaskImportSourceBinding) -> UUID: - """Revalidate prepared custody and consume the current caller's exact source READ.""" - ... - - async def restage_denial(self, error: TaskImportSourceAuthorityDenied) -> None: - """Retain a caller-root denial through the actual issuing source authority.""" - ... - - class TaskImportSourceCommandPort(Protocol): """Manage source custody only; these operations never create or transition Tasks.""" diff --git a/backend/app/modules/artifacts/task_import_sources.py b/backend/app/modules/artifacts/task_import_sources.py index ab87e7e30..6c14a064a 100644 --- a/backend/app/modules/artifacts/task_import_sources.py +++ b/backend/app/modules/artifacts/task_import_sources.py @@ -16,7 +16,7 @@ TaskImportSourceError, TaskImportSourceAction, TaskImportSourceAuthorityDenied, TaskImportSourceAuthorityFacts, TaskImportSourceAuthorizationPort, TaskImportSourceDeclare, TaskImportSourceResponse, - VerifiedTaskImportSourceRead, VerifiedTaskImportSourceBinding, + VerifiedTaskImportSourceRead, ) from app.modules.artifacts.models import ( ArtifactContent, ArtifactOperationReceipt, ArtifactPutAttempt, ArtifactPutObservationReceipt, @@ -30,7 +30,9 @@ ArtifactAdmissionError, ArtifactAdmissionConflictError, ArtifactAdmissionCapacityError, validate_artifact_replica_execution_namespace, ) -from app.modules.tasks.api.task_import import parse_task_import, TASK_IMPORT_MAXIMUM_BYTES +from app.modules.tasks.api.task_import import ( + parse_task_import, TASK_IMPORT_MAXIMUM_BYTES, TaskImportSourceCommitment, VerifiedTaskImportSourceBinding, +) class _TaskImportInspector: @@ -252,10 +254,13 @@ async def _verified_ancestry( ArtifactPutObservationReceipt.observed_byte_count == source.byte_count, ArtifactPutObservationReceipt.expected_byte_count == source.byte_count, ) - if expected is None: + if require_operational: query = query.where(ArtifactPutObservationReceipt.execution_generation == attempt.execution_generation) - else: + elif expected is not None: query = query.where(ArtifactPutObservationReceipt.id == str(expected.observation_receipt_id)) + else: + query = query.order_by(ArtifactPutObservationReceipt.execution_generation.desc(), + ArtifactPutObservationReceipt.id.desc()).limit(1) acknowledged = await self._session.scalar(query) observation_id = acknowledged if acknowledged is None: @@ -273,7 +278,7 @@ async def _verified_ancestry( raise TaskImportSourceError("task_import_source_custody_invalid", 409) return binding, replica - async def source_commitment(self, project_id: UUID, source_id: UUID) -> TaskImportSourceAuthorityFacts: + async def source_commitment(self, project_id: UUID, source_id: UUID) -> TaskImportSourceCommitment: """Read the actual declaration for preparation; this supplies no authority.""" if not self._session.in_transaction(): raise RuntimeError("source commitment requires a caller transaction") @@ -282,9 +287,14 @@ async def source_commitment(self, project_id: UUID, source_id: UUID) -> TaskImpo ).execution_options(populate_existing=True)) if source is None: raise TaskImportSourceError("task_import_source_not_found", 404) - return self._facts(source) + return self._commitment(source) - async def authorize_commitment(self, facts: TaskImportSourceAuthorityFacts) -> UUID: + @staticmethod + def _commitment(source: ArtifactTaskImportSource) -> TaskImportSourceCommitment: + return TaskImportSourceCommitment(UUID(source.id), UUID(source.project_id), source.sha256, + source.byte_count, source.operation_identity) + + async def authorize_commitment(self, facts: TaskImportSourceCommitment) -> UUID: """Fence the actual declaration and authorize a provider-free preparation read.""" if not self._session.in_transaction(): raise RuntimeError("source authorization requires a caller transaction") @@ -294,10 +304,10 @@ async def authorize_commitment(self, facts: TaskImportSourceAuthorityFacts) -> U ).with_for_update(read=True, key_share=True).execution_options(populate_existing=True)) if source is None: raise TaskImportSourceError("task_import_source_not_found", 404) - current = self._facts(source) + current = self._commitment(source) if current != facts: raise TaskImportSourceError("task_import_source_custody_invalid", 409) - return await self._authorization.authorize(TaskImportSourceAction.READ, current) + return await self._authorization.authorize(TaskImportSourceAction.READ, self._facts(source)) async def prepare_binding( self, project_id: UUID, source_id: UUID, diff --git a/backend/app/modules/authorization/domain/audit_targets.py b/backend/app/modules/authorization/domain/audit_targets.py index 48131809a..cafc5d0da 100644 --- a/backend/app/modules/authorization/domain/audit_targets.py +++ b/backend/app/modules/authorization/domain/audit_targets.py @@ -12,7 +12,7 @@ GUIDE_BOUND_PROJECT_MANAGER_ACTIONS, SUBMISSION_POLICY_MUTATIONS, ) from app.modules.authorization.domain.project_create import ProjectCreateResourceContext -from app.modules.authorization.domain.task_authority import TaskAuthorityResourceContext +from app.modules.authorization.domain.task_authority import TaskAuthorityResourceContext, TaskImportBatchResourceContext from app.modules.authorization.domain.task_queues import QueueReadResourceContext from app.modules.authorization.domain.submission_history import HistoryReadResourceContext @@ -50,6 +50,9 @@ def project_authority_audit_target( if type(resource) is ReviewLifecycleActivationContract: return None, resource.resource_type, str(resource.resource_id), "joint_lifecycle_control", str(resource.resource_id) + if type(resource) is TaskImportBatchResourceContext: + return (str(resource.scope_project_id), resource.resource_type, str(resource.resource_id), + resource.resource_type, str(resource.resource_id)) if type(resource) is ContributionPolicyMutationScopeDenialResourceContext: project_id = str(resource.scope_project_id) if resource.project_exists: diff --git a/backend/app/modules/tasks/api/task_import.py b/backend/app/modules/tasks/api/task_import.py index 0abe85038..edf720e5a 100644 --- a/backend/app/modules/tasks/api/task_import.py +++ b/backend/app/modules/tasks/api/task_import.py @@ -3,12 +3,14 @@ import hashlib import json import unicodedata +from collections.abc import AsyncIterator +from contextlib import AbstractAsyncContextManager from dataclasses import dataclass from enum import StrEnum from typing import Annotated, Literal, Protocol from uuid import UUID -from pydantic import BaseModel, ConfigDict, Field, ValidationError, field_validator +from pydantic import BaseModel, ConfigDict, Field, ValidationError, field_validator, model_validator from pydantic_core import PydanticCustomError @@ -56,6 +58,78 @@ async def restage_denial(self, error: TaskImportBatchAuthorityDenied) -> None: ... +@dataclass(frozen=True, slots=True) +class TaskImportSourceCommitment: + """Actual native declaration selected by ART; it supplies no authority.""" + + source_id: UUID + project_id: UUID + sha256: str + byte_count: int + operation_identity: str + + +class VerifiedTaskImportSourceBinding(BaseModel): + """Immutable native byte ancestry; the ART participant revalidates every reference.""" + + model_config = ConfigDict(extra="forbid", strict=True, frozen=True) + + source_id: UUID + project_id: UUID + sha256: str = Field(pattern=r"^sha256:[0-9a-f]{64}$") + byte_count: int = Field(ge=1, le=8388608) + operation_identity: str = Field(pattern=r"^sha256:[0-9a-f]{64}$") + put_attempt_id: UUID + content_id: UUID + replica_id: UUID + verification_job_id: UUID + verification_generation: int = Field(ge=1) + verification_receipt_id: UUID + operation_receipt_id: UUID | None + observation_receipt_id: UUID | None + + @model_validator(mode="after") + def exact_acknowledgement(self): + """Require precisely one retained operation or observation acknowledgement.""" + if (self.operation_receipt_id is None) == (self.observation_receipt_id is None): + raise ValueError("verified source requires exactly one acknowledgement") + return self + + +class TaskImportSourceByteRead(Protocol): + """A bounded, already-verified byte stream scoped to the owning read context.""" + + @property + def stream(self) -> AsyncIterator[bytes]: ... + + +class TaskImportSourceConsumerPort(Protocol): + """TASK's required source capability, implemented only by the existing ART owner.""" + + async def source_commitment(self, project_id: UUID, source_id: UUID) -> TaskImportSourceCommitment: + """Read actual immutable preparation facts without granting authority.""" + ... + + async def authorize_commitment(self, facts: TaskImportSourceCommitment) -> UUID: + """Check fresh actual source authority before exposing preparation outcomes.""" + ... + + async def prepare_binding( + self, project_id: UUID, source_id: UUID, + expected: VerifiedTaskImportSourceBinding | None = None, + ) -> VerifiedTaskImportSourceBinding: + """Retain SOURCE KEY SHARE and validate native receipts before caller AUTH.""" + ... + + async def authorize_binding(self, binding: VerifiedTaskImportSourceBinding) -> UUID: + """Revalidate prepared custody and authorize the current caller freshly.""" + ... + + def open(self, project_id: UUID, source_id: UUID) -> AbstractAsyncContextManager[TaskImportSourceByteRead]: + """Verify actual provider bytes before yielding the bounded source stream.""" + ... + + class TaskImportRow(BaseModel): """Task instructions only; source custody and record IDs are server-owned.""" diff --git a/backend/app/modules/tasks/authorized_commands.py b/backend/app/modules/tasks/authorized_commands.py index 7be57ec73..f276e04ac 100644 --- a/backend/app/modules/tasks/authorized_commands.py +++ b/backend/app/modules/tasks/authorized_commands.py @@ -12,7 +12,7 @@ from sqlalchemy import func from sqlalchemy.exc import IntegrityError -from sqlalchemy.ext.asyncio import AsyncSession +from sqlalchemy.ext.asyncio import AsyncSession, AsyncSessionTransaction from app.modules.contributions.api import LockedCompensationTermsPort from app.core.hashing import canonical_json_hash @@ -68,6 +68,7 @@ class TaskCreationPreparation: reserved: bool current: WorkstreamTask | None facts: TaskAuthorityFacts + transaction: AsyncSessionTransaction class AuthorizedTaskCommands: @@ -178,11 +179,12 @@ async def prepare_creation( ), ) return TaskCreationPreparation(project_id, UUID(proposed.id), payload.model_dump_json(), - receipt, digest, reserved, current, facts) + receipt, digest, reserved, current, facts, self._session.get_transaction()) async def authorize_creation(self, prepared: TaskCreationPreparation) -> TaskAuthorityDecision: """Consume exact current per-Task authority after all caller preparation locks.""" - if not self._session.in_transaction() or prepared.facts.actor_profile_id != self._actor_id: + if (self._session.get_transaction() is not prepared.transaction or not prepared.transaction.is_active + or prepared.facts.actor_profile_id != self._actor_id): raise RuntimeError("task creation authority requires its original caller transaction") handle = await self._authorization.prepare(prepared.facts) try: @@ -194,7 +196,8 @@ async def stage_creation( self, prepared: TaskCreationPreparation, decision: TaskAuthorityDecision, ) -> TaskResponse: """Stage canonical creation/evidence/receipt without opening or committing a root.""" - if not self._session.in_transaction() or prepared.facts.actor_profile_id != self._actor_id: + if (self._session.get_transaction() is not prepared.transaction or not prepared.transaction.is_active + or prepared.facts.actor_profile_id != self._actor_id): raise RuntimeError("task creation staging requires its original caller transaction") payload = TypeAdapter(TaskCreate | ImportedTaskCreate).validate_json(prepared.payload_json) digest = canonical_json_hash({"project_id": str(prepared.project_id), "payload": payload.model_dump(mode="json")}) diff --git a/backend/app/modules/tasks/models.py b/backend/app/modules/tasks/models.py index e8c277137..e1a4137c1 100644 --- a/backend/app/modules/tasks/models.py +++ b/backend/app/modules/tasks/models.py @@ -771,6 +771,7 @@ class TaskImportBatch(Base): CheckConstraint("(get_byte(uuid_send(id), 6) >> 4) = 7 and (get_byte(uuid_send(id), 8) & 192) = 128", name="id_uuid7"), UniqueConstraint("project_id", "sha256", "byte_count", name="uq_task_import_batch_file"), UniqueConstraint("id", "project_id", name="uq_task_import_batch_project"), + UniqueConstraint("creation_command_receipt_id", name="uq_task_import_batch_creation_command"), ForeignKeyConstraint( ["source_id", "project_id", "sha256", "byte_count", "media_type"], ["artifact_task_import_sources.id", "artifact_task_import_sources.project_id", @@ -804,6 +805,9 @@ class TaskImportBatch(Base): id: Mapped[str] = mapped_column(Uuid(as_uuid=False), primary_key=True) project_id: Mapped[str] = mapped_column(ForeignKey("projects.id", ondelete="RESTRICT", deferrable=True, initially="DEFERRED")) source_id: Mapped[str] = mapped_column(Uuid(as_uuid=False)) + creation_command_receipt_id: Mapped[str] = mapped_column(ForeignKey( + "task_import_batch_command_receipts.id", ondelete="RESTRICT", deferrable=True, initially="DEFERRED", + )) sha256: Mapped[str] = mapped_column(String(71)) byte_count: Mapped[int] = mapped_column(BigInteger) media_type: Mapped[str] = mapped_column(String(255), default="application/json") @@ -811,6 +815,7 @@ class TaskImportBatch(Base): mapping_version: Mapped[str] = mapped_column(String(80)) manifest_digest: Mapped[str] = mapped_column(String(71)) row_count: Mapped[int] = mapped_column(Integer) + metadata_label: Mapped[str | None] = mapped_column(String(255)) actor_profile_id: Mapped[str] = mapped_column(ForeignKey("actor_profiles.id", ondelete="RESTRICT", deferrable=True, initially="DEFERRED")) identity_link_id: Mapped[str] = mapped_column(Uuid(as_uuid=False)) authorization_decision_id: Mapped[str | None] = mapped_column(ForeignKey("audit_events.id", ondelete="RESTRICT", deferrable=True, initially="DEFERRED")) @@ -871,6 +876,9 @@ class TaskImportBatchCommandReceipt(Base): UniqueConstraint("actor_profile_id", "action_id", "idempotency_key", name="uq_task_import_command_namespace"), ForeignKeyConstraint(["batch_id", "project_id"], ["task_import_batches.id", "task_import_batches.project_id"], name="fk_task_import_command_batch", ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), + ForeignKeyConstraint(["identity_link_id", "actor_profile_id"], + ["actor_identity_links.id", "actor_identity_links.actor_profile_id"], + name="fk_task_import_command_actor_link", ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), ForeignKeyConstraint( ["source_id", "project_id", "sha256", "byte_count", "media_type"], ["artifact_task_import_sources.id", "artifact_task_import_sources.project_id", @@ -896,6 +904,7 @@ class TaskImportBatchCommandReceipt(Base): id: Mapped[str] = mapped_column(Uuid(as_uuid=False), primary_key=True) actor_profile_id: Mapped[str] = mapped_column(ForeignKey("actor_profiles.id", ondelete="RESTRICT", deferrable=True, initially="DEFERRED")) + identity_link_id: Mapped[str] = mapped_column(Uuid(as_uuid=False)) action_id: Mapped[str] = mapped_column(String(160)) idempotency_key: Mapped[UUID] = mapped_column(Uuid()) request_digest: Mapped[str] = mapped_column(String(71)) diff --git a/backend/app/modules/tasks/router.py b/backend/app/modules/tasks/router.py index e526fafcc..fcce0ec39 100644 --- a/backend/app/modules/tasks/router.py +++ b/backend/app/modules/tasks/router.py @@ -6,7 +6,7 @@ from collections.abc import AsyncIterator from datetime import datetime from uuid import UUID -from app.api.deps.authorization import get_task_commands, enforce_human_authorization_read +from app.api.deps.authorization import get_task_commands, get_task_import_batch_commands, enforce_human_authorization_read from app.modules.tasks.queue_router import router as queue_router from app.modules.tasks.authorized_commands import AuthorizedTaskCommands from app.modules.tasks.api import TaskAuthorityOperation, ContributorTaskDetail, ManagementTaskDetail @@ -27,6 +27,11 @@ TaskWithAssignmentResponse, ) from app.modules.tasks.service import TaskProjectNotReady, TaskServiceError, TaskNotFound +from app.modules.tasks.task_import_batches import TaskImportBatchCommands, TaskImportBatchError +from app.modules.tasks.api.task_import import TaskImportBatchAction +from app.modules.tasks.schemas import TaskImportBatchRequest, TaskImportBatchResponse, TaskImportBatchStatus +from app.interfaces.artifacts import ArtifactStoreError +from pydantic import ValidationError from app.modules.tasks.api.audit_evidence import AuditTaskEvidenceRequest, AuditTaskEvidencePage, TaskEvidenceCursor from app.api.deps.history import HistoryReadOperation, get_history_reads @@ -53,6 +58,55 @@ def require_task_command_key(request: Request) -> UUID: return parse_idempotency_key(values[0] if len(values) == 1 else "") +def task_import_error(exc: Exception) -> StructuredHTTPException: + """Expose bounded parser/row failures and safe storage outcomes without coordinates.""" + details = None + if isinstance(exc, TaskImportBatchError): + code, status_code = exc.code, exc.status_code + if isinstance(exc, TaskImportBatchError) and exc.row_indexes: + details = [{"loc": ["tasks", index, "external_task_id"], "type": "external_task_id_conflict"} + for index in exc.row_indexes] + elif isinstance(exc, (ValidationError, ValueError)): + code, status_code = "task_import_json_invalid", 422 + if isinstance(exc, ValidationError): + details = [{"loc": list(error["loc"]), "type": error["type"], "msg": error["msg"]} + for error in exc.errors(include_input=False, include_context=False, include_url=False)] + else: + code, status_code = "task_import_source_unavailable", 503 + return StructuredHTTPException(status_code=status_code, detail=details or code, + error_code=code, error_message=code.replace("_", " "), retryable=status_code == 503) + + +@router.post("/projects/{project_id}/task-import-batches", response_model=TaskImportBatchResponse, status_code=201, + openapi_extra={"x-workstream-action-id": TaskImportBatchAction.IMPORT.value, + "parameters": [TASK_IDEMPOTENCY_PARAMETER]}) +async def import_task_batch( + project_id: UUID, payload: TaskImportBatchRequest, + key: Annotated[UUID, Depends(require_task_command_key)], + commands: Annotated[TaskImportBatchCommands, Depends(get_task_import_batch_commands)], +) -> TaskImportBatchResponse: + """Import every JSON row into DRAFT or recover the original immutable result.""" + try: + return await commands.import_source(project_id, payload.source_id, idempotency_key=key) + except (TaskImportBatchError, ArtifactStoreError, ValidationError, ValueError) as exc: + raise task_import_error(exc) from exc + + +@router.get("/projects/{project_id}/task-import-batches/{batch_id}", response_model=TaskImportBatchStatus, + dependencies=[Depends(enforce_human_authorization_read)], + openapi_extra={"x-workstream-action-id": TaskImportBatchAction.READ.value}) +async def read_task_batch( + request: Request, project_id: UUID, batch_id: UUID, + commands: Annotated[TaskImportBatchCommands, Depends(get_task_import_batch_commands)], +) -> TaskImportBatchStatus: + """Read native membership and current states under fresh covered-manager authority.""" + from app.core.api_controls import request_ids + try: + return await commands.status(project_id, batch_id, request_id=UUID(request_ids(request)[0])) + except TaskImportBatchError as exc: + raise task_import_error(exc) from exc + + CANONICAL_ERROR_OBJECT_SCHEMA = {"$ref": "#/components/schemas/ApiError"} diff --git a/backend/app/modules/tasks/schemas.py b/backend/app/modules/tasks/schemas.py index cd0c44870..b284f79c6 100644 --- a/backend/app/modules/tasks/schemas.py +++ b/backend/app/modules/tasks/schemas.py @@ -279,6 +279,7 @@ class TaskImportBatchResponse(BaseModel): byte_count: int = Field(ge=1, le=8388608) schema_version: Literal["workstream.task_import.v1"] mapping_version: Literal["workstream.task_import.draft_mapping.v1"] + label: str | None = Field(default=None, min_length=1, max_length=255) row_count: int = Field(ge=1, le=500) created_at: datetime tasks: tuple[TaskResponse, ...] = Field(min_length=1, max_length=500) diff --git a/backend/app/modules/tasks/task_import_batches.py b/backend/app/modules/tasks/task_import_batches.py index 4a781152b..75b0f463e 100644 --- a/backend/app/modules/tasks/task_import_batches.py +++ b/backend/app/modules/tasks/task_import_batches.py @@ -9,12 +9,9 @@ from app.core.hashing import canonical_json_hash from app.core.identifiers import new_record_id -from app.modules.artifacts.api.task_import_source import ( - TaskImportSourceAuthorityFacts, TaskImportSourceBindingPort, - TaskImportSourceCommandPort, VerifiedTaskImportSourceBinding, -) from app.modules.tasks.api.task_import import ( ParsedTaskImport, TASK_IMPORT_MAPPING_VERSION, TASK_IMPORT_MAXIMUM_BYTES, + TaskImportSourceCommitment, TaskImportSourceConsumerPort, VerifiedTaskImportSourceBinding, TaskImportBatchAction, TaskImportBatchAuthorityFacts, TaskImportBatchAuthorizationPort, TaskImportRow, parse_task_import, ) @@ -36,7 +33,7 @@ def __init__(self, code: str, status_code: int, row_indexes: tuple[int, ...] = ( super().__init__(code) -def imported_task_payload(row: TaskImportRow, source: TaskImportSourceAuthorityFacts, batch_id: UUID) -> ImportedTaskCreate: +def imported_task_payload(row: TaskImportRow, source: TaskImportSourceCommitment, batch_id: UUID) -> ImportedTaskCreate: """Map instructions directly and stamp provenance solely from actual native custody.""" return ImportedTaskCreate( **row.model_dump(), source_type="json_import", source_ref=f"task-import-source:{source.source_id}", @@ -72,11 +69,11 @@ class TaskImportBatchCommands: def __init__( self, session: AsyncSession, *, actor_profile_id: UUID, identity_link_id: UUID, authorization: TaskImportBatchAuthorizationPort, tasks: AuthorizedTaskCommands, - source_reader: TaskImportSourceCommandPort, source_binding: TaskImportSourceBindingPort, + source: TaskImportSourceConsumerPort, ) -> None: self._session, self._actor_id, self._link_id = session, actor_profile_id, identity_link_id self._authorization, self._tasks = authorization, tasks - self._source_reader, self._source_binding = source_reader, source_binding + self._source = source @staticmethod def _request_digest(project_id: UUID, source_id: UUID) -> str: @@ -90,30 +87,30 @@ async def _command(self, key: UUID, *, lock: bool = False) -> TaskImportBatchCom ).execution_options(populate_existing=True) return await self._session.scalar(query.with_for_update() if lock else query) - async def _file_batch(self, facts: TaskImportSourceAuthorityFacts, *, lock: bool = False) -> TaskImportBatch | None: + async def _file_batch(self, facts: TaskImportSourceCommitment, *, lock: bool = False) -> TaskImportBatch | None: query = select(TaskImportBatch).where( TaskImportBatch.project_id == str(facts.project_id), TaskImportBatch.sha256 == facts.sha256, TaskImportBatch.byte_count == facts.byte_count, ).execution_options(populate_existing=True) return await self._session.scalar(query.with_for_update() if lock else query) - async def _preflight(self, project_id: UUID, source_id: UUID, key: UUID) -> tuple[TaskImportSourceAuthorityFacts, bool]: + async def _preflight(self, project_id: UUID, source_id: UUID, key: UUID) -> tuple[TaskImportSourceCommitment, bool]: """Determine whether immutable recovery exists without reading provider bytes.""" async with self._session.begin(): command = await self._command(key) if command is not None: - facts = await self._source_binding.source_commitment(UUID(command.project_id), UUID(command.source_id)) - await self._source_binding.authorize_commitment(facts) + facts = await self._source.source_commitment(UUID(command.project_id), UUID(command.source_id)) + await self._source.authorize_commitment(facts) return facts, True - facts = await self._source_binding.source_commitment(project_id, source_id) - await self._source_binding.authorize_commitment(facts) + facts = await self._source.source_commitment(project_id, source_id) + await self._source.authorize_commitment(facts) batch = await self._file_batch(facts) return facts, batch is not None - async def _read_first_import(self, facts: TaskImportSourceAuthorityFacts) -> ParsedTaskImport: + async def _read_first_import(self, facts: TaskImportSourceCommitment) -> ParsedTaskImport: """Finish bounded actual provider verification and parsing before TASK locks.""" raw = bytearray() - async with self._source_reader.open(facts.project_id, facts.source_id) as opened: + async with self._source.open(facts.project_id, facts.source_id) as opened: async for chunk in opened.stream: raw.extend(chunk) if len(raw) > TASK_IMPORT_MAXIMUM_BYTES: @@ -124,26 +121,32 @@ async def _read_first_import(self, facts: TaskImportSourceAuthorityFacts) -> Par return parsed async def _reserve_command( - self, facts: TaskImportSourceAuthorityFacts, key: UUID, request_digest: str, + self, facts: TaskImportSourceCommitment, key: UUID, request_digest: str, ) -> TaskImportBatchCommandReceipt: """Reserve the exact actor/action/key before batch, ART or AUTH locks.""" await self._session.execute(insert(TaskImportBatchCommandReceipt).values( - id=str(new_record_id()), actor_profile_id=str(self._actor_id), action_id=TaskImportBatchAction.IMPORT.value, + id=str(new_record_id()), actor_profile_id=str(self._actor_id), identity_link_id=str(self._link_id), + action_id=TaskImportBatchAction.IMPORT.value, idempotency_key=key, request_digest=request_digest, project_id=str(facts.project_id), source_id=str(facts.source_id), sha256=facts.sha256, byte_count=facts.byte_count, media_type="application/json", source_operation_identity=facts.operation_identity, status="pending", ).on_conflict_do_nothing(constraint="uq_task_import_command_namespace")) return await self._command(key, lock=True) - async def _reserve_batch(self, facts: TaskImportSourceAuthorityFacts, parsed: ParsedTaskImport | None) -> TaskImportBatch: + async def _reserve_batch( + self, facts: TaskImportSourceCommitment, parsed: ParsedTaskImport | None, + command: TaskImportBatchCommandReceipt, + ) -> TaskImportBatch: """Serialize only the exact project/file identity; native FKs remain deferred.""" if parsed is not None: await self._session.execute(insert(TaskImportBatch).values( id=str(new_record_id()), project_id=str(facts.project_id), source_id=str(facts.source_id), + creation_command_receipt_id=command.id, sha256=facts.sha256, byte_count=facts.byte_count, media_type="application/json", schema_version=parsed.document.schema_version, mapping_version=TASK_IMPORT_MAPPING_VERSION, manifest_digest=canonical_json_hash(parsed.document.model_dump(mode="json")), row_count=len(parsed.document.tasks), actor_profile_id=str(self._actor_id), identity_link_id=str(self._link_id), + metadata_label=parsed.document.metadata.label, source_operation_identity=facts.operation_identity, status="pending", ).on_conflict_do_nothing(constraint="uq_task_import_batch_file")) batch = await self._file_batch(facts, lock=True) @@ -161,7 +164,7 @@ def _facts( ) async def _prepare_rows( - self, batch: TaskImportBatch, facts: TaskImportSourceAuthorityFacts, parsed: ParsedTaskImport, + self, batch: TaskImportBatch, facts: TaskImportSourceCommitment, parsed: ParsedTaskImport, ) -> list[tuple[int, TaskCreationPreparation]]: """Prepare every canonical Task retry identity before any ART/AUTH lock.""" prepared = [] @@ -185,7 +188,7 @@ async def _prepare_sources( expected.setdefault(command.source_id, None) prepared = {} for source_id in sorted(expected): - prepared[source_id] = await self._source_binding.prepare_binding( + prepared[source_id] = await self._source.prepare_binding( UUID(batch.project_id), UUID(source_id), expected[source_id], ) selected = prepared[command.source_id] @@ -207,6 +210,10 @@ async def _original_response(self, batch: TaskImportBatch) -> TaskImportBatchRes ).where(TaskImportBatchMember.batch_id == batch.id).order_by(TaskImportBatchMember.row_index))).all() if len(rows) != batch.row_count: raise TaskImportBatchError("task_import_batch_custody_invalid", 409) + manifest = {"schema_version": response.schema_version, "metadata": {"label": response.label}, + "tasks": [{field: getattr(task, field) for field in TaskImportRow.model_fields} for task in response.tasks]} + if response.label != batch.metadata_label or canonical_json_hash(manifest) != batch.manifest_digest: + raise TaskImportBatchError("task_import_batch_custody_invalid", 409) for index, (member, receipt) in enumerate(rows): original = response.tasks[index] instructions = {field: getattr(original, field) for field in TaskImportRow.model_fields} @@ -255,6 +262,7 @@ async def _stage_rows( batch_id=UUID(batch.id), project_id=UUID(batch.project_id), source_id=UUID(batch.source_id), sha256=batch.sha256, byte_count=batch.byte_count, schema_version=batch.schema_version, mapping_version=batch.mapping_version, row_count=batch.row_count, created_at=batch.created_at, + label=batch.metadata_label, tasks=tuple(originals[index] for index in range(batch.row_count)), ) @@ -266,11 +274,11 @@ async def import_source(self, project_id: UUID, source_id: UUID, *, idempotency_ async with self._session.begin(): command = await self._reserve_command(facts, idempotency_key, digest) # Namespace custody may now point at the original selector from a competing commit. - facts = await self._source_binding.source_commitment(UUID(command.project_id), UUID(command.source_id)) - batch = await self._reserve_batch(facts, parsed) + facts = await self._source.source_commitment(UUID(command.project_id), UUID(command.source_id)) + batch = await self._reserve_batch(facts, parsed, command) prepared = (await self._prepare_rows(batch, facts, parsed)) if batch.status == "pending" else [] selected = await self._prepare_sources(batch, command) - await self._source_binding.authorize_binding(selected) + await self._source.authorize_binding(selected) decision_id = await self._authorization.authorize( TaskImportBatchAction.IMPORT, self._facts(batch, selected, idempotency_key, digest), ) @@ -303,8 +311,8 @@ async def status(self, project_id: UUID, batch_id: UUID, *, request_id: UUID) -> ).execution_options(populate_existing=True)) if batch is None: raise TaskImportBatchError("task_import_batch_not_found", 404) - binding = await self._source_binding.prepare_binding(project_id, UUID(batch.source_id), _binding(batch)) - await self._source_binding.authorize_binding(binding) + binding = await self._source.prepare_binding(project_id, UUID(batch.source_id), _binding(batch)) + await self._source.authorize_binding(binding) await self._authorization.authorize(TaskImportBatchAction.READ, self._facts( batch, binding, request_id, canonical_json_hash({"project_id": str(project_id), "batch_id": str(batch_id)}), )) diff --git a/backend/tests/authorization/catalogue_fixtures.py b/backend/tests/authorization/catalogue_fixtures.py index edb9240c2..510bb41d4 100644 --- a/backend/tests/authorization/catalogue_fixtures.py +++ b/backend/tests/authorization/catalogue_fixtures.py @@ -299,6 +299,8 @@ "project.task.queue.read": ("project.task.manage", "WS-ARCH-001-03C4"), "operations.task.queue.read": ("operations.status.read", "WS-ARCH-001-03C4"), "project.task.create": ("project.task.manage", "WS-ARCH-001-03C3"), + "project.task.import": ("project.task.manage", "PILOT-02B"), + "project.task.import_batch.read": ("project.task.manage", "PILOT-02B"), "artifact.task_import_source.declare": ("project.task.manage", "PILOT-02A"), "artifact.task_import_source.upload": ("project.task.manage", "PILOT-02A"), "artifact.task_import_source.read": ("project.task.manage", "PILOT-02A"), @@ -482,6 +484,8 @@ "project.task.queue.read", "operations.task.queue.read", "project.task.create", + "project.task.import", + "project.task.import_batch.read", "artifact.task_import_source.declare", "artifact.task_import_source.upload", "artifact.task_import_source.read", diff --git a/backend/tests/authorization/task_authority/test_audit_contract.py b/backend/tests/authorization/task_authority/test_audit_contract.py index e8f4679e3..ca35a0364 100644 --- a/backend/tests/authorization/task_authority/test_audit_contract.py +++ b/backend/tests/authorization/task_authority/test_audit_contract.py @@ -21,13 +21,18 @@ from tests.test_audit import _authority_input -def test_task_import_source_decision_and_exact_audit_target_are_closed() -> None: +@pytest.mark.parametrize("action,resource_type", [ + (ActionId.ARTIFACT_TASK_IMPORT_SOURCE_DECLARE, "task_import_source"), + (ActionId.PROJECT_TASK_IMPORT, "task_import_batch"), + (ActionId.PROJECT_TASK_IMPORT_BATCH_READ, "task_import_batch"), +]) +def test_task_import_source_decision_and_exact_audit_target_are_closed(action, resource_type) -> None: source_id, project_id, grant_id = uuid4(), uuid4(), uuid4() digest = "sha256:" + "a" * 64 decision = AuthorizationDecision( - decision_id=uuid4(), action_id=ActionId.ARTIFACT_TASK_IMPORT_SOURCE_DECLARE, + decision_id=uuid4(), action_id=action, permission_id=PermissionId.PROJECT_TASK_MANAGE, allowed=True, denial_code=None, - resource_type="task_import_source", resource_id=source_id, + resource_type=resource_type, resource_id=source_id, resource_context_digest=digest, matched_authority_kind=MatchedAuthorityKind.ADMIN_ROLE_GRANT, matched_grant_id=grant_id, matched_scope_project_id=project_id, revalidated=True, request_id=uuid4(), correlation_id=uuid4(), @@ -42,7 +47,7 @@ def test_task_import_source_decision_and_exact_audit_target_are_closed() -> None after_facts={"allowed": True, "resource_context_digest": digest}, ) assert (event.resource_type, event.resource_id, event.target_ref_kind, event.target_ref_id) == ( - "task_import_source", str(source_id), "task_import_source", str(source_id), + resource_type, str(source_id), resource_type, str(source_id), ) with pytest.raises(ValidationError): AuthorizationDecision.model_validate(decision.model_dump() | {"resource_type": "unknown_source"}) diff --git a/backend/tests/tasks/test_task_import_batch_contract.py b/backend/tests/tasks/test_task_import_batch_contract.py index 808dbfc5c..ab14b3436 100644 --- a/backend/tests/tasks/test_task_import_batch_contract.py +++ b/backend/tests/tasks/test_task_import_batch_contract.py @@ -1,14 +1,12 @@ """Instruction mapping and closed original/current batch projections.""" from datetime import UTC, datetime -from uuid import uuid4 import pytest from pydantic import ValidationError from app.core.identifiers import new_record_id -from app.modules.artifacts.api.task_import_source import TaskImportSourceAuthorityFacts -from app.modules.tasks.api.task_import import TaskImportRow +from app.modules.tasks.api.task_import import TaskImportRow, TaskImportSourceCommitment from app.modules.tasks.schemas import ( TaskCreate, TaskImportBatchCurrentTask, TaskImportBatchRequest, TaskImportBatchResponse, TaskImportBatchStatus, TaskResponse, @@ -17,8 +15,8 @@ def _source(): - return TaskImportSourceAuthorityFacts(new_record_id(), new_record_id(), new_record_id(), - "sha256:" + "a" * 64, 100, "sha256:" + "b" * 64, uuid4()) + return TaskImportSourceCommitment(new_record_id(), new_record_id(), + "sha256:" + "a" * 64, 100, "sha256:" + "b" * 64) def _original(source, batch_id, external_id): @@ -27,7 +25,7 @@ def _original(source, batch_id, external_id): TaskImportRow(external_task_id=external_id, title="Instructions", description="Actual work"), source, batch_id, ).model_dump()) values.update(id=str(new_record_id()), project_id=str(source.project_id), status="draft", - created_by=str(source.actor_profile_id), created_at=datetime.now(UTC), updated_at=datetime.now(UTC)) + created_by=str(new_record_id()), created_at=datetime.now(UTC), updated_at=datetime.now(UTC)) return TaskResponse.model_validate(values) diff --git a/docs/engineering/authorization_activation_custody.md b/docs/engineering/authorization_activation_custody.md index 0c94c2ef8..883499cd9 100644 --- a/docs/engineering/authorization_activation_custody.md +++ b/docs/engineering/authorization_activation_custody.md @@ -340,3 +340,12 @@ delivered through canonical PREP. ARCH-04E2-B activates this exact action only inside the hidden complete outcome, with actual immutable AUTH-event/service verification and atomic source publication. No production routing handler is registered. + + +PILOT-02B owns the distinct TASK actions `project.task.import` and +`project.task.import_batch.read` under existing `project.task.manage`. They +require an active human covering Project Manager grant and exact native batch, +selected source, received-byte identity and original manifest facts. They do +not enlarge the ART action custody table or grant screen/release authority. +The [atomic import contract](../spec_chunk_4_task_queue_assignment.md#atomic-json-to-draft-import-contract) +separates immutable original creation facts from current member states. diff --git a/docs/spec_authorization_service.md b/docs/spec_authorization_service.md index 42c87127b..55e4812eb 100644 --- a/docs/spec_authorization_service.md +++ b/docs/spec_authorization_service.md @@ -1715,3 +1715,12 @@ authority and the complete original tuple without issuing another allow or repairing effects. B8 supplies hidden completion delivery; production registration remains unavailable. Human acceptance-source authority is still future work; detached human receipts grant nothing. + + +PILOT-02B owns the distinct TASK actions `project.task.import` and +`project.task.import_batch.read` under existing `project.task.manage`. They +require an active human covering Project Manager grant and exact native batch, +selected source, received-byte identity and original manifest facts. They do +not enlarge the ART action custody table or grant screen/release authority. +The [atomic import contract](spec_chunk_4_task_queue_assignment.md#atomic-json-to-draft-import-contract) +separates immutable original creation facts from current member states. diff --git a/docs/spec_chunk_4_task_queue_assignment.md b/docs/spec_chunk_4_task_queue_assignment.md index 56be353a3..579707ff7 100644 --- a/docs/spec_chunk_4_task_queue_assignment.md +++ b/docs/spec_chunk_4_task_queue_assignment.md @@ -92,12 +92,43 @@ locked guide/policy identities, creator identity or server provenance fields. PILOT-02A supplies usable authorized declaration, upload, status and verified download through the [ART source custody contract](spec_artifact_storage_service.md#task-import-source-custody). These operations create no Tasks. Failed or abandoned declarations remain -retained source records with no batch/task success claim. A later bounded -PILOT-02 operation must import a verified source into DRAFT atomically, enforce -project/external-ID uniqueness and replay/conflict rules, and bind exact ART -and AUTH custody. Explicit screen and release, their existing locked-guide -prerequisites and normal transitions remain unchanged. No public batch import, -batch screen/release or CLI conversion is delivered by source custody alone. +retained source records with no batch/task success claim. The separate atomic JSON-to-DRAFT import contract is below. Source custody alone +still supplies no batch screen/release or CLI conversion. + +### Atomic JSON-to-DRAFT import contract + +`POST /api/v1/projects/{project_id}/task-import-batches` accepts only a native +`source_id` and the shared UUID `Idempotency-Key`. A covered Project Manager's +first import reads and verifies actual provider bytes, parses the retained JSON, +then creates one immutable native batch and every DRAFT Task in one root. Each +row uses the normal authorized Task creation and `TaskCreated` evidence; a +later row, audit, binding or uniqueness failure rolls back the complete batch. +Case-sensitive project/external-ID uniqueness covers all non-NULL Task external +IDs, including normal creation. Existing arbitrary `import_batch_id` strings +remain metadata; only immutable native membership supplies batch custody. + +The server stamps `json_import`, `task-import-source:`, the actual +received-file SHA and the native batch UUID spelling. Normal manual TaskCreate +cannot select `json_import`; row input cannot supply these labels or other +provenance. Published difficulty values through 80 characters are preserved. +The response retains original document order, optional display label and original +Task creation facts; it does not transition or assign any Task. + +After commit, same-key replay and a new key selecting the same actual project/ +SHA/byte-count recover the original batch and Task IDs after fresh batch/source +authority, even after Tasks advance. This recovery uses immutable native +source/verification/acknowledgement receipts and performs no provider read or +reparsing. A different source needs its own actual verified receipt; a claimed +SHA alone cannot recover. Reusing the original key with a changed source selector +conflicts even if both verified sources contain identical bytes. + +`GET /api/v1/projects/{project_id}/task-import-batches/{batch_id}` returns original +creation facts separately from current states selected by ordered native +membership. Missing, foreign and revoked status access is concealed. Explicit +batch screen/release, normal locked-guide prerequisites and CLI/client CSV +conversion remain separate chunks. The bounded implementation and required +native proof are recorded in the +[atomic-import change record](../.commitrail/changes/pilot02-atomic-json-draft-import.md). ## Transitions and locked lineage diff --git a/mcp_server/contracts/authorization_context_get.json b/mcp_server/contracts/authorization_context_get.json index 933ab7c51..49b581b10 100644 --- a/mcp_server/contracts/authorization_context_get.json +++ b/mcp_server/contracts/authorization_context_get.json @@ -1,5 +1,5 @@ { - "canonical_sha256": "0deac394853f543579cb0c73b2adfb150c3389759e3141540becd92c5e1e08de", + "canonical_sha256": "79a0f0e17d6352cd70294e0a1b8d976510f2ecdad5b8b0bf8434052558dc02f9", "components": { "schemas": { "ActionId": { @@ -17,6 +17,8 @@ "project.task.queue.read", "operations.task.queue.read", "project.task.create", + "project.task.import", + "project.task.import_batch.read", "project.task.screen", "project.task.release", "task.claim", @@ -539,7 +541,7 @@ "schema_version": 1, "source": { "action_id": "actor.authorization_context.read", - "backend_git_sha": "7f154137b5e3ad9f597ca2d2d377b8f9d4bda1b3", + "backend_git_sha": "3eb281df518ed0d7f12a6e8eaa4ada29e7e15c87", "method": "GET", "openapi_version": "3.1.0", "path": "/api/v1/actors/me/authorization-context" From 0ba1cc8e8eb710ba5c4c545307b6b0be6f8146e6 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 12:08:45 +0100 Subject: [PATCH 018/283] test(tasks): retain atomic import acceptance and rollback controls --- .ci/behavior-ownership/partition.v1.json | 6 +- .../pilot02-atomic-json-draft-import.md | 17 +- backend/scripts/behavior_ownership.py | 4 + backend/scripts/test_lane_catalogue.py | 3 + .../test_management_commands.py | 41 ++ .../tests/tasks/test_task_import_batches.py | 362 ++++++++++++++++++ backend/tests/test_ci_lane_catalogue.py | 3 + 7 files changed, 430 insertions(+), 6 deletions(-) create mode 100644 backend/tests/tasks/test_task_import_batches.py diff --git a/.ci/behavior-ownership/partition.v1.json b/.ci/behavior-ownership/partition.v1.json index e271d9716..3a1ec3a00 100644 --- a/.ci/behavior-ownership/partition.v1.json +++ b/.ci/behavior-ownership/partition.v1.json @@ -1648,6 +1648,10 @@ "group": "lifecycle", "target": "backend/app/modules/tasks/submitted_bundle.py" }, + { + "group": "lifecycle", + "target": "backend/app/modules/tasks/task_import_batches.py" + }, { "group": "auth", "target": "backend/app/schemas/auth.py" @@ -1797,7 +1801,7 @@ "target": "backend/scripts/validate_test_lane_evidence.py" } ], - "authority_digest": "97a2953c103a4db84ef09f6cc1afe60e23a7f6b235f8cccf1abf1a31f7558f59", + "authority_digest": "fccb894db43d59f708dde7c3b9839b778f9715f685e34070be564c11ad6a5efe", "protected_base_commit": "7676ce4347db0c9694962a9b587a20765e16eac6", "schema": "workstream.behavior-ownership-partition.v1" } diff --git a/.commitrail/changes/pilot02-atomic-json-draft-import.md b/.commitrail/changes/pilot02-atomic-json-draft-import.md index 3d1ce703a..0a30c32e9 100644 --- a/.commitrail/changes/pilot02-atomic-json-draft-import.md +++ b/.commitrail/changes/pilot02-atomic-json-draft-import.md @@ -445,13 +445,18 @@ never silently reinterprets retained rows under a later mapping. | Claim | Command or proof | Result | Remaining uncertainty | |---|---|---|---| | Canonical creation participant | Exact `59d47a6c` isolated native execution of five retained CREATE, denial, rollback and receipt controls | 5 passed in 69.02 seconds; schema `0031_task_import_source`; owned database/role/MinIO cleanup complete | Proves preservation of normal creation; no atomic batch success claim | +| Source consumer and current CREATE participants | Exact `37d8705d` isolated execution of actual immutable-binding substitution/provider-health, public source, canonical denial, CREATE rollback and receipt controls | 10 passed in 120.95 seconds; runner exit 0, schema `0031_task_import_source`; owned database/role/MinIO cleanup complete | Raw `/tmp/pilot02-atomic-37d-source-create-corrected.log` and `.json`; validates existing owner integration, not installed batch schema | | Current owners and concrete gap | Inspect source port/parser, TASK create/replay/models and Issue 489 | Canonical caller-root phases, closed batch DTOs, model representations, ART immutable-binding participant and batch/root/AUTH composition are implemented | New table constraints and guards require sole-author DDL and native proof | -| Public import and atomic effects | Planned isolated runner: `pytest -q tests/tasks/test_task_import_batches.py` with real PostgreSQL 16/MinIO | Not run; tests not authored | All positive/negative/concurrency cases above must pass | +| Public import and atomic effects | Planned isolated runner: `pytest -q tests/tasks/test_task_import_batches.py` with real PostgreSQL 16/MinIO | Eighteen native acceptance cases collect; not executed because batch schema is not installed | Actual 200-Task creation, immutable replay, late-stage rollback, direct SQL guards and intermediate-wait controls must pass after sole-author DDL | | Schema, guards and complete integration | Sole-author native graph/reset/UUID proof, affected guards, complete hosted lanes and aggregate | Not run for this chunk | Exact frozen candidate, actual merge tree and cleanup required | ## Review findings -No implementation review is claimed. Scope preparation identifies the existing +Independent schema/lock handoff review at exact `37d8705d` found no actionable +architecture/reuse/security issue in the non-DDL models, replay and preparation +graph. This qualified review does not prove native guards or public batch +success; those require the integrated migration and real end-to-end execution. +Scope preparation identifies the existing per-command transaction and unbound string provenance as explicit handoff issues. Affected independent planning review found two concrete missing integration requirements: the closed TaskCreated JSON source token and complete batch/header/ @@ -471,9 +476,11 @@ not prove installed custody or a public import result. provider-free ART binding validation and public route composition are coded on this isolated branch; no delivered import capability is claimed. No migration is authored in this worktree. -- Next usable boundary: review the exact batch/membership/receipt schema and - owner preparation/replay graph, then coordinate the sole-author migration and - implement atomic JSON-to-DRAFT import. Explicit batch screen/release and CLI +- Next usable boundary: coordinate the reviewed batch/membership/receipt schema + and owner preparation/replay graph with the sole-author migration, then prove + the coded atomic JSON-to-DRAFT operation through public native acceptance cases. + No migration ordinal is allocated before the actual merged predecessor and + delegated migration queue are reconciled. Explicit batch screen/release and CLI project/source/batch commands with client CSV conversion remain later chunks. - Remaining risks: source prerequisite and current required CI/actual external review remain separate; no deployed import capability or whole Issue 489 claim. diff --git a/backend/scripts/behavior_ownership.py b/backend/scripts/behavior_ownership.py index cec84d850..1f9200337 100644 --- a/backend/scripts/behavior_ownership.py +++ b/backend/scripts/behavior_ownership.py @@ -628,6 +628,9 @@ "backend/app/modules/authorization/task_import_sources.py", "backend/app/modules/tasks/api/task_import.py", }) +PILOT_02B_ATOMIC_IMPORT_TARGETS = frozenset({ + "backend/app/modules/tasks/task_import_batches.py", +}) class BehaviorOwnershipError(RuntimeError): @@ -875,6 +878,7 @@ def _validate_additive_partition_transition( | TASK_COMMAND_REPLAY_TARGETS | PILOT_13_GUIDE_READ_TARGETS | PILOT_02A_IMPORT_SOURCE_TARGETS + | PILOT_02B_ATOMIC_IMPORT_TARGETS ) expected_additions = (approved_additions & additions) - set(trusted_targets) if POL_03A_DECLARATIVE_MODEL_TARGET in additions: diff --git a/backend/scripts/test_lane_catalogue.py b/backend/scripts/test_lane_catalogue.py index 1998be633..3d00bcbab 100644 --- a/backend/scripts/test_lane_catalogue.py +++ b/backend/scripts/test_lane_catalogue.py @@ -437,6 +437,9 @@ class TestLane: TASK_MODULES = ( "tests/tasks/test_task_import_contract.py", + "tests/tasks/test_task_import_batch_contract.py", + "tests/tasks/test_task_import_batch_bindings.py", + "tests/tasks/test_task_import_batches.py", "tests/checkers/execution/test_completion_evidence.py", "tests/checkers/execution/test_completion_contract.py", "tests/tasks/post_submit_routing/test_failure_completion.py", diff --git a/backend/tests/authorization/task_authority/test_management_commands.py b/backend/tests/authorization/task_authority/test_management_commands.py index e88e9af44..3f3a5cc75 100644 --- a/backend/tests/authorization/task_authority/test_management_commands.py +++ b/backend/tests/authorization/task_authority/test_management_commands.py @@ -64,6 +64,47 @@ async def test_create_draft_without_guide(task_client): assert UUID(event.event_payload["references"]["authorization_decision_id"]) +@pytest.mark.parametrize("phase", ["authorize", "stage"]) +async def test_creation_preparation_cannot_move_to_a_later_root(task_client, phase): + """Rolled-back preparation and ALLOW evidence cannot authorize another root.""" + from app.adapters.audit import task_transition_audit + from app.adapters.tasks import task_commands + from app.core.config import get_settings + from app.modules.authorization.task_authorization import PreparedTaskAuthorization + from app.modules.tasks.schemas import TaskCreate + from tests.authorization.task_authority.test_concurrency import actor_context + + project = await task_client.post("/api/v1/projects", headers=auth_headers(), + json={"name": "Preparation root", "slug": "create-root-" + uuid4().hex}) + assert project.status_code == 201, project.text + async with db_session.get_session_factory()() as observer: + from app.modules.actors.models import ActorIdentityLink + actor_id = await observer.scalar(select(ActorIdentityLink.actor_profile_id).where( + ActorIdentityLink.subject == "project-manager-subject", + )) + context = await actor_context(actor_id) + async with db_session.get_session_factory()() as session: + commands = task_commands(session, authorization=PreparedTaskAuthorization(session, context), + audit=task_transition_audit(session), actor_profile_id=context.actor_profile_id, + settings=get_settings()) + async with session.begin(): + prepared = await commands.prepare_creation(UUID(project.json()["id"]), TaskCreate(**complete_task_payload()), + idempotency_key=uuid4()) + decision = await commands.authorize_creation(prepared) + receipt_id = prepared.receipt.id + await session.rollback() + async with session.begin(): + with pytest.raises(RuntimeError, match="original caller transaction"): + if phase == "authorize": + await commands.authorize_creation(prepared) + else: + await commands.stage_creation(prepared, decision) + async with session.begin(): + assert await session.get(WorkstreamTask, str(prepared.task_id)) is None + assert await session.get(TaskCommandReceipt, receipt_id) is None + assert await session.get(AuditEvent, str(decision.decision_id)) is None + + async def test_screen_and_release_lock_approved_context(task_client): project = await create_active_project(task_client) task = await create_draft_task(task_client, project["id"]) diff --git a/backend/tests/tasks/test_task_import_batches.py b/backend/tests/tasks/test_task_import_batches.py new file mode 100644 index 000000000..54ddd0d28 --- /dev/null +++ b/backend/tests/tasks/test_task_import_batches.py @@ -0,0 +1,362 @@ +"""Public atomic JSON-to-DRAFT import with native AUTH, ART and Task custody.""" + +import asyncio +import json +from uuid import uuid4 + +import pytest +from sqlalchemy import func, select, text +from sqlalchemy.exc import DBAPIError + +from app.db import session as db_session +from app.modules.artifacts.models import ArtifactTaskImportSource, ArtifactReplica +from app.modules.artifacts.task_import_sources import ArtifactTaskImportSourceCommands +from app.modules.authorization.task_import_sources import PreparedTaskImportSourceAuthorization +from app.modules.tasks.authorized_commands import AuthorizedTaskCommands +from app.modules.tasks.models import ( + AuditEvent, TaskCommandReceipt, TaskImportBatch, TaskImportBatchCommandReceipt, + TaskImportBatchMember, WorkstreamTask, +) +from app.modules.tasks.task_import_batches import TaskImportBatchCommands +from tests.test_task_import_sources import ( + import_source_client as import_source_client, _declare, _path, _project, +) +from tests.test_tasks import ( + auth_headers, complete_task_payload, create_active_project, set_dev_actor, + task_database_env as task_database_env, +) +from tests.tasks.test_task_import_contract import document + + +async def _verified_source(client, project, value): + """Retain actual bytes through the existing public declaration and upload.""" + raw = (json.dumps(value, ensure_ascii=False, indent=2) + "\n").encode() + source = await _declare(client, project, raw) + uploaded = await client.put(_path(project, source) + "/content", content=raw, + headers=auth_headers() | {"Content-Type": "application/json"}) + assert uploaded.status_code == 200 and uploaded.json()["status"] == "verified", uploaded.text + return source + + +def _batch_path(project): + """Address the sole project-scoped public import owner.""" + return f"/api/v1/projects/{project}/task-import-batches" + + +async def _counts(project): + """Observe committed batch, membership, retry, Task and CREATE effects.""" + async with db_session.get_session_factory()() as session: + counts = [await session.scalar(select(func.count()).select_from(owner).where(owner.project_id == project)) + for owner in (TaskImportBatch, TaskImportBatchMember, TaskImportBatchCommandReceipt, WorkstreamTask)] + counts.append(await session.scalar(select(func.count()).select_from(TaskCommandReceipt).join( + WorkstreamTask, WorkstreamTask.id == TaskCommandReceipt.task_id, + ).where(WorkstreamTask.project_id == project, TaskCommandReceipt.action_id == "project.task.create"))) + counts.append(await session.scalar(select(func.count()).select_from(AuditEvent).where( + AuditEvent.event_payload["references"]["project_id"].as_string() == project, + AuditEvent.event_type == "TaskCreated", + ))) + return tuple(counts) + + +async def test_200_rows_create_one_native_batch_and_exact_task_evidence(import_source_client): + """A real 200-row UTF-8 file creates 200 ordered DRAFT Tasks in one batch.""" + client, value = import_source_client, document(200) + value["tasks"][0]["difficulty"] = "x" * 80 + project = await _project(client) + source = await _verified_source(client, project, value) + headers = auth_headers() + response = await client.post(_batch_path(project), headers=headers, json={"source_id": source["source_id"]}) + assert response.status_code == 201, response.text + result = response.json() + assert (result["project_id"], result["source_id"], result["sha256"], result["byte_count"], result["row_count"]) == ( + project, source["source_id"], source["sha256"], source["byte_count"], 200, + ) + assert result["label"] == value["metadata"]["label"] + assert len({row["id"] for row in result["tasks"]}) == 200 + assert [row["external_task_id"] for row in result["tasks"]] == [row["external_task_id"] for row in value["tasks"]] + assert all(row["status"] == "draft" and row["source_type"] == "json_import" + and row["source_ref"] == f"task-import-source:{source['source_id']}" + and row["source_payload_hash"] == source["sha256"] + and row["import_batch_id"] == result["batch_id"] for row in result["tasks"]) + for instructions, task in zip(value["tasks"], result["tasks"], strict=True): + assert {field: task[field] for field in instructions} == instructions + assert await _counts(project) == (1, 200, 1, 200, 200, 200) + async with db_session.get_session_factory()() as session: + members = list(await session.scalars(select(TaskImportBatchMember).where( + TaskImportBatchMember.batch_id == result["batch_id"], + ).order_by(TaskImportBatchMember.row_index))) + assert [member.task_id for member in members] == [row["id"] for row in result["tasks"]] + for member in members: + receipt = await session.get(TaskCommandReceipt, member.task_command_receipt_id) + decision = await session.get(AuditEvent, member.authorization_decision_id) + event = (await session.scalars(select(AuditEvent).where( + AuditEvent.entity_id == member.task_id, AuditEvent.event_type == "TaskCreated", + ))).one() + assert receipt.response == member.response and receipt.status == "committed" + assert decision.action_id == "project.task.create" and decision.event_type == "SensitiveAuthorizationAllowed" + assert event.event_payload["source_type"] == "json_import" + assert event.event_payload["references"]["authorization_decision_id"] == decision.id + repeated = await client.post(_batch_path(project), headers=headers, json={"source_id": source["source_id"]}) + recovered = await client.post(_batch_path(project), headers=auth_headers(), json={"source_id": source["source_id"]}) + assert repeated.status_code == recovered.status_code == 201 + assert repeated.json() == recovered.json() == result + assert await _counts(project) == (1, 200, 2, 200, 200, 200) + + +async def test_replay_keeps_original_facts_after_advancement_without_provider_or_parser(import_source_client, monkeypatch): + """Committed replay reads native ancestry; current Tasks remain separate facts.""" + client = import_source_client + project = (await create_active_project(client, slug="batch-advance-" + uuid4().hex))["id"] + source = await _verified_source(client, project, document(2)) + headers = auth_headers() + imported = await client.post(_batch_path(project), headers=headers, json={"source_id": source["source_id"]}) + assert imported.status_code == 201, imported.text + result = imported.json() + first = result["tasks"][0]["id"] + for action in ("screen", "release"): + advanced = await client.post(f"/api/v1/tasks/{first}/{action}", headers=auth_headers(), json={}) + assert advanced.status_code == 200, advanced.text + async with db_session.get_session_factory()() as session, session.begin(): + header = await session.get(TaskImportBatch, result["batch_id"]) + replica = await session.get(ArtifactReplica, header.replica_id) + replica.availability_state = "unavailable" + + def forbidden(*args, **kwargs): + raise AssertionError("committed batch replay cannot read provider bytes or reinterpret JSON") + + monkeypatch.setattr(ArtifactTaskImportSourceCommands, "open", forbidden) + monkeypatch.setattr("app.modules.tasks.task_import_batches.parse_task_import", forbidden) + for request_headers in (headers, auth_headers()): + replay = await client.post(_batch_path(project), headers=request_headers, json={"source_id": source["source_id"]}) + assert replay.status_code == 201 and replay.json() == result, replay.text + status = await client.get(_batch_path(project) + "/" + result["batch_id"], headers=auth_headers()) + assert status.status_code == 200, status.text + assert status.json()["creation"] == result + assert [row["status"] for row in status.json()["current_tasks"]] == ["ready", "draft"] + assert await _counts(project) == (1, 2, 2, 2, 2, 2) + + +async def test_different_verified_selector_recovers_but_changed_key_selector_conflicts(import_source_client, monkeypatch): + """Another actual verified source may recover a file, never rewrite its retry key.""" + client = import_source_client + project = await _project(client) + value = document(2) + original = await _verified_source(client, project, value) + headers = auth_headers() + response = await client.post(_batch_path(project), headers=headers, json={"source_id": original["source_id"]}) + assert response.status_code == 201, response.text + alternate = await _verified_source(client, project, value) + assert alternate["source_id"] != original["source_id"] + # A declared parent claims the same SHA/count, but has no verified receipt. + unverified = await _declare(client, project, (json.dumps(value, ensure_ascii=False, indent=2) + "\n").encode()) + + def forbidden(*args, **kwargs): + raise AssertionError("exact-file recovery must not consult provider/parser") + + monkeypatch.setattr(ArtifactTaskImportSourceCommands, "open", forbidden) + monkeypatch.setattr("app.modules.tasks.task_import_batches.parse_task_import", forbidden) + recovered = await client.post(_batch_path(project), headers=auth_headers(), json={"source_id": alternate["source_id"]}) + assert recovered.status_code == 201 and recovered.json() == response.json(), recovered.text + changed = await client.post(_batch_path(project), headers=headers, json={"source_id": alternate["source_id"]}) + assert changed.status_code == 409 and changed.json()["error"]["code"] == "task_import_idempotency_mismatch", changed.text + denied = await client.post(_batch_path(project), headers=auth_headers(), json={"source_id": unverified["source_id"]}) + assert denied.status_code == 409, denied.text + assert await _counts(project) == (1, 2, 2, 2, 2, 2) + + +async def test_existing_manual_external_id_rejects_every_row_without_partial_effects(import_source_client): + """Native external-ID uniqueness covers manual creation and whole-file rollback.""" + client = import_source_client + project = await _project(client) + payload = complete_task_payload() | {"external_task_id": "source-2"} + existing = await client.post(f"/api/v1/projects/{project}/tasks", headers=auth_headers(), json=payload) + assert existing.status_code == 201, existing.text + source = await _verified_source(client, project, document(3)) + rejected = await client.post(_batch_path(project), headers=auth_headers(), json={"source_id": source["source_id"]}) + assert rejected.status_code == 409 and rejected.json()["error"]["code"] == "task_import_external_id_conflict", rejected.text + assert rejected.json()["detail"] == [{"loc": ["tasks", 2, "external_task_id"], "type": "external_task_id_conflict"}] + assert await _counts(project) == (0, 0, 0, 1, 1, 1) + again = await client.post(f"/api/v1/projects/{project}/tasks", headers=auth_headers(), json=payload) + assert again.status_code == 409, again.text + other = await _project(client) + permitted = await client.post(f"/api/v1/projects/{other}/tasks", headers=auth_headers(), json=payload) + case = await client.post(f"/api/v1/projects/{project}/tasks", headers=auth_headers(), json=payload | {"external_task_id": "Source-2"}) + assert permitted.status_code == case.status_code == 201 + for _ in range(2): + nullable = await client.post(f"/api/v1/projects/{project}/tasks", headers=auth_headers(), json=complete_task_payload()) + assert nullable.status_code == 201, nullable.text + + +@pytest.mark.parametrize("failure", ["last_row", "after_all_rows"]) +async def test_late_failure_rolls_back_tasks_receipts_and_successful_evidence(import_source_client, monkeypatch, failure): + """Failure after successful staging leaves no batch or Task creation facts.""" + client = import_source_client + project = await _project(client) + source = await _verified_source(client, project, document(3)) + if failure == "last_row": + stage = AuthorizedTaskCommands.stage_creation + + async def fail_last(commands, prepared, decision): + result = await stage(commands, prepared, decision) + if result.external_task_id == "source-2": + raise RuntimeError("injected failure after the final canonical Task stage") + return result + + monkeypatch.setattr(AuthorizedTaskCommands, "stage_creation", fail_last) + else: + stage = TaskImportBatchCommands._stage_rows + + async def fail_complete(commands, *args, **kwargs): + await stage(commands, *args, **kwargs) + raise RuntimeError("injected failure after all Task and member stages") + + monkeypatch.setattr(TaskImportBatchCommands, "_stage_rows", fail_complete) + response = await client.post(_batch_path(project), headers=auth_headers(), json={"source_id": source["source_id"]}) + assert response.status_code == 500, response.text + assert await _counts(project) == (0, 0, 0, 0, 0, 0) + async with db_session.get_session_factory()() as session: + assert not list(await session.scalars(select(AuditEvent.id).where( + AuditEvent.project_id == project, AuditEvent.action_id.in_(["project.task.create", "project.task.import"]), + AuditEvent.event_type == "SensitiveAuthorizationAllowed", + ))) + assert await session.get(ArtifactTaskImportSource, source["source_id"]) is not None + + +async def test_matching_metadata_label_never_adds_native_membership(import_source_client): + """A manual Task cannot join a batch by spoofing its exposed metadata spelling.""" + client = import_source_client + project = await _project(client) + source = await _verified_source(client, project, document()) + imported = await client.post(_batch_path(project), headers=auth_headers(), json={"source_id": source["source_id"]}) + assert imported.status_code == 201, imported.text + batch = imported.json() + manual = await client.post(f"/api/v1/projects/{project}/tasks", headers=auth_headers(), + json=complete_task_payload() | {"import_batch_id": batch["batch_id"]}) + assert manual.status_code == 201, manual.text + status = await client.get(_batch_path(project) + "/" + batch["batch_id"], headers=auth_headers()) + assert status.status_code == 200 and status.json()["creation"] == batch + assert [row["task_id"] for row in status.json()["current_tasks"]] == [batch["tasks"][0]["id"]] + assert await _counts(project) == (1, 1, 1, 2, 2, 2) + + +async def test_ungranted_actor_cannot_replay_or_read_committed_batch(import_source_client, monkeypatch): + """A role claim never grants current source or immutable batch authority.""" + client = import_source_client + project = await _project(client) + source = await _verified_source(client, project, document()) + headers = auth_headers() + imported = await client.post(_batch_path(project), headers=headers, json={"source_id": source["source_id"]}) + assert imported.status_code == 201, imported.text + before = await _counts(project) + set_dev_actor(monkeypatch, roles="project_manager", subject="ungranted-batch-manager") + captured = [] + restage = PreparedTaskImportSourceAuthorization.restage_denial + + async def observe(authority, error): + captured.append((error.__cause__.decision, authority._context.actor_profile_id)) + await restage(authority, error) + + monkeypatch.setattr(PreparedTaskImportSourceAuthorization, "restage_denial", observe) + for request_headers in (headers, auth_headers()): + denied = await client.post(_batch_path(project), headers=request_headers, json={"source_id": source["source_id"]}) + assert denied.status_code == 403, denied.text + hidden = await client.get(_batch_path(project) + "/" + imported.json()["batch_id"], headers=auth_headers()) + assert hidden.status_code == 404, hidden.text + assert await _counts(project) == before + async with db_session.get_session_factory()() as session: + events = list(await session.scalars(select(AuditEvent).where( + AuditEvent.action_id == "artifact.task_import_source.read", + AuditEvent.event_type == "SensitiveAuthorizationDenied", + ))) + decisions = {str(decision.decision_id): (decision, actor) for decision, actor in captured} + assert len(events) == len(decisions) == 3 + assert set(decisions) == {event.id for event in events} + assert all(event.actor_id == str(decisions[event.id][1]) + and event.request_id == str(decisions[event.id][0].request_id) + and event.action_id == decisions[event.id][0].action_id.value + and event.denial_code == "permission_not_granted" + and event.after_facts["resource_context_digest"] == decisions[event.id][0].resource_context_digest + for event in events) + + +async def test_two_import_roots_wait_on_actual_file_custody_then_recover_one_batch(import_source_client, monkeypatch): + """A gated PostgreSQL wait proves concurrent first imports share one original.""" + client = import_source_client + project = await _project(client) + source = await _verified_source(client, project, document(3)) + original = TaskImportBatchCommands._reserve_batch + first_reserved, second_entered, release = asyncio.Event(), asyncio.Event(), asyncio.Event() + pids, calls = [], 0 + + async def gated(commands, *args, **kwargs): + nonlocal calls + calls += 1 + call = calls + pids.append(await commands._session.scalar(select(func.pg_backend_pid()))) + if call == 2: + second_entered.set() + batch = await original(commands, *args, **kwargs) + if call == 1: + first_reserved.set() + await asyncio.wait_for(release.wait(), timeout=30) + return batch + + monkeypatch.setattr(TaskImportBatchCommands, "_reserve_batch", gated) + path, payload = _batch_path(project), {"source_id": source["source_id"]} + first = asyncio.create_task(client.post(path, headers=auth_headers(), json=payload)) + second = None + try: + await asyncio.wait_for(first_reserved.wait(), timeout=30) + second = asyncio.create_task(client.post(path, headers=auth_headers(), json=payload)) + await asyncio.wait_for(second_entered.wait(), timeout=30) + deadline = asyncio.get_running_loop().time() + 10 + async with db_session.get_session_factory()() as observer: + while True: + blocked = await observer.scalar(text("select :holder = any(pg_blocking_pids(:waiter))"), + {"holder": pids[0], "waiter": pids[1]}) + if blocked: + break + assert asyncio.get_running_loop().time() < deadline, "second root never waited on the original file holder" + await asyncio.sleep(0.05) + release.set() + responses = await asyncio.wait_for(asyncio.gather(first, second), timeout=30) + assert [response.status_code for response in responses] == [201, 201], [response.text for response in responses] + assert responses[0].json() == responses[1].json() + assert await _counts(project) == (1, 3, 2, 3, 3, 3) + finally: + release.set() + for pending in (first, second): + if pending is not None and not pending.done(): + pending.cancel() + await asyncio.gather(*(pending for pending in (first, second) if pending is not None), return_exceptions=True) + + +@pytest.mark.parametrize("table", ["task_import_batches", "task_import_batch_members", "task_import_batch_command_receipts"]) +@pytest.mark.parametrize("operation", ["update", "delete", "truncate"]) +async def test_committed_custody_rejects_direct_sql_mutation(import_source_client, table, operation): + """Each native table refuses row mutation and statement-level truncation.""" + client = import_source_client + project = await _project(client) + source = await _verified_source(client, project, document()) + imported = await client.post(_batch_path(project), headers=auth_headers(), json={"source_id": source["source_id"]}) + assert imported.status_code == 201, imported.text + async with db_session.get_session_factory()() as session, session.begin(): + before = list((await session.execute(text(f"select to_jsonb(t) from {table} t order by id"))).scalars()) + if operation == "truncate": + assert await session.scalar(text( + "select count(*) from pg_trigger where tgrelid=cast(:table as regclass) " + "and not tgisinternal and (tgtype & 32)=32 and (tgtype & 1)=0 and tgenabled='O'" + ), {"table": table}) == 1, "each owner requires its own enabled statement-level TRUNCATE guard" + updates = { + "task_import_batches": "metadata_label='changed display label'", + "task_import_batch_members": "row_index=1", + "task_import_batch_command_receipts": "request_digest='sha256:" + "a" * 64 + "'", + } + statement = {"update": f"update {table} set {updates[table]}", "delete": f"delete from {table}", + "truncate": f"truncate {table} cascade"}[operation] + with pytest.raises(DBAPIError): + async with session.begin_nested(): + await session.execute(text(statement)) + assert list((await session.execute(text(f"select to_jsonb(t) from {table} t order by id"))).scalars()) == before + recovered = await client.post(_batch_path(project), headers=auth_headers(), json={"source_id": source["source_id"]}) + assert recovered.status_code == 201 and recovered.json() == imported.json(), recovered.text diff --git a/backend/tests/test_ci_lane_catalogue.py b/backend/tests/test_ci_lane_catalogue.py index c0fd07cc9..bbcfe65af 100644 --- a/backend/tests/test_ci_lane_catalogue.py +++ b/backend/tests/test_ci_lane_catalogue.py @@ -299,6 +299,9 @@ def test_measured_hotspots_have_explicit_semantic_owners() -> None: "tests/tasks/test_public_queues.py", "tests/tasks/test_locked_compensation.py", "tests/tasks/test_task_import_contract.py", + "tests/tasks/test_task_import_batch_contract.py", + "tests/tasks/test_task_import_batch_bindings.py", + "tests/tasks/test_task_import_batches.py", "tests/authorization/task_queues/test_authority.py", "tests/authorization/task_queues/test_contracts.py", "tests/authorization/task_queues/test_transactions.py", From 4a6d00fc8e40ba35a2ba6bbfb5703fbe3dc0c66d Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 12:16:06 +0100 Subject: [PATCH 019/283] test(tasks): cover native import closure and competing covered actors --- .../pilot02-atomic-json-draft-import.md | 2 +- .../tests/tasks/test_task_import_batches.py | 251 +++++++++++++++++- 2 files changed, 249 insertions(+), 4 deletions(-) diff --git a/.commitrail/changes/pilot02-atomic-json-draft-import.md b/.commitrail/changes/pilot02-atomic-json-draft-import.md index 0a30c32e9..f46acfe2e 100644 --- a/.commitrail/changes/pilot02-atomic-json-draft-import.md +++ b/.commitrail/changes/pilot02-atomic-json-draft-import.md @@ -447,7 +447,7 @@ never silently reinterprets retained rows under a later mapping. | Canonical creation participant | Exact `59d47a6c` isolated native execution of five retained CREATE, denial, rollback and receipt controls | 5 passed in 69.02 seconds; schema `0031_task_import_source`; owned database/role/MinIO cleanup complete | Proves preservation of normal creation; no atomic batch success claim | | Source consumer and current CREATE participants | Exact `37d8705d` isolated execution of actual immutable-binding substitution/provider-health, public source, canonical denial, CREATE rollback and receipt controls | 10 passed in 120.95 seconds; runner exit 0, schema `0031_task_import_source`; owned database/role/MinIO cleanup complete | Raw `/tmp/pilot02-atomic-37d-source-create-corrected.log` and `.json`; validates existing owner integration, not installed batch schema | | Current owners and concrete gap | Inspect source port/parser, TASK create/replay/models and Issue 489 | Canonical caller-root phases, closed batch DTOs, model representations, ART immutable-binding participant and batch/root/AUTH composition are implemented | New table constraints and guards require sole-author DDL and native proof | -| Public import and atomic effects | Planned isolated runner: `pytest -q tests/tasks/test_task_import_batches.py` with real PostgreSQL 16/MinIO | Eighteen native acceptance cases collect; not executed because batch schema is not installed | Actual 200-Task creation, immutable replay, late-stage rollback, direct SQL guards and intermediate-wait controls must pass after sole-author DDL | +| Public import and atomic effects | Planned isolated runner: `pytest -q tests/tasks/test_task_import_batches.py` with real PostgreSQL 16/MinIO | Twenty-four native acceptance cases collect; not executed because batch schema is not installed | Actual 200-Task creation, immutable replay, late-stage rollback, direct SQL guards, exact original-authority revocation and intermediate-wait controls must pass after sole-author DDL | | Schema, guards and complete integration | Sole-author native graph/reset/UUID proof, affected guards, complete hosted lanes and aggregate | Not run for this chunk | Exact frozen candidate, actual merge tree and cleanup required | ## Review findings diff --git a/backend/tests/tasks/test_task_import_batches.py b/backend/tests/tasks/test_task_import_batches.py index 54ddd0d28..cec3175de 100644 --- a/backend/tests/tasks/test_task_import_batches.py +++ b/backend/tests/tasks/test_task_import_batches.py @@ -239,8 +239,9 @@ async def test_matching_metadata_label_never_adds_native_membership(import_sourc assert await _counts(project) == (1, 1, 1, 2, 2, 2) -async def test_ungranted_actor_cannot_replay_or_read_committed_batch(import_source_client, monkeypatch): - """A role claim never grants current source or immutable batch authority.""" +@pytest.mark.parametrize("authority", ["ungranted_actor", "revoked_original"]) +async def test_missing_current_authority_cannot_replay_or_read_committed_batch(import_source_client, monkeypatch, authority): + """Original receipts and claimed roles cannot replace current covered authority.""" client = import_source_client project = await _project(client) source = await _verified_source(client, project, document()) @@ -248,7 +249,22 @@ async def test_ungranted_actor_cannot_replay_or_read_committed_batch(import_sour imported = await client.post(_batch_path(project), headers=headers, json={"source_id": source["source_id"]}) assert imported.status_code == 201, imported.text before = await _counts(project) - set_dev_actor(monkeypatch, roles="project_manager", subject="ungranted-batch-manager") + if authority == "ungranted_actor": + set_dev_actor(monkeypatch, roles="project_manager", subject="ungranted-batch-manager") + else: + from app.modules.authorization.models import AdminRoleGrant + from tests.authorization.guide_activation.pg_support import revoke_manager_grant + from tests.authorization.task_authority.test_concurrency import actor_context + async with db_session.get_session_factory()() as session: + parent = await session.get(ArtifactTaskImportSource, source["source_id"]) + grant = (await session.scalars(select(AdminRoleGrant).where( + AdminRoleGrant.target_actor_profile_id == parent.actor_profile_id, + AdminRoleGrant.role == "project_manager", AdminRoleGrant.status == "active", + ))).one() + grant_id, administrator_id = grant.id, grant.granted_by_actor_profile_id + administrator = await actor_context(administrator_id) + async with db_session.get_session_factory()() as session, session.begin(): + await revoke_manager_grant(session, administrator, grant_id) captured = [] restage = PreparedTaskImportSourceAuthorization.restage_denial @@ -331,6 +347,235 @@ async def gated(commands, *args, **kwargs): await asyncio.gather(*(pending for pending in (first, second) if pending is not None), return_exceptions=True) +async def test_distinct_covered_actors_with_reversed_ids_wait_then_roll_back_one_import(import_source_client, monkeypatch): + """Sorted unique-key writes avoid crossed waits between independently covered actors.""" + from uuid import UUID + from app.adapters.artifacts import task_import_source_commands + from app.adapters.audit import task_transition_audit + from app.adapters.tasks import task_import_batch_commands + from app.core.config import get_settings + from app.modules.authorization.task_authorization import PreparedTaskAuthorization + from app.modules.tasks.schemas import TaskImportBatchResponse + from app.modules.tasks.task_import_batches import TaskImportBatchError + from tests.authorization.task_authority.test_concurrency import actor_context + from tests.project_create_fixtures import grant_system_project_manager + + client = import_source_client + project = await _project(client) + value = document(2) + source = await _verified_source(client, project, value) + async with db_session.get_session_factory()() as session: + original_source = await session.get(ArtifactTaskImportSource, source["source_id"]) + first_context = await actor_context(original_source.actor_profile_id) + set_dev_actor(monkeypatch, roles="project_manager", subject="second-covered-importer") + admitted = await client.get("/api/v1/actors/me", headers=auth_headers()) + assert admitted.status_code == 200, admitted.text + async with db_session.get_session_factory()() as session, session.begin(): + link, _ = await grant_system_project_manager(session, issuer="flow-test", subject="second-covered-importer") + second_actor = link.actor_profile_id + second_context = await actor_context(second_actor) + value["tasks"].reverse() + alternate = await _verified_source(client, project, value) + first_written, second_entered, release = asyncio.Event(), asyncio.Event(), asyncio.Event() + pids, first_calls, second_calls = {}, 0, 0 + original = AuthorizedTaskCommands.stage_creation + + async def gate(commands, *args, **kwargs): + nonlocal first_calls, second_calls + actor = commands._actor_id + if actor == first_context.actor_profile_id: + first_calls += 1 + if first_calls == 1: + pids["first"] = await commands._session.scalar(select(func.pg_backend_pid())) + else: + second_calls += 1 + if second_calls == 1: + pids["second"] = await commands._session.scalar(select(func.pg_backend_pid())) + second_entered.set() + result = await original(commands, *args, **kwargs) + if actor == first_context.actor_profile_id and first_calls == 1: + first_written.set() + await asyncio.wait_for(release.wait(), timeout=30) + return result + + async def run(context, selected_source): + async with db_session.get_session_factory()() as session: + commands = task_import_batch_commands( + session, authorization=PreparedTaskAuthorization(session, context), audit=task_transition_audit(session), + actor_profile_id=context.actor_profile_id, identity_link_id=context.identity_link_id, settings=get_settings(), + source=task_import_source_commands(session, settings=get_settings(), context=context), + ) + return await commands.import_source(UUID(project), UUID(selected_source), idempotency_key=uuid4()) + + monkeypatch.setattr(AuthorizedTaskCommands, "stage_creation", gate) + first = asyncio.create_task(run(first_context, source["source_id"])) + second = None + try: + await asyncio.wait_for(first_written.wait(), timeout=30) + second = asyncio.create_task(run(second_context, alternate["source_id"])) + await asyncio.wait_for(second_entered.wait(), timeout=30) + deadline = asyncio.get_running_loop().time() + 10 + async with db_session.get_session_factory()() as observer: + while True: + blocked = await observer.scalar(text("select :holder = any(pg_blocking_pids(:waiter))"), + {"holder": pids["first"], "waiter": pids["second"]}) + if blocked: + break + assert asyncio.get_running_loop().time() < deadline, "competing sorted uniqueness write never waited" + await asyncio.sleep(0.05) + release.set() + outcomes = await asyncio.wait_for(asyncio.gather(first, second, return_exceptions=True), timeout=30) + assert isinstance(outcomes[0], TaskImportBatchResponse), outcomes + assert isinstance(outcomes[1], TaskImportBatchError) and outcomes[1].code == "task_import_external_id_conflict", outcomes + assert await _counts(project) == (1, 2, 1, 2, 2, 2) + finally: + release.set() + for pending in (first, second): + if pending is not None and not pending.done(): + pending.cancel() + await asyncio.gather(*(pending for pending in (first, second) if pending is not None), return_exceptions=True) + + +async def test_normal_create_takes_common_authority_before_competing_external_id(import_source_client, monkeypatch): + """Normal create waits on the import's AUTH custody before touching uniqueness.""" + from uuid import UUID + from app.adapters.audit import task_transition_audit + from app.adapters.tasks import task_commands + from app.core.config import get_settings + from app.modules.authorization.task_authorization import PreparedTaskAuthorization + from app.modules.tasks.command_replay import TaskReplayConflict + from app.modules.tasks.schemas import TaskCreate + from tests.authorization.task_authority.test_concurrency import actor_context + + client = import_source_client + project = await _project(client) + source = await _verified_source(client, project, document(2)) + async with db_session.get_session_factory()() as session: + parent = await session.get(ArtifactTaskImportSource, source["source_id"]) + context = await actor_context(parent.actor_profile_id) + held, entered, release = asyncio.Event(), asyncio.Event(), asyncio.Event() + pids = {} + stage, authorize = TaskImportBatchCommands._stage_rows, AuthorizedTaskCommands.authorize_creation + + async def hold_import(commands, *args, **kwargs): + result = await stage(commands, *args, **kwargs) + pids["holder"] = await commands._session.scalar(select(func.pg_backend_pid())) + held.set() + await asyncio.wait_for(release.wait(), timeout=30) + return result + + async def observe_manual(commands, prepared): + if json.loads(prepared.payload_json)["source_type"] == "manual": + pids["waiter"] = await commands._session.scalar(select(func.pg_backend_pid())) + entered.set() + return await authorize(commands, prepared) + + async def manual_create(): + async with db_session.get_session_factory()() as session: + commands = task_commands(session, authorization=PreparedTaskAuthorization(session, context), + audit=task_transition_audit(session), actor_profile_id=context.actor_profile_id, + settings=get_settings()) + return await commands.create_task(UUID(project), TaskCreate(**(complete_task_payload() | { + "external_task_id": "source-0", + })), idempotency_key=uuid4()) + + monkeypatch.setattr(TaskImportBatchCommands, "_stage_rows", hold_import) + monkeypatch.setattr(AuthorizedTaskCommands, "authorize_creation", observe_manual) + first = asyncio.create_task(client.post(_batch_path(project), headers=auth_headers(), json={"source_id": source["source_id"]})) + second = None + try: + await asyncio.wait_for(held.wait(), timeout=30) + second = asyncio.create_task(manual_create()) + await asyncio.wait_for(entered.wait(), timeout=30) + deadline = asyncio.get_running_loop().time() + 10 + async with db_session.get_session_factory()() as observer: + while True: + blocked = await observer.scalar(text("select :holder = any(pg_blocking_pids(:waiter))"), pids) + if blocked: + break + assert asyncio.get_running_loop().time() < deadline, "normal CREATE never waited on the import authority holder" + await asyncio.sleep(0.05) + release.set() + outcomes = await asyncio.wait_for(asyncio.gather(first, second, return_exceptions=True), timeout=30) + assert outcomes[0].status_code == 201, outcomes[0].text + assert isinstance(outcomes[1], TaskReplayConflict) and outcomes[1].code == "external_task_id_conflict", outcomes + assert await _counts(project) == (1, 2, 1, 2, 2, 2) + finally: + release.set() + for pending in (first, second): + if pending is not None and not pending.done(): + pending.cancel() + await asyncio.gather(*(pending for pending in (first, second) if pending is not None), return_exceptions=True) + + +@pytest.mark.parametrize("substitution", ["foreign_verification", "foreign_task", "pending_header"]) +async def test_native_commit_refuses_partial_or_foreign_custody(import_source_client, monkeypatch, substitution): + """Native closure rejects corruption after genuine ART and CREATE validation.""" + client = import_source_client + project = await _project(client) + value = document(2) + source = await _verified_source(client, project, value) + foreign_receipt, foreign_task = None, None + if substitution == "foreign_verification": + alternate = await _verified_source(client, project, value) + from app.modules.artifacts.models import ArtifactPutAttempt, ArtifactVerificationJob, ArtifactVerificationReceipt + async with db_session.get_session_factory()() as session: + foreign_receipt = await session.scalar(select(ArtifactVerificationReceipt.id).join( + ArtifactVerificationJob, ArtifactVerificationJob.id == ArtifactVerificationReceipt.verification_job_id, + ).join(ArtifactPutAttempt, ArtifactPutAttempt.id == ArtifactVerificationJob.originating_put_attempt_id).where( + ArtifactPutAttempt.task_import_source_id == alternate["source_id"], + ).order_by(ArtifactVerificationReceipt.created_at.desc()).limit(1)) + assert foreign_receipt is not None + elif substitution == "foreign_task": + created = await client.post(f"/api/v1/projects/{project}/tasks", headers=auth_headers(), json=complete_task_payload()) + assert created.status_code == 201, created.text + foreign_task = created.json()["id"] + before = await _counts(project) + original = TaskImportBatchCommands._stage_rows + + async def corrupt(commands, batch, parsed, prepared): + result = await original(commands, batch, parsed, prepared) + if substitution == "foreign_task": + # Corrupt the final, not-yet-flushed member INSERT so an existing + # append-only UPDATE guard cannot mask a missing initial binding. + members = [row for row in commands._session.new if isinstance(row, TaskImportBatchMember)] + assert len(members) == 1 + members[0].task_id = foreign_task + return result + + monkeypatch.setattr(TaskImportBatchCommands, "_stage_rows", corrupt) + if substitution == "foreign_verification": + from app.modules.tasks import task_import_batches as owner + stage_binding = owner._stage_binding + + def corrupt_header(row, binding): + stage_binding(row, binding) + if isinstance(row, TaskImportBatch): + row.verification_receipt_id = str(foreign_receipt) + + monkeypatch.setattr(owner, "_stage_binding", corrupt_header) + elif substitution == "pending_header": + from sqlalchemy import event + from sqlalchemy.orm import Session + + def retain_pending(session, flush_context, instances): + for row in list(session.dirty): + if isinstance(row, TaskImportBatch): + # Discard completion entirely. No invalid header UPDATE or + # CHECK can mask the missing deferred reservation closure. + session.expire(row) + + event.listen(Session, "before_flush", retain_pending) + try: + rejected = await client.post(_batch_path(project), headers=auth_headers(), json={"source_id": source["source_id"]}) + assert rejected.status_code == 503, rejected.text + assert rejected.json()["error"]["retryable"] is True + assert await _counts(project) == before + finally: + if substitution == "pending_header": + event.remove(Session, "before_flush", retain_pending) + + @pytest.mark.parametrize("table", ["task_import_batches", "task_import_batch_members", "task_import_batch_command_receipts"]) @pytest.mark.parametrize("operation", ["update", "delete", "truncate"]) async def test_committed_custody_rejects_direct_sql_mutation(import_source_client, table, operation): From 96b1fb820fecdde86e034af0679195fc1940b8b0 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 13:15:29 +0100 Subject: [PATCH 020/283] refactor(tasks): compose canonical transitions and native batch membership --- .../tasks/api/task_import_membership.py | 26 ++++ .../app/modules/tasks/authorized_commands.py | 136 ++++++++++++++---- backend/app/modules/tasks/router.py | 3 +- .../app/modules/tasks/task_import_batches.py | 45 +----- .../modules/tasks/task_import_membership.py | 86 +++++++++++ .../test_management_participants.py | 109 ++++++++++++++ .../tests/tasks/test_task_import_batches.py | 2 +- 7 files changed, 334 insertions(+), 73 deletions(-) create mode 100644 backend/app/modules/tasks/api/task_import_membership.py create mode 100644 backend/app/modules/tasks/task_import_membership.py create mode 100644 backend/tests/authorization/task_authority/test_management_participants.py diff --git a/backend/app/modules/tasks/api/task_import_membership.py b/backend/app/modules/tasks/api/task_import_membership.py new file mode 100644 index 000000000..1a1d593f5 --- /dev/null +++ b/backend/app/modules/tasks/api/task_import_membership.py @@ -0,0 +1,26 @@ +"""Native immutable import membership; these facts never grant Task authority.""" + +from dataclasses import dataclass +from uuid import UUID + + +class TaskImportBatchError(RuntimeError): + """A controlled batch outcome with bounded document-row diagnostics.""" + + def __init__(self, code: str, status_code: int, row_indexes: tuple[int, ...] = ()): + self.code, self.status_code, self.row_indexes = code, status_code, row_indexes + super().__init__(code) + + +@dataclass(frozen=True, slots=True) +class TaskImportMemberIdentity: + """One actual ordered native row and its original canonical CREATE custody.""" + + member_id: UUID + task_id: UUID + row_index: int + external_task_id: str + row_digest: str + create_idempotency_key: UUID + task_command_receipt_id: UUID + authorization_decision_id: UUID diff --git a/backend/app/modules/tasks/authorized_commands.py b/backend/app/modules/tasks/authorized_commands.py index f276e04ac..907398c46 100644 --- a/backend/app/modules/tasks/authorized_commands.py +++ b/backend/app/modules/tasks/authorized_commands.py @@ -71,6 +71,21 @@ class TaskCreationPreparation: transaction: AsyncSessionTransaction +@dataclass(frozen=True, slots=True) +class TaskTransitionPreparation: + """TASK/assignment custody and exact current facts retained in one caller root.""" + + task: WorkstreamTask + assignment: TaskAssignment | None + operation: TaskAuthorityOperation + reason: str | None + receipt: TaskCommandReceipt + request_digest: str + reserved: bool + facts: TaskAuthorityFacts + transaction: AsyncSessionTransaction + + class AuthorizedTaskCommands: """TASK owns state and assignment; AUTH owns permission and current grants.""" @@ -144,10 +159,13 @@ async def _locked_task( if request_digest is not None: facts = replace(facts, request_digest=request_digest, replay_command_id=self._replay.manager_replay(receipt, operation, task_id, self._actor_id, idempotency_key) if receipt else None) + decision = await self._authorize_facts(facts) + return task, assignment, decision + + async def _authorize_facts(self, facts: TaskAuthorityFacts) -> TaskAuthorityDecision: handle = await self._authorization.prepare(facts) try: - decision_id = await self._authorization.consume(handle, facts) - return task, assignment, decision_id + return await self._authorization.consume(handle, facts) finally: self._authorization.close(handle) @@ -238,35 +256,91 @@ async def _manage_transition( self, task_id: UUID, operation: TaskAuthorityOperation, reason: str | None, key: UUID, ) -> TaskResponse: async with self._session.begin(): - receipt, digest, reserved = await self._replay.reserve(self._actor_id, operation, key, task_id, reason) - task, assignment, decision_id = await self._locked_task( - task_id, operation, reason, idempotency_key=key, receipt=receipt, request_digest=digest, - ) - replayed = self._replay.recover(receipt, digest, self._facts(task, assignment, operation, reason), - task, assignment, reserved=reserved) - if replayed is not None: - return replayed - before = task.status - target = "screening" if operation is TaskAuthorityOperation.SCREEN else "ready" - self._contexts._ensure_transition_allowed(before, target) - if operation is TaskAuthorityOperation.SCREEN: - context = await self._contexts._load_active_policy_context(task.project_id) - self._contexts._validate_task_contract_fields(task) - self._contexts._stamp_locked_context(task, context) - else: - if not reason or not reason.strip(): - raise TaskValidationError("release decision reason is required") - self._contexts._ensure_locked_context(task) - context = await self._contexts._load_locked_task_context(task) - self._contexts._validate_installed_plans(context.facts) - task.status = target - await self._session.flush() - await self._record_management(task, operation, decision_id, before, reason) - await self._session.flush() - await self._session.refresh(task) - response = self._contexts.task_response_for_authority(task, can_manage=True) - self._replay.complete(receipt, None, self._facts(task, None, operation, reason), response) - await self._session.flush() + prepared = await self.prepare_transition(task_id, operation, reason, idempotency_key=key) + decision = await self.authorize_transition(prepared) + response = await self.stage_transition(prepared, decision) + return response + + async def prepare_transition( + self, task_id: UUID, operation: TaskAuthorityOperation, reason: str | None, + *, idempotency_key: UUID, project_id: UUID | None = None, + ) -> TaskTransitionPreparation: + """Reserve canonical retry custody and lock TASK before the caller takes AUTH.""" + if operation not in {TaskAuthorityOperation.SCREEN, TaskAuthorityOperation.RELEASE}: + raise ValueError("task transition participant supports SCREEN/RELEASE only") + transaction = self._session.get_transaction() + if transaction is None or not transaction.is_active: + raise RuntimeError("task transition preparation requires the caller transaction") + receipt, digest, reserved = await self._replay.reserve( + self._actor_id, operation, idempotency_key, task_id, reason, + ) + task = (await self._repo.lock_project_task(project_id, task_id) if project_id is not None + else await self._repo.get_task(str(task_id), for_update=True)) + if task is None: + raise TaskNotFound("task not found") + assignment = await self._repo.get_active_assignment(task.id, for_update=True) + facts = replace( + self._facts(task, assignment, operation, reason, idempotency_key), request_digest=digest, + replay_command_id=self._replay.manager_replay(receipt, operation, task_id, self._actor_id, idempotency_key), + ) + return TaskTransitionPreparation(task, assignment, operation, reason, receipt, digest, + reserved, facts, transaction) + + def _validate_transition_preparation(self, prepared: TaskTransitionPreparation) -> None: + if (self._session.get_transaction() is not prepared.transaction or not prepared.transaction.is_active + or prepared.facts.actor_profile_id != self._actor_id): + raise RuntimeError("task transition requires its original caller transaction") + current = replace( + self._facts(prepared.task, prepared.assignment, prepared.operation, prepared.reason, + prepared.facts.idempotency_key), request_digest=prepared.request_digest, + replay_command_id=self._replay.manager_replay( + prepared.receipt, prepared.operation, UUID(prepared.task.id), self._actor_id, + prepared.facts.idempotency_key, + ), + ) + if (current != prepared.facts + or prepared.request_digest != canonical_json_hash({"task_id": prepared.task.id, "reason": prepared.reason})): + raise TaskValidationError("task transition preparation changed") + + async def authorize_transition(self, prepared: TaskTransitionPreparation) -> TaskAuthorityDecision: + """Consume fresh exact per-Task authority after all caller preparation locks.""" + self._validate_transition_preparation(prepared) + return await self._authorize_facts(prepared.facts) + + async def stage_transition( + self, prepared: TaskTransitionPreparation, decision: TaskAuthorityDecision, + ) -> TaskResponse: + """Flush the normal transition, guide locks, audit and receipt in the caller root.""" + self._validate_transition_preparation(prepared) + task, assignment, operation, reason = (prepared.task, prepared.assignment, + prepared.operation, prepared.reason) + replayed = self._replay.recover( + prepared.receipt, prepared.request_digest, self._facts(task, assignment, operation, reason), + task, assignment, reserved=prepared.reserved, + ) + if replayed is not None: + return replayed + before = task.status + target = "screening" if operation is TaskAuthorityOperation.SCREEN else "ready" + self._contexts._ensure_transition_allowed(before, target) + if operation is TaskAuthorityOperation.SCREEN: + context = await self._contexts._load_active_policy_context(task.project_id) + self._contexts._validate_task_contract_fields(task) + self._contexts._stamp_locked_context(task, context) + else: + if not reason or not reason.strip(): + raise TaskValidationError("release decision reason is required") + self._contexts._ensure_locked_context(task) + context = await self._contexts._load_locked_task_context(task) + self._contexts._validate_installed_plans(context.facts) + task.status = target + await self._session.flush() + await self._record_management(task, operation, decision, before, reason) + await self._session.flush() + await self._session.refresh(task) + response = self._contexts.task_response_for_authority(task, can_manage=True) + self._replay.complete(prepared.receipt, None, self._facts(task, None, operation, reason), response) + await self._session.flush() return response async def _record_management( diff --git a/backend/app/modules/tasks/router.py b/backend/app/modules/tasks/router.py index fcce0ec39..5635208b7 100644 --- a/backend/app/modules/tasks/router.py +++ b/backend/app/modules/tasks/router.py @@ -27,7 +27,8 @@ TaskWithAssignmentResponse, ) from app.modules.tasks.service import TaskProjectNotReady, TaskServiceError, TaskNotFound -from app.modules.tasks.task_import_batches import TaskImportBatchCommands, TaskImportBatchError +from app.modules.tasks.task_import_batches import TaskImportBatchCommands +from app.modules.tasks.api.task_import_membership import TaskImportBatchError from app.modules.tasks.api.task_import import TaskImportBatchAction from app.modules.tasks.schemas import TaskImportBatchRequest, TaskImportBatchResponse, TaskImportBatchStatus from app.interfaces.artifacts import ArtifactStoreError diff --git a/backend/app/modules/tasks/task_import_batches.py b/backend/app/modules/tasks/task_import_batches.py index 75b0f463e..b54dbbfaf 100644 --- a/backend/app/modules/tasks/task_import_batches.py +++ b/backend/app/modules/tasks/task_import_batches.py @@ -15,24 +15,18 @@ TaskImportBatchAction, TaskImportBatchAuthorityFacts, TaskImportBatchAuthorizationPort, TaskImportRow, parse_task_import, ) +from app.modules.tasks.api.task_import_membership import TaskImportBatchError +from app.modules.tasks.task_import_membership import TaskImportMembership from app.modules.tasks.authorized_commands import AuthorizedTaskCommands, TaskCreationPreparation from app.modules.tasks.command_replay import TaskReplayConflict from app.modules.tasks.models import ( - TaskCommandReceipt, TaskImportBatch, TaskImportBatchCommandReceipt, TaskImportBatchMember, WorkstreamTask, + TaskImportBatch, TaskImportBatchCommandReceipt, TaskImportBatchMember, WorkstreamTask, ) from app.modules.tasks.schemas import ( ImportedTaskCreate, TaskImportBatchResponse, TaskImportBatchCurrentTask, TaskImportBatchStatus, ) -class TaskImportBatchError(RuntimeError): - """A controlled batch outcome with bounded document-row diagnostics.""" - - def __init__(self, code: str, status_code: int, row_indexes: tuple[int, ...] = ()): - self.code, self.status_code, self.row_indexes = code, status_code, row_indexes - super().__init__(code) - - def imported_task_payload(row: TaskImportRow, source: TaskImportSourceCommitment, batch_id: UUID) -> ImportedTaskCreate: """Map instructions directly and stamp provenance solely from actual native custody.""" return ImportedTaskCreate( @@ -197,37 +191,8 @@ async def _prepare_sources( return selected async def _original_response(self, batch: TaskImportBatch) -> TaskImportBatchResponse: - """Recover immutable creation facts; mutable Task state is not replay input.""" - response = TaskImportBatchResponse.model_validate(batch.response) - if (str(response.batch_id), str(response.project_id), str(response.source_id), response.sha256, - response.byte_count, response.row_count, response.schema_version, response.mapping_version) != ( - batch.id, batch.project_id, batch.source_id, batch.sha256, batch.byte_count, batch.row_count, - batch.schema_version, batch.mapping_version, - ): - raise TaskImportBatchError("task_import_batch_custody_invalid", 409) - rows = (await self._session.execute(select(TaskImportBatchMember, TaskCommandReceipt).join( - TaskCommandReceipt, TaskCommandReceipt.id == TaskImportBatchMember.task_command_receipt_id, - ).where(TaskImportBatchMember.batch_id == batch.id).order_by(TaskImportBatchMember.row_index))).all() - if len(rows) != batch.row_count: - raise TaskImportBatchError("task_import_batch_custody_invalid", 409) - manifest = {"schema_version": response.schema_version, "metadata": {"label": response.label}, - "tasks": [{field: getattr(task, field) for field in TaskImportRow.model_fields} for task in response.tasks]} - if response.label != batch.metadata_label or canonical_json_hash(manifest) != batch.manifest_digest: - raise TaskImportBatchError("task_import_batch_custody_invalid", 409) - for index, (member, receipt) in enumerate(rows): - original = response.tasks[index] - instructions = {field: getattr(original, field) for field in TaskImportRow.model_fields} - if (member.row_index != index or member.project_id != batch.project_id or member.task_id != original.id - or member.external_task_id != original.external_task_id - or member.row_digest != canonical_json_hash(instructions) - or member.response != original.model_dump(mode="json") - or receipt.response != member.response or receipt.status != "committed" - or receipt.action_id != "project.task.create" or receipt.task_id != member.task_id - or receipt.actor_profile_id != batch.actor_profile_id - or receipt.idempotency_key != member.create_idempotency_key - or original.created_by != batch.actor_profile_id): - raise TaskImportBatchError("task_import_batch_custody_invalid", 409) - return response + """Recover immutable creation facts through the one native membership owner.""" + return (await TaskImportMembership(self._session).validate(batch)).creation async def _stage_rows( self, batch: TaskImportBatch, parsed: ParsedTaskImport, diff --git a/backend/app/modules/tasks/task_import_membership.py b/backend/app/modules/tasks/task_import_membership.py new file mode 100644 index 000000000..280686c35 --- /dev/null +++ b/backend/app/modules/tasks/task_import_membership.py @@ -0,0 +1,86 @@ +"""One native membership validator shared by import/status and bulk transitions.""" + +from dataclasses import dataclass +from uuid import UUID + +from sqlalchemy import select +from sqlalchemy.ext.asyncio import AsyncSession + +from app.core.hashing import canonical_json_hash +from app.modules.tasks.api.task_import import TaskImportRow +from app.modules.tasks.api.task_import_membership import ( + TaskImportBatchError, TaskImportMemberIdentity, +) +from app.modules.tasks.models import TaskCommandReceipt, TaskImportBatch, TaskImportBatchMember +from app.modules.tasks.schemas import TaskImportBatchResponse + + +@dataclass(frozen=True, slots=True) +class TaskImportMembershipSnapshot: + """TASK-internal typed original response plus complete immutable member custody.""" + + creation: TaskImportBatchResponse + manifest_digest: str + members: tuple[TaskImportMemberIdentity, ...] + + +class TaskImportMembership: + """Read actual immutable rows; caller AUTH remains separate and mandatory.""" + + def __init__(self, session: AsyncSession): + self._session = session + + async def prepare(self, project_id: UUID, batch_id: UUID) -> TaskImportMembershipSnapshot: + """Select only a committed native batch in the existing caller transaction.""" + transaction = self._session.get_transaction() + if transaction is None or not transaction.is_active: + raise RuntimeError("task import membership requires the caller transaction") + batch = await self._session.scalar(select(TaskImportBatch).where( + TaskImportBatch.id == str(batch_id), TaskImportBatch.project_id == str(project_id), + TaskImportBatch.status == "committed", + ).with_for_update(read=True, key_share=True).execution_options(populate_existing=True)) + if batch is None: + raise TaskImportBatchError("task_import_batch_not_found", 404) + return await self.validate(batch) + + async def validate(self, batch: TaskImportBatch) -> TaskImportMembershipSnapshot: + """Recover immutable creation facts; mutable Task state is not replay input.""" + response = TaskImportBatchResponse.model_validate(batch.response) + if (str(response.batch_id), str(response.project_id), str(response.source_id), response.sha256, + response.byte_count, response.row_count, response.schema_version, response.mapping_version) != ( + batch.id, batch.project_id, batch.source_id, batch.sha256, batch.byte_count, batch.row_count, + batch.schema_version, batch.mapping_version, + ): + raise TaskImportBatchError("task_import_batch_custody_invalid", 409) + rows = (await self._session.execute(select(TaskImportBatchMember, TaskCommandReceipt).join( + TaskCommandReceipt, TaskCommandReceipt.id == TaskImportBatchMember.task_command_receipt_id, + ).where(TaskImportBatchMember.batch_id == batch.id).order_by(TaskImportBatchMember.row_index))).all() + if len(rows) != batch.row_count: + raise TaskImportBatchError("task_import_batch_custody_invalid", 409) + manifest = {"schema_version": response.schema_version, "metadata": {"label": response.label}, + "tasks": [{field: getattr(task, field) for field in TaskImportRow.model_fields} for task in response.tasks]} + if response.label != batch.metadata_label or canonical_json_hash(manifest) != batch.manifest_digest: + raise TaskImportBatchError("task_import_batch_custody_invalid", 409) + for index, (member, receipt) in enumerate(rows): + original = response.tasks[index] + instructions = {field: getattr(original, field) for field in TaskImportRow.model_fields} + if (member.row_index != index or member.project_id != batch.project_id or member.task_id != original.id + or member.external_task_id != original.external_task_id + or member.row_digest != canonical_json_hash(instructions) + or member.response != original.model_dump(mode="json") + or receipt.response != member.response or receipt.status != "committed" + or receipt.action_id != "project.task.create" or receipt.task_id != member.task_id + or receipt.actor_profile_id != batch.actor_profile_id + or receipt.idempotency_key != member.create_idempotency_key + or original.created_by != batch.actor_profile_id): + raise TaskImportBatchError("task_import_batch_custody_invalid", 409) + return TaskImportMembershipSnapshot( + creation=response, manifest_digest=batch.manifest_digest, + members=tuple(TaskImportMemberIdentity( + member_id=UUID(member.id), task_id=UUID(member.task_id), row_index=member.row_index, + external_task_id=member.external_task_id, row_digest=member.row_digest, + create_idempotency_key=member.create_idempotency_key, + task_command_receipt_id=member.task_command_receipt_id, + authorization_decision_id=UUID(member.authorization_decision_id), + ) for member, _ in rows), + ) diff --git a/backend/tests/authorization/task_authority/test_management_participants.py b/backend/tests/authorization/task_authority/test_management_participants.py new file mode 100644 index 000000000..9aeffaebc --- /dev/null +++ b/backend/tests/authorization/task_authority/test_management_participants.py @@ -0,0 +1,109 @@ +"""Native canonical transitions compose and roll back in one caller-owned root.""" + +from uuid import UUID, uuid4 + +import pytest +from sqlalchemy import select + +from app.adapters.audit import task_transition_audit +from app.adapters.tasks import task_commands +from app.core.config import get_settings +from app.db import session as db_session +from app.modules.actors.models import ActorIdentityLink +from app.modules.authorization.task_authorization import PreparedTaskAuthorization +from app.modules.tasks.api.authorization import TaskAuthorityOperation +from app.modules.tasks.models import AuditEvent, TaskCommandReceipt, WorkstreamTask +from tests.authorization.task_authority.test_concurrency import actor_context +from tests.test_tasks import ( + task_database_env as task_database_env, + task_client as task_client, + create_active_project, + create_draft_task, +) + + +async def manager_context(): + async with db_session.get_session_factory()() as session: + actor_id = await session.scalar(select(ActorIdentityLink.actor_profile_id).where( + ActorIdentityLink.subject == "project-manager-subject", + )) + return await actor_context(actor_id) + + +def commands(session, context): + return task_commands( + session, authorization=PreparedTaskAuthorization(session, context), + audit=task_transition_audit(session), actor_profile_id=context.actor_profile_id, + settings=get_settings(), + ) + + +@pytest.mark.parametrize("phase", ["authorize", "stage"]) +async def test_transition_preparation_cannot_cross_roots(task_client, phase): + project = await create_active_project(task_client) + task = await create_draft_task(task_client, project["id"]) + context = await manager_context() + async with db_session.get_session_factory()() as session: + owner = commands(session, context) + async with session.begin(): + prepared = await owner.prepare_transition( + UUID(task["id"]), TaskAuthorityOperation.SCREEN, "Canonical screening", + idempotency_key=uuid4(), project_id=UUID(project["id"]), + ) + decision = await owner.authorize_transition(prepared) + receipt_id = prepared.receipt.id + await session.rollback() + async with session.begin(): + with pytest.raises(RuntimeError, match="original caller transaction"): + if phase == "authorize": + await owner.authorize_transition(prepared) + else: + await owner.stage_transition(prepared, decision) + async with session.begin(): + assert await session.get(TaskCommandReceipt, receipt_id) is None + assert await session.get(AuditEvent, str(decision.decision_id)) is None + current = await session.get(WorkstreamTask, task["id"]) + assert current.status == "draft" and current.locked_guide_version is None + + +async def test_two_task_transition_late_failure_rolls_back_complete_root(task_client, monkeypatch): + project = await create_active_project(task_client) + tasks = [await create_draft_task(task_client, project["id"]) for _ in range(2)] + context = await manager_context() + async with db_session.get_session_factory()() as session: + owner = commands(session, context) + original = owner._record_management + observed = [] + + async def fail_after_second_audit(*args, **kwargs): + await original(*args, **kwargs) + observed.append(args[0].id) + if len(observed) == 2: + raise RuntimeError("second canonical transition staged") + + monkeypatch.setattr(owner, "_record_management", fail_after_second_audit) + with pytest.raises(RuntimeError, match="second canonical transition staged"): + async with session.begin(): + prepared = [await owner.prepare_transition( + UUID(task["id"]), TaskAuthorityOperation.SCREEN, "Complete batch", + idempotency_key=uuid4(), project_id=UUID(project["id"]), + ) for task in sorted(tasks, key=lambda value: UUID(value["id"]).int)] + decisions = [await owner.authorize_transition(value) for value in prepared] + receipt_ids = [value.receipt.id for value in prepared] + for value, decision in zip(prepared, decisions, strict=True): + await owner.stage_transition(value, decision) + assert observed == [task["id"] for task in sorted(tasks, key=lambda value: UUID(value["id"]).int)] + async with session.begin(): + for value in tasks: + current = await session.get(WorkstreamTask, value["id"], populate_existing=True) + assert current.status == "draft" and current.locked_guide_version is None + assert not list(await session.scalars(select(TaskCommandReceipt.id).where( + TaskCommandReceipt.id.in_(receipt_ids), + ))) + assert not list(await session.scalars(select(AuditEvent.id).where( + AuditEvent.id.in_([str(value.decision_id) for value in decisions]), + ))) + assert not list(await session.scalars(select(AuditEvent.id).where( + AuditEvent.entity_id.in_([value["id"] for value in tasks]), + AuditEvent.event_type == "TaskScreened", + ))) diff --git a/backend/tests/tasks/test_task_import_batches.py b/backend/tests/tasks/test_task_import_batches.py index cec3175de..8b2cf0478 100644 --- a/backend/tests/tasks/test_task_import_batches.py +++ b/backend/tests/tasks/test_task_import_batches.py @@ -356,7 +356,7 @@ async def test_distinct_covered_actors_with_reversed_ids_wait_then_roll_back_one from app.core.config import get_settings from app.modules.authorization.task_authorization import PreparedTaskAuthorization from app.modules.tasks.schemas import TaskImportBatchResponse - from app.modules.tasks.task_import_batches import TaskImportBatchError + from app.modules.tasks.api.task_import_membership import TaskImportBatchError from tests.authorization.task_authority.test_concurrency import actor_context from tests.project_create_fixtures import grant_system_project_manager From 486dba3381101f8f913410b834a5911a16db24d7 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 14:10:35 +0100 Subject: [PATCH 021/283] feat: define Workstream default checker --- .ci/behavior-ownership/partition.v1.json | 10 +- .../pilot04-workstream-default-checker.md | 137 +++++++ .../modules/checkers/api/default_checker.py | 275 ++++++++++++++ .../app/modules/checkers/default_checker.py | 285 ++++++++++++++ backend/scripts/behavior_ownership.py | 7 + backend/scripts/test_lane_catalogue.py | 2 + .../tests/checkers/default/test_contract.py | 105 ++++++ .../tests/checkers/default/test_execution.py | 357 ++++++++++++++++++ backend/tests/test_ci_lane_catalogue.py | 2 + docs/architecture_checker_framework.md | 17 +- docs/roadmap_status.md | 9 +- 11 files changed, 1199 insertions(+), 7 deletions(-) create mode 100644 .commitrail/changes/pilot04-workstream-default-checker.md create mode 100644 backend/app/modules/checkers/api/default_checker.py create mode 100644 backend/app/modules/checkers/default_checker.py create mode 100644 backend/tests/checkers/default/test_contract.py create mode 100644 backend/tests/checkers/default/test_execution.py diff --git a/.ci/behavior-ownership/partition.v1.json b/.ci/behavior-ownership/partition.v1.json index 437aa00b0..c8b515802 100644 --- a/.ci/behavior-ownership/partition.v1.json +++ b/.ci/behavior-ownership/partition.v1.json @@ -848,6 +848,10 @@ "group": "artifacts", "target": "backend/app/modules/checkers/api/artifact_paths.py" }, + { + "group": "artifacts", + "target": "backend/app/modules/checkers/api/default_checker.py" + }, { "group": "artifacts", "target": "backend/app/modules/checkers/api/execution.py" @@ -896,6 +900,10 @@ "group": "artifacts", "target": "backend/app/modules/checkers/compiler.py" }, + { + "group": "artifacts", + "target": "backend/app/modules/checkers/default_checker.py" + }, { "group": "artifacts", "target": "backend/app/modules/checkers/delivery_authority.py" @@ -1805,7 +1813,7 @@ "target": "backend/scripts/validate_test_lane_evidence.py" } ], - "authority_digest": "93906ccf711fb56664d96d5ad646991ab2877131a2c83e09643a84180e547c27", + "authority_digest": "8eb8e05679f811271c2a07399e4da7b6048d074fb72168d30fba876ca7f11d16", "protected_base_commit": "7676ce4347db0c9694962a9b587a20765e16eac6", "schema": "workstream.behavior-ownership-partition.v1" } diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md new file mode 100644 index 000000000..f89ea1e79 --- /dev/null +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -0,0 +1,137 @@ +# [PILOT-04] Define The One Workstream Default Checker + +- Initiative: None +- Durable disposition: Complete +- Intended merge outcome: Deliver one versioned, unselected Workstream default + checker contract and implementation with exactly four blocking defaults and + warning-only summary and attestation observations. + +## Intent + +Issue #491 replaces the built-in pre- and post-submit catalogues with one +Workstream-owned default checker plus digest-pinned project images. The merged +external service can execute project images, but the repository does not yet +have the one default checker whose behavior must precede those images. This +change establishes that executable behavior and its stable result contract +without selecting it in the current intake path. + +## Current behavior + +`backend/app/modules/checkers/pre_submit_execution.py` dispatches the current +versioned pre-submit catalogue. It mixes platform custody checks, project rules, +packet requirements and advisories. The post-submit catalogue separately owns +structural defaults. Both remain active until complete replacement proof permits +one clean cutover. The merged external runtime is intentionally unselected. + +## Bounded change + +### Allowed + +- This record. +- `backend/app/modules/checkers/api/default_checker.py` for closed input/result + contracts, stable checker identity and behavior digest. +- `backend/app/modules/checkers/default_checker.py` for the four Workstream + defaults over detached ART/TASK facts and the existing CHECKERS-owned bounded + material-read capability. +- Focused tests under `backend/tests/checkers/default/` for every positive, + negative, infrastructure and warning boundary. +- The minimum test-lane and behavior-owner metadata needed to run the new tests + and assign the two new modules exactly once. +- `docs/architecture_checker_framework.md` and the exact PILOT-04 checker rows + in `docs/roadmap_status.md` for the implemented but unselected boundary. + +### Not allowed + +- No policy binding, guide activation/F-020, external project-image selection, + service composition, public route, CLI or Submission/admission caller wiring. +- No migration, registry mutation, durable run/result/receipt, scheduler, + retry worker, acceptance or routing behavior. +- No deletion, bypass or parallel execution of either current catalogue. No + change to their hashes, policies, active callers or tests. +- No project required-file, project size, forbidden-file or generic rule logic. + No extra blocking Workstream default. Summary and attestation remain warnings. +- No held PILOT-05, PILOT-06 or PILOT-09 work, deployment, merge or issue closure. + +## Design and decisions + +The checker consumes detached owner facts rather than reparsing a ZIP or +inventing storage access: ART's structural inspection, server-computed archive +commitment and canonical semantic manifest, plus TASK/ART canonical predecessor +identity. It reads bytes only through the existing CHECKERS-owned callback-scoped +material capability, recomputes the manifest identity and rechecks every file +digest. The existing ART sealed-tree projection satisfies that capability without +a CHECKERS-to-ART dependency or any path/storage authority. Unsafe contributor +archives become the one archive-safety finding; storage-integrity and timeout +failures remain recoverable infrastructure outcomes. Exact material/manifest +disagreement also fails as infrastructure instead of blaming the contributor. + +The result always has four ordered blocking slots: archive safety, received +identity, high-confidence secrets and task-rule-aware unchanged resubmission. +An evaluated slot is `passed` or `failed`; a slot unavailable after an unsafe +archive is `not_run`. Warning-only summary and attestation observations are +separate closed values. Findings retain only stable categories and counts, not +matched bytes or contributor text. + +The checker has a code-owned version and canonical behavior digest. Its manifest +contains the exact four check identities, warning identities, and each secret +signature's category, executable regex source and flags. The implementation +compiles from that same canonical constant, so detector changes alter the +behavior digest and golden contract proof. This is a Workstream implementation +that changes only with a deploy; project rules remain external images. + +This component is unselected. A later bounded cutover will bind approved +external policy entries, execute every required pre-image through the merged +service, and invoke the existing caller-owned atomic Submission operation only +after this checker and all required project checks pass. Both catalogues are +removed only after complete pre/post replacement proof; no parallel runtime is +introduced here. + +## Acceptance criteria + +- [x] The result contract admits exactly four ordered blocking checks and only + the closed warning-only summary/attestation observations. +- [x] Valid safe ZIP custody, recomputed manifest identity, no high-confidence + secret and first/changed work pass all four defaults. +- [x] Malformed, encrypted, unsafe, colliding or platform-limit archives return + one bounded archive finding and do not expose material to later checks. +- [x] Stored-byte/manifest disagreement, inspection timeout/integrity failure or + stale/unavailable predecessor facts are infrastructure outcomes, never work + findings or silent passes. +- [x] Exact private-key, cloud-credential and API-token signatures fail without + retaining matched content; representative near misses pass. +- [x] Exact archive or semantic-manifest replay fails unless the canonical task + rules/predecessor changed, with parity against the canonical owner semantics. +- [x] Empty summary and attestation add warnings only and never change the four + blocking verdicts. +- [x] Existing catalogue identities, hashes and execution tests remain unchanged; + no production composition selects the new checker. + +## Risk and review routing + +- Risk class: L1 +- Required reviewers: architecture, security, reuse_dedup, qa, test_delta, + documentation, product_ops, ci_integrity +- Human review focus: Exact four-default boundary, high-confidence pattern + precision, contributor-vs-infrastructure classification, reuse of ART custody + and predecessor ownership, bounded secret-free results, and absence of a + parallel active execution path. + +## Evidence + +| Claim | Command or proof | Result | Remaining uncertainty | +|---|---|---|---| +| Current owner map | Source inspection of ART inspection/manifest/change owners, both current catalogues and the merged external runtime | Complete at main `e77c48b1086c95cc4c2fc05bdf2fdcffdce52494` | Policy binding, live pre-admission orchestration, post cutover and catalogue removal remain later slices | +| Default behavior and actual ART callback | `pytest -q tests/checkers/default/test_contract.py tests/checkers/default/test_execution.py` | 25 passed | Component remains deliberately unselected | +| Test-lane ownership and focused behavior | `pytest -q tests/checkers/default/test_contract.py tests/checkers/default/test_execution.py tests/test_ci_lane_catalogue.py` | 71 passed | Hosted full-suite evidence follows in the draft PR | +| Public module boundary | `pytest -q tests/architecture/test_module_boundaries.py::test_repository_matches_the_protected_module_boundary tests/architecture/test_module_boundaries.py::test_art_implements_checker_consumer_ports_without_a_public_cycle` | 2 passed | Existing catalogues retain their recorded debt until cutover | +| Behavior-owner partition | `python -m scripts.behavior_ownership validate` | Passed | Hosted evidence still validates the exact merge tree | + +## Reconciliation + +- Current-source reconciliation: Started from merged PR #528 at main + `e77c48b1086c95cc4c2fc05bdf2fdcffdce52494`. +- Next usable boundary: Bind approved external policy identities and compose the + default plus every required project pre-image before the existing atomic + Submission operation. +- Remaining risks: No caller selects this component in this change; whole-issue + acceptance, F-020 and both-catalogue removal remain open. diff --git a/backend/app/modules/checkers/api/default_checker.py b/backend/app/modules/checkers/api/default_checker.py new file mode 100644 index 000000000..1f1d66f55 --- /dev/null +++ b/backend/app/modules/checkers/api/default_checker.py @@ -0,0 +1,275 @@ +"""Closed contract for the one Workstream-owned default checker.""" + +from __future__ import annotations + +from dataclasses import dataclass +from typing import Literal, Self +from uuid import UUID + +from pydantic import BaseModel, ConfigDict, Field, model_validator + +from app.core.hashing import canonical_json_hash +from app.modules.checkers.api.materialization import SubmissionMaterialEntry +from app.modules.checkers.api.pre_submit import SubmissionPacketView + + +WORKSTREAM_DEFAULT_CHECKER_ID = "workstream.default" +WORKSTREAM_DEFAULT_CHECKER_VERSION = "v1" +WORKSTREAM_DEFAULT_CHECK_IDS = ( + "archive_safe", + "received_identity_exact", + "high_confidence_secrets_absent", + "submission_changed_for_current_rules", +) +WORKSTREAM_DEFAULT_WARNING_CODES = ( + "submission_summary_missing", + "submission_attestation_missing", +) +WORKSTREAM_DEFAULT_SECRET_SIGNATURES = ( + ( + "pem_private_key", + r"-----BEGIN (?:RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----", + 0, + ), + ("aws_access_key_id", r"(? None: + if ( + type(value) is not str + or len(value) != 71 + or not value.startswith("sha256:") + or any(character not in "0123456789abcdef" for character in value[7:]) + ): + raise ValueError("default checker digest is invalid") + + +@dataclass(frozen=True, slots=True) +class WorkstreamDefaultPredecessor: + """Detached canonical predecessor identity supplied by the TASK/ART owners.""" + + submission_id: UUID + submission_version: int + archive_sha256: str + semantic_manifest_sha256: str + + def __post_init__(self) -> None: + """Reject incomplete or caller-shaped predecessor identities.""" + if type(self.submission_id) is not UUID: + raise ValueError("default checker predecessor id is invalid") + if type(self.submission_version) is not int or self.submission_version <= 0: + raise ValueError("default checker predecessor version is invalid") + _require_sha256(self.archive_sha256) + _require_sha256(self.semantic_manifest_sha256) + + +@dataclass(frozen=True, slots=True) +class WorkstreamDefaultCheckerInput: + """Detached exact custody and task-rule facts; never storage authority.""" + + archive_sha256: str + archive_byte_count: int + archive_media_type: str + semantic_manifest_sha256: str + entries: tuple[SubmissionMaterialEntry, ...] + predecessor: WorkstreamDefaultPredecessor | None + predecessor_exists: bool + current_predecessor: WorkstreamDefaultPredecessor | None + current_rules_sha256: str + predecessor_rules_sha256: str | None + packet: SubmissionPacketView + + def __post_init__(self) -> None: + """Reject malformed detached facts before any callback-scoped byte read.""" + _require_sha256(self.archive_sha256) + _require_sha256(self.semantic_manifest_sha256) + _require_sha256(self.current_rules_sha256) + if ( + type(self.archive_byte_count) is not int + or self.archive_byte_count <= 0 + or self.archive_media_type != "application/zip" + or type(self.entries) is not tuple + or any(type(item) is not SubmissionMaterialEntry for item in self.entries) + or ( + self.predecessor is not None + and type(self.predecessor) is not WorkstreamDefaultPredecessor + ) + or ( + self.current_predecessor is not None + and type(self.current_predecessor) is not WorkstreamDefaultPredecessor + ) + or type(self.predecessor_exists) is not bool + or type(self.packet) is not SubmissionPacketView + or (self.predecessor_rules_sha256 is None) != (self.predecessor is None) + ): + raise ValueError("default checker input is invalid") + if self.predecessor_rules_sha256 is not None: + _require_sha256(self.predecessor_rules_sha256) + + +class WorkstreamDefaultCheckerValue(BaseModel): + """Strict immutable value emitted by the default checker.""" + + model_config = ConfigDict(extra="forbid", frozen=True, revalidate_instances="always") + + +class WorkstreamDefaultCheck(WorkstreamDefaultCheckerValue): + """One of the four ordered blocking default outcomes.""" + + check_id: WorkstreamDefaultCheckId + status: WorkstreamDefaultCheckStatus + failure_code: WorkstreamDefaultFailureCode | None = None + finding_count: int = Field(ge=0) + + @model_validator(mode="after") + def validate_outcome(self) -> Self: + """Keep failures explicit and passes/not-run values finding-free.""" + if (self.status == "failed") != ( + self.failure_code is not None and self.finding_count > 0 + ): + raise ValueError("default checker outcome shape is invalid") + if self.status != "failed" and ( + self.failure_code is not None or self.finding_count != 0 + ): + raise ValueError("default checker non-failure outcome is invalid") + if self.status == "failed" and not _failure_matches_check( + self.check_id, self.failure_code + ): + raise ValueError("default checker failure does not match its check") + return self + + +class WorkstreamDefaultWarning(WorkstreamDefaultCheckerValue): + """One warning-only packet observation.""" + + code: WorkstreamDefaultWarningCode + + +class WorkstreamDefaultCheckerResult(WorkstreamDefaultCheckerValue): + """Complete result from the one versioned Workstream default checker.""" + + schema_version: Literal["workstream.default_checker_result.v1"] = ( + "workstream.default_checker_result.v1" + ) + checker_id: Literal["workstream.default"] = WORKSTREAM_DEFAULT_CHECKER_ID + checker_version: Literal["v1"] = WORKSTREAM_DEFAULT_CHECKER_VERSION + behavior_sha256: str = Field(pattern=r"^sha256:[0-9a-f]{64}$") + eligible: bool + checks: tuple[WorkstreamDefaultCheck, ...] = Field(min_length=4, max_length=4) + warnings: tuple[WorkstreamDefaultWarning, ...] = Field(max_length=2) + + @model_validator(mode="after") + def validate_complete_result(self) -> Self: + """Require the exact four defaults, stable behavior and derived eligibility.""" + if self.behavior_sha256 != WORKSTREAM_DEFAULT_BEHAVIOR_SHA256: + raise ValueError("default checker behavior identity differs") + if tuple(item.check_id for item in self.checks) != WORKSTREAM_DEFAULT_CHECK_IDS: + raise ValueError("default checker result is incomplete or reordered") + warning_codes = tuple(item.code for item in self.warnings) + if ( + len(warning_codes) != len(set(warning_codes)) + or warning_codes != tuple( + code for code in WORKSTREAM_DEFAULT_WARNING_CODES if code in warning_codes + ) + ): + raise ValueError("default checker warnings are duplicated or reordered") + if self.eligible != all(item.status == "passed" for item in self.checks): + raise ValueError("default checker eligibility differs from blocking checks") + return self + + +def _failure_matches_check( + check_id: WorkstreamDefaultCheckId, + failure_code: WorkstreamDefaultFailureCode | None, +) -> bool: + """Bind every closed failure category to exactly one blocking default.""" + if failure_code is None: + return False + if check_id == "archive_safe": + return failure_code.startswith("submission_archive_") and failure_code not in { + "submission_archive_unchanged" + } + if check_id == "high_confidence_secrets_absent": + return failure_code == "high_confidence_secret_detected" + if check_id == "submission_changed_for_current_rules": + return failure_code in { + "submission_archive_unchanged", + "submission_manifest_unchanged", + } + return False + + +__all__ = ( + "WORKSTREAM_DEFAULT_BEHAVIOR_MANIFEST", + "WORKSTREAM_DEFAULT_BEHAVIOR_SHA256", + "WORKSTREAM_DEFAULT_CHECKER_ID", + "WORKSTREAM_DEFAULT_CHECKER_VERSION", + "WORKSTREAM_DEFAULT_CHECK_IDS", + "WORKSTREAM_DEFAULT_SECRET_SIGNATURES", + "WORKSTREAM_DEFAULT_WARNING_CODES", + "WorkstreamDefaultArchiveFailureCode", + "WorkstreamDefaultCheck", + "WorkstreamDefaultCheckId", + "WorkstreamDefaultCheckerInput", + "WorkstreamDefaultCheckerResult", + "WorkstreamDefaultFailureCode", + "WorkstreamDefaultPredecessor", + "WorkstreamDefaultWarning", +) diff --git a/backend/app/modules/checkers/default_checker.py b/backend/app/modules/checkers/default_checker.py new file mode 100644 index 000000000..c8c866e93 --- /dev/null +++ b/backend/app/modules/checkers/default_checker.py @@ -0,0 +1,285 @@ +"""Unselected implementation of the one Workstream default checker.""" + +from __future__ import annotations + +import hashlib +import re +from typing import cast + +from app.core.hashing import canonical_json_hash +from app.modules.checkers.api.default_checker import ( + WORKSTREAM_DEFAULT_BEHAVIOR_SHA256, + WORKSTREAM_DEFAULT_SECRET_SIGNATURES, + WorkstreamDefaultArchiveFailureCode, + WorkstreamDefaultCheck, + WorkstreamDefaultCheckId, + WorkstreamDefaultCheckerInput, + WorkstreamDefaultCheckerResult, + WorkstreamDefaultFailureCode, + WorkstreamDefaultWarning, +) +from app.modules.checkers.api.materialization import ( + SubmissionMaterialEntry, + SubmissionMaterialView, +) +from app.modules.checkers.api.pre_submit import SubmissionPacketView + + +_CONTRIBUTOR_ARCHIVE_FAILURES = frozenset( + { + "submission_archive_malformed", + "submission_archive_limit_exceeded", + "submission_archive_unsafe_entry", + "submission_archive_collision", + "submission_archive_encrypted", + } +) +_SECRET_SIGNATURES = tuple( + re.compile(pattern.encode("ascii"), flags) + for _, pattern, flags in WORKSTREAM_DEFAULT_SECRET_SIGNATURES +) + + +class WorkstreamDefaultCheckerUnavailable(RuntimeError): + """Fail closed without attributing an infrastructure defect to the contributor.""" + + +def evaluate_rejected_archive( + failure: WorkstreamDefaultArchiveFailureCode, + *, + packet: SubmissionPacketView, +) -> WorkstreamDefaultCheckerResult: + """Return one bounded work finding for a contributor-correctable unsafe ZIP.""" + if failure not in _CONTRIBUTOR_ARCHIVE_FAILURES: + raise WorkstreamDefaultCheckerUnavailable(str(failure)) + return _result( + checks=( + _failed("archive_safe", cast(WorkstreamDefaultFailureCode, failure)), + _not_run("received_identity_exact"), + _not_run("high_confidence_secrets_absent"), + _not_run("submission_changed_for_current_rules"), + ), + warnings=_warnings(packet), + ) + + +def evaluate_verified_archive( + value: WorkstreamDefaultCheckerInput, + material: SubmissionMaterialView, +) -> WorkstreamDefaultCheckerResult: + """Evaluate all four defaults during one callback-scoped verified-byte lifetime.""" + try: + manifest_entries = _validated_entries(value.entries) + observed_entries = _validated_entries(material.entries) + if observed_entries != manifest_entries: + raise WorkstreamDefaultCheckerUnavailable( + "submission_material_identity_invalid" + ) + if canonical_json_hash(_manifest_body(manifest_entries)) != ( + value.semantic_manifest_sha256 + ): + raise WorkstreamDefaultCheckerUnavailable( + "submission_manifest_identity_invalid" + ) + secret_file_count = _verify_files_and_count_secrets(material, manifest_entries) + change_failure = _change_failure(value) + except WorkstreamDefaultCheckerUnavailable: + raise + except Exception as exc: + raise WorkstreamDefaultCheckerUnavailable( + "workstream_default_checker_input_unavailable" + ) from exc + checks = ( + _passed("archive_safe"), + _passed("received_identity_exact"), + ( + _failed( + "high_confidence_secrets_absent", + "high_confidence_secret_detected", + count=secret_file_count, + ) + if secret_file_count + else _passed("high_confidence_secrets_absent") + ), + ( + _failed("submission_changed_for_current_rules", change_failure) + if change_failure is not None + else _passed("submission_changed_for_current_rules") + ), + ) + return _result(checks=checks, warnings=_warnings(value.packet)) + + +def _validated_entries( + values: tuple[object, ...], +) -> tuple[SubmissionMaterialEntry, ...]: + """Detach and validate the exact canonical entry projection.""" + entries = tuple( + SubmissionMaterialEntry( + normalized_path=getattr(item, "normalized_path"), + entry_type=cast(str, getattr(item, "entry_type")), + byte_count=getattr(item, "byte_count"), + sha256=getattr(item, "sha256"), + executable=getattr(item, "executable"), + ) + for item in values + ) + if tuple(sorted(entries, key=lambda item: item.normalized_path)) != entries: + raise ValueError("default checker entries are not canonical") + if len({item.normalized_path for item in entries}) != len(entries): + raise ValueError("default checker entries are duplicated") + for item in entries: + if type(item.normalized_path) is not str or not item.normalized_path: + raise ValueError("default checker entry path is invalid") + if item.entry_type == "directory": + if item.byte_count != 0 or item.sha256 is not None or item.executable is not None: + raise ValueError("default checker directory entry is invalid") + continue + if ( + item.entry_type != "file" + or type(item.byte_count) is not int + or item.byte_count < 0 + or type(item.executable) is not bool + or not _is_sha256(item.sha256) + ): + raise ValueError("default checker file entry is invalid") + return entries + + +def _manifest_body(entries: tuple[SubmissionMaterialEntry, ...]) -> dict[str, object]: + """Recompute the canonical ART semantic-manifest body from detached facts.""" + body_entries: list[dict[str, object]] = [] + for entry in entries: + if entry.entry_type == "directory": + body_entries.append( + {"normalized_path": entry.normalized_path, "entry_type": "directory"} + ) + else: + body_entries.append( + { + "normalized_path": entry.normalized_path, + "entry_type": "file", + "sha256": entry.sha256, + "byte_count": entry.byte_count, + "executable": entry.executable, + } + ) + return { + "schema_version": "workstream.submission_bundle_manifest.v1", + "entries": body_entries, + } + + +def _change_failure( + value: WorkstreamDefaultCheckerInput, +) -> WorkstreamDefaultFailureCode | None: + """Apply unchanged-work refusal only when the canonical task rules are unchanged.""" + predecessor = value.predecessor + if predecessor is None: + if value.predecessor_exists or value.current_predecessor is not None: + raise WorkstreamDefaultCheckerUnavailable( + "submission_canonical_predecessor_unavailable" + ) + return None + if not value.predecessor_exists: + raise WorkstreamDefaultCheckerUnavailable( + "submission_canonical_predecessor_unavailable" + ) + if value.current_predecessor != predecessor: + raise WorkstreamDefaultCheckerUnavailable("submission_predecessor_stale") + if value.predecessor_rules_sha256 != value.current_rules_sha256: + return None + if value.archive_sha256 == predecessor.archive_sha256: + return "submission_archive_unchanged" + if value.semantic_manifest_sha256 == predecessor.semantic_manifest_sha256: + return "submission_manifest_unchanged" + return None + + +def _verify_files_and_count_secrets( + material: SubmissionMaterialView, + entries: tuple[SubmissionMaterialEntry, ...], +) -> int: + """Verify every file again and count matches without retaining matched bytes.""" + affected = 0 + for entry in entries: + if entry.entry_type != "file": + continue + content = material.read_file( + entry.normalized_path, maximum_bytes=entry.byte_count + ) + if ( + len(content) != entry.byte_count + or f"sha256:{hashlib.sha256(content).hexdigest()}" != entry.sha256 + ): + raise WorkstreamDefaultCheckerUnavailable( + "submission_material_identity_invalid" + ) + if any(pattern.search(content) is not None for pattern in _SECRET_SIGNATURES): + affected += 1 + return affected + + +def _is_sha256(value: object) -> bool: + return ( + type(value) is str + and len(value) == 71 + and value.startswith("sha256:") + and all(character in "0123456789abcdef" for character in value[7:]) + ) + + +def _warnings(packet: SubmissionPacketView) -> tuple[WorkstreamDefaultWarning, ...]: + """Return stable warning-only absence signals in canonical order.""" + values = [] + if not packet.summary.strip(): + values.append(WorkstreamDefaultWarning(code="submission_summary_missing")) + if not packet.contributor_attestation.strip(): + values.append(WorkstreamDefaultWarning(code="submission_attestation_missing")) + return tuple(values) + + +def _passed(check_id: WorkstreamDefaultCheckId) -> WorkstreamDefaultCheck: + return WorkstreamDefaultCheck( + check_id=check_id, status="passed", failure_code=None, finding_count=0 + ) + + +def _not_run(check_id: WorkstreamDefaultCheckId) -> WorkstreamDefaultCheck: + return WorkstreamDefaultCheck( + check_id=check_id, status="not_run", failure_code=None, finding_count=0 + ) + + +def _failed( + check_id: WorkstreamDefaultCheckId, + failure_code: WorkstreamDefaultFailureCode, + *, + count: int = 1, +) -> WorkstreamDefaultCheck: + return WorkstreamDefaultCheck( + check_id=check_id, + status="failed", + failure_code=failure_code, + finding_count=count, + ) + + +def _result( + *, + checks: tuple[WorkstreamDefaultCheck, ...], + warnings: tuple[WorkstreamDefaultWarning, ...], +) -> WorkstreamDefaultCheckerResult: + return WorkstreamDefaultCheckerResult( + behavior_sha256=WORKSTREAM_DEFAULT_BEHAVIOR_SHA256, + eligible=all(item.status == "passed" for item in checks), + checks=checks, + warnings=warnings, + ) + + +__all__ = ( + "WorkstreamDefaultCheckerUnavailable", + "evaluate_rejected_archive", + "evaluate_verified_archive", +) diff --git a/backend/scripts/behavior_ownership.py b/backend/scripts/behavior_ownership.py index 27e88905b..b593166c4 100644 --- a/backend/scripts/behavior_ownership.py +++ b/backend/scripts/behavior_ownership.py @@ -144,6 +144,12 @@ "backend/app/modules/artifacts/preparation.py", } ) +PILOT_04_DEFAULT_CHECKER_TARGETS = frozenset( + { + "backend/app/modules/checkers/api/default_checker.py", + "backend/app/modules/checkers/default_checker.py", + } +) LOCAL_PILOT_HELPER_TARGETS = frozenset( { "backend/scripts/ensure_local_minio_bucket.py", @@ -817,6 +823,7 @@ def _validate_additive_partition_transition( | CI_LANE_CATALOGUE_TARGETS | PILOT_04_REGISTRY_TARGETS | PILOT_04_RUNTIME_TARGETS + | PILOT_04_DEFAULT_CHECKER_TARGETS | LOCAL_PILOT_HELPER_TARGETS | MODULE_BOUNDARY_FOUNDATION_TARGETS | MODULE_PUBLIC_API_FOUNDATION_TARGETS diff --git a/backend/scripts/test_lane_catalogue.py b/backend/scripts/test_lane_catalogue.py index 4c6e8c842..33020c03d 100644 --- a/backend/scripts/test_lane_catalogue.py +++ b/backend/scripts/test_lane_catalogue.py @@ -416,6 +416,8 @@ class TestLane: # Checker delivery shares project dispatch ownership and the existing # three-way partition; exclusive placement exceeded the hosted execution cap. CHECKER_DELIVERY_MODULES = ( + "tests/checkers/default/test_contract.py", + "tests/checkers/default/test_execution.py", "tests/checkers/external/test_contracts.py", "tests/checkers/external/test_runtime.py", "tests/checkers/external/test_migration.py", diff --git a/backend/tests/checkers/default/test_contract.py b/backend/tests/checkers/default/test_contract.py new file mode 100644 index 000000000..0df7ffa4c --- /dev/null +++ b/backend/tests/checkers/default/test_contract.py @@ -0,0 +1,105 @@ +"""Contract proof for the one Workstream-owned default checker.""" + +from __future__ import annotations + +import pytest +from pydantic import ValidationError + +from app.modules.checkers.api.default_checker import ( + WORKSTREAM_DEFAULT_BEHAVIOR_MANIFEST, + WORKSTREAM_DEFAULT_BEHAVIOR_SHA256, + WORKSTREAM_DEFAULT_CHECK_IDS, + WorkstreamDefaultCheck, + WorkstreamDefaultCheckerResult, +) +from app.core.hashing import canonical_json_hash + + +def _passing_result() -> WorkstreamDefaultCheckerResult: + return WorkstreamDefaultCheckerResult( + behavior_sha256=WORKSTREAM_DEFAULT_BEHAVIOR_SHA256, + eligible=True, + checks=tuple( + WorkstreamDefaultCheck( + check_id=check_id, + status="passed", + failure_code=None, + finding_count=0, + ) + for check_id in WORKSTREAM_DEFAULT_CHECK_IDS + ), + warnings=(), + ) + + +def test_behavior_identity_and_exact_four_check_order_are_stable() -> None: + result = _passing_result() + + assert WORKSTREAM_DEFAULT_BEHAVIOR_SHA256 == ( + "sha256:af2c604f792c4456d3b222036c772161b1503eace65ff90c3d3a23d9d348c28f" + ) + assert tuple(item.check_id for item in result.checks) == WORKSTREAM_DEFAULT_CHECK_IDS + + for changed in ( + result.model_copy(update={"checks": result.checks[:-1]}), + result.model_copy(update={"checks": tuple(reversed(result.checks))}), + result.model_copy(update={"behavior_sha256": "sha256:" + "0" * 64}), + ): + with pytest.raises(ValidationError): + WorkstreamDefaultCheckerResult.model_validate(changed) + + +def test_behavior_identity_binds_executable_secret_patterns_and_flags() -> None: + changed = { + **WORKSTREAM_DEFAULT_BEHAVIOR_MANIFEST, + "secret_signatures": [ + *WORKSTREAM_DEFAULT_BEHAVIOR_MANIFEST["secret_signatures"][:-1], + { + **WORKSTREAM_DEFAULT_BEHAVIOR_MANIFEST["secret_signatures"][-1], + "pattern": "changed", + }, + ], + } + + assert canonical_json_hash(changed) != WORKSTREAM_DEFAULT_BEHAVIOR_SHA256 + + +def test_failure_shape_is_bound_to_its_exact_default() -> None: + with pytest.raises(ValidationError): + WorkstreamDefaultCheck( + check_id="received_identity_exact", + status="failed", + failure_code="high_confidence_secret_detected", + finding_count=1, + ) + with pytest.raises(ValidationError): + WorkstreamDefaultCheck( + check_id="high_confidence_secrets_absent", + status="passed", + failure_code="high_confidence_secret_detected", + finding_count=1, + ) + with pytest.raises(ValidationError): + WorkstreamDefaultCheck( + check_id="high_confidence_secrets_absent", + status="passed", + failure_code="high_confidence_secret_detected", + finding_count=0, + ) + + +def test_warning_order_is_closed_and_does_not_change_eligibility() -> None: + result = _passing_result() + values = result.model_dump(mode="python") + values["warnings"] = [ + {"code": "submission_attestation_missing"}, + {"code": "submission_summary_missing"}, + ] + + with pytest.raises(ValidationError): + WorkstreamDefaultCheckerResult.model_validate(values) + + values = result.model_dump(mode="python") + values["eligible"] = False + with pytest.raises(ValidationError): + WorkstreamDefaultCheckerResult.model_validate(values) diff --git a/backend/tests/checkers/default/test_execution.py b/backend/tests/checkers/default/test_execution.py new file mode 100644 index 000000000..56ed90d6d --- /dev/null +++ b/backend/tests/checkers/default/test_execution.py @@ -0,0 +1,357 @@ +"""Behavior proof for the unselected Workstream default checker.""" + +from __future__ import annotations + +import hashlib +from dataclasses import replace +from io import BytesIO +from pathlib import Path +from typing import Any, cast +import zipfile + +import pytest + +from app.core.identifiers import new_record_id +from app.modules.artifacts.sources import ArtifactCommitment +from app.modules.artifacts.submission_archive import ( + SubmissionArchiveFailureCode, + SubmissionArchiveInspector, + SubmissionArchiveLimits, +) +from app.modules.artifacts.submission_manifest import build_submission_manifest +from app.modules.checkers.api.default_checker import ( + WorkstreamDefaultCheckerInput, + WorkstreamDefaultPredecessor, +) +from app.modules.checkers.api.materialization import SubmissionMaterialEntry +from app.modules.checkers.default_checker import ( + WorkstreamDefaultCheckerUnavailable, + evaluate_rejected_archive, + evaluate_verified_archive, +) +from app.modules.checkers.api.pre_submit import SubmissionPacketView + + +RULES_A = "sha256:" + "a" * 64 +RULES_B = "sha256:" + "b" * 64 + + +def _archive(files: dict[str, bytes], *, comment: bytes = b"") -> bytes: + target = BytesIO() + with zipfile.ZipFile(target, "w") as output: + output.comment = comment + for path, content in sorted(files.items()): + entry = zipfile.ZipInfo(path, date_time=(1980, 1, 1, 0, 0, 0)) + output.writestr(entry, content) + return target.getvalue() + + +def _facts(value: bytes): + inspector = SubmissionArchiveInspector(SubmissionArchiveLimits()) + inspection = inspector.inspect(BytesIO(value)) + manifest = build_submission_manifest(inspection) + commitment = ArtifactCommitment( + "sha256:" + hashlib.sha256(value).hexdigest(), len(value), "application/zip" + ) + return inspector, inspection, manifest, commitment + + +def _input( + value: bytes, + *, + predecessor: WorkstreamDefaultPredecessor | None = None, + current_predecessor: WorkstreamDefaultPredecessor | None = None, + current_rules_sha256: str = RULES_A, + predecessor_rules_sha256: str | None = None, + summary: str = "Implemented the requested behavior.", + attestation: str = "I confirm the submitted material is authorized.", +) -> WorkstreamDefaultCheckerInput: + _, inspection, manifest, commitment = _facts(value) + return WorkstreamDefaultCheckerInput( + archive_sha256=commitment.sha256, + archive_byte_count=commitment.byte_count, + archive_media_type=commitment.media_type, + semantic_manifest_sha256=manifest.sha256, + entries=tuple( + SubmissionMaterialEntry( + item.normalized_path, + item.entry_type.value, + item.byte_count, + item.sha256, + item.executable, + ) + for item in inspection.entries + ), + predecessor=predecessor, + predecessor_exists=predecessor is not None, + current_predecessor=current_predecessor, + current_rules_sha256=current_rules_sha256, + predecessor_rules_sha256=predecessor_rules_sha256, + packet=SubmissionPacketView( + summary=summary, contributor_attestation=attestation + ), + ) + + +def _evaluate(value: bytes, request: WorkstreamDefaultCheckerInput, workspace: Path): + inspector, inspection, _, _ = _facts(value) + workspace.mkdir(mode=0o700) + return inspector.project_and_run( + BytesIO(value), + workspace, + expected=inspection, + callback=lambda tree: evaluate_verified_archive(request, tree), + ) + + +def test_safe_first_submission_passes_exact_four_defaults(tmp_path: Path) -> None: + archive = _archive({"src/main.txt": b"verified work"}) + result = _evaluate(archive, _input(archive), tmp_path / "work") + + assert result.eligible is True + assert [item.status for item in result.checks] == ["passed"] * 4 + assert result.warnings == () + + +@pytest.mark.parametrize( + "failure", + [ + SubmissionArchiveFailureCode.MALFORMED, + SubmissionArchiveFailureCode.LIMIT_EXCEEDED, + SubmissionArchiveFailureCode.UNSAFE_ENTRY, + SubmissionArchiveFailureCode.COLLISION, + SubmissionArchiveFailureCode.ENCRYPTED, + ], +) +def test_contributor_archive_failures_return_one_bounded_finding( + failure: SubmissionArchiveFailureCode, +) -> None: + result = evaluate_rejected_archive( + failure.value, + packet=SubmissionPacketView(summary="", contributor_attestation=""), + ) + + assert result.eligible is False + assert result.checks[0].failure_code == failure.value + assert [item.status for item in result.checks] == [ + "failed", + "not_run", + "not_run", + "not_run", + ] + assert [item.code for item in result.warnings] == [ + "submission_summary_missing", + "submission_attestation_missing", + ] + + +@pytest.mark.parametrize( + "failure", + [ + SubmissionArchiveFailureCode.INTEGRITY_FAILURE, + SubmissionArchiveFailureCode.TIMEOUT, + ], +) +def test_archive_infrastructure_failures_never_become_work_findings( + failure: SubmissionArchiveFailureCode, +) -> None: + with pytest.raises(WorkstreamDefaultCheckerUnavailable, match=failure.value): + evaluate_rejected_archive( + failure.value, + packet=SubmissionPacketView( + summary="summary", contributor_attestation="attestation" + ), + ) + + +@pytest.mark.parametrize( + "secret", + [ + b"-----BEGIN OPENSSH PRIVATE KEY-----\nencoded", + b"AKIAIOSFODNN7EXAMPLE", + b"ghp_" + b"a" * 36, + b"github_pat_" + b"a" * 82, + b"glpat-" + b"a" * 20, + b"AIza" + b"a" * 35, + b"xoxb-" + b"a" * 20, + b"sk_live_" + b"a" * 16, + ], +) +def test_high_confidence_secret_signatures_fail_without_retaining_values( + secret: bytes, tmp_path: Path +) -> None: + archive = _archive({"src/config.txt": b"prefix " + secret + b" suffix"}) + result = _evaluate(archive, _input(archive), tmp_path / "work") + + assert result.eligible is False + assert result.checks[2].failure_code == "high_confidence_secret_detected" + assert result.checks[2].finding_count == 1 + assert secret.decode() not in result.model_dump_json() + + +def test_secret_near_misses_and_missing_packet_text_are_warning_only( + tmp_path: Path, +) -> None: + archive = _archive( + { + "notes.txt": ( + b"BEGIN PUBLIC KEY; AKIA-too-short; ghp_short; " + b"sk_test_1234567890123456" + ) + } + ) + result = _evaluate( + archive, + _input(archive, summary=" \n", attestation=""), + tmp_path / "work", + ) + + assert result.eligible is True + assert [item.status for item in result.checks] == ["passed"] * 4 + assert [item.code for item in result.warnings] == [ + "submission_summary_missing", + "submission_attestation_missing", + ] + + +def test_exact_and_semantic_replay_fail_until_task_rules_change(tmp_path: Path) -> None: + first = _archive({"src/main.txt": b"same work"}) + _, _, manifest, commitment = _facts(first) + predecessor = WorkstreamDefaultPredecessor( + new_record_id(), 1, commitment.sha256, manifest.sha256 + ) + + exact = _evaluate( + first, + _input( + first, + predecessor=predecessor, + current_predecessor=predecessor, + predecessor_rules_sha256=RULES_A, + ), + tmp_path / "exact", + ) + repacked = _archive({"src/main.txt": b"same work"}, comment=b"repacked") + semantic = _evaluate( + repacked, + _input( + repacked, + predecessor=predecessor, + current_predecessor=predecessor, + predecessor_rules_sha256=RULES_A, + ), + tmp_path / "semantic", + ) + rules_changed = _evaluate( + first, + _input( + first, + predecessor=predecessor, + current_predecessor=predecessor, + current_rules_sha256=RULES_B, + predecessor_rules_sha256=RULES_A, + ), + tmp_path / "rules-changed", + ) + with pytest.raises( + WorkstreamDefaultCheckerUnavailable, match="submission_predecessor_stale" + ): + _evaluate( + first, + _input( + first, + predecessor=predecessor, + current_predecessor=WorkstreamDefaultPredecessor( + new_record_id(), + 2, + commitment.sha256, + manifest.sha256, + ), + current_rules_sha256=RULES_B, + predecessor_rules_sha256=RULES_A, + ), + tmp_path / "rules-changed-stale", + ) + + assert exact.checks[3].failure_code == "submission_archive_unchanged" + assert semantic.checks[3].failure_code == "submission_manifest_unchanged" + assert rules_changed.checks[3].status == "passed" + assert rules_changed.eligible is True + + +def test_stale_predecessor_and_cross_archive_manifest_are_infrastructure( + tmp_path: Path, +) -> None: + archive = _archive({"src/main.txt": b"candidate"}) + _, _, manifest, _ = _facts(archive) + predecessor = WorkstreamDefaultPredecessor( + new_record_id(), 1, "sha256:" + "1" * 64, "sha256:" + "2" * 64 + ) + stale = WorkstreamDefaultPredecessor( + new_record_id(), 2, "sha256:" + "3" * 64, "sha256:" + "4" * 64 + ) + with pytest.raises( + WorkstreamDefaultCheckerUnavailable, match="submission_predecessor_stale" + ): + _evaluate( + archive, + _input( + archive, + predecessor=predecessor, + current_predecessor=stale, + predecessor_rules_sha256=RULES_A, + ), + tmp_path / "stale", + ) + + other = _archive({"src/other.txt": b"other"}) + cross = _input(archive) + assert cross.semantic_manifest_sha256 == manifest.sha256 + with pytest.raises( + WorkstreamDefaultCheckerUnavailable, match="submission_material_identity_invalid" + ): + _evaluate(other, cross, tmp_path / "cross") + + +def test_detached_manifest_and_callback_bytes_cannot_be_substituted( + tmp_path: Path, +) -> None: + archive = _archive({"src/main.txt": b"candidate"}) + request = _input(archive) + with pytest.raises( + WorkstreamDefaultCheckerUnavailable, + match="submission_manifest_identity_invalid", + ): + _evaluate( + archive, + replace(request, semantic_manifest_sha256="sha256:" + "0" * 64), + tmp_path / "manifest", + ) + + other = _archive({"src/main.txt": b"substitute"}) + with pytest.raises( + WorkstreamDefaultCheckerUnavailable, + match="submission_material_identity_invalid", + ): + _evaluate(other, request, tmp_path / "bytes") + + +def test_predecessor_currentness_rejects_duck_typed_equal_values() -> None: + class AlwaysEqual: + def __eq__(self, other: object) -> bool: + return True + + archive = _archive({"src/main.txt": b"candidate"}) + request = _input(archive) + foreign = cast(Any, AlwaysEqual()) + + with pytest.raises(ValueError, match="default checker input is invalid"): + replace(request, current_predecessor=foreign) + with pytest.raises(ValueError, match="default checker input is invalid"): + replace( + request, + predecessor=foreign, + predecessor_exists=True, + current_predecessor=foreign, + predecessor_rules_sha256=RULES_A, + ) diff --git a/backend/tests/test_ci_lane_catalogue.py b/backend/tests/test_ci_lane_catalogue.py index 165e8b18b..1f95d04b8 100644 --- a/backend/tests/test_ci_lane_catalogue.py +++ b/backend/tests/test_ci_lane_catalogue.py @@ -44,6 +44,8 @@ def test_committed_lanes_cover_recursive_inventory_exactly_once() -> None: def test_checker_delivery_and_routing_preparation_partition_every_node_once() -> None: delivery = { + "tests/checkers/default/test_contract.py", + "tests/checkers/default/test_execution.py", "tests/checkers/external/test_contracts.py", "tests/checkers/external/test_migration.py", "tests/checkers/external/test_postgresql.py", diff --git a/docs/architecture_checker_framework.md b/docs/architecture_checker_framework.md index 1a827c05d..d239a3ed9 100644 --- a/docs/architecture_checker_framework.md +++ b/docs/architecture_checker_framework.md @@ -244,6 +244,19 @@ The default checker, ART custody and project images must replace every required outcome before either current catalogue is removed. Human reviewers continue to own final quality judgment. +The unselected `workstream.default` v1 component implements this closed result +boundary. It consumes detached ART/TASK custody facts and reads verified bytes +only through the existing CHECKERS-owned callback-scoped material capability; +it receives no path or storage authority and introduces no CHECKERS-to-ART +dependency. It reports four ordered blocking slots and separate warning-only +summary/attestation absence; matched secret bytes and contributor text never +enter its result. Malformed or +unsafe contributor ZIPs are bounded work findings, while storage integrity, +inspection timeout, stale predecessor and mixed-custody failures remain +recoverable infrastructure outcomes. The unchanged-work check compares the +canonical predecessor only when its locked task-rules digest is still current. +This component has no active caller yet and does not alter either catalogue. + The clean-cutover intake order is fixed. ART receives the ZIP, computes its SHA-256, verifies the stored bytes, safely opens it within platform limits and builds the manifest before any external image can read material. The one @@ -276,8 +289,8 @@ readiness requires `runsc`; local `runc` is reported as `docker-dev`. This hidden mechanism is not selected by either current catalogue and stores no run state. Policy binding, caller-owned phase authority/currentness, durable -attempt and isolation receipts, the one default checker, project-image routing, -F-020 and public intake remain required before cutover. +attempt and isolation receipts, composition of the unselected default checker, +project-image routing, F-020 and public intake remain required before cutover. The replacement must remove both current pre- and post-submit catalogues after end-to-end replacement proof. It must not retain a legacy/new parallel path, weaken caller-owned atomicity or bypass phase identity and currentness checks. diff --git a/docs/roadmap_status.md b/docs/roadmap_status.md index 5ec873859..1f032b7be 100644 --- a/docs/roadmap_status.md +++ b/docs/roadmap_status.md @@ -260,7 +260,7 @@ cannot be reused as post-submission review-gate evidence. See the | Task readiness and claim | **Foundation with grant-backed manager and contributor commands** | Task records, assignments and locked work context; guide-bound ContributionPolicyVersion locked before `READY` and copied to TaskAssignment; detached project/guide display; public project-scoped ready, management and operational queues with distinct current grant authority and signed bounded live pagination; public contributor/management detail with exact project and assignment authority; separate current live work-context projections with exact receipt-selected review/revision/ContributionPolicy identities and no obsolete economic fields; explicit management/operational/audit locked-context projections using one historical resolver, with separate public manager, system-Operator and Audit Authority access; immutable contributor/management requirements using one historical translator, with public exact Contributor and Manager authority; bounded public Audit Authority lifecycle evidence with atomic project/task scoping and exact transition references; public manager create/screen/release use exact covered Project Manager authority, atomic audit and replay; claim/start/contributor context use exact-project Submitter grants; assigned context lists documents only and distinct `task.guide.read` verifies locked originals before delivery; separate manager context and system-Operator start; durable claim/start retry receipts with fresh authority and exact assignment checks; hidden exact-assignment invalidation with committed cause verification, delivery fencing, exact fixed-service authority and decision-bound immutable release evidence; atomic authority-loss publication and registered prefork delivery; PILOT-14 exposes both locked contribution types in ready rows and Contributor detail for active exact-project Submitters or Reviewers as unpaid or exact instrument/unit/quantity awards, without Finance binding facts; claim/start remain Submitter-only | Public intake cutover follows evaluation/remediation prerequisites | | Bulk task source custody | **Public backend source foundation delivered** | PILOT-02A provides covered-PM project-bound declaration, canonical 1..500-row JSON upload with exact SHA/count, fresh-authority replay, source status and independently verified download using existing ART custody; linear migration and public-route PostgreSQL/MinIO custody, rollback, concurrency and recovery tests pass | Atomic DRAFT import, separate explicit batch screen/release and CLI conversion; issue 489 remains open | | Contributor artifact preparation | **Hidden and proven** | One outer ZIP; bounded scratch inspection; canonical manifest; shared evaluation-content capacity and exact locked-policy checks before attempts or durable intent; platform and project prechecks; unchanged-work rejection; durable put intent; verification; capacity-charged ready admission; hidden final handoff validates the exact activated historical guide through owner ports | Complete the later public admission-only cutover | -| Pre-submission intake checking | **Hidden with approved-guide lineage and same-request feedback; external contract and unselected runtime mechanism delivered** | Separate versioned pre-submission catalogue, locked effective-plan compilation, platform/project checks during continuous preparation, and one internal phase command covering execution/replay with the JSON precheck removed; the mounted authorized hidden route returns exact ordered bounded feedback for blocking findings before Submission creation while remaining absent from OpenAPI. ARCH-03D connects approved-guide lineage through the final durable handoff. PILOT-04 publishes the strict normalized external pre-submit identity, immutable authorized digest-pinned registry, unselected Rust service/SDK and ART callback grant for verified read-only material without routing a product request | Implement one Workstream default checker containing exactly the four approved blocking behaviors; bind and route every required digest-pinned project pre-image only after verified ZIP identity/manifest; require all prechecks to pass before the caller-owned atomic Submission/`evaluation_pending`/initial-dispatch transaction. Work findings create no Submission and leave the task `in_progress`; infrastructure failures remain recoverable. Bind approved policies, prove F-020 recovery and public intake integration, then remove both legacy catalogues without a parallel path | +| Pre-submission intake checking | **Hidden with approved-guide lineage and same-request feedback; unselected default/external components delivered** | Separate versioned pre-submission catalogue, locked effective-plan compilation, platform/project checks during continuous preparation, and one internal phase command covering execution/replay with the JSON precheck removed; the mounted authorized hidden route returns exact ordered bounded feedback for blocking findings before Submission creation while remaining absent from OpenAPI. ARCH-03D connects approved-guide lineage through the final durable handoff. PILOT-04 publishes the strict normalized external pre-submit identity, immutable authorized digest-pinned registry, unselected Rust service/SDK and ART callback grant for verified read-only material, plus one unselected versioned Workstream default checker with exactly the four approved blocking outcomes and warning-only summary/attestation absence | Bind and route every required digest-pinned project pre-image only after verified ZIP identity/manifest; compose the default checker and require all prechecks to pass before the caller-owned atomic Submission/`evaluation_pending`/initial-dispatch transaction. Work findings create no Submission and leave the task `in_progress`; infrastructure failures remain recoverable. Bind approved policies, prove F-020 recovery and public intake integration, then remove both legacy catalogues without a parallel path | | Immutable Submission creation | **Hidden foundation; public packet creation retired** | Contributor preparation authority; durable pre-submit reservation and exact completed-evidence recovery without rerunning checks; atomic admission consumption; TASK-owned admission-backed creation with exact assignment ContributionPolicyVersion, locked policy lineage and service/database checked-packet custody; fixed-service artifact binding; replay/concurrency/rollback proof | Finish downstream evaluation and the canonical public integration. The retained submission-list GET is not a usable creation POST | | Post-submission evaluation and governed outcome | **Hidden authorized outcomes; external contract, registry and unselected runtime mechanism delivered; automatic production routing unavailable** | PILOT-04 supplies normalized external checker contracts, an immutable authorized OCI-digest registry, and an unselected Rust service/SDK with a typed Unix-socket adapter and ART callback grant, without product composition or policy authority. Exact ART input/output custody, durable current checker results, actual input/execute/finalize receipts, TASK request/source reservation and B7 hidden request delivery; 04E3A gives that hidden handler the existing Celery ART provider lease with invocation-scoped scratch; 04E2-B binds real route AUTH, source publication and complete true/false success consequences with database closure, shared audit/outbox and exact replay; B8 wires hidden completion delivery to the committed operation; 04F1 verifies current completed failure evidence and 04F2 routes exact current contributor-correctable results to `needs_revision` under both policy modes with no REV/CON effect. | Bind and execute digest-pinned external checkers with replacement proof before removing the superseded catalogue; registry and hidden runtime foundations alone do not activate execution. Complete exact-cause replacement intake and setup-fault/Operator recovery before 04E3 production registration and false-guide activation. True handoff has no REV/CON prerequisite. No public intake or live human review/revision is supplied. | | Review queue and lease | **Hidden persistence foundation** | Queue/admission idempotency and ReviewLease/preference persistence; complete unavailable REV action/principal catalogue and typed AUTH contracts; ART-07A1 metadata-only packet contract and REV-03B immutable normalized packet persistence with live ingest custody; REV-04A Review/finding/resolution and completed request storage | Future resolver proof; canonical admission from `allow_review`; claim/lease/packet authority; lease copies the Submission-stamped policy version with no CON lookup | @@ -957,9 +957,10 @@ proof. The [offline gVisor build spike](engineering/pilot00-gvisor-offline-build-spike.md) selects a sealed-cache Kaniko builder plus a separate gVisor oracle sandbox for PILOT-04/PILOT-06. PILOT-04 now has a normalized external request/result -contract, immutable authorized digest-pinned registry and hidden unselected Rust -service/SDK with a typed Unix-socket adapter and request-bound ART grant. Product -runtime composition and policy routing remain absent. The spike proves only the +contract, immutable authorized digest-pinned registry, hidden unselected Rust +service/SDK with a typed Unix-socket adapter and request-bound ART grant, and an +unselected versioned Workstream default checker with its exact four blocking +outcomes. Product runtime composition and policy routing remain absent. The spike proves only the included small Linux fixture; representative task sizing, hosted hardening and macOS fallback evidence remain. From 12fb1032f19ea4606a1856c837067e828568bef9 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 13:00:32 +0100 Subject: [PATCH 022/283] feat(cli): convert task briefs and manage import source custody --- .../changes/pilot02-bulk-transitions-cli.md | 186 ++++++++++++++ cli/README.md | 52 ++++ cli/internal/api/client.go | 10 +- cli/internal/api/task_import_source.go | 123 ++++++++++ cli/internal/command/command.go | 1 + cli/internal/command/task_batch.go | 98 ++++++++ cli/internal/command/task_batch_source.go | 92 +++++++ cli/internal/taskimport/convert.go | 231 ++++++++++++++++++ cli/internal/taskimport/convert_test.go | 115 +++++++++ cli/internal/taskimport/json.go | 155 ++++++++++++ cli/internal/taskimport/json_test.go | 49 ++++ cli/tests/integration/test_http_boundary.py | 3 + cli/tests/integration/test_task_batch_csv.py | 102 ++++++++ .../test_task_batch_sources_http.py | 158 ++++++++++++ 14 files changed, 1370 insertions(+), 5 deletions(-) create mode 100644 .commitrail/changes/pilot02-bulk-transitions-cli.md create mode 100644 cli/internal/api/task_import_source.go create mode 100644 cli/internal/command/task_batch.go create mode 100644 cli/internal/command/task_batch_source.go create mode 100644 cli/internal/taskimport/convert.go create mode 100644 cli/internal/taskimport/convert_test.go create mode 100644 cli/internal/taskimport/json.go create mode 100644 cli/internal/taskimport/json_test.go create mode 100644 cli/tests/integration/test_task_batch_csv.py create mode 100644 cli/tests/integration/test_task_batch_sources_http.py diff --git a/.commitrail/changes/pilot02-bulk-transitions-cli.md b/.commitrail/changes/pilot02-bulk-transitions-cli.md new file mode 100644 index 000000000..234418e86 --- /dev/null +++ b/.commitrail/changes/pilot02-bulk-transitions-cli.md @@ -0,0 +1,186 @@ +# PILOT-02C — Atomic batch screening/release and explicit CLI intake + +- Initiative: `None` +- Durable disposition: `Planned` +- Intended merge outcome: Covered Project Managers explicitly screen and release every immutable imported batch member atomically and use the public CLI for separate source/import/status/screen/release operations and local CSV conversion. + +## Intent + +Issue [489](https://github.com/Flow-Research/workstream/issues/489) requires +separate all-or-nothing screening and release after canonical JSON import. +PILOT-02A supplies ART source custody; PILOT-02B supplies immutable native batch +membership and canonical CREATE participation. Normal single-Task SCREEN/RELEASE +already own guide locks, validation, per-Task authority, audit and retry receipts. +Their current root transaction prevents composition across a complete batch. + +## Bounded change + +### Allowed + +- New TASK batch-transition owner and typed API contracts under + `backend/app/modules/tasks/task_batch_transitions.py` and + `backend/app/modules/tasks/api/task_batch_transition.py`; native membership + selection only. Extend exact existing SCREEN/RELEASE participants in + `authorized_commands.py` through prepare/authorize/stage phases. Coordinate + these regions with the atomic-import owner before edits. +- New route/dependency modules and append-only composition of the typed batch + transition owner. Shared TASK `router.py`, `schemas.py`, model/receipt and AUTH + regions require an explicit owner handoff before edits. Existing per-Task + SCREEN/RELEASE actions and canonical denial handling remain mandatory. +- New Go CLI `internal/taskimport/` conversion/validation, scoped + `internal/api/task_import*.go`, `internal/command/task_batch*.go`, and one + registration in `internal/command/command.go`; focused native Go/HTTP and + real public backend journey tests. Reuse existing HTTP client and output/error + conventions. Source admission, import, status, screen and release stay explicit. +- Lead-approved exact `cli/internal/api/client.go` PUT additions: classify PUT + alongside POST/PATCH at the three existing mutation checks and require the + canonical error envelope for POST/PUT. Disable automatic body replay and retain + uncertain-write reporting; no other shared-client changes are authorized. +- Exact CLI proof paths are new `cli/tests/integration/test_task_batch_csv.py` + and `test_task_batch_sources_http.py`; the existing HTTP fixture receives one + PUT handler delegating to its unchanged exact-body POST capture. No retained + GET/PATCH/POST expectations or test guards are removed. +- Current TASK/AUTH/ART and CLI contracts, README, affected roadmap sections, + this record, and exact coordinated owner/lane/selected-contract metadata. +- Required schema/receipt changes only through the sole migration author after + the aggregate replay contract is reviewed and its exact DDL is handed off. + +### Not allowed + +No atomic-import/source owner rewrites, migration authorship or ordinal allocation, +arbitrary `Task.import_batch_id` membership, contributor creation, route calls, +per-row commits, alternate transition rules, skipped SCREENING, guide/activation +loosening, checker changes, external adapters, automatic write retries, provider +access, payouts, CI reductions, deployment, merge or issue-closing keywords. + +## Design and decisions + +Use native committed batch/member identities and preserve original row order in +responses. Lock all selected TASK/Assignment custody deterministically before +CHECKERS/project-policy or AUTH custody. Canonical single-Task operations and +bulk operations share the same flush-only participants and existing per-Task +receipts. One caller root authorizes every member and commits all lifecycle, +locked-guide, audit and receipt effects together. Aggregate exact-key custody +must bind the project, native batch, operation, reason and immutable membership; +its concrete receipt design is reviewed with the atomic owner before backend +composition. Replay reauthorizes the current covered PM and never reapplies +effects. Partial advanced state, crossed membership or any late failure refuses +the whole request. + +The lead confirmed canonical replay currentness on this assignment: every member +must still match the recorded SCREEN/RELEASE post-state, locked-context hash and +unassigned custody. A partly advanced or assigned batch conflicts atomically even +with unchanged input/key. Atomic-import replay's original DRAFT facts after +advancement remain a separate contract. CLI uncertain-write instructions retain +the same key/request, and warn that subsequent state changes can prevent replay. + +### Proposed aggregate custody for owner review + +The import/source command receipt cannot represent SCREEN/RELEASE, and the +canonical per-Task namespace admits only one Task per actor/action/key. A dedicated +`TaskBatchTransitionReceipt` plus append-only `TaskBatchTransitionMember` is +proposed; no new AUTH action or alternative Task writer is needed. The root's +receipt namespace is actor + existing SCREEN/RELEASE action + caller UUID key. +It binds exact project/native batch, reason request digest and original immutable +batch manifest. Successful member links bind every native import member in row +order to its canonical per-Task command receipt and consumed authority decision. +Per-Task keys are server-created random keys retained in those exact links; +callers never choose membership or per-row keys. + +Reservation and complete native membership preparation occur before any AUTH. +Prepare each canonical Task operation in UUID order (receipt, Task, assignment), +then consume all fresh per-Task authority, then stage shared canonical transitions. +Only after all succeed does the aggregate become committed with its exact ordered +response. Replay uses the retained per-Task links, freshly authorizes all members, +and runs canonical currentness recovery. Changed request and member/receipt drift +are conflicts after authority; no successful staging survives a late failure. +Direct-SQL guards must enforce exact closed action, complete membership, canonical +receipt/action/Task/actor/project equality, audit equality, original row order, +success response equality and immutable committed rows. Pending reservations +remain transaction-local, never a separately committed partial lifecycle. + +No migration ordinal is allocated here. The sole author receives the final exact +models and constraints only after this custody design and shared regions are +reviewed. New tables are justified by the concrete aggregate/per-Task namespace +gap; no business snapshot or generic batch framework is proposed. + +Proposed public routes are POST project-scoped native batch `/screen` and +`/release`, with a bounded reason and caller UUID Idempotency-Key. Responses name +the exact project/batch/operation and 1..500 ordered Task results. Release requires +its normal nonblank reason and all locked prerequisites. + +CLI uses `project task-batch` with explicit project/source/batch selectors and +caller-owned keys. Local `convert-csv --input FILE --out FILE` creates bounded +UTF-8 canonical JSON without network or token access; output refuses existing +files. It handles CSV quoting, Unicode and semicolon-separated skill fields, +maps category to task_type and languages/tools to skill_tags, validates 1..500 +rows, required case-sensitive external IDs and document limits, and reports the +SHA/count of its exact output bytes. Those JSON bytes are the uploaded server +source; no original-CSV retention claim is made. +CSV headers accept canonical row names plus `source_id` for `external_task_id`, +`category` for `task_type`, and semicolon `languages`/`tools` appended after +`skill_tags`. Duplicate/unknown headers and simultaneous alias/canonical headers +are refused. Blank semicolon segments are omitted; other instruction text and +case-sensitive external IDs are preserved. One optional UTF-8 BOM is accepted. + +## Acceptance criteria + +- A real 200-row source/import followed by one SCREEN and one RELEASE produces + 200 READY Tasks with exact immutable membership, per-Task authority/audit and + the normal locked guide/policy fields. +- Invalid/missing prerequisite, unauthorized member, arbitrary metadata, + partial advanced state, changed key payload or late write failure leaves no + partial lifecycle, successful audit or receipt effects. +- Fresh-authority exact replay and actual PostgreSQL concurrent lock controls + preserve original identities, deterministic order and revocation refusal. +- CLI performs only explicitly requested writes, validates exact returned + selectors and bounded results, never automatically retries, and preserves + caller keys for manual unchanged-request recovery. +- CSV quoting/UTF-8/semicolon mapping and invalid/duplicate/501-row/oversized + cases are discriminated; output SHA/count equals uploaded JSON bytes. +- Required complete CI, independent AUTH/architecture/product/QA review and + current source documentation are reconciled at the final tested head. + +## Risk and review routing + +- Risk class: `L1`. +- Required reviewers: AUTH/security, architecture/reuse, product operations, + QA/test delta and affected documentation/CI ownership, coordinated by the lead. +- Human review focus: aggregate replay custody, shared participant parity, + locking/rollback and explicit CLI write semantics. + +## Evidence + +Inspection at atomic checkpoint `4a6d00fc8` identifies the reusable canonical +SCREEN/RELEASE root and the native `TaskImportBatchMember` custody. This branch +is based on the unmerged atomic candidate; reconcile after its human merge or +use an explicitly coordinated stacked draft. Native schema/storage claims are +pending the sole-author migrations and actual isolated PostgreSQL/MinIO drills. +The offline converter is implemented with focused Go boundary checks and built +CLI/server-parser proof for quoting/Unicode, exact JSON commitment, no-clobber, +invalid CSV zero-output effects and 500/501 rows. This proof needs no token/API +configuration and makes no database or source-storage claim. Shared backend +transition code is not yet edited; aggregate custody is awaiting owner review. +Source CLI uses separate existing declaration/upload/status routes and sends exact +original JSON bytes. Go tests/vet/tidy-diff and built CLI CSV/source boundary plus +retained HTTP/profile/project/guide declaration checks pass. The PUT transport +control removes only its write classification: the actual HTTP/2 peer then +receives two identical bodies on two connections and the client loses uncertain +write reporting. The correct implementation receives one body/connection and +reports uncertainty. Source was restored byte-exact after that control. + +The atomic owner explicitly handed off SCREEN/RELEASE phase extraction and the +native original/member validator at clean `4a6d00fc8`. CREATE preparation, +import/source ancestry and `_prepare_sources` remain with that owner. The shared +validator extraction must preserve label/manifest, ordered native Member/CREATE +receipt/response validation and advanced-state-independent original facts. Its +commit will be shared back with the atomic owner to avoid parallel validators. + +## Reconciliation + +- Current-source reconciliation: Preserve the atomic owner's import/status and + source custody; shared-file regions require handoff before edits. +- Next usable boundary: Complete the separate explicit bulk/CLI journey under + issue 489; whole-issue completion requires every agreed acceptance criterion. +- Remaining risks: Aggregate receipt/currentness design and native concurrency + proof remain to be established before backend public composition. diff --git a/cli/README.md b/cli/README.md index 05b059c8c..4100d4cf5 100644 --- a/cli/README.md +++ b/cli/README.md @@ -418,6 +418,58 @@ foreign projects and unauthenticated/unauthorized callers are also denied. Explicit worker application is not queued broker-delivery, live setup inference or deployment proof. +## Prepare a task-import JSON source + +```sh +workstream project task-batch convert-csv --input briefs.csv --out briefs.json --label 'Evaluation briefs' --output json +workstream project task-batch source-declare PROJECT_ID --input briefs.json --idempotency-key SOURCE_UUID --output json +workstream project task-batch source-upload PROJECT_ID SOURCE_ID --input briefs.json --output json +workstream project task-batch source-status PROJECT_ID SOURCE_ID --output json +``` + +Conversion is local and needs no token or API configuration. It accepts quoted +UTF-8 CSV, including embedded commas/newlines and one optional UTF-8 BOM. It +requires 1..500 task rows and bounds both input CSV and generated JSON to 8MiB. +Invalid input produces no JSON file. `--out` must name a new file; an existing +file is never overwritten. The report names the SHA-256 and byte count of the +complete generated JSON, including its final newline. Upload those exact bytes. +Workstream retains the converted JSON source; this does not retain the original +CSV. Retain that original separately if your own workflow requires it. + +| CSV header | JSON task field | Conversion | +| --- | --- | --- | +| `external_task_id` or `source_id` | `external_task_id` | Required exact, case-sensitive source identifier | +| `title`, `description` | Same names | Required nonblank instruction text, preserved without trimming | +| `task_type` or `category` | `task_type` | Optional category, preserved | +| `skill_tags`, `languages`, `tools` | `skill_tags` | Semicolon segments concatenate in this order; trim segments and omit blank segments | +| `difficulty`, `acceptance_criteria`, `rejection_criteria` | Same names | Optional text, preserved | +| `estimated_time_minutes` | Same name | Optional whole minutes in 1..525600 | + +Unknown/duplicate headers, simultaneous alias/canonical headers, duplicate IDs, +padded/control-character IDs, invalid UTF-8/NUL, malformed quoting and row/field +limits are refused. No Task identities, guide locks or creator authority can be +supplied through CSV. The canonical JSON contract is +[`contracts/task-import.schema.json`](../contracts/task-import.schema.json). +JSON files also receive bounded canonical validation before declaration/upload, +including duplicate object members, strict field types and exact external IDs. +Their original whitespace/bytes are preserved for the commitment and upload. + +Declaration, upload and status are separate operations under current covered-PM +authority. Declaration sends only the exact JSON SHA/count with the caller's +UUID key and returns a source ID. Upload sends one raw `application/json` PUT +to that explicit project/source and carries no separate idempotency key; retained +source custody controls its replay. Status reads the actual retained ART state. +The CLI verifies returned selectors and, for writes, the exact file commitment. +A returned source/status establishes byte custody only; it does not create, +screen or release Tasks. + +Source writes never retry automatically, including after HTTP/2 GOAWAY. If a +declaration outcome is unknown, manually replay only the unchanged project, +JSON file bytes and caller key. For an uncertain upload, inspect `source-status` +and then manually replay the unchanged project/source/file if appropriate. +Server storage recovery can remain pending; inspect the actual returned status +instead of treating every successful HTTP response as verified storage. + ## Create a draft project shell ```sh diff --git a/cli/internal/api/client.go b/cli/internal/api/client.go index 9a21da5c0..87e258bfd 100644 --- a/cli/internal/api/client.go +++ b/cli/internal/api/client.go @@ -318,7 +318,7 @@ func (c *Client) requestWithKey(ctx context.Context, method, path, query string, } func (c *Client) requestWithResponseLimit(ctx context.Context, method, path, query string, body []byte, key string, successStatus, responseLimit int) (json.RawMessage, error) { - mutation := method == http.MethodPatch || method == http.MethodPost + mutation := method == http.MethodPatch || method == http.MethodPost || method == http.MethodPut response, err := c.openRequest(ctx, c.http, method, path, query, body, key, "application/json") if err != nil { return nil, err @@ -349,7 +349,7 @@ func (c *Client) openRequest(ctx context.Context, requestClient *http.Client, me } func (c *Client) openBodyRequest(ctx context.Context, requestClient *http.Client, method, path, query string, reader io.Reader, length int64, key, accept, contentType string) (*http.Response, error) { - mutation := method == http.MethodPatch || method == http.MethodPost + mutation := method == http.MethodPatch || method == http.MethodPost || method == http.MethodPut target := c.origin + path if query != "" { target += "?" + query @@ -393,7 +393,7 @@ func (c *Client) responseCorrelation(response *http.Response) string { } func (c *Client) responseFailure(method string, response *http.Response, responseBody []byte) error { - mutation := method == http.MethodPatch || method == http.MethodPost + mutation := method == http.MethodPatch || method == http.MethodPost || method == http.MethodPut correlation := c.responseCorrelation(response) code := "api_error" knownEnvelope := false @@ -410,7 +410,7 @@ func (c *Client) responseFailure(method string, response *http.Response, respons code = envelope.Error.Code } } - if method == http.MethodPost { + if method == http.MethodPost || method == http.MethodPut { knownEnvelope = canonicalMutationError(responseBody, response.Header.Get("Content-Type")) } // A complete API 4xx envelope is a known denial, independent of code @@ -419,7 +419,7 @@ func (c *Client) responseFailure(method string, response *http.Response, respons OutcomeUnknown: mutation && (response.StatusCode < 400 || response.StatusCode >= 500 || !knownEnvelope)} } -// POST writes need a complete public ApiError, not a gateway's code-shaped +// POST/PUT writes need a complete public ApiError, not a gateway's code-shaped // JSON. Profile PATCH deliberately retains its existing response contract. func canonicalMutationError(raw []byte, contentType string) bool { mediaType, _, err := mime.ParseMediaType(contentType) diff --git a/cli/internal/api/task_import_source.go b/cli/internal/api/task_import_source.go new file mode 100644 index 000000000..730164a81 --- /dev/null +++ b/cli/internal/api/task_import_source.go @@ -0,0 +1,123 @@ +package api + +import ( + "context" + "encoding/json" + "errors" + "net/http" + "net/url" + + "github.com/Flow-Research/workstream/cli/internal/taskimport" +) + +// TaskImportSource reports retained JSON byte custody, never Task creation. +type TaskImportSource struct { + SourceID string `json:"source_id"` + ProjectID string `json:"project_id"` + SHA256 string `json:"sha256"` + ByteCount int `json:"byte_count"` + MediaType string `json:"media_type"` + Status string `json:"status"` + CreatedAt string `json:"created_at"` +} + +func taskImportSourcePath(project string) string { + return "/api/v1/projects/" + url.PathEscape(project) + "/task-import-sources" +} + +// DeclareTaskImportSource commits only the exact original JSON SHA/byte count. +// Source upload and atomic Task import remain separate explicit commands. +func (c *Client) DeclareTaskImportSource(ctx context.Context, project string, body []byte, key string) (Result[TaskImportSource], error) { + var result Result[TaskImportSource] + if !validUUID(project) || !validUUID(key) || len(project) > 100 || len(key) > 100 { + return result, errors.New("PROJECT_ID and --idempotency-key must be UUIDs") + } + commitment, err := taskimport.ValidateJSON(body) + if err != nil { + return result, err + } + request, err := json.Marshal(struct { + SHA256 string `json:"sha256"` + ByteCount int `json:"byte_count"` + }{commitment.SHA256, commitment.ByteCount}) + if err != nil { + return result, err + } + raw, err := c.requestWithKey(ctx, http.MethodPost, taskImportSourcePath(project), "", request, key, http.StatusCreated) + if err != nil { + return result, taskImportSourceFailure(err, "declare") + } + result, err = c.decodeTaskImportSource(raw, project, "") + if err != nil || result.Value.SHA256 != commitment.SHA256 || result.Value.ByteCount != commitment.ByteCount { + return Result[TaskImportSource]{}, taskImportSourceFailure(&Failure{Code: "invalid_api_response", OutcomeUnknown: true}, "declare") + } + return result, nil +} + +// UploadTaskImportSource sends the unchanged validated JSON once to the explicit +// retained source. It does not declare a source or create/screen/release Tasks. +func (c *Client) UploadTaskImportSource(ctx context.Context, project, source string, body []byte) (Result[TaskImportSource], error) { + var result Result[TaskImportSource] + if !validUUID(project) || !validUUID(source) || len(project) > 100 || len(source) > 100 { + return result, errors.New("PROJECT_ID and SOURCE_ID must be UUIDs") + } + commitment, err := taskimport.ValidateJSON(body) + if err != nil { + return result, err + } + raw, err := c.requestWithKey(ctx, http.MethodPut, taskImportSourcePath(project)+"/"+url.PathEscape(source)+"/content", "", body, "", http.StatusOK) + if err != nil { + return result, taskImportSourceFailure(err, "upload") + } + result, err = c.decodeTaskImportSource(raw, project, source) + if err != nil || result.Value.SHA256 != commitment.SHA256 || result.Value.ByteCount != commitment.ByteCount { + return Result[TaskImportSource]{}, taskImportSourceFailure(&Failure{Code: "invalid_api_response", OutcomeUnknown: true}, "upload") + } + return result, nil +} + +func (c *Client) TaskImportSourceStatus(ctx context.Context, project, source string) (Result[TaskImportSource], error) { + var result Result[TaskImportSource] + if !validUUID(project) || !validUUID(source) || len(project) > 100 || len(source) > 100 { + return result, errors.New("PROJECT_ID and SOURCE_ID must be UUIDs") + } + raw, err := c.request(ctx, http.MethodGet, taskImportSourcePath(project)+"/"+url.PathEscape(source), "", nil) + if err != nil { + return result, err + } + return c.decodeTaskImportSource(raw, project, source) +} + +func (c *Client) decodeTaskImportSource(raw json.RawMessage, project, source string) (Result[TaskImportSource], error) { + var value TaskImportSource + _, err := contextObject(raw, &value, []string{"source_id", "project_id", "sha256", "byte_count", "media_type", "status", "created_at"}, nil) + status := map[string]bool{ + "declared": true, "prepared": true, "put_in_flight": true, "acknowledgement_unknown": true, + "object_confirmed": true, "absent_replay_required": true, "integrity_mismatch": true, + "provider_unavailable": true, "conflict": true, "verified": true, "missing": true, + } + if err != nil || !validUUID(value.SourceID) || !sameUUID(value.ProjectID, project) || + (source != "" && !sameUUID(value.SourceID, source)) || !contextPolicyDigest.MatchString(value.SHA256) || + value.ByteCount < 1 || value.ByteCount > taskimport.MaxBytes || value.MediaType != "application/json" || + !status[value.Status] || !validTime(value.CreatedAt) { + return Result[TaskImportSource]{}, &Failure{Code: "invalid_api_response"} + } + for _, metadata := range []string{value.SourceID, value.ProjectID, value.SHA256, value.MediaType, value.Status, value.CreatedAt} { + if !c.safeMetadata(metadata) || sameUUID(metadata, c.token) { + return Result[TaskImportSource]{}, &Failure{Code: "invalid_api_response"} + } + } + return Result[TaskImportSource]{Raw: raw, Value: value}, nil +} + +func taskImportSourceFailure(err error, operation string) error { + var failure *Failure + if errors.As(err, &failure) && failure.OutcomeUnknown { + if operation == "declare" { + failure.RecoveryHint = "source declaration outcome unknown; manually replay only the unchanged project, JSON file bytes and idempotency key" + } else { + failure.RecoveryHint = "source upload outcome unknown; inspect source-status, then manually replay only the unchanged project, source and JSON file bytes" + } + } + return err +} diff --git a/cli/internal/command/command.go b/cli/internal/command/command.go index ba8484c70..f3e4ba3bc 100644 --- a/cli/internal/command/command.go +++ b/cli/internal/command/command.go @@ -109,6 +109,7 @@ func Run(args []string, stdout, stderr io.Writer, getenv environment, version st project := &cobra.Command{Use: "project", Short: "Public project operations"} addTaskReads(project, client, &output, stdout) + addTaskBatch(project, client, &output, stdout) addProjectCreate(project, client, &output, stdout) addGuideCreate(project, client, &output, stdout) project.AddCommand(&cobra.Command{ diff --git a/cli/internal/command/task_batch.go b/cli/internal/command/task_batch.go new file mode 100644 index 000000000..81a008763 --- /dev/null +++ b/cli/internal/command/task_batch.go @@ -0,0 +1,98 @@ +package command + +import ( + "encoding/json" + "fmt" + "io" + "os" + + "github.com/Flow-Research/workstream/cli/internal/api" + "github.com/Flow-Research/workstream/cli/internal/taskimport" + "github.com/spf13/cobra" +) + +func addTaskBatch(project *cobra.Command, client func() (*api.Client, error), output *string, stdout io.Writer) { + batch := &cobra.Command{Use: "task-batch", Short: "Explicit task import, screening and release operations"} + addTaskBatchCSV(batch, output, stdout) + addTaskBatchSources(batch, client, output, stdout) + project.AddCommand(batch) +} + +func addTaskBatchCSV(batch *cobra.Command, output *string, stdout io.Writer) { + var input, destination, label string + convert := &cobra.Command{ + Use: "convert-csv", Short: "Convert local CSV briefs to uploadable JSON without contacting the server", Args: cobra.NoArgs, + RunE: func(_ *cobra.Command, _ []string) error { + if *output != "text" && *output != "json" { + return commandError{"invalid_output", "--output must be text or json"} + } + if destination == "" { + return commandError{"invalid_arguments", "--out must name a new JSON file"} + } + file, err := openTaskBatchInput(input) + if err != nil { + return err + } + defer file.Close() + converted, err := taskimport.ConvertCSV(file, label) + if err != nil { + return commandError{"invalid_task_import_csv", err.Error()} + } + if err := writeNewTaskBatchJSON(destination, converted.Bytes); err != nil { + return err + } + if *output == "json" { + raw, err := json.Marshal(struct { + JSONPath string `json:"json_path"` + SHA256 string `json:"sha256"` + ByteCount int `json:"byte_count"` + RowCount int `json:"row_count"` + }{destination, converted.SHA256, converted.ByteCount, converted.RowCount}) + if err != nil { + return err + } + return writeJSON(stdout, raw) + } + _, err = fmt.Fprintf(stdout, "JSON file: %s\nSHA-256: %s\nJSON bytes: %d\nTasks: %d\n", safeText(destination), converted.SHA256, converted.ByteCount, converted.RowCount) + return err + }, + } + convert.Flags().StringVar(&input, "input", "", "Required regular UTF-8 CSV file, at most 8MiB") + convert.Flags().StringVar(&destination, "out", "", "Required new JSON file; existing files are never overwritten") + convert.Flags().StringVar(&label, "label", "", "Optional batch display label, at most 255 characters") + batch.AddCommand(convert) +} + +func openTaskBatchInput(path string) (*os.File, error) { + bad := commandError{"invalid_arguments", "--input must be a readable regular file of 1..8388608 bytes"} + info, err := os.Stat(path) + if err != nil || !info.Mode().IsRegular() || info.Size() < 1 || info.Size() > taskimport.MaxBytes { + return nil, bad + } + file, err := os.Open(path) + if err != nil { + return nil, bad + } + info, err = file.Stat() + if err != nil || !info.Mode().IsRegular() || info.Size() < 1 || info.Size() > taskimport.MaxBytes { + file.Close() + return nil, bad + } + return file, nil +} + +func writeNewTaskBatchJSON(path string, body []byte) error { + file, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0o600) + if err != nil { + return commandError{"invalid_arguments", "--out must name a writable new file; existing files are never overwritten"} + } + written, writeErr := file.Write(body) + closeErr := file.Close() + if writeErr != nil || closeErr != nil || written != len(body) { + // This command created the file and has not published a commitment. + // Remove only its incomplete local conversion output. + os.Remove(path) + return commandError{"task_import_output_failed", "could not write complete JSON output"} + } + return nil +} diff --git a/cli/internal/command/task_batch_source.go b/cli/internal/command/task_batch_source.go new file mode 100644 index 000000000..244bd4336 --- /dev/null +++ b/cli/internal/command/task_batch_source.go @@ -0,0 +1,92 @@ +package command + +import ( + "fmt" + "io" + + "github.com/Flow-Research/workstream/cli/internal/api" + "github.com/Flow-Research/workstream/cli/internal/taskimport" + "github.com/spf13/cobra" +) + +func addTaskBatchSources(batch *cobra.Command, client func() (*api.Client, error), output *string, stdout io.Writer) { + var input, key string + declare := &cobra.Command{ + Use: "source-declare PROJECT_ID", Short: "Declare exact JSON byte custody; does not upload or import", Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + apiClient, err := client() + if err != nil { + return err + } + body, err := readTaskBatchJSON(input) + if err != nil { + return err + } + result, err := apiClient.DeclareTaskImportSource(cmd.Context(), args[0], body, key) + if err != nil { + return err + } + return writeTaskBatchSource(stdout, *output, result) + }, + } + declare.Flags().StringVar(&input, "input", "", "Required canonical UTF-8 JSON file, at most 8MiB; exact bytes determine the commitment") + declare.Flags().StringVar(&key, "idempotency-key", "", "Required caller UUID; retain unchanged file and key for manual declaration replay") + batch.AddCommand(declare) + var uploadInput string + upload := &cobra.Command{ + Use: "source-upload PROJECT_ID SOURCE_ID", Short: "Upload exact JSON once to a declared source; does not import", Args: cobra.ExactArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + apiClient, err := client() + if err != nil { + return err + } + body, err := readTaskBatchJSON(uploadInput) + if err != nil { + return err + } + result, err := apiClient.UploadTaskImportSource(cmd.Context(), args[0], args[1], body) + if err != nil { + return err + } + return writeTaskBatchSource(stdout, *output, result) + }, + } + upload.Flags().StringVar(&uploadInput, "input", "", "Required unchanged canonical JSON file matching the source SHA/count, at most 8MiB") + batch.AddCommand(upload) + batch.AddCommand(&cobra.Command{ + Use: "source-status PROJECT_ID SOURCE_ID", Short: "Inspect retained JSON custody under current authority", Args: cobra.ExactArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + apiClient, err := client() + if err != nil { + return err + } + result, err := apiClient.TaskImportSourceStatus(cmd.Context(), args[0], args[1]) + if err != nil { + return err + } + return writeTaskBatchSource(stdout, *output, result) + }, + }) +} + +func readTaskBatchJSON(path string) ([]byte, error) { + file, err := openTaskBatchInput(path) + if err != nil { + return nil, err + } + defer file.Close() + body, err := io.ReadAll(io.LimitReader(file, taskimport.MaxBytes+1)) + if err != nil || len(body) < 1 || len(body) > taskimport.MaxBytes { + return nil, commandError{"invalid_arguments", "--input must contain 1..8388608 readable JSON bytes"} + } + return body, nil +} + +func writeTaskBatchSource(stdout io.Writer, output string, result api.Result[api.TaskImportSource]) error { + if output == "json" { + return writeJSON(stdout, result.Raw) + } + value := result.Value + _, err := fmt.Fprintf(stdout, "Source: %s\nProject: %s\nSHA-256: %s\nJSON bytes: %d\nStorage status: %s\n", safeText(value.SourceID), safeText(value.ProjectID), value.SHA256, value.ByteCount, safeText(value.Status)) + return err +} diff --git a/cli/internal/taskimport/convert.go b/cli/internal/taskimport/convert.go new file mode 100644 index 000000000..f3cfaa1c6 --- /dev/null +++ b/cli/internal/taskimport/convert.go @@ -0,0 +1,231 @@ +// Package taskimport converts local CSV briefs into the server's sole JSON +// import format. The returned commitment identifies JSON bytes, never CSV bytes. +package taskimport + +import ( + "bytes" + "crypto/sha256" + "encoding/csv" + "encoding/hex" + "encoding/json" + "fmt" + "io" + "strconv" + "strings" + "unicode" + "unicode/utf8" +) + +const MaxBytes = 8 * 1024 * 1024 +const MaxRows = 500 + +// Conversion carries the exact upload bytes and their independently reportable +// commitment. Callers must write/upload Bytes without reserializing the document. +type Conversion struct { + Bytes []byte + SHA256 string + ByteCount int + RowCount int +} + +type document struct { + SchemaVersion string `json:"schema_version"` + Metadata metadata `json:"metadata"` + Tasks []row `json:"tasks"` +} + +type metadata struct { + Label *string `json:"label"` +} + +type row struct { + ExternalTaskID string `json:"external_task_id"` + Title string `json:"title"` + Description string `json:"description"` + TaskType string `json:"task_type,omitempty"` + Difficulty string `json:"difficulty,omitempty"` + SkillTags []string `json:"skill_tags"` + EstimatedTimeMinutes *int `json:"estimated_time_minutes,omitempty"` + AcceptanceCriteria string `json:"acceptance_criteria,omitempty"` + RejectionCriteria string `json:"rejection_criteria,omitempty"` +} + +// InputError identifies a bounded CSV row/field failure without echoing briefs. +// Row is the one-based task row, excluding the header; zero denotes the document. +type InputError struct { + Row int + Field string + Code string +} + +func (e *InputError) Error() string { + if e.Row > 0 { + return fmt.Sprintf("CSV task row %d: %s (%s)", e.Row, e.Code, e.Field) + } + return fmt.Sprintf("CSV input: %s (%s)", e.Code, e.Field) +} + +func invalid(index int, field, code string) error { + return &InputError{Row: index, Field: field, Code: code} +} + +// ConvertCSV accepts quoted UTF-8 CSV with required external_task_id (or source_id), +// title and description headers. category aliases task_type; semicolon-separated +// skill_tags, languages and tools concatenate in that order, omitting blank +// segments. Aliases cannot coexist. No input text is otherwise trimmed/repaired. +func ConvertCSV(input io.Reader, label string) (Conversion, error) { + body, err := io.ReadAll(io.LimitReader(input, MaxBytes+1)) + if err != nil { + return Conversion{}, invalid(0, "document", "unreadable") + } + if len(body) == 0 || len(body) > MaxBytes { + return Conversion{}, invalid(0, "document", "requires_1_to_8388608_bytes") + } + if !utf8.Valid(body) || bytes.IndexByte(body, 0) >= 0 { + return Conversion{}, invalid(0, "document", "requires_utf8_without_nul") + } + if label != "" && !validText(label, 255, true) { + return Conversion{}, invalid(0, "label", "invalid_label") + } + reader := csv.NewReader(bytes.NewReader(bytes.TrimPrefix(body, []byte{0xef, 0xbb, 0xbf}))) + reader.FieldsPerRecord = -1 + header, err := reader.Read() + if err != nil { + return Conversion{}, invalid(0, "header", "invalid_csv_header") + } + columns, err := headers(header) + if err != nil { + return Conversion{}, err + } + doc := document{SchemaVersion: "workstream.task_import.v1", Tasks: make([]row, 0)} + if label != "" { + doc.Metadata.Label = &label + } + seen := make(map[string]struct{}) + for index := 1; ; index++ { + values, readErr := reader.Read() + if readErr == io.EOF { + break + } + if index > MaxRows { + return Conversion{}, invalid(index, "tasks", "maximum_500_rows") + } + if readErr != nil || len(values) != len(header) { + return Conversion{}, invalid(index, "row", "invalid_csv_row") + } + value, parseErr := parseRow(values, columns, index) + if parseErr != nil { + return Conversion{}, parseErr + } + if _, duplicate := seen[value.ExternalTaskID]; duplicate { + return Conversion{}, invalid(index, "external_task_id", "duplicate_external_task_id") + } + seen[value.ExternalTaskID] = struct{}{} + doc.Tasks = append(doc.Tasks, value) + } + if len(doc.Tasks) == 0 { + return Conversion{}, invalid(0, "tasks", "requires_at_least_one_row") + } + encoded, err := json.Marshal(doc) + if err != nil { + return Conversion{}, invalid(0, "document", "cannot_encode_json") + } + encoded = append(encoded, '\n') + if len(encoded) > MaxBytes { + return Conversion{}, invalid(0, "document", "json_exceeds_8388608_bytes") + } + sum := sha256.Sum256(encoded) + return Conversion{Bytes: encoded, SHA256: "sha256:" + hex.EncodeToString(sum[:]), ByteCount: len(encoded), RowCount: len(doc.Tasks)}, nil +} + +func headers(values []string) (map[string]int, error) { + allowed := map[string]bool{ + "external_task_id": true, "source_id": true, "title": true, "description": true, + "task_type": true, "category": true, "difficulty": true, "skill_tags": true, + "languages": true, "tools": true, "estimated_time_minutes": true, + "acceptance_criteria": true, "rejection_criteria": true, + } + columns := make(map[string]int) + for index, field := range values { + if !allowed[field] { + return nil, invalid(0, "header", "unknown_header") + } + if _, exists := columns[field]; exists { + return nil, invalid(0, "header", "duplicate_header") + } + columns[field] = index + } + for alias, canonical := range map[string]string{"source_id": "external_task_id", "category": "task_type"} { + if index, exists := columns[alias]; exists { + if _, conflict := columns[canonical]; conflict { + return nil, invalid(0, "header", "conflicting_alias_headers") + } + columns[canonical] = index + } + } + for _, required := range []string{"external_task_id", "title", "description"} { + if _, present := columns[required]; !present { + return nil, invalid(0, required, "required_header_missing") + } + } + return columns, nil +} + +func validText(value string, maximum int, nonblank bool) bool { + return utf8.ValidString(value) && !strings.ContainsRune(value, 0) && utf8.RuneCountInString(value) <= maximum && (!nonblank || strings.TrimSpace(value) != "") +} + +func parseRow(values []string, columns map[string]int, index int) (row, error) { + get := func(field string) string { + if column, exists := columns[field]; exists { + return values[column] + } + return "" + } + result := row{ + ExternalTaskID: get("external_task_id"), Title: get("title"), Description: get("description"), + TaskType: get("task_type"), Difficulty: get("difficulty"), SkillTags: []string{}, + AcceptanceCriteria: get("acceptance_criteria"), RejectionCriteria: get("rejection_criteria"), + } + for _, field := range []struct { + name string + value string + maximum int + nonblank bool + }{ + {"external_task_id", result.ExternalTaskID, 200, true}, {"title", result.Title, 255, true}, + {"description", result.Description, 50000, true}, {"task_type", result.TaskType, 80, false}, + {"difficulty", result.Difficulty, 80, false}, {"acceptance_criteria", result.AcceptanceCriteria, 50000, false}, + {"rejection_criteria", result.RejectionCriteria, 50000, false}, + } { + if !validText(field.value, field.maximum, field.nonblank) { + return row{}, invalid(index, field.name, "invalid_field") + } + } + if strings.TrimSpace(result.ExternalTaskID) != result.ExternalTaskID || strings.IndexFunc(result.ExternalTaskID, unicode.IsControl) >= 0 { + return row{}, invalid(index, "external_task_id", "ambiguous_external_task_id") + } + for _, field := range []string{"skill_tags", "languages", "tools"} { + for _, part := range strings.Split(get(field), ";") { + tag := strings.TrimSpace(part) + if tag == "" { + continue + } + if !validText(tag, 200, true) { + return row{}, invalid(index, field, "invalid_skill_tag") + } + result.SkillTags = append(result.SkillTags, tag) + } + } + if len(result.SkillTags) > 100 { + return row{}, invalid(index, "skill_tags", "maximum_100_tags") + } + if text := get("estimated_time_minutes"); text != "" { + minutes, err := strconv.Atoi(text) + if err != nil || minutes < 1 || minutes > 525600 { + return row{}, invalid(index, "estimated_time_minutes", "invalid_minutes") + } + result.EstimatedTimeMinutes = &minutes + } + return result, nil +} diff --git a/cli/internal/taskimport/convert_test.go b/cli/internal/taskimport/convert_test.go new file mode 100644 index 000000000..20228e9ae --- /dev/null +++ b/cli/internal/taskimport/convert_test.go @@ -0,0 +1,115 @@ +package taskimport + +import ( + "crypto/sha256" + "encoding/csv" + "encoding/hex" + "encoding/json" + "errors" + "fmt" + "strings" + "testing" +) + +func TestQuotedUnicodeCSVCommitment(t *testing.T) { + input := "\ufeffsource_id,title,description,category,skill_tags,languages,tools,estimated_time_minutes,acceptance_criteria\r\n" + + "brief-É,\"Caption, français\",\"First line\nSecond line: 日本語\",caption,\" review ; ;accuracy\",fr;ja,editor,30,Usable caption\r\n" + result, err := ConvertCSV(strings.NewReader(input), "Multilingual briefs") + if err != nil { + t.Fatal(err) + } + var value document + if err := json.Unmarshal(result.Bytes, &value); err != nil { + t.Fatal(err) + } + if value.SchemaVersion != "workstream.task_import.v1" || value.Metadata.Label == nil || *value.Metadata.Label != "Multilingual briefs" || len(value.Tasks) != 1 { + t.Fatalf("unexpected document metadata: %#v", value) + } + task := value.Tasks[0] + if task.ExternalTaskID != "brief-É" || task.Title != "Caption, français" || task.Description != "First line\nSecond line: 日本語" || task.TaskType != "caption" || strings.Join(task.SkillTags, ";") != "review;accuracy;fr;ja;editor" || task.EstimatedTimeMinutes == nil || *task.EstimatedTimeMinutes != 30 { + t.Fatalf("CSV instructions were mapped incorrectly: %#v", task) + } + sum := sha256.Sum256(result.Bytes) + if result.SHA256 != "sha256:"+hex.EncodeToString(sum[:]) || result.ByteCount != len(result.Bytes) || result.RowCount != 1 || result.Bytes[len(result.Bytes)-1] != '\n' { + t.Fatal("commitment does not identify the complete written JSON bytes") + } + again, err := ConvertCSV(strings.NewReader(input), "Multilingual briefs") + if err != nil || string(again.Bytes) != string(result.Bytes) { + t.Fatal("unchanged conversion did not produce identical bytes") + } +} + +func TestCSVRefusalsProduceNoOutput(t *testing.T) { + for _, test := range []struct { + name, input, code string + row int + }{ + {"duplicate header", "external_task_id,title,title,description\na,T,T,D\n", "duplicate_header", 0}, + {"unknown header", "external_task_id,title,description,created_by\na,T,D,actor\n", "unknown_header", 0}, + {"missing id header", "title,description\nT,D\n", "required_header_missing", 0}, + {"crossed id aliases", "external_task_id,source_id,title,description\na,b,T,D\n", "conflicting_alias_headers", 0}, + {"crossed category aliases", "external_task_id,title,description,task_type,category\na,T,D,A,B\n", "conflicting_alias_headers", 0}, + {"no rows", "external_task_id,title,description\n", "requires_at_least_one_row", 0}, + {"bad quote", "external_task_id,title,description\na,\"unterminated,D\n", "invalid_csv_row", 1}, + {"wrong columns", "external_task_id,title,description\na,T,D,extra\n", "invalid_csv_row", 1}, + {"duplicate id", "external_task_id,title,description\na,T,D\na,T2,D2\n", "duplicate_external_task_id", 2}, + {"blank instructions", "external_task_id,title,description\na, ,D\n", "invalid_field", 1}, + {"padded id", "external_task_id,title,description\n a,T,D\n", "ambiguous_external_task_id", 1}, + {"control id", "external_task_id,title,description\na\t,T,D\n", "ambiguous_external_task_id", 1}, + {"nul", "external_task_id,title,description\na,T,D\x00\n", "requires_utf8_without_nul", 0}, + {"invalid utf8", "external_task_id,title,description\na,T,D\xff\n", "requires_utf8_without_nul", 0}, + {"bad minutes", "external_task_id,title,description,estimated_time_minutes\na,T,D,0\n", "invalid_minutes", 1}, + {"oversized title", "external_task_id,title,description\na," + strings.Repeat("é", 256) + ",D\n", "invalid_field", 1}, + {"too many tags", "external_task_id,title,description,skill_tags\na,T,D," + strings.Repeat("tag;", 101) + "\n", "maximum_100_tags", 1}, + } { + t.Run(test.name, func(t *testing.T) { + result, err := ConvertCSV(strings.NewReader(test.input), "") + var refusal *InputError + if !errors.As(err, &refusal) || refusal.Code != test.code || refusal.Row != test.row || len(result.Bytes) != 0 { + t.Fatalf("expected bounded refusal %s at row %d with zero output; got %#v, %v", test.code, test.row, result, err) + } + }) + } +} + +func TestRowAndByteBoundaries(t *testing.T) { + var input strings.Builder + input.WriteString("external_task_id,title,description\n") + for index := 0; index < MaxRows; index++ { + fmt.Fprintf(&input, "task-%d,T,D\n", index) + } + result, err := ConvertCSV(strings.NewReader(input.String()), "") + if err != nil || result.RowCount != MaxRows { + t.Fatalf("500 rows should be admitted: %v", err) + } + input.WriteString("task-501,T,D\n") + _, err = ConvertCSV(strings.NewReader(input.String()), "") + var refusal *InputError + if !errors.As(err, &refusal) || refusal.Code != "maximum_500_rows" || refusal.Row != 501 { + t.Fatalf("501 rows should be refused: %v", err) + } + _, err = ConvertCSV(strings.NewReader(strings.Repeat("x", MaxBytes+1)), "") + if !errors.As(err, &refusal) || refusal.Code != "requires_1_to_8388608_bytes" { + t.Fatalf("oversized CSV should be refused before parsing: %v", err) + } + // JSON escapes these otherwise valid CSV instructions. Enforce the output + // bound too; input within 8MiB must not produce an unuploadable document. + var expanded strings.Builder + writer := csv.NewWriter(&expanded) + writer.Write([]string{"external_task_id", "title", "description"}) + for index := 0; index < 40; index++ { + writer.Write([]string{fmt.Sprint(index), "T", strings.Repeat("\x01", 40000)}) + } + writer.Flush() + _, err = ConvertCSV(strings.NewReader(expanded.String()), "") + if !errors.As(err, &refusal) || refusal.Code != "json_exceeds_8388608_bytes" { + t.Fatalf("oversized converted JSON should be refused: %v", err) + } +} + +func TestExternalIDsAreCaseSensitive(t *testing.T) { + result, err := ConvertCSV(strings.NewReader("external_task_id,title,description\na,T,D\nA,T,D\n"), "") + if err != nil || result.RowCount != 2 { + t.Fatalf("distinct case-sensitive IDs should survive: %v", err) + } +} diff --git a/cli/internal/taskimport/json.go b/cli/internal/taskimport/json.go new file mode 100644 index 000000000..ede51e0dd --- /dev/null +++ b/cli/internal/taskimport/json.go @@ -0,0 +1,155 @@ +package taskimport + +import ( + "bytes" + "crypto/sha256" + "encoding/hex" + "encoding/json" + jsonv2 "encoding/json/v2" + "strconv" + "strings" + "unicode" + "unicode/utf8" +) + +// ValidateJSON checks the canonical server input without rewriting its bytes. +// The commitment is therefore usable for separate declaration and upload. +func ValidateJSON(body []byte) (Conversion, error) { + if len(body) == 0 || len(body) > MaxBytes { + return Conversion{}, invalid(0, "document", "requires_1_to_8388608_bytes") + } + if !utf8.Valid(body) { + return Conversion{}, invalid(0, "document", "requires_utf8_without_nul") + } + fields, err := jsonObject(body, map[string]bool{"schema_version": true, "metadata": true, "tasks": true}) + if err != nil { + return Conversion{}, invalid(0, "document", "invalid_json_document") + } + version, err := jsonString(fields["schema_version"], false) + if err != nil || version != "workstream.task_import.v1" { + return Conversion{}, invalid(0, "schema_version", "invalid_schema_version") + } + if raw, present := fields["metadata"]; present { + metadata, err := jsonObject(raw, map[string]bool{"label": true}) + if err != nil { + return Conversion{}, invalid(0, "metadata", "invalid_metadata") + } + if raw, present := metadata["label"]; present && !jsonNull(raw) { + label, err := jsonString(raw, false) + if err != nil || len(label) == 0 || !validText(label, 255, false) { + return Conversion{}, invalid(0, "label", "invalid_label") + } + } + } + var members []json.RawMessage + if jsonv2.Unmarshal(fields["tasks"], &members) != nil || len(members) < 1 || len(members) > MaxRows { + return Conversion{}, invalid(0, "tasks", "requires_1_to_500_rows") + } + seen := make(map[string]bool) + for index, raw := range members { + id, err := validateJSONRow(raw, index+1) + if err != nil { + return Conversion{}, err + } + if seen[id] { + return Conversion{}, invalid(index+1, "external_task_id", "duplicate_external_task_id") + } + seen[id] = true + } + sum := sha256.Sum256(body) + return Conversion{Bytes: body, SHA256: "sha256:" + hex.EncodeToString(sum[:]), ByteCount: len(body), RowCount: len(members)}, nil +} + +func jsonObject(raw []byte, allowed map[string]bool) (map[string]json.RawMessage, error) { + var fields map[string]json.RawMessage + if err := jsonv2.Unmarshal(raw, &fields); err != nil { + return nil, err + } + if fields == nil { + return nil, invalid(0, "object", "requires_object") + } + for field := range fields { + if !allowed[field] { + return nil, invalid(0, "object", "unknown_field") + } + } + return fields, nil +} + +func jsonString(raw []byte, nullable bool) (string, error) { + if nullable && jsonNull(raw) { + return "", nil + } + var value *string + if err := jsonv2.Unmarshal(raw, &value); err != nil { + return "", err + } + if value == nil { + return "", invalid(0, "text", "requires_string") + } + return *value, nil +} + +func jsonNull(raw []byte) bool { return bytes.Equal(bytes.TrimSpace(raw), []byte("null")) } + +func validateJSONRow(raw []byte, index int) (string, error) { + allowed := map[string]bool{ + "external_task_id": true, "title": true, "description": true, "task_type": true, + "difficulty": true, "skill_tags": true, "estimated_time_minutes": true, + "acceptance_criteria": true, "rejection_criteria": true, + } + fields, err := jsonObject(raw, allowed) + if err != nil { + return "", invalid(index, "row", "invalid_json_row") + } + var id string + for _, field := range []struct { + name string + maximum int + required bool + }{ + {"external_task_id", 200, true}, {"title", 255, true}, {"description", 50000, true}, + {"task_type", 80, false}, {"difficulty", 80, false}, + {"acceptance_criteria", 50000, false}, {"rejection_criteria", 50000, false}, + } { + raw, present := fields[field.name] + if !present && !field.required { + continue + } + value, err := jsonString(raw, !field.required) + if err != nil || !validText(value, field.maximum, field.required) { + return "", invalid(index, field.name, "invalid_field") + } + if field.name == "external_task_id" { + if strings.TrimSpace(value) != value || strings.IndexFunc(value, unicode.IsControl) >= 0 { + return "", invalid(index, field.name, "ambiguous_external_task_id") + } + id = value + } + } + if raw, present := fields["skill_tags"]; present { + var tags []*string + if jsonv2.Unmarshal(raw, &tags) != nil || tags == nil || len(tags) > 100 { + return "", invalid(index, "skill_tags", "invalid_skill_tags") + } + for _, tag := range tags { + if tag == nil || !validText(*tag, 200, true) { + return "", invalid(index, "skill_tags", "invalid_skill_tag") + } + } + } + if raw, present := fields["estimated_time_minutes"]; present && !jsonNull(raw) { + raw = bytes.TrimSpace(raw) + // Pydantic's strict integer excludes JSON decimal/exponent notation. + for _, digit := range raw { + if digit < '0' || digit > '9' { + return "", invalid(index, "estimated_time_minutes", "invalid_minutes") + } + } + minutes, err := strconv.Atoi(string(raw)) + if err != nil || minutes < 1 || minutes > 525600 { + return "", invalid(index, "estimated_time_minutes", "invalid_minutes") + } + } + return id, nil +} diff --git a/cli/internal/taskimport/json_test.go b/cli/internal/taskimport/json_test.go new file mode 100644 index 000000000..0d1537fc0 --- /dev/null +++ b/cli/internal/taskimport/json_test.go @@ -0,0 +1,49 @@ +package taskimport + +import ( + "crypto/sha256" + "encoding/hex" + "strings" + "testing" +) + +func TestJSONValidationPreservesInputCommitment(t *testing.T) { + input := []byte(" {\n\"schema_version\":\"workstream.task_import.v1\",\"metadata\": {\"label\": null},\"tasks\":[{\"external_task_id\":\"É\",\"title\":\"Caption\",\"description\":\"日本語\",\"skill_tags\":[],\"difficulty\":null,\"estimated_time_minutes\": 30}]}\n") + result, err := ValidateJSON(input) + sum := sha256.Sum256(input) + if err != nil || string(result.Bytes) != string(input) || result.ByteCount != len(input) || result.RowCount != 1 || result.SHA256 != "sha256:"+hex.EncodeToString(sum[:]) { + t.Fatalf("valid original JSON bytes must remain unchanged: %#v, %v", result, err) + } + converted, err := ConvertCSV(strings.NewReader("external_task_id,title,description\na,T,D\n"), "") + if err != nil { + t.Fatal(err) + } + checked, err := ValidateJSON(converted.Bytes) + if err != nil || checked.SHA256 != converted.SHA256 { + t.Fatalf("converter output must pass canonical validation unchanged: %v", err) + } +} + +func TestAmbiguousAndNoncanonicalJSONRefused(t *testing.T) { + base := `{"schema_version":"workstream.task_import.v1","tasks":[{"external_task_id":"a","title":"T","description":"D"}]}` + for _, input := range []string{ + strings.Replace(base, `"title":"T"`, `"title":"T","title":"other"`, 1), + strings.Replace(base, `"title":"T"`, `"title":null`, 1), + strings.Replace(base, `"title":"T"`, `"title":"\ud800"`, 1), + strings.Replace(base, `"title":"T"`, `"title":"\u0000"`, 1), + strings.Replace(base, `"external_task_id":"a"`, `"external_task_id":" a"`, 1), + strings.Replace(base, `"description":"D"`, `"description":"D","skill_tags":null`, 1), + strings.Replace(base, `"description":"D"`, `"description":"D","skill_tags":[null]`, 1), + strings.Replace(base, `"description":"D"`, `"description":"D","estimated_time_minutes":1.0`, 1), + strings.Replace(base, `"description":"D"`, `"description":"D","estimated_time_minutes":true`, 1), + strings.Replace(base, `"description":"D"`, `"description":"D","created_by":"actor"`, 1), + strings.Replace(base, `"tasks":`, `"metadata":null,"tasks":`, 1), + strings.Replace(base, `"tasks":`, `"metadata":{"label":""},"tasks":`, 1), + base + `{}`, + } { + result, err := ValidateJSON([]byte(input)) + if err == nil || len(result.Bytes) != 0 { + t.Fatalf("noncanonical JSON must produce no upload commitment: %s", input) + } + } +} diff --git a/cli/tests/integration/test_http_boundary.py b/cli/tests/integration/test_http_boundary.py index 5c9cf1b0d..7a0ba8480 100644 --- a/cli/tests/integration/test_http_boundary.py +++ b/cli/tests/integration/test_http_boundary.py @@ -94,6 +94,9 @@ def do_POST(self): # noqa: N802 - standard HTTP handler interface after_body() self.do_GET() + def do_PUT(self): # noqa: N802 - same exact-byte capture for source writes + self.do_POST() + def do_CONNECT(self): # noqa: N802 - captures attempted HTTPS proxy use requests.append( (self.command, self.path, self.headers.get("Authorization")) diff --git a/cli/tests/integration/test_task_batch_csv.py b/cli/tests/integration/test_task_batch_csv.py new file mode 100644 index 000000000..26562921a --- /dev/null +++ b/cli/tests/integration/test_task_batch_csv.py @@ -0,0 +1,102 @@ +"""Built offline CSV conversion produces the exact server-accepted JSON source.""" + +from hashlib import sha256 +import json + +from app.modules.tasks.api.task_import import parse_task_import + + +def convert(cli, source, destination, *extra): + return cli( + "not-an-api-origin", + "", + "--output", + "json", + "project", + "task-batch", + "convert-csv", + "--input", + str(source), + "--out", + str(destination), + *extra, + ) + + +def test_offline_conversion_server_contract_and_no_clobber(cli, tmp_path): + source = tmp_path / "briefs.csv" + source.write_text( + "source_id,title,description,category,skill_tags,languages,tools\n" + 'brief-é,"Caption, français","First line\n日本語",caption,' + "review;accuracy,fr;ja,editor\n", + encoding="utf-8", + ) + destination = tmp_path / "briefs.json" + result = convert(cli, source, destination, "--label", "Multilingual briefs") + assert result.returncode == 0 and result.stderr == "", result.stderr + raw = destination.read_bytes() + report = json.loads(result.stdout) + assert report == { + "json_path": str(destination), + "sha256": "sha256:" + sha256(raw).hexdigest(), + "byte_count": len(raw), + "row_count": 1, + } + parsed = parse_task_import(raw) + assert parsed.sha256 == report["sha256"] + assert parsed.byte_count == report["byte_count"] + task = parsed.document.tasks[0] + assert task.external_task_id == "brief-é" + assert task.title == "Caption, français" + assert task.description == "First line\n日本語" + assert task.task_type == "caption" + assert task.skill_tags == ["review", "accuracy", "fr", "ja", "editor"] + assert parsed.document.metadata.label == "Multilingual briefs" + + repeated = convert(cli, source, destination) + assert repeated.returncode == 2 + assert json.loads(repeated.stderr)["error"]["code"] == "invalid_arguments" + assert destination.read_bytes() == raw + second = tmp_path / "second.json" + assert ( + convert(cli, source, second, "--label", "Multilingual briefs").returncode == 0 + ) + assert second.read_bytes() == raw + + +def test_invalid_csv_does_not_create_or_modify_output(cli, tmp_path): + source = tmp_path / "briefs.csv" + destination = tmp_path / "briefs.json" + for raw in ( + b"external_task_id,title,description\na,T,D\na,T,D\n", + b"external_task_id,title,description\na,T,D\xff\n", + b"external_task_id,title,description\na,T,D\x00\n", + b"external_task_id,title,description\na,T\n", + b'external_task_id,title,description\na,"broken,D\n', + b"external_task_id,title,description,unknown\na,T,D,x\n", + ): + source.write_bytes(raw) + result = convert(cli, source, destination) + assert result.returncode == 2 + assert json.loads(result.stderr)["error"]["code"] == "invalid_task_import_csv" + assert not destination.exists() + + +def test_csv_500_vs_501_rows(cli, tmp_path): + source = tmp_path / "briefs.csv" + source.write_text( + "external_task_id,title,description\n" + + "".join(f"brief-{index},Task,Instructions\n" for index in range(500)), + encoding="utf-8", + ) + destination = tmp_path / "briefs.json" + result = convert(cli, source, destination) + assert result.returncode == 0, result.stderr + assert len(parse_task_import(destination.read_bytes()).document.tasks) == 500 + with source.open("a", encoding="utf-8") as stream: + stream.write("brief-501,Task,Instructions\n") + refused = tmp_path / "refused.json" + result = convert(cli, source, refused) + assert result.returncode == 2 + assert json.loads(result.stderr)["error"]["code"] == "invalid_task_import_csv" + assert not refused.exists() diff --git a/cli/tests/integration/test_task_batch_sources_http.py b/cli/tests/integration/test_task_batch_sources_http.py new file mode 100644 index 000000000..18c66f9b8 --- /dev/null +++ b/cli/tests/integration/test_task_batch_sources_http.py @@ -0,0 +1,158 @@ +"""Built source CLI preserves exact bytes and treats uncertain PUTs as writes.""" + +from hashlib import sha256 +import json + +from http2_fixture import goaway_fixture +from test_contributor_task_mutations import KEY, canonical_error +from test_guide_proposal_http import OTHER +from test_http_boundary import PROJECT, TOKEN, http_fixture + +SOURCE = OTHER +RAW = ( + b'{\n "schema_version":"workstream.task_import.v1", "tasks":[' + b'{"external_task_id":"brief-1","title":"Caption","description":"Brief"}]}\n' +) + + +def source(status="verified"): + return { + "source_id": SOURCE, + "project_id": PROJECT, + "sha256": "sha256:" + sha256(RAW).hexdigest(), + "byte_count": len(RAW), + "media_type": "application/json", + "status": status, + "created_at": "2026-10-11T12:00:00Z", + } + + +def invoke( + cli, origin, operation, path=None, *, project=PROJECT, target=SOURCE, **kwargs +): + args = ["-o", "json", "project", "task-batch", operation, project] + if operation != "source-declare": + args.append(target) + if path is not None: + args.extend(("--input", str(path))) + if operation == "source-declare": + args.extend(("--idempotency-key", KEY)) + return cli(origin, TOKEN, *args, **kwargs) + + +def test_source_operations_are_separate_exact_requests(cli, tmp_path): + path = tmp_path / "briefs.json" + path.write_bytes(RAW) + with http_fixture() as (origin, response, requests): + response.update(status=201, body=json.dumps(source("declared")).encode()) + result = invoke(cli, origin, "source-declare", path) + assert result.returncode == 0 and result.stderr == "", result.stderr + assert json.loads(result.stdout) == source("declared") + assert response["commands"] == [ + ( + "application/json", + [KEY], + {"sha256": source()["sha256"], "byte_count": len(RAW)}, + ) + ] + response.update(status=200, body=json.dumps(source()).encode()) + result = invoke(cli, origin, "source-upload", path) + assert result.returncode == 0 and result.stderr == "", result.stderr + assert json.loads(result.stdout) == source() + assert response["raw_commands"][-1] == RAW + assert response["commands"][-1][0:2] == ("application/json", None) + result = invoke(cli, origin, "source-status") + assert result.returncode == 0 and json.loads(result.stdout) == source() + prefix = f"/api/v1/projects/{PROJECT}/task-import-sources" + assert requests == [ + ("POST", prefix, "Bearer " + TOKEN), + ("PUT", f"{prefix}/{SOURCE}/content", "Bearer " + TOKEN), + ("GET", f"{prefix}/{SOURCE}", "Bearer " + TOKEN), + ] + + +def test_source_invalid_requests_never_contact_server(cli, tmp_path): + path = tmp_path / "briefs.json" + with http_fixture() as (origin, _response, requests): + for raw in ( + RAW.replace(b'"title":"Caption"', b'"title":"Caption","title":"x"'), + RAW.replace( + b'"description":"Brief"', b'"description":"Brief","created_by":"x"' + ), + RAW.replace( + b'"external_task_id":"brief-1"', b'"external_task_id":" brief-1"' + ), + RAW.replace(b'"title":"Caption"', b'"title":null'), + RAW + b"{}", + b" ", + ): + path.write_bytes(raw) + for operation in ("source-declare", "source-upload"): + assert invoke(cli, origin, operation, path).returncode == 2 + path.write_bytes(RAW) + assert ( + invoke(cli, origin, "source-upload", path, target="../private").returncode + == 2 + ) + assert ( + invoke(cli, origin, "source-status", project="../private").returncode == 2 + ) + assert requests == [] + + +def test_source_crossed_or_malformed_receipts_are_uncertain_writes(cli, tmp_path): + path = tmp_path / "briefs.json" + path.write_bytes(RAW) + with http_fixture() as (origin, response, requests): + variants = [ + source() | {"project_id": SOURCE}, + source() | {"source_id": PROJECT}, + source() | {"sha256": "sha256:" + "f" * 64}, + source() | {"byte_count": len(RAW) + 1}, + source() | {"media_type": "text/csv"}, + source() | {"status": "imported"}, + source() | {"storage_key": "private"}, + ] + for body in variants: + response.update(status=200, body=json.dumps(body).encode()) + result = invoke(cli, origin, "source-upload", path) + assert result.returncode == 1 and result.stdout == "" + error = json.loads(result.stderr)["error"] + assert error["code"] == "invalid_api_response" + assert error["outcome_unknown"] is True + assert len(requests) == len(variants) + + +def test_source_put_error_envelope_and_connection_loss(cli, tmp_path): + path = tmp_path / "briefs.json" + path.write_bytes(RAW) + with http_fixture() as (origin, response, requests): + response.update(status=403, body=json.dumps(canonical_error()).encode()) + denied = invoke(cli, origin, "source-upload", path) + assert denied.returncode == 1 + assert not json.loads(denied.stderr)["error"].get("outcome_unknown", False) + for status, body in ( + (403, b'{"error":{"code":"permission_not_granted"}}'), + (500, json.dumps(canonical_error()).encode()), + ): + response.update(status=status, body=body) + result = invoke(cli, origin, "source-upload", path) + assert result.returncode == 1 + assert json.loads(result.stderr)["error"]["outcome_unknown"] is True + response.update(drop=True) + result = invoke(cli, origin, "source-upload", path) + assert result.returncode == 1 + assert json.loads(result.stderr)["error"]["outcome_unknown"] is True + assert len(requests) == 4 + assert response["raw_commands"] == [RAW] * 4 + + +def test_source_put_http2_goaway_never_replays_bytes(cli, tmp_path): + path = tmp_path / "briefs.json" + path.write_bytes(RAW) + with goaway_fixture(tmp_path) as (origin, env, bodies, connections): + result = invoke(cli, origin, "source-upload", path, extra_env=env) + assert connections == ["h2"] and bodies == [RAW] + assert result.returncode == 1 + error = json.loads(result.stderr)["error"] + assert error["code"] == "service_unavailable" and error["outcome_unknown"] is True From b5df2bd29a5f19fabc13770d6dbf858f222f8f3f Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 13:15:29 +0100 Subject: [PATCH 023/283] refactor(tasks): compose canonical transitions and native batch membership --- .../changes/pilot02-bulk-transitions-cli.md | 29 +++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/.commitrail/changes/pilot02-bulk-transitions-cli.md b/.commitrail/changes/pilot02-bulk-transitions-cli.md index 234418e86..3d9c5fdfc 100644 --- a/.commitrail/changes/pilot02-bulk-transitions-cli.md +++ b/.commitrail/changes/pilot02-bulk-transitions-cli.md @@ -23,6 +23,12 @@ Their current root transaction prevents composition across a complete batch. selection only. Extend exact existing SCREEN/RELEASE participants in `authorized_commands.py` through prepare/authorize/stage phases. Coordinate these regions with the atomic-import owner before edits. +- Explicit atomic-owner handoff permits the single native membership owner in + `task_import_membership.py`, its small `api/task_import_membership.py` error/row + facts, exact original-response wrapper replacement, and batch error import + updates in TASK router/import tests. A tiny `_locked_task` extraction shares + its unchanged AUTH prepare/consume/finally-close block through `_authorize_facts`. + CREATE methods/dataclass and source ancestry preparation remain untouched. - New route/dependency modules and append-only composition of the typed batch transition owner. Shared TASK `router.py`, `schemas.py`, model/receipt and AUTH regions require an explicit owner handoff before edits. Existing per-Task @@ -40,6 +46,9 @@ Their current root transaction prevents composition across a complete batch. and `test_task_batch_sources_http.py`; the existing HTTP fixture receives one PUT handler delegating to its unchanged exact-body POST capture. No retained GET/PATCH/POST expectations or test guards are removed. +- Native participant lifetime/composition proof is owned in + `backend/tests/authorization/task_authority/test_management_participants.py`; + it extends the existing management proof using actual PostgreSQL and AUTH. - Current TASK/AUTH/ART and CLI contracts, README, affected roadmap sections, this record, and exact coordinated owner/lane/selected-contract metadata. - Required schema/receipt changes only through the sole migration author after @@ -98,6 +107,12 @@ Direct-SQL guards must enforce exact closed action, complete membership, canonic receipt/action/Task/actor/project equality, audit equality, original row order, success response equality and immutable committed rows. Pending reservations remain transaction-local, never a separately committed partial lifecycle. +Committed aggregate/member UPDATE and DELETE and statement-level TRUNCATE must +be refused. Deferred commit closure requires exactly the complete original native +member set/count; no subset, duplicate, substituted Task, action, actor, project, +decision, receipt or response is admitted. Reservation actor/Task/batch FKs must +defer premature AUTH/ART locks. The atomic owner independently reviewed this +namespace/closure design and found no shared-region blocker. No migration ordinal is allocated here. The sole author receives the final exact models and constraints only after this custody design and shared regions are @@ -159,8 +174,9 @@ pending the sole-author migrations and actual isolated PostgreSQL/MinIO drills. The offline converter is implemented with focused Go boundary checks and built CLI/server-parser proof for quoting/Unicode, exact JSON commitment, no-clobber, invalid CSV zero-output effects and 500/501 rows. This proof needs no token/API -configuration and makes no database or source-storage claim. Shared backend -transition code is not yet edited; aggregate custody is awaiting owner review. +configuration and makes no database or source-storage claim. Canonical +SCREEN/RELEASE extraction and the single native membership owner are implemented; +aggregate models/public composition remain pending. Source CLI uses separate existing declaration/upload/status routes and sends exact original JSON bytes. Go tests/vet/tidy-diff and built CLI CSV/source boundary plus retained HTTP/profile/project/guide declaration checks pass. The PUT transport @@ -175,6 +191,15 @@ import/source ancestry and `_prepare_sources` remain with that owner. The shared validator extraction must preserve label/manifest, ordered native Member/CREATE receipt/response validation and advanced-state-independent original facts. Its commit will be shared back with the atomic owner to avoid parallel validators. +Protected-base module-boundary validation and canonical import parser checks +pass. A native preflight proves retained single-Task SCREEN/RELEASE replay/guide +lock parity, successor-guide/currentness behavior, foreign-root participant +refusal, and two-Task late-failure rollback including actual successful AUTH +decisions. Its database/role cleanup is complete. The initial run used the dirty +extraction atop the CLI checkpoint, so exact frozen-head replay is still required. +This uses existing schema through source0031 and canonical seeded project +prerequisites; it proves Task/AUTH transactions, not new batch DDL, provider bytes, +live setup inference or a complete 200-member public bulk journey. ## Reconciliation From 8800c441e01e7624cd3aa3d06a610154a39254ab Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 13:47:36 +0100 Subject: [PATCH 024/283] Implement caller-root task batch screen and release custody --- .../changes/pilot02-bulk-transitions-cli.md | 49 +++ backend/app/adapters/tasks/__init__.py | 11 + .../app/api/deps/task_batch_transitions.py | 25 ++ .../tasks/api/task_batch_transition.py | 62 ++++ .../app/modules/tasks/authorized_commands.py | 11 +- backend/app/modules/tasks/command_replay.py | 12 +- backend/app/modules/tasks/models.py | 8 + backend/app/modules/tasks/router.py | 2 + .../tasks/task_batch_transition_models.py | 84 ++++++ .../tasks/task_batch_transition_router.py | 69 +++++ .../modules/tasks/task_batch_transitions.py | 207 +++++++++++++ .../test_task_batch_transition_contract.py | 63 ++++ .../tasks/test_task_batch_transitions.py | 283 ++++++++++++++++++ 13 files changed, 883 insertions(+), 3 deletions(-) create mode 100644 backend/app/api/deps/task_batch_transitions.py create mode 100644 backend/app/modules/tasks/api/task_batch_transition.py create mode 100644 backend/app/modules/tasks/task_batch_transition_models.py create mode 100644 backend/app/modules/tasks/task_batch_transition_router.py create mode 100644 backend/app/modules/tasks/task_batch_transitions.py create mode 100644 backend/tests/tasks/test_task_batch_transition_contract.py create mode 100644 backend/tests/tasks/test_task_batch_transitions.py diff --git a/.commitrail/changes/pilot02-bulk-transitions-cli.md b/.commitrail/changes/pilot02-bulk-transitions-cli.md index 3d9c5fdfc..4d4d599c5 100644 --- a/.commitrail/changes/pilot02-bulk-transitions-cli.md +++ b/.commitrail/changes/pilot02-bulk-transitions-cli.md @@ -23,6 +23,11 @@ Their current root transaction prevents composition across a complete batch. selection only. Extend exact existing SCREEN/RELEASE participants in `authorized_commands.py` through prepare/authorize/stage phases. Coordinate these regions with the atomic-import owner before edits. +- Aggregate custody is owned in `task_batch_transition_models.py`: exactly one + actor/action/key aggregate and its complete native member links. Lead review + approved compact ordered receipt projections and a scoped batch-write client + deadline, to be selected after native 200/500 measurements. No global transport + change or claimed measured ten-minute requirement is authorized. - Explicit atomic-owner handoff permits the single native membership owner in `task_import_membership.py`, its small `api/task_import_membership.py` error/row facts, exact original-response wrapper replacement, and batch error import @@ -33,6 +38,15 @@ Their current root transaction prevents composition across a complete batch. transition owner. Shared TASK `router.py`, `schemas.py`, model/receipt and AUTH regions require an explicit owner handoff before edits. Existing per-Task SCREEN/RELEASE actions and canonical denial handling remain mandatory. +- Atomic-owner-approved canonical custody hunks are the nullable + `TaskCommandReceipt.batch_transition_receipt_id` column/closed action constraint, + optional `command_replay.reserve` binding argument, and SCREEN/RELEASE + preparation/digest validation only. CREATE and other retained command digests + remain unchanged. New delivery is exactly `task_batch_transition_router.py`, + `api/deps/task_batch_transitions.py`, one TASK-router include and one TASK-adapter + factory. The new dependency composes inside the existing `get_task_commands` + yielding lifecycle; it neither duplicates AUTH denial handling nor creates an + alternate authority owner. - New Go CLI `internal/taskimport/` conversion/validation, scoped `internal/api/task_import*.go`, `internal/command/task_batch*.go`, and one registration in `internal/command/command.go`; focused native Go/HTTP and @@ -49,6 +63,10 @@ Their current root transaction prevents composition across a complete batch. - Native participant lifetime/composition proof is owned in `backend/tests/authorization/task_authority/test_management_participants.py`; it extends the existing management proof using actual PostgreSQL and AUTH. +- Closed response proof is `tests/tasks/test_task_batch_transition_contract.py`; + actual public native journeys/rollback/revocation/wait proof is + `tests/tasks/test_task_batch_transitions.py`. These two modules require exact + TASK lane/inventory registration after coordinated atomic/current-main union. - Current TASK/AUTH/ART and CLI contracts, README, affected roadmap sections, this record, and exact coordinated owner/lane/selected-contract metadata. - Required schema/receipt changes only through the sole migration author after @@ -114,6 +132,37 @@ decision, receipt or response is admitted. Reservation actor/Task/batch FKs must defer premature AUTH/ART locks. The atomic owner independently reviewed this namespace/closure design and found no shared-region blocker. +Links alone could reuse earlier committed single-Task receipts and misrepresent +one aggregate root. The lead approved explicit nullable canonical receipt root +binding, subject to the atomic owner's exact model/replay handoff. Bulk receipts +bind `batch_transition_receipt_id` into their request digest; existing null +single-Task and CREATE request digests remain byte-compatible. Deferred closure +must require that exact binding and its canonical success/AUTH evidence, so a +historical standalone success cannot be enrolled after the fact. + +### Implemented aggregate checkpoint, migration pending + +The aggregate models, compact public DTO, native membership selection, reservation, +sorted all-Task preparation, fresh all-member AUTH, canonical staging and exact +ordered replay are implemented. Both public routes compose through the actual +canonical Task denial lifecycle. Successful AUTH, Task effects, member links and +both receipt layers share one root; the response is validated/serialized before +commit. Complete replay compares all native links and canonical root binding, +recovers each normal retained current-state receipt, and compares the complete +original compact response. An identity-link mismatch also rolls back the root. + +Pure compact-contract plus retained parser verification passed 41 cases. Ruff and +the protected module-boundary validator passed without exemptions or new private +edges. Native participant proof at the earlier exact clean extraction head +`4400568a484a8a3fdf1a428d3ef78e560c892c27` passed five cases in 225.05 seconds +through migration 0031 with cleanup complete; it proves the extraction only. +The newly written aggregate tests cover complete 200/500-member public journeys, +fresh-authorized exact replay, injected failure after the second actual canonical +write, changed-input/partial-advance rollback, real grant-revocation denial and an +observed native holder/waiter before concurrent same-key recovery. They have not +run because aggregate custody DDL is pending the sole migration author. No native +aggregate, native 200/500 timing, full CI, or readiness claim is made here. + No migration ordinal is allocated here. The sole author receives the final exact models and constraints only after this custody design and shared regions are reviewed. New tables are justified by the concrete aggregate/per-Task namespace diff --git a/backend/app/adapters/tasks/__init__.py b/backend/app/adapters/tasks/__init__.py index 119c23581..3e236fb1b 100644 --- a/backend/app/adapters/tasks/__init__.py +++ b/backend/app/adapters/tasks/__init__.py @@ -124,6 +124,17 @@ def contributor_task_repository(session: AsyncSession) -> TaskRepository: return TaskRepository(session, compensation_terms=locked_compensation_terms_port(session)) +def task_batch_transition_commands( + session: AsyncSession, *, tasks: AuthorizedTaskCommands, + actor_profile_id: UUID, identity_link_id: UUID, +): + """Bind the batch root to the same canonical Task authority and participants.""" + from app.modules.tasks.task_batch_transitions import TaskBatchTransitionCommands + return TaskBatchTransitionCommands( + session, tasks=tasks, actor_profile_id=actor_profile_id, identity_link_id=identity_link_id, + ) + + def task_submission_context_port(session: AsyncSession) -> TaskSubmissionContextPort: """Bind the public TASK submission-context port to its repository.""" return TaskRepository(session) diff --git a/backend/app/api/deps/task_batch_transitions.py b/backend/app/api/deps/task_batch_transitions.py new file mode 100644 index 000000000..73ccb9194 --- /dev/null +++ b/backend/app/api/deps/task_batch_transitions.py @@ -0,0 +1,25 @@ +"""Compose a batch root inside the existing canonical Task denial lifecycle.""" + +from typing import Annotated + +from fastapi import Depends +from sqlalchemy.ext.asyncio import AsyncSession + +from app.api.deps.authorization import get_authorization_actor_identity, get_task_commands +from app.db.session import get_db_session +from app.modules.authorization.api import ActorIdentityFacts +from app.modules.tasks.api.task_batch_transition import TaskBatchTransitionPort + + +async def get_task_batch_transition_commands( + tasks: Annotated[object, Depends(get_task_commands)], + identity: Annotated[ActorIdentityFacts, Depends(get_authorization_actor_identity)], + session: Annotated[AsyncSession, Depends(get_db_session)], +) -> TaskBatchTransitionPort: + """Reuse the actual issuing AUTH owner for rollback and denial-only restaging.""" + from app.adapters.tasks import task_batch_transition_commands + + return task_batch_transition_commands( + session, tasks=tasks, actor_profile_id=identity.actor_profile_id, + identity_link_id=identity.identity_link_id, + ) diff --git a/backend/app/modules/tasks/api/task_batch_transition.py b/backend/app/modules/tasks/api/task_batch_transition.py new file mode 100644 index 000000000..221ae46ea --- /dev/null +++ b/backend/app/modules/tasks/api/task_batch_transition.py @@ -0,0 +1,62 @@ +"""Closed batch transition requests and compact canonical receipt projections.""" + +from typing import Literal, Protocol +from uuid import UUID + +from pydantic import BaseModel, ConfigDict, Field, model_validator + + +class TaskBatchTransitionRequest(BaseModel): + """One normal transition reason; membership comes only from the native batch.""" + + model_config = ConfigDict(extra="forbid", frozen=True) + + reason: str | None = Field(default=None, max_length=4000) + + +class TaskBatchTransitionResult(BaseModel): + """Ordered canonical success facts without repeating Task instructions.""" + + model_config = ConfigDict(extra="forbid", frozen=True) + + task_id: UUID + row_index: int = Field(ge=0, le=499) + status: Literal["screening", "ready"] + locked_guide_version: str = Field(min_length=1, max_length=100) + locked_contribution_policy_version_id: UUID + locked_context_hash: str = Field(pattern=r"^sha256:[0-9a-f]{64}$") + + +class TaskBatchTransitionResponse(BaseModel): + """The complete original ordered result, recoverable only while all Tasks match.""" + + model_config = ConfigDict(extra="forbid", frozen=True) + + project_id: UUID + batch_id: UUID + operation: Literal["screen", "release"] + row_count: int = Field(ge=1, le=500) + tasks: tuple[TaskBatchTransitionResult, ...] = Field(min_length=1, max_length=500) + + @model_validator(mode="after") + def complete_order(self): + """Refuse partial, duplicated or incorrectly ordered public membership.""" + status = "screening" if self.operation == "screen" else "ready" + if (len(self.tasks) != self.row_count + or len({task.task_id for task in self.tasks}) != self.row_count + or any(task.row_index != index or task.status != status + for index, task in enumerate(self.tasks))): + raise ValueError("task batch transition membership is invalid") + return self + + +class TaskBatchTransitionPort(Protocol): + """Own one complete transition root; no caller may supply individual members.""" + + async def screen( + self, project_id: UUID, batch_id: UUID, reason: str | None, *, idempotency_key: UUID, + ) -> TaskBatchTransitionResponse: ... + + async def release( + self, project_id: UUID, batch_id: UUID, reason: str | None, *, idempotency_key: UUID, + ) -> TaskBatchTransitionResponse: ... diff --git a/backend/app/modules/tasks/authorized_commands.py b/backend/app/modules/tasks/authorized_commands.py index 907398c46..08c43bec8 100644 --- a/backend/app/modules/tasks/authorized_commands.py +++ b/backend/app/modules/tasks/authorized_commands.py @@ -84,6 +84,7 @@ class TaskTransitionPreparation: reserved: bool facts: TaskAuthorityFacts transaction: AsyncSessionTransaction + batch_transition_receipt_id: UUID | None = None class AuthorizedTaskCommands: @@ -264,6 +265,7 @@ async def _manage_transition( async def prepare_transition( self, task_id: UUID, operation: TaskAuthorityOperation, reason: str | None, *, idempotency_key: UUID, project_id: UUID | None = None, + batch_transition_receipt_id: UUID | None = None, ) -> TaskTransitionPreparation: """Reserve canonical retry custody and lock TASK before the caller takes AUTH.""" if operation not in {TaskAuthorityOperation.SCREEN, TaskAuthorityOperation.RELEASE}: @@ -273,6 +275,7 @@ async def prepare_transition( raise RuntimeError("task transition preparation requires the caller transaction") receipt, digest, reserved = await self._replay.reserve( self._actor_id, operation, idempotency_key, task_id, reason, + batch_transition_receipt_id=batch_transition_receipt_id, ) task = (await self._repo.lock_project_task(project_id, task_id) if project_id is not None else await self._repo.get_task(str(task_id), for_update=True)) @@ -284,7 +287,7 @@ async def prepare_transition( replay_command_id=self._replay.manager_replay(receipt, operation, task_id, self._actor_id, idempotency_key), ) return TaskTransitionPreparation(task, assignment, operation, reason, receipt, digest, - reserved, facts, transaction) + reserved, facts, transaction, batch_transition_receipt_id) def _validate_transition_preparation(self, prepared: TaskTransitionPreparation) -> None: if (self._session.get_transaction() is not prepared.transaction or not prepared.transaction.is_active @@ -298,8 +301,12 @@ def _validate_transition_preparation(self, prepared: TaskTransitionPreparation) prepared.facts.idempotency_key, ), ) + values = {"task_id": prepared.task.id, "reason": prepared.reason} + if prepared.batch_transition_receipt_id is not None: + values["batch_transition_receipt_id"] = str(prepared.batch_transition_receipt_id) if (current != prepared.facts - or prepared.request_digest != canonical_json_hash({"task_id": prepared.task.id, "reason": prepared.reason})): + or prepared.receipt.batch_transition_receipt_id != prepared.batch_transition_receipt_id + or prepared.request_digest != canonical_json_hash(values)): raise TaskValidationError("task transition preparation changed") async def authorize_transition(self, prepared: TaskTransitionPreparation) -> TaskAuthorityDecision: diff --git a/backend/app/modules/tasks/command_replay.py b/backend/app/modules/tasks/command_replay.py index c8dee2265..a2b5c46a3 100644 --- a/backend/app/modules/tasks/command_replay.py +++ b/backend/app/modules/tasks/command_replay.py @@ -34,15 +34,25 @@ def __init__(self, session: AsyncSession): async def reserve( self, actor_id: UUID, operation: TaskAuthorityOperation, key: UUID, task_id: UUID, reason: str | None, *, request_value: dict | None = None, + batch_transition_receipt_id: UUID | None = None, ) -> tuple[TaskCommandReceipt, str, bool]: if not isinstance(key, UUID): raise ValueError("task command requires an idempotency UUID") - digest = canonical_json_hash(request_value if request_value is not None else {"task_id": str(task_id), "reason": reason}) + if batch_transition_receipt_id is not None and ( + operation not in {TaskAuthorityOperation.SCREEN, TaskAuthorityOperation.RELEASE} + or request_value is not None or not isinstance(batch_transition_receipt_id, UUID) + ): + raise ValueError("batch receipt binding requires a canonical SCREEN/RELEASE participant") + values = request_value if request_value is not None else {"task_id": str(task_id), "reason": reason} + if batch_transition_receipt_id is not None: + values = {**values, "batch_transition_receipt_id": str(batch_transition_receipt_id)} + digest = canonical_json_hash(values) inserted_id = new_record_id() receipt_id = await self._session.scalar( insert(TaskCommandReceipt).values( id=inserted_id, actor_profile_id=str(actor_id), action_id=operation.value, idempotency_key=key, request_digest=digest, task_id=str(task_id), status="pending", + batch_transition_receipt_id=batch_transition_receipt_id, ).on_conflict_do_update( index_elements=[TaskCommandReceipt.actor_profile_id, TaskCommandReceipt.action_id, TaskCommandReceipt.idempotency_key], diff --git a/backend/app/modules/tasks/models.py b/backend/app/modules/tasks/models.py index e1a4137c1..47fab0efb 100644 --- a/backend/app/modules/tasks/models.py +++ b/backend/app/modules/tasks/models.py @@ -46,6 +46,8 @@ class TaskCommandReceipt(Base): name="task_command_action", ), CheckConstraint("request_digest ~ '^sha256:[0-9a-f]{64}$'", name="task_command_request_digest"), + CheckConstraint("batch_transition_receipt_id is null or action_id in ('project.task.screen','project.task.release')", + name="task_command_batch_transition_action"), CheckConstraint( "(status='pending' and assignment_id is null and contributor_id is null " "and locked_context_hash is null and response is null and committed_at is null) or " @@ -74,6 +76,12 @@ class TaskCommandReceipt(Base): action_id: Mapped[str] = mapped_column(String(160)) idempotency_key: Mapped[UUID] = mapped_column(Uuid()) request_digest: Mapped[str] = mapped_column(String(71)) + # Existing single-Task/CREATE receipts remain null. Bulk participation is + # immutable receipt provenance, never an AUTH selector or a mutable Task flag. + batch_transition_receipt_id: Mapped[UUID | None] = mapped_column(ForeignKey( + "task_batch_transition_receipts.id", name="fk_task_command_batch_transition", + ondelete="RESTRICT", deferrable=True, initially="DEFERRED", + )) # Defer TASK custody until after reservation and proposed-task insertion. task_id: Mapped[str] = mapped_column(ForeignKey( "workstream_tasks.id", name="fk_task_command_task", deferrable=True, initially="DEFERRED", diff --git a/backend/app/modules/tasks/router.py b/backend/app/modules/tasks/router.py index 5635208b7..39fab6c4e 100644 --- a/backend/app/modules/tasks/router.py +++ b/backend/app/modules/tasks/router.py @@ -8,6 +8,7 @@ from uuid import UUID from app.api.deps.authorization import get_task_commands, get_task_import_batch_commands, enforce_human_authorization_read from app.modules.tasks.queue_router import router as queue_router +from app.modules.tasks.task_batch_transition_router import router as batch_transition_router from app.modules.tasks.authorized_commands import AuthorizedTaskCommands from app.modules.tasks.api import TaskAuthorityOperation, ContributorTaskDetail, ManagementTaskDetail from typing import Annotated @@ -46,6 +47,7 @@ router = APIRouter(tags=["tasks"]) # Static queue routes precede the project-scoped task UUID route. router.include_router(queue_router) +router.include_router(batch_transition_router) TASK_IDEMPOTENCY_PARAMETER = { "name": "Idempotency-Key", "in": "header", "required": True, diff --git a/backend/app/modules/tasks/task_batch_transition_models.py b/backend/app/modules/tasks/task_batch_transition_models.py new file mode 100644 index 000000000..76fa32845 --- /dev/null +++ b/backend/app/modules/tasks/task_batch_transition_models.py @@ -0,0 +1,84 @@ +"""TASK-owned aggregate success custody over canonical per-Task command receipts.""" + +from datetime import datetime +from uuid import UUID + +from sqlalchemy import CheckConstraint, DateTime, ForeignKey, ForeignKeyConstraint, Integer, String, Text, UniqueConstraint, Uuid +from sqlalchemy.dialects.postgresql import JSONB +from sqlalchemy.orm import Mapped, mapped_column +from sqlalchemy.sql import func + +from app.db.base import Base + + +class TaskBatchTransitionReceipt(Base): + """One actor/action/key root, committed only with every native batch member.""" + + __tablename__ = "task_batch_transition_receipts" + __table_args__ = ( + CheckConstraint("(get_byte(uuid_send(id), 6) >> 4) = 7 and (get_byte(uuid_send(id), 8) & 192) = 128", name="id_uuid7"), + UniqueConstraint("actor_profile_id", "action_id", "idempotency_key", name="uq_task_batch_transition_namespace"), + UniqueConstraint("id", "project_id", "batch_id", name="uq_task_batch_transition_parent"), + ForeignKeyConstraint(["batch_id", "project_id"], ["task_import_batches.id", "task_import_batches.project_id"], + name="fk_task_batch_transition_batch", ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), + ForeignKeyConstraint(["identity_link_id", "actor_profile_id"], ["actor_identity_links.id", "actor_identity_links.actor_profile_id"], + name="fk_task_batch_transition_actor_link", ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), + CheckConstraint("action_id in ('project.task.screen','project.task.release')", name="action"), + CheckConstraint("request_digest ~ '^sha256:[0-9a-f]{64}$' and manifest_digest ~ '^sha256:[0-9a-f]{64}$' " + "and membership_digest ~ '^sha256:[0-9a-f]{64}$'", name="digests"), + CheckConstraint("row_count between 1 and 500", name="bounds"), + CheckConstraint("reason is null or length(reason)<=4000", name="reason_bounds"), + CheckConstraint("action_id<>'project.task.release' or (reason is not null and length(btrim(reason))>0)", + name="release_reason"), + CheckConstraint("(status='pending' and response is null and committed_at is null) or " + "(status='committed' and response is not null and jsonb_typeof(response)='object' " + "and committed_at is not null)", name="state_shape"), + ) + + id: Mapped[UUID] = mapped_column(Uuid(), primary_key=True) + actor_profile_id: Mapped[str] = mapped_column(ForeignKey("actor_profiles.id", ondelete="RESTRICT", deferrable=True, initially="DEFERRED")) + identity_link_id: Mapped[str] = mapped_column(Uuid(as_uuid=False)) + action_id: Mapped[str] = mapped_column(String(160)) + idempotency_key: Mapped[UUID] = mapped_column(Uuid()) + request_digest: Mapped[str] = mapped_column(String(71)) + reason: Mapped[str | None] = mapped_column(Text) + project_id: Mapped[str] = mapped_column(Uuid(as_uuid=False)) + batch_id: Mapped[str] = mapped_column(Uuid(as_uuid=False)) + manifest_digest: Mapped[str] = mapped_column(String(71)) + membership_digest: Mapped[str] = mapped_column(String(71)) + row_count: Mapped[int] = mapped_column(Integer) + status: Mapped[str] = mapped_column(String(16), default="pending") + response: Mapped[dict | None] = mapped_column(JSONB(none_as_null=True)) + created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now()) + committed_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True)) + + +class TaskBatchTransitionMember(Base): + """Immutable original row linked to its root-bound canonical success and AUTH.""" + + __tablename__ = "task_batch_transition_members" + __table_args__ = ( + CheckConstraint("(get_byte(uuid_send(id), 6) >> 4) = 7 and (get_byte(uuid_send(id), 8) & 192) = 128", name="id_uuid7"), + UniqueConstraint("transition_receipt_id", "row_index", name="uq_task_batch_transition_member_row"), + UniqueConstraint("transition_receipt_id", "native_member_id", name="uq_task_batch_transition_member_native"), + UniqueConstraint("transition_receipt_id", "task_id", name="uq_task_batch_transition_member_task"), + UniqueConstraint("task_command_receipt_id", name="uq_task_batch_transition_member_command"), + ForeignKeyConstraint(["transition_receipt_id", "project_id", "batch_id"], + ["task_batch_transition_receipts.id", "task_batch_transition_receipts.project_id", "task_batch_transition_receipts.batch_id"], + name="fk_task_batch_transition_member_parent", ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), + ForeignKeyConstraint(["task_id", "project_id"], ["workstream_tasks.id", "workstream_tasks.project_id"], + name="fk_task_batch_transition_member_task", ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), + CheckConstraint("row_index between 0 and 499", name="row_index"), + ) + + id: Mapped[UUID] = mapped_column(Uuid(), primary_key=True) + transition_receipt_id: Mapped[UUID] = mapped_column(Uuid()) + project_id: Mapped[str] = mapped_column(Uuid(as_uuid=False)) + batch_id: Mapped[str] = mapped_column(Uuid(as_uuid=False)) + native_member_id: Mapped[str] = mapped_column(ForeignKey("task_import_batch_members.id", ondelete="RESTRICT", deferrable=True, initially="DEFERRED")) + task_id: Mapped[str] = mapped_column(Uuid(as_uuid=False)) + row_index: Mapped[int] = mapped_column(Integer) + task_idempotency_key: Mapped[UUID] = mapped_column(Uuid()) + task_command_receipt_id: Mapped[UUID] = mapped_column(ForeignKey("task_command_receipts.id", ondelete="RESTRICT", deferrable=True, initially="DEFERRED")) + authorization_decision_id: Mapped[str] = mapped_column(ForeignKey("audit_events.id", ondelete="RESTRICT", deferrable=True, initially="DEFERRED")) + created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now()) diff --git a/backend/app/modules/tasks/task_batch_transition_router.py b/backend/app/modules/tasks/task_batch_transition_router.py new file mode 100644 index 000000000..b42b37cc5 --- /dev/null +++ b/backend/app/modules/tasks/task_batch_transition_router.py @@ -0,0 +1,69 @@ +"""Explicit project-scoped all-member SCREEN and RELEASE delivery.""" + +from typing import Annotated +from uuid import UUID + +from fastapi import APIRouter, Depends, Request + +from app.api.deps.task_batch_transitions import get_task_batch_transition_commands +from app.core.api_controls import StructuredHTTPException, parse_idempotency_key +from app.modules.tasks.api.authorization import TaskAuthorityOperation +from app.modules.tasks.api.task_batch_transition import ( + TaskBatchTransitionPort, TaskBatchTransitionRequest, TaskBatchTransitionResponse, +) +from app.modules.tasks.api.task_import_membership import TaskImportBatchError +from app.modules.tasks.service import TaskServiceError + +router = APIRouter(tags=["tasks"]) +_KEY_PARAMETER = {"name": "Idempotency-Key", "in": "header", "required": True, + "schema": {"type": "string", "format": "uuid"}} + + +def require_batch_transition_key(request: Request) -> UUID: + """Require one exact caller retry UUID before resolving a mutating actor.""" + values = request.headers.getlist("Idempotency-Key") + return parse_idempotency_key(values[0] if len(values) == 1 else "") + + +def _error(exc: TaskImportBatchError | TaskServiceError) -> StructuredHTTPException: + code = getattr(exc, "code", None) or "task_batch_transition_invalid" + return StructuredHTTPException( + status_code=exc.status_code, detail=str(exc), error_code=code, + error_message=str(exc), retryable=getattr(exc, "retryable", False), + ) + + +@router.post( + "/projects/{project_id}/task-import-batches/{batch_id}/screen", + response_model=TaskBatchTransitionResponse, + openapi_extra={"x-workstream-action-id": TaskAuthorityOperation.SCREEN.value, + "parameters": [_KEY_PARAMETER]}, +) +async def screen_task_batch( + project_id: UUID, batch_id: UUID, payload: TaskBatchTransitionRequest, + key: Annotated[UUID, Depends(require_batch_transition_key)], + commands: Annotated[TaskBatchTransitionPort, Depends(get_task_batch_transition_commands)], +) -> TaskBatchTransitionResponse: + """Screen the complete native batch or recover its still-current exact result.""" + try: + return await commands.screen(project_id, batch_id, payload.reason, idempotency_key=key) + except (TaskImportBatchError, TaskServiceError) as exc: + raise _error(exc) from exc + + +@router.post( + "/projects/{project_id}/task-import-batches/{batch_id}/release", + response_model=TaskBatchTransitionResponse, + openapi_extra={"x-workstream-action-id": TaskAuthorityOperation.RELEASE.value, + "parameters": [_KEY_PARAMETER]}, +) +async def release_task_batch( + project_id: UUID, batch_id: UUID, payload: TaskBatchTransitionRequest, + key: Annotated[UUID, Depends(require_batch_transition_key)], + commands: Annotated[TaskBatchTransitionPort, Depends(get_task_batch_transition_commands)], +) -> TaskBatchTransitionResponse: + """Release all members with normal reason and locked prerequisites, or none.""" + try: + return await commands.release(project_id, batch_id, payload.reason, idempotency_key=key) + except (TaskImportBatchError, TaskServiceError) as exc: + raise _error(exc) from exc diff --git a/backend/app/modules/tasks/task_batch_transitions.py b/backend/app/modules/tasks/task_batch_transitions.py new file mode 100644 index 000000000..272834ac3 --- /dev/null +++ b/backend/app/modules/tasks/task_batch_transitions.py @@ -0,0 +1,207 @@ +"""One caller-root SCREEN/RELEASE over complete immutable native batch membership.""" + +from dataclasses import dataclass +from datetime import UTC, datetime +from uuid import UUID, uuid4 + +from sqlalchemy import select +from sqlalchemy.dialects.postgresql import insert +from sqlalchemy.ext.asyncio import AsyncSession + +from app.core.hashing import canonical_json_hash +from app.core.identifiers import new_record_id +from app.modules.tasks.api.authorization import TaskAuthorityDecision, TaskAuthorityOperation +from app.modules.tasks.api.task_batch_transition import ( + TaskBatchTransitionRequest, TaskBatchTransitionResponse, TaskBatchTransitionResult, +) +from app.modules.tasks.api.task_import_membership import TaskImportBatchError, TaskImportMemberIdentity +from app.modules.tasks.authorized_commands import AuthorizedTaskCommands, TaskTransitionPreparation +from app.modules.tasks.command_replay import TaskReplayConflict +from app.modules.tasks.schemas import TaskResponse +from app.modules.tasks.task_batch_transition_models import TaskBatchTransitionMember, TaskBatchTransitionReceipt +from app.modules.tasks.task_import_membership import TaskImportMembership, TaskImportMembershipSnapshot + + +@dataclass(frozen=True, slots=True) +class _PreparedMember: + native: TaskImportMemberIdentity + task: TaskTransitionPreparation + retained: TaskBatchTransitionMember | None + + +def _membership_digest(snapshot: TaskImportMembershipSnapshot) -> str: + """Seal the actual ordered native member and original CREATE identities.""" + return canonical_json_hash({"members": [{ + "member_id": str(row.member_id), "task_id": str(row.task_id), "row_index": row.row_index, + "external_task_id": row.external_task_id, "row_digest": row.row_digest, + "create_idempotency_key": str(row.create_idempotency_key), + "task_command_receipt_id": str(row.task_command_receipt_id), + "authorization_decision_id": str(row.authorization_decision_id), + } for row in snapshot.members]}) + + +class TaskBatchTransitionCommands: + """Compose canonical participants; never infer membership from a mutable Task.""" + + def __init__( + self, session: AsyncSession, *, actor_profile_id: UUID, identity_link_id: UUID, + tasks: AuthorizedTaskCommands, + ) -> None: + self._session, self._actor_id, self._link_id = session, actor_profile_id, identity_link_id + self._tasks = tasks + self._membership = TaskImportMembership(session) + + async def screen( + self, project_id: UUID, batch_id: UUID, reason: str | None, *, idempotency_key: UUID, + ) -> TaskBatchTransitionResponse: + """Screen every native member, preserving the normal guide-locking owner.""" + return await self._transition(project_id, batch_id, TaskAuthorityOperation.SCREEN, reason, idempotency_key) + + async def release( + self, project_id: UUID, batch_id: UUID, reason: str | None, *, idempotency_key: UUID, + ) -> TaskBatchTransitionResponse: + """Release every native member with its normal reason and locked prerequisites.""" + return await self._transition(project_id, batch_id, TaskAuthorityOperation.RELEASE, reason, idempotency_key) + + async def _reserve( + self, snapshot: TaskImportMembershipSnapshot, operation: TaskAuthorityOperation, + reason: str | None, key: UUID, digest: str, + ) -> tuple[TaskBatchTransitionReceipt, bool]: + """Serialize the caller namespace without updating an immutable success row.""" + identifier = new_record_id() + await self._session.execute(insert(TaskBatchTransitionReceipt).values( + id=identifier, actor_profile_id=str(self._actor_id), identity_link_id=str(self._link_id), + action_id=operation.value, idempotency_key=key, request_digest=digest, reason=reason, + project_id=str(snapshot.creation.project_id), batch_id=str(snapshot.creation.batch_id), + manifest_digest=snapshot.manifest_digest, membership_digest=_membership_digest(snapshot), + row_count=len(snapshot.members), status="pending", + ).on_conflict_do_nothing(constraint="uq_task_batch_transition_namespace")) + receipt = await self._session.scalar(select(TaskBatchTransitionReceipt).where( + TaskBatchTransitionReceipt.actor_profile_id == str(self._actor_id), + TaskBatchTransitionReceipt.action_id == operation.value, + TaskBatchTransitionReceipt.idempotency_key == key, + ).with_for_update().execution_options(populate_existing=True)) + if receipt is None: + raise RuntimeError("task batch transition reservation disappeared") + return receipt, receipt.id == identifier + + async def _prepare( + self, snapshot: TaskImportMembershipSnapshot, receipt: TaskBatchTransitionReceipt, + operation: TaskAuthorityOperation, reason: str | None, + ) -> tuple[list[_PreparedMember], int]: + """Acquire every actual Task/assignment in UUID order before the first AUTH.""" + links = (await self._session.scalars(select(TaskBatchTransitionMember).where( + TaskBatchTransitionMember.transition_receipt_id == receipt.id, + ).order_by(TaskBatchTransitionMember.row_index))).all() + by_member = {row.native_member_id: row for row in links} + prepared = [] + for native in sorted(snapshot.members, key=lambda row: row.task_id.int): + retained = by_member.get(str(native.member_id)) + key = retained.task_idempotency_key if retained is not None else uuid4() + task = await self._tasks.prepare_transition( + native.task_id, operation, reason, idempotency_key=key, + project_id=snapshot.creation.project_id, batch_transition_receipt_id=receipt.id, + ) + prepared.append(_PreparedMember(native, task, retained)) + return prepared, len(links) + + @staticmethod + def _validate_custody( + snapshot: TaskImportMembershipSnapshot, receipt: TaskBatchTransitionReceipt, + rows: list[_PreparedMember], digest: str, reason: str | None, + link_count: int, *, reserved: bool, + ) -> None: + """Compare original custody only after every member has fresh authority.""" + if receipt.request_digest != digest or receipt.reason != reason: + raise TaskReplayConflict("idempotency_mismatch") + if (receipt.project_id != str(snapshot.creation.project_id) + or receipt.batch_id != str(snapshot.creation.batch_id) + or receipt.manifest_digest != snapshot.manifest_digest + or receipt.membership_digest != _membership_digest(snapshot) + or receipt.row_count != len(rows)): + raise TaskImportBatchError("task_batch_transition_custody_invalid", 409) + if receipt.status == "pending": + if not reserved: + raise TaskReplayConflict("idempotency_pending") + if link_count or any(row.retained is not None or not row.task.reserved for row in rows): + raise TaskImportBatchError("task_batch_transition_custody_invalid", 409) + return + if receipt.status != "committed" or link_count != len(rows): + raise TaskImportBatchError("task_batch_transition_custody_invalid", 409) + for row in rows: + link, canonical = row.retained, row.task.receipt + if (link is None or row.task.reserved + or link.transition_receipt_id != receipt.id + or link.project_id != receipt.project_id or link.batch_id != receipt.batch_id + or link.task_id != str(row.native.task_id) or link.row_index != row.native.row_index + or link.native_member_id != str(row.native.member_id) + or link.task_command_receipt_id != canonical.id + or link.task_idempotency_key != canonical.idempotency_key + or canonical.status != "committed" or canonical.action_id != receipt.action_id + or canonical.actor_profile_id != receipt.actor_profile_id + or canonical.batch_transition_receipt_id != receipt.id): + raise TaskImportBatchError("task_batch_transition_custody_invalid", 409) + + @staticmethod + def _result(row: _PreparedMember, response: TaskResponse) -> TaskBatchTransitionResult: + """Project actual canonical receipt facts instead of a second state snapshot.""" + canonical = row.task.receipt + if (canonical.response != response.model_dump(mode="json") + or response.id != str(row.native.task_id) + or canonical.locked_context_hash is None): + raise TaskImportBatchError("task_batch_transition_custody_invalid", 409) + return TaskBatchTransitionResult( + task_id=row.native.task_id, row_index=row.native.row_index, status=response.status, + locked_guide_version=response.locked_guide_version, + locked_contribution_policy_version_id=response.locked_contribution_policy_version_id, + locked_context_hash=canonical.locked_context_hash, + ) + + async def _transition( + self, project_id: UUID, batch_id: UUID, operation: TaskAuthorityOperation, + reason: str | None, key: UUID, + ) -> TaskBatchTransitionResponse: + if not all(isinstance(value, UUID) for value in (project_id, batch_id, key)): + raise ValueError("task batch transition selectors are invalid") + reason = TaskBatchTransitionRequest(reason=reason).reason + digest = canonical_json_hash({"project_id": str(project_id), "batch_id": str(batch_id), + "operation": operation.value, "reason": reason}) + async with self._session.begin(): + snapshot = await self._membership.prepare(project_id, batch_id) + receipt, reserved = await self._reserve(snapshot, operation, reason, key, digest) + rows, link_count = await self._prepare(snapshot, receipt, operation, reason) + decisions: list[TaskAuthorityDecision] = [] + for row in rows: + decisions.append(await self._tasks.authorize_transition(row.task)) + self._validate_custody(snapshot, receipt, rows, digest, reason, link_count, reserved=reserved) + if (any(row.task.facts.actor_profile_id != self._actor_id for row in rows) + or any(decision.identity_link_id != self._link_id for decision in decisions)): + raise TaskImportBatchError("task_batch_transition_custody_invalid", 409) + results = [] + for row, decision in zip(rows, decisions, strict=True): + response = await self._tasks.stage_transition(row.task, decision) + results.append(self._result(row, response)) + if reserved: + self._session.add(TaskBatchTransitionMember( + id=new_record_id(), transition_receipt_id=receipt.id, + project_id=str(project_id), batch_id=str(batch_id), + native_member_id=str(row.native.member_id), task_id=str(row.native.task_id), + row_index=row.native.row_index, task_idempotency_key=row.task.receipt.idempotency_key, + task_command_receipt_id=row.task.receipt.id, + authorization_decision_id=str(decision.decision_id), + )) + response = TaskBatchTransitionResponse( + project_id=project_id, batch_id=batch_id, + operation="screen" if operation is TaskAuthorityOperation.SCREEN else "release", + row_count=len(rows), tasks=tuple(sorted(results, key=lambda row: row.row_index)), + ) + encoded = response.model_dump(mode="json") + if reserved: + receipt.response, receipt.status, receipt.committed_at = encoded, "committed", datetime.now(UTC) + await self._session.flush() + elif receipt.response != encoded: + raise TaskImportBatchError("task_batch_transition_custody_invalid", 409) + # Validate/detach before root commit; serialization failure rolls back + # every Task, receipt, lifecycle event and successful AUTH decision. + response = TaskBatchTransitionResponse.model_validate_json(response.model_dump_json()) + return response diff --git a/backend/tests/tasks/test_task_batch_transition_contract.py b/backend/tests/tasks/test_task_batch_transition_contract.py new file mode 100644 index 000000000..95cde6c64 --- /dev/null +++ b/backend/tests/tasks/test_task_batch_transition_contract.py @@ -0,0 +1,63 @@ +"""Compact batch contracts reject partial and substituted ordered success facts.""" + +from uuid import uuid4 + +import pytest +from pydantic import ValidationError + +from app.modules.tasks.api.task_batch_transition import TaskBatchTransitionRequest, TaskBatchTransitionResponse + + +def response_value(count=2): + """Use different Task identities with the same legitimate locked guide version.""" + return {"project_id": str(uuid4()), "batch_id": str(uuid4()), "operation": "screen", "row_count": count, + "tasks": [{"task_id": str(uuid4()), "row_index": index, "status": "screening", + "locked_guide_version": "v1.0.0", "locked_contribution_policy_version_id": str(uuid4()), + "locked_context_hash": "sha256:" + "a" * 64} for index in range(count)]} + + +def test_response_preserves_complete_500_row_order_and_string_guide_versions(): + value = response_value(500) + response = TaskBatchTransitionResponse.model_validate(value) + assert response.model_dump(mode="json") == value + assert TaskBatchTransitionResponse.model_validate_json(response.model_dump_json()) == response + + +@pytest.mark.parametrize("change", ["missing", "reordered", "duplicate", "foreign_status", "bad_hash", "unlocked", "extra"]) +def test_incomplete_or_substituted_success_is_refused(change): + value = response_value() + if change == "missing": + value["tasks"].pop() + elif change == "reordered": + value["tasks"].reverse() + elif change == "duplicate": + value["tasks"][1]["task_id"] = value["tasks"][0]["task_id"] + elif change == "foreign_status": + value["tasks"][1]["status"] = "ready" + elif change == "bad_hash": + value["tasks"][1]["locked_context_hash"] = "unverified" + elif change == "unlocked": + value["tasks"][1]["locked_guide_version"] = None + else: + value["tasks"][1]["instructions"] = "private DTO" + with pytest.raises(ValidationError): + TaskBatchTransitionResponse.model_validate(value) + + +@pytest.mark.parametrize("count", [0, 501]) +def test_public_row_bounds_are_explicit(count): + with pytest.raises(ValidationError): + TaskBatchTransitionResponse.model_validate(response_value(count)) + + +def test_release_and_reason_contracts_are_separate_from_screen(): + value = response_value() + value["operation"] = "release" + for task in value["tasks"]: + task["status"] = "ready" + assert TaskBatchTransitionResponse.model_validate(value).operation == "release" + assert TaskBatchTransitionRequest(reason="Decision\nwith Unicode café").reason.endswith("café") + with pytest.raises(ValidationError): + TaskBatchTransitionRequest(reason="x" * 4001) + with pytest.raises(ValidationError): + TaskBatchTransitionRequest.model_validate({"task_ids": [str(uuid4())]}) diff --git a/backend/tests/tasks/test_task_batch_transitions.py b/backend/tests/tasks/test_task_batch_transitions.py new file mode 100644 index 000000000..f55801f7c --- /dev/null +++ b/backend/tests/tasks/test_task_batch_transitions.py @@ -0,0 +1,283 @@ +"""Public complete-member transitions with actual PostgreSQL, AUTH and source bytes.""" + +import asyncio +import time +from datetime import UTC, datetime +from uuid import UUID, uuid4 + +import pytest +from sqlalchemy import func, select, text +from sqlalchemy.exc import DBAPIError + +from app.core.hashing import canonical_json_hash +from app.core.identifiers import new_record_id +from app.db import session as db_session +from app.modules.actors.models import ActorIdentityLink +from app.modules.authorization.models import AdminRoleGrant +from app.modules.authorization.runtime import ActorKind, ActorStatus, HumanAuthorizationContext, IdentityLinkStatus +from app.modules.tasks.authorized_commands import AuthorizedTaskCommands +from app.modules.tasks.models import AuditEvent, TaskCommandReceipt, WorkstreamTask +from app.modules.tasks.service import TaskValidationError +from app.modules.tasks.task_batch_transition_models import TaskBatchTransitionMember, TaskBatchTransitionReceipt +from app.modules.tasks.task_batch_transitions import TaskBatchTransitionCommands +from app.modules.tasks.task_batch_transitions import _membership_digest +from app.modules.tasks.task_import_membership import TaskImportMembership +from tests.authorization.guide_activation.pg_support import revoke_manager_grant +from tests.test_task_import_sources import import_source_client as import_source_client +from tests.test_tasks import task_database_env as task_database_env, auth_headers, create_active_project +from tests.tasks.test_task_import_batches import _batch_path, _verified_source +from tests.tasks.test_task_import_contract import document + + +async def _import(client, count=2): + """Create actual retained bytes and native membership with screenable instructions.""" + project = (await create_active_project(client, slug="bulk-" + uuid4().hex))["id"] + value = document(count) + for row in value["tasks"]: + row.update(acceptance_criteria="Accurate, complete work", rejection_criteria="Incomplete work") + source = await _verified_source(client, project, value) + imported = await client.post(_batch_path(project), headers=auth_headers(), json={"source_id": source["source_id"]}) + assert imported.status_code == 201, imported.text + return project, imported.json() + + +def _path(project, batch, operation): + return f"{_batch_path(project)}/{batch['batch_id']}/{operation}" + + +async def _success_facts(project): + """Observe committed success identities rather than relying on response status alone.""" + async with db_session.get_session_factory()() as session: + task_ids = list(await session.scalars(select(WorkstreamTask.id).where(WorkstreamTask.project_id == project))) + tasks = list((await session.execute(select( + WorkstreamTask.id, WorkstreamTask.status, WorkstreamTask.locked_guide_version, + WorkstreamTask.locked_contribution_policy_version_id, + ).where(WorkstreamTask.project_id == project).order_by(WorkstreamTask.id))).all()) + roots = set(await session.scalars(select(TaskBatchTransitionReceipt.id).where(TaskBatchTransitionReceipt.project_id == project))) + members = set(await session.scalars(select(TaskBatchTransitionMember.id).where(TaskBatchTransitionMember.project_id == project))) + receipts = set(await session.scalars(select(TaskCommandReceipt.id).where( + TaskCommandReceipt.task_id.in_(task_ids), TaskCommandReceipt.action_id.in_(["project.task.screen", "project.task.release"]), + ))) + lifecycle = set(await session.scalars(select(AuditEvent.id).where( + AuditEvent.entity_id.in_(task_ids), AuditEvent.event_type.in_(["TaskScreened", "TaskReleased"]), + ))) + allows = set(await session.scalars(select(AuditEvent.id).where( + AuditEvent.resource_id.in_(task_ids), AuditEvent.event_type == "SensitiveAuthorizationAllowed", + AuditEvent.action_id.in_(["project.task.screen", "project.task.release"]), + ))) + return tasks, roots, members, receipts, lifecycle, allows + + +@pytest.mark.parametrize("count", [200, 500]) +async def test_public_source_import_screen_release_complete_journey(import_source_client, count, record_property): + """Every exact native member reaches READY with original ordered retained receipts.""" + client = import_source_client + project, batch = await _import(client, count) + for operation, status in (("screen", "screening"), ("release", "ready")): + key, payload = auth_headers(), {"reason": "Explicit complete-batch decision"} + started = time.monotonic() + result = await client.post(_path(project, batch, operation), headers=key, json=payload) + record_property(f"{count}_{operation}_seconds", time.monotonic() - started) + assert result.status_code == 200, result.text + original = result.json() + assert original["project_id"] == project and original["batch_id"] == batch["batch_id"] + assert original["operation"] == operation and original["row_count"] == count + assert [row["task_id"] for row in original["tasks"]] == [row["id"] for row in batch["tasks"]] + assert [row["row_index"] for row in original["tasks"]] == list(range(count)) + assert all(row["status"] == status and row["locked_guide_version"] for row in original["tasks"]) + before = await _success_facts(project) + replay = await client.post(_path(project, batch, operation), headers=key, json=payload) + assert replay.status_code == 200 and replay.json() == original, replay.text + after = await _success_facts(project) + assert before[:-1] == after[:-1] and len(after[-1] - before[-1]) == count + async with db_session.get_session_factory()() as session: + root = (await session.scalars(select(TaskBatchTransitionReceipt).where( + TaskBatchTransitionReceipt.project_id == project, + TaskBatchTransitionReceipt.action_id == f"project.task.{operation}", + ))).one() + links = list(await session.scalars(select(TaskBatchTransitionMember).where( + TaskBatchTransitionMember.transition_receipt_id == root.id, + ).order_by(TaskBatchTransitionMember.row_index))) + assert root.response == original and root.status == "committed" and len(links) == count + assert len({link.task_idempotency_key for link in links}) == count + for link, row in zip(links, original["tasks"], strict=True): + receipt = await session.get(TaskCommandReceipt, link.task_command_receipt_id) + decision = await session.get(AuditEvent, link.authorization_decision_id) + assert receipt.batch_transition_receipt_id == root.id + assert receipt.task_id == link.task_id == row["task_id"] + assert receipt.response["status"] == row["status"] + assert receipt.locked_context_hash == row["locked_context_hash"] + assert decision.action_id == root.action_id and decision.resource_id == row["task_id"] + assert decision.event_type == "SensitiveAuthorizationAllowed" + facts = await _success_facts(project) + assert len(facts[1]) == 2 and all(len(values) == count * 2 for values in facts[2:5]) + assert all(row.status == "ready" for row in facts[0]) + + +async def test_late_staging_failure_and_partial_advance_replay_roll_back_whole_batch(import_source_client, monkeypatch): + """A real second canonical write followed by failure leaves no partial success.""" + client = import_source_client + project, batch = await _import(client) + before = await _success_facts(project) + original_stage, calls = AuthorizedTaskCommands.stage_transition, 0 + + async def fail_after_second_write(commands, prepared, decision): + nonlocal calls + response = await original_stage(commands, prepared, decision) + calls += 1 + if calls == 2: + raise TaskValidationError("Injected late canonical failure") + return response + + key, payload = auth_headers(), {"reason": "Whole-batch screening"} + monkeypatch.setattr(AuthorizedTaskCommands, "stage_transition", fail_after_second_write) + failed = await client.post(_path(project, batch, "screen"), headers=key, json=payload) + assert failed.status_code == 422 and calls == 2, failed.text + assert await _success_facts(project) == before + monkeypatch.setattr(AuthorizedTaskCommands, "stage_transition", original_stage) + successful = await client.post(_path(project, batch, "screen"), headers=key, json=payload) + assert successful.status_code == 200, successful.text + before = await _success_facts(project) + changed = await client.post(_path(project, batch, "screen"), headers=key, json={"reason": "Changed reason"}) + assert changed.status_code == 409 and changed.json()["error"]["code"] == "idempotency_mismatch", changed.text + assert await _success_facts(project) == before + advanced = await client.post(f"/api/v1/tasks/{batch['tasks'][0]['id']}/release", headers=auth_headers(), + json={"reason": "Separate later decision"}) + assert advanced.status_code == 200, advanced.text + before = await _success_facts(project) + replay = await client.post(_path(project, batch, "screen"), headers=key, json=payload) + assert replay.status_code in {403, 409}, replay.text + assert await _success_facts(project) == before + + +async def test_revoked_manager_cannot_replay_a_successful_bulk_write(import_source_client): + """The real canonical grant-revocation owner invalidates retained-key authority.""" + client = import_source_client + project, batch = await _import(client) + key, payload = auth_headers(), {"reason": "Before revocation"} + result = await client.post(_path(project, batch, "screen"), headers=key, json=payload) + assert result.status_code == 200, result.text + before = await _success_facts(project) + async with db_session.get_session_factory()() as session, session.begin(): + grant = (await session.scalars(select(AdminRoleGrant).where( + AdminRoleGrant.role == "project_manager", AdminRoleGrant.status == "active", + ))).one() + link = (await session.scalars(select(ActorIdentityLink).where( + ActorIdentityLink.actor_profile_id == grant.granted_by_actor_profile_id, + ))).one() + context = HumanAuthorizationContext( + actor_profile_id=UUID(link.actor_profile_id), identity_link_id=UUID(link.id), + actor_kind=ActorKind.HUMAN, actor_status=ActorStatus.ACTIVE, + identity_link_status=IdentityLinkStatus.ACTIVE, request_id=uuid4(), correlation_id=uuid4(), + ) + await revoke_manager_grant(session, context, UUID(str(grant.id))) + denied = await client.post(_path(project, batch, "screen"), headers=key, json=payload) + assert denied.status_code == 403 and denied.json()["error"]["code"] == "permission_not_granted", denied.text + assert await _success_facts(project) == before + async with db_session.get_session_factory()() as session: + denials = list(await session.scalars(select(AuditEvent).where( + AuditEvent.action_id == "project.task.screen", AuditEvent.event_type == "SensitiveAuthorizationDenied", + ))) + assert len(denials) == 1 and denials[0].denial_code == "permission_not_granted" + + +async def test_same_key_concurrent_roots_observe_native_wait_then_one_success(import_source_client, monkeypatch): + """An observed PostgreSQL blocker proves aggregate reservation serialization.""" + client = import_source_client + project, batch = await _import(client) + original = TaskBatchTransitionCommands._reserve + reserved, entered, release = asyncio.Event(), asyncio.Event(), asyncio.Event() + pids, calls = [], 0 + + async def gated(commands, *args, **kwargs): + nonlocal calls + calls += 1 + call = calls + pids.append(await commands._session.scalar(select(func.pg_backend_pid()))) + if call == 2: + entered.set() + result = await original(commands, *args, **kwargs) + if call == 1: + reserved.set() + await asyncio.wait_for(release.wait(), timeout=30) + return result + + monkeypatch.setattr(TaskBatchTransitionCommands, "_reserve", gated) + key, payload = auth_headers(), {"reason": "Concurrent exact request"} + first = asyncio.create_task(client.post(_path(project, batch, "screen"), headers=key, json=payload)) + second = None + try: + await asyncio.wait_for(reserved.wait(), timeout=30) + second = asyncio.create_task(client.post(_path(project, batch, "screen"), headers=key, json=payload)) + await asyncio.wait_for(entered.wait(), timeout=30) + deadline = asyncio.get_running_loop().time() + 10 + async with db_session.get_session_factory()() as observer: + while not await observer.scalar(text("select :holder = any(pg_blocking_pids(:waiter))"), + {"holder": pids[0], "waiter": pids[1]}): + assert asyncio.get_running_loop().time() < deadline, "no aggregate holder/waiter was observed" + await asyncio.sleep(0.05) + release.set() + responses = await asyncio.wait_for(asyncio.gather(first, second), timeout=60) + assert all(response.status_code == 200 for response in responses), [response.text for response in responses] + assert responses[0].json() == responses[1].json() + facts = await _success_facts(project) + assert len(facts[1]) == 1 and all(len(values) == 2 for values in facts[2:5]) and len(facts[-1]) == 4 + finally: + release.set() + for pending in (first, second): + if pending is not None and not pending.done(): + pending.cancel() + await asyncio.gather(*(pending for pending in (first, second) if pending is not None), return_exceptions=True) + + +async def test_sql_cannot_attach_old_standalone_successes_to_a_new_aggregate(import_source_client): + """Real earlier canonical successes lack aggregate-root provenance and cannot enroll.""" + client = import_source_client + project, batch = await _import(client) + reason = "Historical standalone screening" + for task in batch["tasks"]: + screened = await client.post(f"/api/v1/tasks/{task['id']}/screen", headers=auth_headers(), json={"reason": reason}) + assert screened.status_code == 200, screened.text + before = await _success_facts(project) + root_id = new_record_id() + async with db_session.get_session_factory()() as session: + with pytest.raises(DBAPIError) as caught: + async with session.begin(): + snapshot = await TaskImportMembership(session).prepare(UUID(project), UUID(batch["batch_id"])) + receipts = {row.task_id: row for row in await session.scalars(select(TaskCommandReceipt).where( + TaskCommandReceipt.task_id.in_([row["id"] for row in batch["tasks"]]), + TaskCommandReceipt.action_id == "project.task.screen", + ))} + assert len(receipts) == 2 and all(row.batch_transition_receipt_id is None for row in receipts.values()) + actor = next(iter(receipts.values())).actor_profile_id + link = (await session.scalars(select(ActorIdentityLink).where(ActorIdentityLink.actor_profile_id == actor))).one() + compact = {"project_id": project, "batch_id": batch["batch_id"], "operation": "screen", "row_count": 2, + "tasks": [{"task_id": str(row.task_id), "row_index": row.row_index, "status": "screening", + "locked_guide_version": receipts[str(row.task_id)].response["locked_guide_version"], + "locked_contribution_policy_version_id": receipts[str(row.task_id)].response["locked_contribution_policy_version_id"], + "locked_context_hash": receipts[str(row.task_id)].locked_context_hash} for row in snapshot.members]} + root = TaskBatchTransitionReceipt( + id=root_id, actor_profile_id=actor, identity_link_id=link.id, action_id="project.task.screen", + idempotency_key=uuid4(), request_digest=canonical_json_hash({"project_id": project, + "batch_id": batch["batch_id"], "operation": "project.task.screen", "reason": reason}), + reason=reason, project_id=project, batch_id=batch["batch_id"], row_count=2, + manifest_digest=snapshot.manifest_digest, membership_digest=_membership_digest(snapshot), + status="pending", + ) + session.add(root) + await session.flush() + for native in snapshot.members: + receipt = receipts[str(native.task_id)] + event = (await session.scalars(select(AuditEvent).where( + AuditEvent.entity_id == str(native.task_id), AuditEvent.event_type == "TaskScreened", + ))).one() + session.add(TaskBatchTransitionMember( + id=new_record_id(), transition_receipt_id=root_id, project_id=project, batch_id=batch["batch_id"], + native_member_id=str(native.member_id), task_id=str(native.task_id), row_index=native.row_index, + task_idempotency_key=receipt.idempotency_key, task_command_receipt_id=receipt.id, + authorization_decision_id=event.event_payload["references"]["authorization_decision_id"], + )) + root.status, root.response, root.committed_at = "committed", compact, datetime.now(UTC) + await session.flush() + assert getattr(caught.value.orig, "sqlstate", None) == "23514" + assert await _success_facts(project) == before From 915f6033cbfc0f3a40ea094b5925dfa43f7d40cd Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 14:10:33 +0100 Subject: [PATCH 025/283] Add explicit task batch CLI commands and repair admission composition --- .../changes/pilot02-bulk-transitions-cli.md | 32 +- .../app/api/deps/task_batch_transitions.py | 2 +- .../modules/tasks/task_batch_transitions.py | 3 + .../test_task_batch_transition_contract.py | 10 + .../tasks/test_task_batch_transitions.py | 4 + cli/README.md | 27 ++ cli/internal/api/task_import_batch.go | 305 ++++++++++++++++++ cli/internal/command/task_batch.go | 1 + cli/internal/command/task_batch_commands.go | 106 ++++++ .../test_task_batch_commands_http.py | 269 +++++++++++++++ 10 files changed, 757 insertions(+), 2 deletions(-) create mode 100644 cli/internal/api/task_import_batch.go create mode 100644 cli/internal/command/task_batch_commands.go create mode 100644 cli/tests/integration/test_task_batch_commands_http.py diff --git a/.commitrail/changes/pilot02-bulk-transitions-cli.md b/.commitrail/changes/pilot02-bulk-transitions-cli.md index 4d4d599c5..bef1e3be2 100644 --- a/.commitrail/changes/pilot02-bulk-transitions-cli.md +++ b/.commitrail/changes/pilot02-bulk-transitions-cli.md @@ -57,7 +57,8 @@ Their current root transaction prevents composition across a complete batch. canonical error envelope for POST/PUT. Disable automatic body replay and retain uncertain-write reporting; no other shared-client changes are authorized. - Exact CLI proof paths are new `cli/tests/integration/test_task_batch_csv.py` - and `test_task_batch_sources_http.py`; the existing HTTP fixture receives one + and `test_task_batch_sources_http.py`, plus + `test_task_batch_commands_http.py`; the existing HTTP fixture receives one PUT handler delegating to its unchanged exact-body POST capture. No retained GET/PATCH/POST expectations or test guards are removed. - Native participant lifetime/composition proof is owned in @@ -163,6 +164,35 @@ observed native holder/waiter before concurrent same-key recovery. They have not run because aggregate custody DDL is pending the sole migration author. No native aggregate, native 200/500 timing, full CI, or readiness claim is made here. +Peer review of aggregate checkpoint `42900b036` found that the new dependency +projected immutable identity after the canonical Task dependency rolled back and +expired the resolved ORM actor/link. The repair projects the existing public +`ActorIdentityFacts` first, before that rollback; no row refresh, implicit read, +new authority owner or private actor import is introduced. Peer native dependency +expiration replay and installed aggregate public proof remain separate evidence. +The same peer review found missing/blank RELEASE input reached the native pending +receipt reason CHECK before normal validation. The repair uses the canonical +`TaskValidationError` reason requirement before opening/reserving the root, +retains the native CHECK, and adds public missing/blank negative controls asserting +unchanged aggregate, Task, lifecycle and successful authority facts. Valid inputs +still consume every member's fresh canonical AUTH. +The repaired pure compact/admission plus retained parser checks passed 44 cases +in 7.40 seconds; the protected module-boundary check also exited successfully. +The owned idle PostgreSQL container was stopped after the earlier native proof's +isolated DB/role cleanup, while aggregate DDL remains pending. + +CLI import/status/screen/release are implemented as separate exact typed calls. +Original/status responses are bounded to 16MiB, compact transitions to 2MiB, +with complete 1..500 ordered membership and strict original DRAFT/source custody. +Status validates original and current identities independently. The six new +built-CLI HTTP cases passed in 15.03 seconds, including complete 500-row output, +crossed/malformed/partial refusal, invalid selectors/keys producing zero requests, +canonical versus unrecognized denial, dropped connections and one-body/one-h2 +GOAWAY behavior. These are controlled HTTP fixtures, not native batch proof. +Go compilation, focused package tests and `go vet ./...` passed. The longer +deadline for batch writes has not been selected: it remains dependent on actual +native 200/500 timing, and existing transport semantics remain unchanged. + No migration ordinal is allocated here. The sole author receives the final exact models and constraints only after this custody design and shared regions are reviewed. New tables are justified by the concrete aggregate/per-Task namespace diff --git a/backend/app/api/deps/task_batch_transitions.py b/backend/app/api/deps/task_batch_transitions.py index 73ccb9194..0556ca300 100644 --- a/backend/app/api/deps/task_batch_transitions.py +++ b/backend/app/api/deps/task_batch_transitions.py @@ -12,8 +12,8 @@ async def get_task_batch_transition_commands( - tasks: Annotated[object, Depends(get_task_commands)], identity: Annotated[ActorIdentityFacts, Depends(get_authorization_actor_identity)], + tasks: Annotated[object, Depends(get_task_commands)], session: Annotated[AsyncSession, Depends(get_db_session)], ) -> TaskBatchTransitionPort: """Reuse the actual issuing AUTH owner for rollback and denial-only restaging.""" diff --git a/backend/app/modules/tasks/task_batch_transitions.py b/backend/app/modules/tasks/task_batch_transitions.py index 272834ac3..b4692d1e7 100644 --- a/backend/app/modules/tasks/task_batch_transitions.py +++ b/backend/app/modules/tasks/task_batch_transitions.py @@ -18,6 +18,7 @@ from app.modules.tasks.authorized_commands import AuthorizedTaskCommands, TaskTransitionPreparation from app.modules.tasks.command_replay import TaskReplayConflict from app.modules.tasks.schemas import TaskResponse +from app.modules.tasks.service import TaskValidationError from app.modules.tasks.task_batch_transition_models import TaskBatchTransitionMember, TaskBatchTransitionReceipt from app.modules.tasks.task_import_membership import TaskImportMembership, TaskImportMembershipSnapshot @@ -164,6 +165,8 @@ async def _transition( if not all(isinstance(value, UUID) for value in (project_id, batch_id, key)): raise ValueError("task batch transition selectors are invalid") reason = TaskBatchTransitionRequest(reason=reason).reason + if operation is TaskAuthorityOperation.RELEASE and (not reason or not reason.strip()): + raise TaskValidationError("release decision reason is required") digest = canonical_json_hash({"project_id": str(project_id), "batch_id": str(batch_id), "operation": operation.value, "reason": reason}) async with self._session.begin(): diff --git a/backend/tests/tasks/test_task_batch_transition_contract.py b/backend/tests/tasks/test_task_batch_transition_contract.py index 95cde6c64..ce28e4266 100644 --- a/backend/tests/tasks/test_task_batch_transition_contract.py +++ b/backend/tests/tasks/test_task_batch_transition_contract.py @@ -6,6 +6,8 @@ from pydantic import ValidationError from app.modules.tasks.api.task_batch_transition import TaskBatchTransitionRequest, TaskBatchTransitionResponse +from app.modules.tasks.service import TaskValidationError +from app.modules.tasks.task_batch_transitions import TaskBatchTransitionCommands def response_value(count=2): @@ -61,3 +63,11 @@ def test_release_and_reason_contracts_are_separate_from_screen(): TaskBatchTransitionRequest(reason="x" * 4001) with pytest.raises(ValidationError): TaskBatchTransitionRequest.model_validate({"task_ids": [str(uuid4())]}) + + +@pytest.mark.parametrize("reason", [None, "", " \n"]) +async def test_release_reason_is_refused_before_any_transaction_or_authority(reason): + """Admission must reject incomplete input without accessing a session or Task port.""" + owner = TaskBatchTransitionCommands(None, actor_profile_id=uuid4(), identity_link_id=uuid4(), tasks=None) + with pytest.raises(TaskValidationError, match="release decision reason is required"): + await owner.release(uuid4(), uuid4(), reason, idempotency_key=uuid4()) diff --git a/backend/tests/tasks/test_task_batch_transitions.py b/backend/tests/tasks/test_task_batch_transitions.py index f55801f7c..2acd3c2da 100644 --- a/backend/tests/tasks/test_task_batch_transitions.py +++ b/backend/tests/tasks/test_task_batch_transitions.py @@ -138,6 +138,10 @@ async def fail_after_second_write(commands, prepared, decision): successful = await client.post(_path(project, batch, "screen"), headers=key, json=payload) assert successful.status_code == 200, successful.text before = await _success_facts(project) + for reason in (None, " \n"): + refused = await client.post(_path(project, batch, "release"), headers=auth_headers(), json={"reason": reason}) + assert refused.status_code == 422 and refused.json()["error"]["code"] == "task_batch_transition_invalid", refused.text + assert await _success_facts(project) == before changed = await client.post(_path(project, batch, "screen"), headers=key, json={"reason": "Changed reason"}) assert changed.status_code == 409 and changed.json()["error"]["code"] == "idempotency_mismatch", changed.text assert await _success_facts(project) == before diff --git a/cli/README.md b/cli/README.md index 4100d4cf5..63c9612be 100644 --- a/cli/README.md +++ b/cli/README.md @@ -463,6 +463,33 @@ The CLI verifies returned selectors and, for writes, the exact file commitment. A returned source/status establishes byte custody only; it does not create, screen or release Tasks. +Continue with explicit batch operations after source verification: + +```sh +workstream project task-batch import PROJECT_ID SOURCE_ID --idempotency-key IMPORT_UUID --output json +workstream project task-batch status PROJECT_ID BATCH_ID --output json +workstream project task-batch screen PROJECT_ID BATCH_ID --idempotency-key SCREEN_UUID --reason 'Briefs meet the approved guide' --output json +workstream project task-batch release PROJECT_ID BATCH_ID --idempotency-key RELEASE_UUID --reason 'All members are ready for work' --output json +``` + +Import returns the complete original ordered DRAFT creation facts. Status keeps +those originals separate from the current member states. SCREEN and RELEASE +select every member from immutable native membership and return ordered compact +Task IDs, statuses and locked lineage. Normal guide/policy prerequisites still +apply; release requires a nonblank reason. Each write requires its own retained +caller UUID. No command combines upload/import/screen/release or chooses per-row +retry keys. Responses are limited to 1..500 complete members: original/status +JSON is bounded to 16MiB and compact transition JSON to 2MiB. Invalid, crossed, +duplicate or partial responses are refused without partial output. + +Batch writes never retry automatically. An unknown outcome requires inspection +of `status` as an observation, followed by manual replay of the unchanged project, +source/batch, action, reason and key. SCREEN/RELEASE replay also requires every +member to retain its original post-state, locked context and unassigned custody; +later Task changes or revoked authority can prevent recovery with the same key. +The aggregate migration and real 200/500-row journey/timing proofs remain pending +in this draft implementation; no native bulk readiness is claimed. + Source writes never retry automatically, including after HTTP/2 GOAWAY. If a declaration outcome is unknown, manually replay only the unchanged project, JSON file bytes and caller key. For an uncertain upload, inspect `source-status` diff --git a/cli/internal/api/task_import_batch.go b/cli/internal/api/task_import_batch.go new file mode 100644 index 000000000..7d5b343cd --- /dev/null +++ b/cli/internal/api/task_import_batch.go @@ -0,0 +1,305 @@ +package api + +import ( + "context" + "encoding/json" + jsonv2 "encoding/json/v2" + "errors" + "net/http" + "net/url" + "regexp" + "strings" + "unicode/utf8" + + "github.com/Flow-Research/workstream/cli/internal/taskimport" +) + +const taskImportResponseLimit = 16 * 1024 * 1024 +const taskBatchTransitionResponseLimit = 2 * 1024 * 1024 + +// ImportedTask identifies one original DRAFT creation, even after later advancement. +type ImportedTask struct { + ID string `json:"id"` + ExternalTaskID string `json:"external_task_id"` + Status string `json:"status"` + ProjectID string `json:"project_id"` + SourceType string `json:"source_type"` + SourceRef string `json:"source_ref"` + SourcePayloadHash string `json:"source_payload_hash"` + ImportBatchID string `json:"import_batch_id"` + CreatedBy string `json:"created_by"` + CreatedAt string `json:"created_at"` + UpdatedAt string `json:"updated_at"` +} + +// TaskImportBatch preserves original complete ordered creation custody. +type TaskImportBatch struct { + BatchID string `json:"batch_id"` + ProjectID string `json:"project_id"` + SourceID string `json:"source_id"` + SHA256 string `json:"sha256"` + ByteCount int `json:"byte_count"` + SchemaVersion string `json:"schema_version"` + MappingVersion string `json:"mapping_version"` + Label *string `json:"label"` + RowCount int `json:"row_count"` + CreatedAt string `json:"created_at"` + Tasks []ImportedTask `json:"-"` +} + +type taskImportEnvelope struct { + BatchID string `json:"batch_id"` + ProjectID string `json:"project_id"` + SourceID string `json:"source_id"` + SHA256 string `json:"sha256"` + ByteCount int `json:"byte_count"` + SchemaVersion string `json:"schema_version"` + MappingVersion string `json:"mapping_version"` + Label *string `json:"label"` + RowCount int `json:"row_count"` + CreatedAt string `json:"created_at"` + Tasks []json.RawMessage `json:"tasks"` +} + +type CurrentBatchTask struct { + TaskID string `json:"task_id"` + RowIndex int `json:"row_index"` + Status string `json:"status"` +} + +type TaskImportBatchStatus struct { + Creation TaskImportBatch + CurrentTasks []CurrentBatchTask +} + +type TaskBatchTransitionTask struct { + TaskID string `json:"task_id"` + RowIndex int `json:"row_index"` + Status string `json:"status"` + LockedGuideVersion string `json:"locked_guide_version"` + LockedContributionPolicyVersionID string `json:"locked_contribution_policy_version_id"` + LockedContextHash string `json:"locked_context_hash"` +} + +type TaskBatchTransition struct { + ProjectID string `json:"project_id"` + BatchID string `json:"batch_id"` + Operation string `json:"operation"` + RowCount int `json:"row_count"` + Tasks []TaskBatchTransitionTask `json:"tasks"` +} + +func taskImportBatchPath(project string) string { + return "/api/v1/projects/" + url.PathEscape(project) + "/task-import-batches" +} + +func validBatchSelectors(values ...string) bool { + for _, value := range values { + if len(value) > 100 || !validUUID(value) { + return false + } + } + return true +} + +// ImportTaskBatch selects existing source custody. It does not upload, screen or release. +func (c *Client) ImportTaskBatch(ctx context.Context, project, source, key string) (Result[TaskImportBatch], error) { + var result Result[TaskImportBatch] + if !validBatchSelectors(project, source, key) { + return result, errors.New("PROJECT_ID, SOURCE_ID and --idempotency-key must be UUIDs") + } + body, _ := json.Marshal(map[string]string{"source_id": source}) + raw, err := c.requestWithResponseLimit(ctx, http.MethodPost, taskImportBatchPath(project), "", body, key, http.StatusCreated, taskImportResponseLimit) + if err != nil { + return result, taskBatchWriteFailure(err) + } + value, err := c.decodeTaskImportBatch(raw, project, "", source) + if err != nil { + return result, taskBatchWriteFailure(&Failure{Code: "invalid_api_response", OutcomeUnknown: true}) + } + return Result[TaskImportBatch]{Raw: raw, Value: value}, nil +} + +func (c *Client) TaskBatchStatus(ctx context.Context, project, batch string) (Result[TaskImportBatchStatus], error) { + var result Result[TaskImportBatchStatus] + if !validBatchSelectors(project, batch) { + return result, errors.New("PROJECT_ID and BATCH_ID must be UUIDs") + } + raw, err := c.requestWithResponseLimit(ctx, http.MethodGet, taskImportBatchPath(project)+"/"+url.PathEscape(batch), "", nil, "", http.StatusOK, taskImportResponseLimit) + if err != nil { + return result, err + } + var envelope struct { + Creation json.RawMessage `json:"creation"` + CurrentTasks []json.RawMessage `json:"current_tasks"` + } + if _, err = contextObject(raw, &envelope, []string{"creation", "current_tasks"}, nil); err != nil { + return result, &Failure{Code: "invalid_api_response"} + } + creation, err := c.decodeTaskImportBatch(envelope.Creation, project, batch, "") + if err != nil || len(envelope.CurrentTasks) != creation.RowCount { + return result, &Failure{Code: "invalid_api_response"} + } + value := TaskImportBatchStatus{Creation: creation, CurrentTasks: make([]CurrentBatchTask, 0, creation.RowCount)} + for index, rawTask := range envelope.CurrentTasks { + var task CurrentBatchTask + _, err = contextObject(rawTask, &task, []string{"task_id", "row_index", "status"}, nil) + if err != nil || task.RowIndex != index || !sameUUID(task.TaskID, creation.Tasks[index].ID) || !batchStatusPattern.MatchString(task.Status) || !c.safeMetadata(task.Status) { + return result, &Failure{Code: "invalid_api_response"} + } + value.CurrentTasks = append(value.CurrentTasks, task) + } + return Result[TaskImportBatchStatus]{Raw: raw, Value: value}, nil +} + +func (c *Client) TransitionTaskBatch(ctx context.Context, project, batch, operation, key string, reason *string) (Result[TaskBatchTransition], error) { + var result Result[TaskBatchTransition] + if !validBatchSelectors(project, batch, key) || (operation != "screen" && operation != "release") { + return result, errors.New("PROJECT_ID, BATCH_ID and --idempotency-key must be UUIDs; action must be screen or release") + } + if (reason != nil && (!utf8.ValidString(*reason) || utf8.RuneCountInString(*reason) > 4000)) || + (operation == "release" && (reason == nil || strings.TrimSpace(*reason) == "")) { + return result, errors.New("reason must contain at most 4000 UTF-8 characters; release requires a nonblank reason") + } + body, err := json.Marshal(struct { + Reason *string `json:"reason"` + }{reason}) + if err != nil { + return result, err + } + raw, err := c.requestWithResponseLimit(ctx, http.MethodPost, taskImportBatchPath(project)+"/"+url.PathEscape(batch)+"/"+operation, "", body, key, http.StatusOK, taskBatchTransitionResponseLimit) + if err != nil { + return result, taskBatchWriteFailure(err) + } + value, err := c.decodeBatchTransition(raw, project, batch, operation) + if err != nil { + return result, taskBatchWriteFailure(&Failure{Code: "invalid_api_response", OutcomeUnknown: true}) + } + return Result[TaskBatchTransition]{Raw: raw, Value: value}, nil +} + +var batchStatusPattern = regexp.MustCompile(`^[a-z][a-z0-9_]{0,29}$`) + +func taskBatchWriteFailure(err error) error { + var failure *Failure + if errors.As(err, &failure) && failure.OutcomeUnknown { + failure.RecoveryHint = "batch outcome unknown; inspect status as observation, then manually replay only the unchanged project, source/batch, action, reason and idempotency key; later Task or authority changes may prevent replay" + } + return err +} + +func (c *Client) decodeBatchTransition(raw json.RawMessage, project, batch, operation string) (TaskBatchTransition, error) { + var value TaskBatchTransition + fields, err := contextObject(raw, &value, []string{"project_id", "batch_id", "operation", "row_count", "tasks"}, nil) + if err != nil || !sameUUID(value.ProjectID, project) || !sameUUID(value.BatchID, batch) || value.Operation != operation || value.RowCount < 1 || value.RowCount > taskimport.MaxRows || len(value.Tasks) != value.RowCount { + return value, &Failure{Code: "invalid_api_response"} + } + var rows []json.RawMessage + if jsonv2.Unmarshal(fields["tasks"], &rows) != nil { + return value, &Failure{Code: "invalid_api_response"} + } + seen := make(map[[16]byte]bool) + status := "screening" + if operation == "release" { + status = "ready" + } + for index, task := range value.Tasks { + var exact TaskBatchTransitionTask + _, err := contextObject(rows[index], &exact, []string{"task_id", "row_index", "status", "locked_guide_version", "locked_contribution_policy_version_id", "locked_context_hash"}, nil) + id, valid := uuidIdentity(task.TaskID) + if err != nil || !valid || seen[id] || task.RowIndex != index || task.Status != status || + !validUUID(task.LockedContributionPolicyVersionID) || !policyHash.MatchString(task.LockedContextHash) || + !utf8.ValidString(task.LockedGuideVersion) || utf8.RuneCountInString(task.LockedGuideVersion) < 1 || utf8.RuneCountInString(task.LockedGuideVersion) > 100 || + !c.safeMetadata(task.TaskID) || !c.safeMetadata(task.LockedGuideVersion) || !c.safeMetadata(task.LockedContributionPolicyVersionID) || !c.safeMetadata(task.LockedContextHash) { + return value, &Failure{Code: "invalid_api_response"} + } + seen[id] = true + } + return value, nil +} + +func (c *Client) decodeTaskImportBatch(raw json.RawMessage, project, batch, source string) (TaskImportBatch, error) { + var envelope taskImportEnvelope + _, err := contextObject(raw, &envelope, []string{"batch_id", "project_id", "source_id", "sha256", "byte_count", "schema_version", "mapping_version", "row_count", "created_at", "tasks"}, nil) + if err != nil || !validUUID(envelope.BatchID) || !sameUUID(envelope.ProjectID, project) || !validUUID(envelope.SourceID) || + (batch != "" && !sameUUID(envelope.BatchID, batch)) || (source != "" && !sameUUID(envelope.SourceID, source)) || + !policyHash.MatchString(envelope.SHA256) || envelope.ByteCount < 1 || envelope.ByteCount > taskimport.MaxBytes || + envelope.RowCount < 1 || envelope.RowCount > taskimport.MaxRows || len(envelope.Tasks) != envelope.RowCount || + envelope.SchemaVersion != "workstream.task_import.v1" || envelope.MappingVersion != "workstream.task_import.draft_mapping.v1" || !validTime(envelope.CreatedAt) { + return TaskImportBatch{}, &Failure{Code: "invalid_api_response"} + } + if envelope.Label != nil && (!utf8.ValidString(*envelope.Label) || utf8.RuneCountInString(*envelope.Label) < 1 || utf8.RuneCountInString(*envelope.Label) > 255 || strings.ContainsRune(*envelope.Label, 0) || !c.safeMetadata(*envelope.Label)) { + return TaskImportBatch{}, &Failure{Code: "invalid_api_response"} + } + value := TaskImportBatch{BatchID: envelope.BatchID, ProjectID: envelope.ProjectID, SourceID: envelope.SourceID, SHA256: envelope.SHA256, ByteCount: envelope.ByteCount, SchemaVersion: envelope.SchemaVersion, MappingVersion: envelope.MappingVersion, Label: envelope.Label, RowCount: envelope.RowCount, CreatedAt: envelope.CreatedAt, Tasks: make([]ImportedTask, 0, envelope.RowCount)} + seen, external := make(map[[16]byte]bool), make(map[string]bool) + for _, row := range envelope.Tasks { + task, err := c.decodeImportedTask(row, value) + id, valid := uuidIdentity(task.ID) + if err != nil || !valid || seen[id] || external[task.ExternalTaskID] { + return value, &Failure{Code: "invalid_api_response"} + } + seen[id], external[task.ExternalTaskID] = true, true + value.Tasks = append(value.Tasks, task) + } + return value, nil +} + +var originalTaskFields = []string{ + "id", "project_id", "locked_contribution_policy_version_id", "locked_guide_version", "locked_review_policy_id", "locked_review_policy_generation", "locked_review_policy_hash", "locked_revision_policy_id", "locked_revision_policy_generation", "locked_revision_policy_hash", "locked_guide_source_snapshot_id", "locked_guide_source_snapshot_hash", "locked_effective_project_submission_artifact_policy_id", "locked_effective_project_submission_artifact_policy_hash", "locked_pre_submit_checker_policy_id", "locked_pre_submit_checker_bundle_hash", "source_type", "source_ref", "source_payload_hash", "import_batch_id", "external_task_id", "title", "description", "task_type", "difficulty", "skill_tags", "estimated_time_minutes", "status", "acceptance_criteria", "rejection_criteria", "deadline_at", "created_by", "assigned_to", "created_at", "updated_at", +} + +func (c *Client) decodeImportedTask(raw json.RawMessage, batch TaskImportBatch) (ImportedTask, error) { + var task ImportedTask + var fields map[string]json.RawMessage + if err := jsonv2.Unmarshal(raw, &fields); err != nil || len(fields) != len(originalTaskFields) { + return task, &Failure{Code: "invalid_api_response"} + } + for _, field := range originalTaskFields { + value, present := fields[field] + if !present || ((strings.HasPrefix(field, "locked_") || field == "assigned_to" || field == "deadline_at") && string(value) != "null") { + return task, &Failure{Code: "invalid_api_response"} + } + } + // The complete public TaskResponse field set was checked above. Decode only + // identities used by CLI output; validate instructions through the canonical + // local import parser without retaining a second private Task DTO. + if jsonv2.Unmarshal(raw, &task) != nil || !sameUUID(task.ProjectID, batch.ProjectID) || task.Status != "draft" || + task.SourceType != "json_import" || task.SourceRef != "task-import-source:"+batch.SourceID || task.SourcePayloadHash != batch.SHA256 || + !sameUUID(task.ImportBatchID, batch.BatchID) || !validUUID(task.CreatedBy) || !validTime(task.CreatedAt) || !validTime(task.UpdatedAt) { + return task, &Failure{Code: "invalid_api_response"} + } + instructions := make(map[string]json.RawMessage) + for _, field := range []string{"external_task_id", "title", "description", "task_type", "difficulty", "skill_tags", "estimated_time_minutes", "acceptance_criteria", "rejection_criteria"} { + instructions[field] = fields[field] + if field == "skill_tags" { + var tags []string + if jsonv2.Unmarshal(fields[field], &tags) != nil { + return task, &Failure{Code: "invalid_api_response"} + } + for _, tag := range tags { + if !c.safeMetadata(tag) { + return task, &Failure{Code: "invalid_api_response"} + } + } + } else if field != "estimated_time_minutes" && string(fields[field]) != "null" { + var text string + if jsonv2.Unmarshal(fields[field], &text) != nil || !c.safeMetadata(text) { + return task, &Failure{Code: "invalid_api_response"} + } + } + } + validation, err := json.Marshal(map[string]any{"schema_version": "workstream.task_import.v1", "tasks": []any{instructions}}) + if err == nil { + _, err = taskimport.ValidateJSON(validation) + } + if err != nil { + return task, &Failure{Code: "invalid_api_response"} + } + for _, metadata := range []string{task.ID, task.ProjectID, task.SourceRef, task.SourcePayloadHash, task.ImportBatchID, task.CreatedBy, task.CreatedAt, task.UpdatedAt} { + if !c.safeMetadata(metadata) { + return task, &Failure{Code: "invalid_api_response"} + } + } + return task, nil +} diff --git a/cli/internal/command/task_batch.go b/cli/internal/command/task_batch.go index 81a008763..0fcd47193 100644 --- a/cli/internal/command/task_batch.go +++ b/cli/internal/command/task_batch.go @@ -15,6 +15,7 @@ func addTaskBatch(project *cobra.Command, client func() (*api.Client, error), ou batch := &cobra.Command{Use: "task-batch", Short: "Explicit task import, screening and release operations"} addTaskBatchCSV(batch, output, stdout) addTaskBatchSources(batch, client, output, stdout) + addTaskBatchCommands(batch, client, output, stdout) project.AddCommand(batch) } diff --git a/cli/internal/command/task_batch_commands.go b/cli/internal/command/task_batch_commands.go new file mode 100644 index 000000000..b4e9f4d01 --- /dev/null +++ b/cli/internal/command/task_batch_commands.go @@ -0,0 +1,106 @@ +package command + +import ( + "fmt" + "io" + + "github.com/Flow-Research/workstream/cli/internal/api" + "github.com/spf13/cobra" +) + +func addTaskBatchCommands(batch *cobra.Command, client func() (*api.Client, error), output *string, stdout io.Writer) { + var importKey string + importCommand := &cobra.Command{ + Use: "import PROJECT_ID SOURCE_ID", Short: "Import every retained JSON row into DRAFT; does not screen or release", Args: cobra.ExactArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + apiClient, err := client() + if err != nil { + return err + } + result, err := apiClient.ImportTaskBatch(cmd.Context(), args[0], args[1], importKey) + if err != nil { + return err + } + if *output == "json" { + return writeJSON(stdout, result.Raw) + } + if err := writeTaskBatchCreation(stdout, result.Value); err != nil { + return err + } + for index, task := range result.Value.Tasks { + if _, err := fmt.Fprintf(stdout, "Row %d: %s | %s | original %s\n", index, task.ID, safeText(task.ExternalTaskID), task.Status); err != nil { + return err + } + } + return nil + }, + } + importCommand.Flags().StringVar(&importKey, "idempotency-key", "", "Required caller UUID; retain unchanged source and key for manual replay") + batch.AddCommand(importCommand) + batch.AddCommand(&cobra.Command{ + Use: "status PROJECT_ID BATCH_ID", Short: "Read complete native membership, original creation and separate current states", Args: cobra.ExactArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + apiClient, err := client() + if err != nil { + return err + } + result, err := apiClient.TaskBatchStatus(cmd.Context(), args[0], args[1]) + if err != nil { + return err + } + if *output == "json" { + return writeJSON(stdout, result.Raw) + } + if err := writeTaskBatchCreation(stdout, result.Value.Creation); err != nil { + return err + } + for _, task := range result.Value.CurrentTasks { + if _, err := fmt.Fprintf(stdout, "Row %d: %s | current %s\n", task.RowIndex, task.TaskID, safeText(task.Status)); err != nil { + return err + } + } + return nil + }, + }) + for _, operation := range []string{"screen", "release"} { + var key, reason string + command := &cobra.Command{ + Use: operation + " PROJECT_ID BATCH_ID", Short: "Explicitly " + operation + " every native member atomically", Args: cobra.ExactArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + apiClient, err := client() + if err != nil { + return err + } + var decision *string + if cmd.Flags().Changed("reason") { + decision = &reason + } + result, err := apiClient.TransitionTaskBatch(cmd.Context(), args[0], args[1], operation, key, decision) + if err != nil { + return err + } + if *output == "json" { + return writeJSON(stdout, result.Raw) + } + value := result.Value + if _, err := fmt.Fprintf(stdout, "Batch: %s\nProject: %s\nOperation: %s\nTasks: %d\n", value.BatchID, value.ProjectID, value.Operation, value.RowCount); err != nil { + return err + } + for _, task := range value.Tasks { + if _, err := fmt.Fprintf(stdout, "Row %d: %s | %s | guide %s\n", task.RowIndex, task.TaskID, task.Status, safeText(task.LockedGuideVersion)); err != nil { + return err + } + } + return nil + }, + } + command.Flags().StringVar(&key, "idempotency-key", "", "Required caller UUID; manual unchanged-key replay requires every member still matches its original post-state") + command.Flags().StringVar(&reason, "reason", "", "At most 4000 UTF-8 characters; release requires a nonblank decision reason") + batch.AddCommand(command) + } +} + +func writeTaskBatchCreation(stdout io.Writer, value api.TaskImportBatch) error { + _, err := fmt.Fprintf(stdout, "Batch: %s\nProject: %s\nSource: %s\nSHA-256: %s\nJSON bytes: %d\nTasks: %d\nOriginal state: draft\n", value.BatchID, value.ProjectID, value.SourceID, value.SHA256, value.ByteCount, value.RowCount) + return err +} diff --git a/cli/tests/integration/test_task_batch_commands_http.py b/cli/tests/integration/test_task_batch_commands_http.py new file mode 100644 index 000000000..38c8f637e --- /dev/null +++ b/cli/tests/integration/test_task_batch_commands_http.py @@ -0,0 +1,269 @@ +"""Built batch CLI uses separate typed calls and preserves uncertain-write recovery.""" + +from copy import deepcopy +import json +from uuid import UUID + +from app.modules.tasks.schemas import TaskResponse +from http2_fixture import goaway_fixture +from test_contributor_task_mutations import KEY, canonical_error +from test_http_boundary import ACTOR, PROJECT, TOKEN, http_fixture +from test_task_batch_sources_http import SOURCE + +BATCH = "018f0ebc-7966-7e8d-bc4d-1cae1e000006" + + +def creation(count=2): + """Construct public DTO-shaped HTTP fixtures; these are not native custody proof.""" + tasks = [] + for index in range(count): + row = dict.fromkeys(TaskResponse.model_fields) + row.update( + id=str(UUID(int=UUID(ACTOR).int + 1000 + index)), + project_id=PROJECT, + external_task_id=f"brief-{index}", + title="Caption café", + description="Quoted\nbrief", + skill_tags=["French"], + source_type="json_import", + source_ref=f"task-import-source:{SOURCE}", + source_payload_hash="sha256:" + "a" * 64, + import_batch_id=BATCH, + status="draft", + created_by=ACTOR, + created_at="2026-10-11T12:00:00Z", + updated_at="2026-10-11T12:00:00Z", + ) + tasks.append(TaskResponse.model_validate(row).model_dump(mode="json")) + return { + "batch_id": BATCH, + "project_id": PROJECT, + "source_id": SOURCE, + "sha256": "sha256:" + "a" * 64, + "byte_count": 1000, + "schema_version": "workstream.task_import.v1", + "mapping_version": "workstream.task_import.draft_mapping.v1", + "label": None, + "row_count": count, + "created_at": "2026-10-11T12:00:00Z", + "tasks": tasks, + } + + +def status(count=2): + original = creation(count) + return { + "creation": original, + "current_tasks": [ + {"task_id": row["id"], "row_index": index, "status": "ready"} + for index, row in enumerate(original["tasks"]) + ], + } + + +def transition(operation="screen", count=2): + return { + "project_id": PROJECT, + "batch_id": BATCH, + "operation": operation, + "row_count": count, + "tasks": [ + { + "task_id": row["id"], + "row_index": index, + "status": "screening" if operation == "screen" else "ready", + "locked_guide_version": "v1.0.0", + "locked_contribution_policy_version_id": ACTOR, + "locked_context_hash": "sha256:" + "b" * 64, + } + for index, row in enumerate(creation(count)["tasks"]) + ], + } + + +def invoke( + cli, + origin, + operation, + *, + project=PROJECT, + target=None, + key=KEY, + reason="Decision", + **kwargs, +): + args = [ + "-o", + "json", + "project", + "task-batch", + operation, + project, + target or (SOURCE if operation == "import" else BATCH), + ] + if operation != "status": + args.extend(("--idempotency-key", key)) + if operation in {"screen", "release"} and reason is not None: + args.extend(("--reason", reason)) + return cli(origin, TOKEN, *args, **kwargs) + + +def test_explicit_commands_preserve_original_and_current_facts_and_exact_requests(cli): + with http_fixture() as (origin, response, requests): + response.update(status=201, body=json.dumps(creation()).encode()) + result = invoke(cli, origin, "import") + assert result.returncode == 0 and json.loads(result.stdout) == creation(), ( + result.stderr + ) + response.update(status=200, body=json.dumps(status()).encode()) + result = invoke(cli, origin, "status") + assert result.returncode == 0 and json.loads(result.stdout) == status(), ( + result.stderr + ) + for operation in ("screen", "release"): + response.update(body=json.dumps(transition(operation)).encode()) + for _ in range(2): + result = invoke(cli, origin, operation) + assert result.returncode == 0 and json.loads( + result.stdout + ) == transition(operation), result.stderr + prefix = f"/api/v1/projects/{PROJECT}/task-import-batches" + assert requests == [ + ("POST", prefix, "Bearer " + TOKEN), + ("GET", f"{prefix}/{BATCH}", "Bearer " + TOKEN), + *( + ("POST", f"{prefix}/{BATCH}/{operation}", "Bearer " + TOKEN) + for operation in ("screen", "screen", "release", "release") + ), + ] + assert response["commands"] == [ + ("application/json", [KEY], {"source_id": SOURCE}), + *[("application/json", [KEY], {"reason": "Decision"}) for _ in range(4)], + ] + + +def test_complete_500_row_original_status_and_compact_results_are_not_truncated(cli): + with http_fixture() as (origin, response, _requests): + for operation, body, code in ( + ("import", creation(500), 201), + ("status", status(500), 200), + ("screen", transition(count=500), 200), + ): + raw = json.dumps(body).encode() + assert len(raw) > 64 * 1024 + response.update(status=code, body=raw) + result = invoke(cli, origin, operation) + assert result.returncode == 0 and json.loads(result.stdout) == body, ( + result.stderr + ) + + +def test_malformed_or_crossed_original_receipts_are_uncertain_imports(cli): + values = [] + for field, value in ( + ("project_id", SOURCE), + ("source_id", PROJECT), + ("row_count", 3), + ("schema_version", "other"), + ): + values.append(creation() | {field: value}) + for change in ("advanced", "locked", "duplicate", "source", "extra", "null"): + value = deepcopy(creation()) + row = value["tasks"][1] + if change == "advanced": + row["status"] = "ready" + elif change == "locked": + row["locked_guide_version"] = "v1.0.0" + elif change == "duplicate": + row["id"] = value["tasks"][0]["id"] + elif change == "source": + row["source_ref"] = "task-import-source:" + PROJECT + elif change == "extra": + row["provider_path"] = "private" + else: + row["title"] = None + values.append(value) + with http_fixture() as (origin, response, requests): + for value in values: + response.update(status=201, body=json.dumps(value).encode()) + result = invoke(cli, origin, "import") + assert result.returncode == 1 and result.stdout == "", result.stderr + assert json.loads(result.stderr)["error"]["outcome_unknown"] is True + assert len(requests) == len(values) + + +def test_malformed_complete_membership_and_current_projection_are_refused(cli): + with http_fixture() as (origin, response, _requests): + value = status() + value["current_tasks"].reverse() + response.update(body=json.dumps(value).encode()) + result = invoke(cli, origin, "status") + assert ( + result.returncode == 1 + and "outcome_unknown" not in json.loads(result.stderr)["error"] + ) + for change in ( + "missing", + "duplicate", + "reordered", + "null_index", + "foreign_status", + "missing_lock", + ): + value = transition() + if change == "missing": + value["tasks"].pop() + elif change == "duplicate": + value["tasks"][1]["task_id"] = value["tasks"][0]["task_id"] + elif change == "reordered": + value["tasks"].reverse() + elif change == "null_index": + value["tasks"][0]["row_index"] = None + elif change == "foreign_status": + value["tasks"][1]["status"] = "ready" + else: + value["tasks"][1]["locked_context_hash"] = None + response.update(body=json.dumps(value).encode()) + result = invoke(cli, origin, "screen") + assert ( + result.returncode == 1 + and json.loads(result.stderr)["error"]["outcome_unknown"] is True + ) + + +def test_invalid_selectors_keys_and_release_reasons_make_zero_requests(cli): + with http_fixture() as (origin, _response, requests): + for operation in ("import", "status", "screen", "release"): + assert invoke(cli, origin, operation, project="../private").returncode == 2 + assert invoke(cli, origin, operation, target="../private").returncode == 2 + for operation in ("import", "screen", "release"): + assert invoke(cli, origin, operation, key="").returncode == 2 + assert invoke(cli, origin, "release", reason=None).returncode == 2 + assert invoke(cli, origin, "release", reason=" \n").returncode == 2 + assert invoke(cli, origin, "screen", reason="x" * 4001).returncode == 2 + assert requests == [] + + +def test_uncertain_batch_writes_are_once_only_and_preserve_manual_recovery( + cli, tmp_path +): + with http_fixture() as (origin, response, requests): + for operation in ("import", "screen", "release"): + response.update(drop=True) + result = invoke(cli, origin, operation) + assert result.returncode == 1 and result.stdout == "" + assert json.loads(result.stderr)["error"]["outcome_unknown"] is True + assert len(requests) == 3 + response.update( + drop=False, status=403, body=json.dumps(canonical_error()).encode() + ) + result = invoke(cli, origin, "release") + assert "outcome_unknown" not in json.loads(result.stderr)["error"] + response.update(body=b'{"detail":"unrecognized denial"}') + result = invoke(cli, origin, "release") + assert json.loads(result.stderr)["error"]["outcome_unknown"] is True + with goaway_fixture(tmp_path) as (origin, env, bodies, connections): + result = invoke(cli, origin, "release", extra_env=env) + assert result.returncode == 1 and connections == ["h2"] + assert bodies == [b'{"reason":"Decision"}'] + assert json.loads(result.stderr)["error"]["outcome_unknown"] is True From da85efdc494a0b39ea4a3297b0db79adbda13f69 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 14:20:06 +0100 Subject: [PATCH 026/283] Register bulk transition models in canonical graph --- .../changes/pilot02-bulk-transitions-cli.md | 27 ++- backend/app/db/models.py | 4 + .../tasks/task_batch_transition/__init__.py | 1 + .../tasks/task_batch_transition/models.py | 165 ++++++++++++++++++ .../tasks/task_batch_transition_models.py | 84 --------- .../modules/tasks/task_batch_transitions.py | 2 +- .../test_task_batch_transition_contract.py | 77 +++++++- .../tasks/test_task_batch_transitions.py | 2 +- 8 files changed, 266 insertions(+), 96 deletions(-) create mode 100644 backend/app/modules/tasks/task_batch_transition/__init__.py create mode 100644 backend/app/modules/tasks/task_batch_transition/models.py delete mode 100644 backend/app/modules/tasks/task_batch_transition_models.py diff --git a/.commitrail/changes/pilot02-bulk-transitions-cli.md b/.commitrail/changes/pilot02-bulk-transitions-cli.md index bef1e3be2..53e509d95 100644 --- a/.commitrail/changes/pilot02-bulk-transitions-cli.md +++ b/.commitrail/changes/pilot02-bulk-transitions-cli.md @@ -23,7 +23,7 @@ Their current root transaction prevents composition across a complete batch. selection only. Extend exact existing SCREEN/RELEASE participants in `authorized_commands.py` through prepare/authorize/stage phases. Coordinate these regions with the atomic-import owner before edits. -- Aggregate custody is owned in `task_batch_transition_models.py`: exactly one +- Aggregate custody is owned in `task_batch_transition/models.py`: exactly one actor/action/key aggregate and its complete native member links. Lead review approved compact ordered receipt projections and a scoped batch-write client deadline, to be selected after native 200/500 measurements. No global transport @@ -34,6 +34,13 @@ Their current root transaction prevents composition across a complete batch. updates in TASK router/import tests. A tiny `_locked_task` extraction shares its unchanged AUTH prepare/consume/finally-close block through `_authorize_facts`. CREATE methods/dataclass and source ancestry preparation remain untouched. +- Sole schema-owner handoff authorizes only the two aggregate model imports in + `backend/app/db/models.py`. The new model owner is relocated once to + `task_batch_transition/models.py` so canonical registration uses the existing + protected metadata-discovery exception, without an alias or new private debt. + A fresh-process canonical-only metadata/FK compiler check belongs in the + existing compact-contract test module. Migration, Alembic/env, fingerprints, + reset lists and schema-owner inventory remain with the sole migration author. - New route/dependency modules and append-only composition of the typed batch transition owner. Shared TASK `router.py`, `schemas.py`, model/receipt and AUTH regions require an explicit owner handoff before edits. Existing per-Task @@ -168,8 +175,9 @@ Peer review of aggregate checkpoint `42900b036` found that the new dependency projected immutable identity after the canonical Task dependency rolled back and expired the resolved ORM actor/link. The repair projects the existing public `ActorIdentityFacts` first, before that rollback; no row refresh, implicit read, -new authority owner or private actor import is introduced. Peer native dependency -expiration replay and installed aggregate public proof remain separate evidence. +new authority owner or private actor import is introduced. The peer dependency-order/ORM-expiration discriminator uses actual FastAPI and +attached SQLAlchemy models without SQL, schema or AUTH execution. It proves the +composition defect and correction; native aggregate public proof remains pending. The same peer review found missing/blank RELEASE input reached the native pending receipt reason CHECK before normal validation. The repair uses the canonical `TaskValidationError` reason requirement before opening/reserving the root, @@ -181,6 +189,19 @@ in 7.40 seconds; the protected module-boundary check also exited successfully. The owned idle PostgreSQL container was stopped after the earlier native proof's isolated DB/role cleanup, while aggregate DDL remains pending. +Peer review also found the canonical model graph omitted the aggregate tables, +so the new canonical receipt FK could not resolve in a fresh process. The repair +registers both aggregate classes through the existing metadata-discovery owner +and relocates their unchanged bodies once to the protected `.models` shape. +The focused regression imports only `app.db.models` in a fresh interpreter, +resolves every canonical FK and compiles the canonical receipt and aggregate +tables with the PostgreSQL dialect. This is model-graph proof, not installed DDL +or native aggregate proof. +The focused compact/admission/model-graph module passed 15 cases in 7.98 seconds. +Removing only canonical registration makes the fresh-process check fail at the +missing aggregate table; registration was restored exactly. The protected +module-boundary validator passed without ledger changes or gate exemptions. + CLI import/status/screen/release are implemented as separate exact typed calls. Original/status responses are bounded to 16MiB, compact transitions to 2MiB, with complete 1..500 ordered membership and strict original DRAFT/source custody. diff --git a/backend/app/db/models.py b/backend/app/db/models.py index cf90e66ad..61866890b 100644 --- a/backend/app/db/models.py +++ b/backend/app/db/models.py @@ -87,6 +87,10 @@ TaskAssignment, WorkstreamTask, ) +from app.modules.tasks.task_batch_transition.models import ( # noqa: F401 + TaskBatchTransitionMember, + TaskBatchTransitionReceipt, +) from app.modules.tasks.post_submit_routing.models import ( # noqa: F401 TaskPostSubmitRoutingManifest, TaskRoutingRequest, diff --git a/backend/app/modules/tasks/task_batch_transition/__init__.py b/backend/app/modules/tasks/task_batch_transition/__init__.py new file mode 100644 index 000000000..3d50d38a5 --- /dev/null +++ b/backend/app/modules/tasks/task_batch_transition/__init__.py @@ -0,0 +1 @@ +"""TASK-owned aggregate transition custody.""" diff --git a/backend/app/modules/tasks/task_batch_transition/models.py b/backend/app/modules/tasks/task_batch_transition/models.py new file mode 100644 index 000000000..cc0057b2a --- /dev/null +++ b/backend/app/modules/tasks/task_batch_transition/models.py @@ -0,0 +1,165 @@ +"""TASK-owned aggregate success custody over canonical per-Task command receipts.""" + +from datetime import datetime +from uuid import UUID + +from sqlalchemy import ( + CheckConstraint, + DateTime, + ForeignKey, + ForeignKeyConstraint, + Integer, + String, + Text, + UniqueConstraint, + Uuid, +) +from sqlalchemy.dialects.postgresql import JSONB +from sqlalchemy.orm import Mapped, mapped_column +from sqlalchemy.sql import func + +from app.db.base import Base + + +class TaskBatchTransitionReceipt(Base): + """One actor/action/key root, committed only with every native batch member.""" + + __tablename__ = "task_batch_transition_receipts" + __table_args__ = ( + CheckConstraint( + "(get_byte(uuid_send(id), 6) >> 4) = 7 and (get_byte(uuid_send(id), 8) & 192) = 128", + name="id_uuid7", + ), + UniqueConstraint( + "actor_profile_id", + "action_id", + "idempotency_key", + name="uq_task_batch_transition_namespace", + ), + UniqueConstraint("id", "project_id", "batch_id", name="uq_task_batch_transition_parent"), + ForeignKeyConstraint( + ["batch_id", "project_id"], + ["task_import_batches.id", "task_import_batches.project_id"], + name="fk_task_batch_transition_batch", + ondelete="RESTRICT", + deferrable=True, + initially="DEFERRED", + ), + ForeignKeyConstraint( + ["identity_link_id", "actor_profile_id"], + ["actor_identity_links.id", "actor_identity_links.actor_profile_id"], + name="fk_task_batch_transition_actor_link", + ondelete="RESTRICT", + deferrable=True, + initially="DEFERRED", + ), + CheckConstraint( + "action_id in ('project.task.screen','project.task.release')", name="action" + ), + CheckConstraint( + "request_digest ~ '^sha256:[0-9a-f]{64}$' and manifest_digest ~ '^sha256:[0-9a-f]{64}$' " + "and membership_digest ~ '^sha256:[0-9a-f]{64}$'", + name="digests", + ), + CheckConstraint("row_count between 1 and 500", name="bounds"), + CheckConstraint("reason is null or length(reason)<=4000", name="reason_bounds"), + CheckConstraint( + "action_id<>'project.task.release' or (reason is not null and length(btrim(reason))>0)", + name="release_reason", + ), + CheckConstraint( + "(status='pending' and response is null and committed_at is null) or " + "(status='committed' and response is not null and jsonb_typeof(response)='object' " + "and committed_at is not null)", + name="state_shape", + ), + ) + + id: Mapped[UUID] = mapped_column(Uuid(), primary_key=True) + actor_profile_id: Mapped[str] = mapped_column( + ForeignKey("actor_profiles.id", ondelete="RESTRICT", deferrable=True, initially="DEFERRED") + ) + identity_link_id: Mapped[str] = mapped_column(Uuid(as_uuid=False)) + action_id: Mapped[str] = mapped_column(String(160)) + idempotency_key: Mapped[UUID] = mapped_column(Uuid()) + request_digest: Mapped[str] = mapped_column(String(71)) + reason: Mapped[str | None] = mapped_column(Text) + project_id: Mapped[str] = mapped_column(Uuid(as_uuid=False)) + batch_id: Mapped[str] = mapped_column(Uuid(as_uuid=False)) + manifest_digest: Mapped[str] = mapped_column(String(71)) + membership_digest: Mapped[str] = mapped_column(String(71)) + row_count: Mapped[int] = mapped_column(Integer) + status: Mapped[str] = mapped_column(String(16), default="pending") + response: Mapped[dict | None] = mapped_column(JSONB(none_as_null=True)) + created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now()) + committed_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True)) + + +class TaskBatchTransitionMember(Base): + """Immutable original row linked to its root-bound canonical success and AUTH.""" + + __tablename__ = "task_batch_transition_members" + __table_args__ = ( + CheckConstraint( + "(get_byte(uuid_send(id), 6) >> 4) = 7 and (get_byte(uuid_send(id), 8) & 192) = 128", + name="id_uuid7", + ), + UniqueConstraint( + "transition_receipt_id", "row_index", name="uq_task_batch_transition_member_row" + ), + UniqueConstraint( + "transition_receipt_id", + "native_member_id", + name="uq_task_batch_transition_member_native", + ), + UniqueConstraint( + "transition_receipt_id", "task_id", name="uq_task_batch_transition_member_task" + ), + UniqueConstraint("task_command_receipt_id", name="uq_task_batch_transition_member_command"), + ForeignKeyConstraint( + ["transition_receipt_id", "project_id", "batch_id"], + [ + "task_batch_transition_receipts.id", + "task_batch_transition_receipts.project_id", + "task_batch_transition_receipts.batch_id", + ], + name="fk_task_batch_transition_member_parent", + ondelete="RESTRICT", + deferrable=True, + initially="DEFERRED", + ), + ForeignKeyConstraint( + ["task_id", "project_id"], + ["workstream_tasks.id", "workstream_tasks.project_id"], + name="fk_task_batch_transition_member_task", + ondelete="RESTRICT", + deferrable=True, + initially="DEFERRED", + ), + CheckConstraint("row_index between 0 and 499", name="row_index"), + ) + + id: Mapped[UUID] = mapped_column(Uuid(), primary_key=True) + transition_receipt_id: Mapped[UUID] = mapped_column(Uuid()) + project_id: Mapped[str] = mapped_column(Uuid(as_uuid=False)) + batch_id: Mapped[str] = mapped_column(Uuid(as_uuid=False)) + native_member_id: Mapped[str] = mapped_column( + ForeignKey( + "task_import_batch_members.id", + ondelete="RESTRICT", + deferrable=True, + initially="DEFERRED", + ) + ) + task_id: Mapped[str] = mapped_column(Uuid(as_uuid=False)) + row_index: Mapped[int] = mapped_column(Integer) + task_idempotency_key: Mapped[UUID] = mapped_column(Uuid()) + task_command_receipt_id: Mapped[UUID] = mapped_column( + ForeignKey( + "task_command_receipts.id", ondelete="RESTRICT", deferrable=True, initially="DEFERRED" + ) + ) + authorization_decision_id: Mapped[str] = mapped_column( + ForeignKey("audit_events.id", ondelete="RESTRICT", deferrable=True, initially="DEFERRED") + ) + created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now()) diff --git a/backend/app/modules/tasks/task_batch_transition_models.py b/backend/app/modules/tasks/task_batch_transition_models.py deleted file mode 100644 index 76fa32845..000000000 --- a/backend/app/modules/tasks/task_batch_transition_models.py +++ /dev/null @@ -1,84 +0,0 @@ -"""TASK-owned aggregate success custody over canonical per-Task command receipts.""" - -from datetime import datetime -from uuid import UUID - -from sqlalchemy import CheckConstraint, DateTime, ForeignKey, ForeignKeyConstraint, Integer, String, Text, UniqueConstraint, Uuid -from sqlalchemy.dialects.postgresql import JSONB -from sqlalchemy.orm import Mapped, mapped_column -from sqlalchemy.sql import func - -from app.db.base import Base - - -class TaskBatchTransitionReceipt(Base): - """One actor/action/key root, committed only with every native batch member.""" - - __tablename__ = "task_batch_transition_receipts" - __table_args__ = ( - CheckConstraint("(get_byte(uuid_send(id), 6) >> 4) = 7 and (get_byte(uuid_send(id), 8) & 192) = 128", name="id_uuid7"), - UniqueConstraint("actor_profile_id", "action_id", "idempotency_key", name="uq_task_batch_transition_namespace"), - UniqueConstraint("id", "project_id", "batch_id", name="uq_task_batch_transition_parent"), - ForeignKeyConstraint(["batch_id", "project_id"], ["task_import_batches.id", "task_import_batches.project_id"], - name="fk_task_batch_transition_batch", ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), - ForeignKeyConstraint(["identity_link_id", "actor_profile_id"], ["actor_identity_links.id", "actor_identity_links.actor_profile_id"], - name="fk_task_batch_transition_actor_link", ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), - CheckConstraint("action_id in ('project.task.screen','project.task.release')", name="action"), - CheckConstraint("request_digest ~ '^sha256:[0-9a-f]{64}$' and manifest_digest ~ '^sha256:[0-9a-f]{64}$' " - "and membership_digest ~ '^sha256:[0-9a-f]{64}$'", name="digests"), - CheckConstraint("row_count between 1 and 500", name="bounds"), - CheckConstraint("reason is null or length(reason)<=4000", name="reason_bounds"), - CheckConstraint("action_id<>'project.task.release' or (reason is not null and length(btrim(reason))>0)", - name="release_reason"), - CheckConstraint("(status='pending' and response is null and committed_at is null) or " - "(status='committed' and response is not null and jsonb_typeof(response)='object' " - "and committed_at is not null)", name="state_shape"), - ) - - id: Mapped[UUID] = mapped_column(Uuid(), primary_key=True) - actor_profile_id: Mapped[str] = mapped_column(ForeignKey("actor_profiles.id", ondelete="RESTRICT", deferrable=True, initially="DEFERRED")) - identity_link_id: Mapped[str] = mapped_column(Uuid(as_uuid=False)) - action_id: Mapped[str] = mapped_column(String(160)) - idempotency_key: Mapped[UUID] = mapped_column(Uuid()) - request_digest: Mapped[str] = mapped_column(String(71)) - reason: Mapped[str | None] = mapped_column(Text) - project_id: Mapped[str] = mapped_column(Uuid(as_uuid=False)) - batch_id: Mapped[str] = mapped_column(Uuid(as_uuid=False)) - manifest_digest: Mapped[str] = mapped_column(String(71)) - membership_digest: Mapped[str] = mapped_column(String(71)) - row_count: Mapped[int] = mapped_column(Integer) - status: Mapped[str] = mapped_column(String(16), default="pending") - response: Mapped[dict | None] = mapped_column(JSONB(none_as_null=True)) - created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now()) - committed_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True)) - - -class TaskBatchTransitionMember(Base): - """Immutable original row linked to its root-bound canonical success and AUTH.""" - - __tablename__ = "task_batch_transition_members" - __table_args__ = ( - CheckConstraint("(get_byte(uuid_send(id), 6) >> 4) = 7 and (get_byte(uuid_send(id), 8) & 192) = 128", name="id_uuid7"), - UniqueConstraint("transition_receipt_id", "row_index", name="uq_task_batch_transition_member_row"), - UniqueConstraint("transition_receipt_id", "native_member_id", name="uq_task_batch_transition_member_native"), - UniqueConstraint("transition_receipt_id", "task_id", name="uq_task_batch_transition_member_task"), - UniqueConstraint("task_command_receipt_id", name="uq_task_batch_transition_member_command"), - ForeignKeyConstraint(["transition_receipt_id", "project_id", "batch_id"], - ["task_batch_transition_receipts.id", "task_batch_transition_receipts.project_id", "task_batch_transition_receipts.batch_id"], - name="fk_task_batch_transition_member_parent", ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), - ForeignKeyConstraint(["task_id", "project_id"], ["workstream_tasks.id", "workstream_tasks.project_id"], - name="fk_task_batch_transition_member_task", ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), - CheckConstraint("row_index between 0 and 499", name="row_index"), - ) - - id: Mapped[UUID] = mapped_column(Uuid(), primary_key=True) - transition_receipt_id: Mapped[UUID] = mapped_column(Uuid()) - project_id: Mapped[str] = mapped_column(Uuid(as_uuid=False)) - batch_id: Mapped[str] = mapped_column(Uuid(as_uuid=False)) - native_member_id: Mapped[str] = mapped_column(ForeignKey("task_import_batch_members.id", ondelete="RESTRICT", deferrable=True, initially="DEFERRED")) - task_id: Mapped[str] = mapped_column(Uuid(as_uuid=False)) - row_index: Mapped[int] = mapped_column(Integer) - task_idempotency_key: Mapped[UUID] = mapped_column(Uuid()) - task_command_receipt_id: Mapped[UUID] = mapped_column(ForeignKey("task_command_receipts.id", ondelete="RESTRICT", deferrable=True, initially="DEFERRED")) - authorization_decision_id: Mapped[str] = mapped_column(ForeignKey("audit_events.id", ondelete="RESTRICT", deferrable=True, initially="DEFERRED")) - created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now()) diff --git a/backend/app/modules/tasks/task_batch_transitions.py b/backend/app/modules/tasks/task_batch_transitions.py index b4692d1e7..66668e2d6 100644 --- a/backend/app/modules/tasks/task_batch_transitions.py +++ b/backend/app/modules/tasks/task_batch_transitions.py @@ -19,7 +19,7 @@ from app.modules.tasks.command_replay import TaskReplayConflict from app.modules.tasks.schemas import TaskResponse from app.modules.tasks.service import TaskValidationError -from app.modules.tasks.task_batch_transition_models import TaskBatchTransitionMember, TaskBatchTransitionReceipt +from app.modules.tasks.task_batch_transition.models import TaskBatchTransitionMember, TaskBatchTransitionReceipt from app.modules.tasks.task_import_membership import TaskImportMembership, TaskImportMembershipSnapshot diff --git a/backend/tests/tasks/test_task_batch_transition_contract.py b/backend/tests/tasks/test_task_batch_transition_contract.py index ce28e4266..2a19640b0 100644 --- a/backend/tests/tasks/test_task_batch_transition_contract.py +++ b/backend/tests/tasks/test_task_batch_transition_contract.py @@ -1,21 +1,40 @@ """Compact batch contracts reject partial and substituted ordered success facts.""" +from pathlib import Path +import subprocess +import sys from uuid import uuid4 import pytest from pydantic import ValidationError -from app.modules.tasks.api.task_batch_transition import TaskBatchTransitionRequest, TaskBatchTransitionResponse +from app.modules.tasks.api.task_batch_transition import ( + TaskBatchTransitionRequest, + TaskBatchTransitionResponse, +) from app.modules.tasks.service import TaskValidationError from app.modules.tasks.task_batch_transitions import TaskBatchTransitionCommands def response_value(count=2): """Use different Task identities with the same legitimate locked guide version.""" - return {"project_id": str(uuid4()), "batch_id": str(uuid4()), "operation": "screen", "row_count": count, - "tasks": [{"task_id": str(uuid4()), "row_index": index, "status": "screening", - "locked_guide_version": "v1.0.0", "locked_contribution_policy_version_id": str(uuid4()), - "locked_context_hash": "sha256:" + "a" * 64} for index in range(count)]} + return { + "project_id": str(uuid4()), + "batch_id": str(uuid4()), + "operation": "screen", + "row_count": count, + "tasks": [ + { + "task_id": str(uuid4()), + "row_index": index, + "status": "screening", + "locked_guide_version": "v1.0.0", + "locked_contribution_policy_version_id": str(uuid4()), + "locked_context_hash": "sha256:" + "a" * 64, + } + for index in range(count) + ], + } def test_response_preserves_complete_500_row_order_and_string_guide_versions(): @@ -25,7 +44,10 @@ def test_response_preserves_complete_500_row_order_and_string_guide_versions(): assert TaskBatchTransitionResponse.model_validate_json(response.model_dump_json()) == response -@pytest.mark.parametrize("change", ["missing", "reordered", "duplicate", "foreign_status", "bad_hash", "unlocked", "extra"]) +@pytest.mark.parametrize( + "change", + ["missing", "reordered", "duplicate", "foreign_status", "bad_hash", "unlocked", "extra"], +) def test_incomplete_or_substituted_success_is_refused(change): value = response_value() if change == "missing": @@ -68,6 +90,47 @@ def test_release_and_reason_contracts_are_separate_from_screen(): @pytest.mark.parametrize("reason", [None, "", " \n"]) async def test_release_reason_is_refused_before_any_transaction_or_authority(reason): """Admission must reject incomplete input without accessing a session or Task port.""" - owner = TaskBatchTransitionCommands(None, actor_profile_id=uuid4(), identity_link_id=uuid4(), tasks=None) + owner = TaskBatchTransitionCommands( + None, actor_profile_id=uuid4(), identity_link_id=uuid4(), tasks=None + ) with pytest.raises(TaskValidationError, match="release decision reason is required"): await owner.release(uuid4(), uuid4(), reason, idempotency_key=uuid4()) + + +def test_canonical_model_graph_resolves_bulk_receipt_foreign_keys_in_fresh_process(): + """Runtime/Alembic registration must work without importing the bulk caller first.""" + result = subprocess.run( + [ + sys.executable, + "-c", + """ +import sys +assert not any(name.startswith('app.') for name in sys.modules) +import app.db.models +from app.db.base import Base +from sqlalchemy.dialects.postgresql import dialect +from sqlalchemy.schema import CreateTable + +tables = Base.metadata.tables +receipt = tables['task_command_receipts'] +root = tables['task_batch_transition_receipts'] +member = tables['task_batch_transition_members'] +assert next(iter(receipt.c.batch_transition_receipt_id.foreign_keys)).column is root.c.id +assert next(iter(member.c.transition_receipt_id.foreign_keys)).column is root.c.id +for table in tables.values(): + for foreign_key in table.foreign_keys: + assert foreign_key.column.table.key in tables +for table in (receipt, root, member): + ddl = str(CreateTable(table).compile(dialect=dialect())) + assert 'CREATE TABLE ' + table.name in ddl +print('canonical graph and aggregate receipt FK compilation passed') +""", + ], + cwd=Path(__file__).resolve().parents[2], + capture_output=True, + text=True, + timeout=30, + check=False, + ) + assert result.returncode == 0, result.stdout + result.stderr + assert result.stdout.strip() == "canonical graph and aggregate receipt FK compilation passed" diff --git a/backend/tests/tasks/test_task_batch_transitions.py b/backend/tests/tasks/test_task_batch_transitions.py index 2acd3c2da..c63bb2179 100644 --- a/backend/tests/tasks/test_task_batch_transitions.py +++ b/backend/tests/tasks/test_task_batch_transitions.py @@ -18,7 +18,7 @@ from app.modules.tasks.authorized_commands import AuthorizedTaskCommands from app.modules.tasks.models import AuditEvent, TaskCommandReceipt, WorkstreamTask from app.modules.tasks.service import TaskValidationError -from app.modules.tasks.task_batch_transition_models import TaskBatchTransitionMember, TaskBatchTransitionReceipt +from app.modules.tasks.task_batch_transition.models import TaskBatchTransitionMember, TaskBatchTransitionReceipt from app.modules.tasks.task_batch_transitions import TaskBatchTransitionCommands from app.modules.tasks.task_batch_transitions import _membership_digest from app.modules.tasks.task_import_membership import TaskImportMembership From cb3b565b2f4e1e9c06444dd90e7d2d9e5ceb983e Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 14:25:46 +0100 Subject: [PATCH 027/283] Register bounded bulk proofs and document replay contract --- .ci/behavior-ownership/partition.v1.json | 22 +++++++++- .../changes/pilot02-bulk-transitions-cli.md | 29 ++++++++++--- backend/scripts/behavior_ownership.py | 8 ++++ backend/scripts/test_lane_catalogue.py | 2 + backend/tests/test_ci_lane_catalogue.py | 2 + docs/roadmap_status.md | 6 +++ docs/spec_chunk_4_task_queue_assignment.md | 43 +++++++++++++++++-- 7 files changed, 101 insertions(+), 11 deletions(-) diff --git a/.ci/behavior-ownership/partition.v1.json b/.ci/behavior-ownership/partition.v1.json index 0299a7946..6aa075074 100644 --- a/.ci/behavior-ownership/partition.v1.json +++ b/.ci/behavior-ownership/partition.v1.json @@ -104,6 +104,10 @@ "group": "shared", "target": "backend/app/api/deps/rate_controls.py" }, + { + "group": "lifecycle", + "target": "backend/app/api/deps/task_batch_transitions.py" + }, { "group": "shared", "target": "backend/app/api/router.py" @@ -1548,6 +1552,10 @@ "group": "lifecycle", "target": "backend/app/modules/tasks/api/submitted_bundle.py" }, + { + "group": "lifecycle", + "target": "backend/app/modules/tasks/api/task_batch_transition.py" + }, { "group": "lifecycle", "target": "backend/app/modules/tasks/api/task_detail.py" @@ -1660,6 +1668,18 @@ "group": "lifecycle", "target": "backend/app/modules/tasks/submitted_bundle.py" }, + { + "group": "lifecycle", + "target": "backend/app/modules/tasks/task_batch_transition/models.py" + }, + { + "group": "lifecycle", + "target": "backend/app/modules/tasks/task_batch_transition_router.py" + }, + { + "group": "lifecycle", + "target": "backend/app/modules/tasks/task_batch_transitions.py" + }, { "group": "lifecycle", "target": "backend/app/modules/tasks/task_import_batches.py" @@ -1817,7 +1837,7 @@ "target": "backend/scripts/validate_test_lane_evidence.py" } ], - "authority_digest": "36fe9ccf77c46fdfed571b5a853cb6495c4a9a2f45d29d794b5840ce75270cb3", + "authority_digest": "05053353728987a58aaef286ffa68bdbb2ca94bba2f5dc3519423f95738f88b4", "protected_base_commit": "7676ce4347db0c9694962a9b587a20765e16eac6", "schema": "workstream.behavior-ownership-partition.v1" } diff --git a/.commitrail/changes/pilot02-bulk-transitions-cli.md b/.commitrail/changes/pilot02-bulk-transitions-cli.md index 53e509d95..5188fc9e7 100644 --- a/.commitrail/changes/pilot02-bulk-transitions-cli.md +++ b/.commitrail/changes/pilot02-bulk-transitions-cli.md @@ -75,6 +75,11 @@ Their current root transaction prevents composition across a complete batch. actual public native journeys/rollback/revocation/wait proof is `tests/tasks/test_task_batch_transitions.py`. These two modules require exact TASK lane/inventory registration after coordinated atomic/current-main union. +- Exact metadata hunks are two TASK catalogue registrations and their unchanged + exact-set assertion in `backend/tests/test_ci_lane_catalogue.py`, plus five + explicit `PILOT_02C_BULK_TRANSITION_TARGETS` paths and additive partition + regeneration. Preserve all atomic/source and ten-lane entries, retained + assignments, protected-base custody and zero private-edge growth. - Current TASK/AUTH/ART and CLI contracts, README, affected roadmap sections, this record, and exact coordinated owner/lane/selected-contract metadata. - Required schema/receipt changes only through the sole migration author after @@ -268,15 +273,17 @@ case-sensitive external IDs are preserved. One optional UTF-8 BOM is accepted. Inspection at atomic checkpoint `4a6d00fc8` identifies the reusable canonical SCREEN/RELEASE root and the native `TaskImportBatchMember` custody. This branch -is based on the unmerged atomic candidate; reconcile after its human merge or -use an explicitly coordinated stacked draft. Native schema/storage claims are +is reconciled onto the unmerged atomic candidate `91183adafec37e7ad7eda624ad3556d89dc54ce6`; +preserve its source/member/ten-lane metadata union and use only an explicitly +coordinated stacked draft before its human merge. Native schema/storage claims are pending the sole-author migrations and actual isolated PostgreSQL/MinIO drills. The offline converter is implemented with focused Go boundary checks and built CLI/server-parser proof for quoting/Unicode, exact JSON commitment, no-clobber, invalid CSV zero-output effects and 500/501 rows. This proof needs no token/API configuration and makes no database or source-storage claim. Canonical SCREEN/RELEASE extraction and the single native membership owner are implemented; -aggregate models/public composition remain pending. +aggregate models/public composition are also implemented, with native aggregate +DDL and actual public proof still pending. Source CLI uses separate existing declaration/upload/status routes and sends exact original JSON bytes. Go tests/vet/tidy-diff and built CLI CSV/source boundary plus retained HTTP/profile/project/guide declaration checks pass. The PUT transport @@ -296,16 +303,26 @@ pass. A native preflight proves retained single-Task SCREEN/RELEASE replay/guide lock parity, successor-guide/currentness behavior, foreign-root participant refusal, and two-Task late-failure rollback including actual successful AUTH decisions. Its database/role cleanup is complete. The initial run used the dirty -extraction atop the CLI checkpoint, so exact frozen-head replay is still required. +extraction atop the CLI checkpoint; the later exact `4400568` five-case native +replay above supplies the qualified frozen extraction proof. This uses existing schema through source0031 and canonical seeded project prerequisites; it proves Task/AUTH transactions, not new batch DDL, provider bytes, live setup inference or a complete 200-member public bulk journey. ## Reconciliation +The additive bulk metadata preserves every trusted assignment and the existing +protected base: 459 unique production targets validate, with exactly five new +bulk paths. The complete ten-lane inventory covers 523 test modules. Its exact +TASK owner assertion is extended by the two actual new proof modules; the focused +catalogue suite passes 46 cases in 7.79 seconds without weakening any gate. +Canonical TASK/CLI documentation distinguishes current-state transition replay +from original import replay and still marks native aggregate readiness pending. + - Current-source reconciliation: Preserve the atomic owner's import/status and source custody; shared-file regions require handoff before edits. - Next usable boundary: Complete the separate explicit bulk/CLI journey under issue 489; whole-issue completion requires every agreed acceptance criterion. -- Remaining risks: Aggregate receipt/currentness design and native concurrency - proof remain to be established before backend public composition. +- Remaining risks: The implemented aggregate receipt/currentness contract still + needs sole-author native closure DDL, direct-SQL refusal, public rollback and + concurrency proof, and measured 200/500 journeys before readiness. diff --git a/backend/scripts/behavior_ownership.py b/backend/scripts/behavior_ownership.py index 9279b97a6..db23e2e9e 100644 --- a/backend/scripts/behavior_ownership.py +++ b/backend/scripts/behavior_ownership.py @@ -640,6 +640,13 @@ "backend/app/modules/tasks/task_import_membership.py", "backend/app/modules/tasks/api/task_import_membership.py", }) +PILOT_02C_BULK_TRANSITION_TARGETS = frozenset({ + "backend/app/api/deps/task_batch_transitions.py", + "backend/app/modules/tasks/api/task_batch_transition.py", + "backend/app/modules/tasks/task_batch_transition/models.py", + "backend/app/modules/tasks/task_batch_transition_router.py", + "backend/app/modules/tasks/task_batch_transitions.py", +}) class BehaviorOwnershipError(RuntimeError): @@ -889,6 +896,7 @@ def _validate_additive_partition_transition( | PILOT_13_GUIDE_READ_TARGETS | PILOT_02A_IMPORT_SOURCE_TARGETS | PILOT_02B_ATOMIC_IMPORT_TARGETS + | PILOT_02C_BULK_TRANSITION_TARGETS ) expected_additions = (approved_additions & additions) - set(trusted_targets) if POL_03A_DECLARATIVE_MODEL_TARGET in additions: diff --git a/backend/scripts/test_lane_catalogue.py b/backend/scripts/test_lane_catalogue.py index bd799145e..87b7620fc 100644 --- a/backend/scripts/test_lane_catalogue.py +++ b/backend/scripts/test_lane_catalogue.py @@ -439,6 +439,8 @@ class TestLane: TASK_MODULES = ( + "tests/tasks/test_task_batch_transition_contract.py", + "tests/tasks/test_task_batch_transitions.py", "tests/tasks/test_task_import_contract.py", "tests/tasks/test_task_import_batch_contract.py", "tests/tasks/test_task_import_batch_bindings.py", diff --git a/backend/tests/test_ci_lane_catalogue.py b/backend/tests/test_ci_lane_catalogue.py index 99ee38392..57398b868 100644 --- a/backend/tests/test_ci_lane_catalogue.py +++ b/backend/tests/test_ci_lane_catalogue.py @@ -304,6 +304,8 @@ def test_measured_hotspots_have_explicit_semantic_owners() -> None: "tests/tasks/test_public_queues.py", "tests/tasks/test_locked_compensation.py", "tests/tasks/test_task_import_contract.py", + "tests/tasks/test_task_batch_transition_contract.py", + "tests/tasks/test_task_batch_transitions.py", "tests/tasks/test_task_import_batch_contract.py", "tests/tasks/test_task_import_batch_bindings.py", "tests/tasks/test_task_import_batches.py", diff --git a/docs/roadmap_status.md b/docs/roadmap_status.md index 5ec873859..860ada7b4 100644 --- a/docs/roadmap_status.md +++ b/docs/roadmap_status.md @@ -373,6 +373,12 @@ cannot be reused as post-submission review-gate evidence. See the automatic recovery, proven through public routes on PostgreSQL and MinIO. It creates no Tasks; issue 489 retains atomic DRAFT import, explicit batch screen/release and CLI conversion as future boundaries. + The [PILOT-02C bulk/CLI candidate](../.commitrail/changes/pilot02-bulk-transitions-cli.md) + implements caller-root canonical SCREEN/RELEASE composition and separate CLI + source/import/status/screen/release commands with local CSV-to-JSON conversion. + Focused model/contract and controlled CLI HTTP proof do not establish native + aggregate readiness: sole-author DDL, public PostgreSQL/MinIO 200/500-member + journeys and complete review/CI remain pending. Issue 489 stays open. [CLI manager task browsing](../.commitrail/initiatives/WS-CLI-001/WS-CLI-001-04.md) adds one-page task discovery and exact task detail through existing manager reads, with server-owned live authority and opaque continuation. diff --git a/docs/spec_chunk_4_task_queue_assignment.md b/docs/spec_chunk_4_task_queue_assignment.md index 7f06b1b0b..14fe536e0 100644 --- a/docs/spec_chunk_4_task_queue_assignment.md +++ b/docs/spec_chunk_4_task_queue_assignment.md @@ -124,12 +124,47 @@ conflicts even if both verified sources contain identical bytes. `GET /api/v1/projects/{project_id}/task-import-batches/{batch_id}` returns original creation facts separately from current states selected by ordered native -membership. Missing, foreign and revoked status access is concealed. Explicit -batch screen/release, normal locked-guide prerequisites and CLI/client CSV -conversion remain separate chunks. The bounded implementation and required -native proof are recorded in the +membership. Missing, foreign and revoked status access is concealed. The bounded +implementation and required native proof are recorded in the [atomic-import change record](../.commitrail/changes/pilot02-atomic-json-draft-import.md). +### Explicit whole-batch screening and release contract + +Separate `POST /api/v1/projects/{project_id}/task-import-batches/{batch_id}/screen` +and `/release` accept a reason and exactly one UUID `Idempotency-Key`. SCREEN +permits an omitted reason; RELEASE requires the normal nonblank decision reason. +Both operate on the complete immutable native import membership, preserving +original row order. Arbitrary `Task.import_batch_id` metadata cannot select +members. Each actual Task consumes fresh covered-PM authority through the normal +SCREEN/RELEASE owner, with all Task/assignment custody locked before authority +and guide/policy evaluation. One caller transaction commits every member's normal +transition, guide/policy locks, authority evidence and success receipt together; +a late failure rolls back the complete successful effect set. + +The compact response identifies project, native batch, operation and row count, +then returns every ordered Task ID, row index, poststate, locked guide version, +locked ContributionPolicyVersion ID and locked context hash. It repeats no Task +instructions. SCREEN returns `screening`; RELEASE returns `ready`. The server +records a separate aggregate retry namespace and retained canonical per-Task +keys; callers cannot choose those row keys or attach old standalone successes. + +Same-key replay reauthorizes every current member and recovers the exact recorded +response only while all Tasks retain their corresponding poststate, unassigned +custody and locked context. A partially advanced or assigned member refuses the +whole operation, as does a changed reason, selector or member set. This differs +from import replay, which recovers original DRAFT creation facts after Tasks +advance. An uncertain client write requires manual replay of the unchanged +project, batch, operation, reason and key; later authority or Task changes may +prevent recovery. There are no automatic write retries or per-row commits. + +The CLI keeps local CSV conversion, source declaration/upload/status, import, +batch status, screening and release explicit. UTF-8 quoted CSV and semicolon skill +fields produce validated canonical JSON; its exact bytes supply the uploaded +SHA/count. The server retains those JSON bytes, with no claim to retaining the +original CSV. Native aggregate DDL and the public 200/500-member journey remain +pending in the [bulk/CLI change record](../.commitrail/changes/pilot02-bulk-transitions-cli.md); +this contract does not establish delivered bulk readiness. + ## Transitions and locked lineage Stored task states use the canonical lowercase tokens: From 63c21b21aed7001c2912869a251425eee8a13c1b Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 14:29:31 +0100 Subject: [PATCH 028/283] Cover native aggregate closure and retained custody refusals --- .../changes/pilot02-bulk-transitions-cli.md | 6 ++ .../tasks/test_task_batch_transitions.py | 82 ++++++++++++++++++- 2 files changed, 87 insertions(+), 1 deletion(-) diff --git a/.commitrail/changes/pilot02-bulk-transitions-cli.md b/.commitrail/changes/pilot02-bulk-transitions-cli.md index 5188fc9e7..8e9d4e3a2 100644 --- a/.commitrail/changes/pilot02-bulk-transitions-cli.md +++ b/.commitrail/changes/pilot02-bulk-transitions-cli.md @@ -175,6 +175,12 @@ write, changed-input/partial-advance rollback, real grant-revocation denial and observed native holder/waiter before concurrent same-key recovery. They have not run because aggregate custody DDL is pending the sole migration author. No native aggregate, native 200/500 timing, full CI, or readiness claim is made here. +The native module also carries two commit-closure controls after genuine +canonical stages: omitting the final initial member INSERT and leaving the root +pending. Both require a complete successful-effect rollback. Direct SQL controls +cover UPDATE/DELETE and TRUNCATE refusal for each committed aggregate table, +unchanged retained facts and fresh-authorized exact replay afterward. They are +written controls awaiting installed schema, not executed native evidence. Peer review of aggregate checkpoint `42900b036` found that the new dependency projected immutable identity after the canonical Task dependency rolled back and diff --git a/backend/tests/tasks/test_task_batch_transitions.py b/backend/tests/tasks/test_task_batch_transitions.py index c63bb2179..6bb957a48 100644 --- a/backend/tests/tasks/test_task_batch_transitions.py +++ b/backend/tests/tasks/test_task_batch_transitions.py @@ -6,8 +6,9 @@ from uuid import UUID, uuid4 import pytest -from sqlalchemy import func, select, text +from sqlalchemy import event, func, select, text from sqlalchemy.exc import DBAPIError +from sqlalchemy.orm import Session from app.core.hashing import canonical_json_hash from app.core.identifiers import new_record_id @@ -285,3 +286,82 @@ async def test_sql_cannot_attach_old_standalone_successes_to_a_new_aggregate(imp await session.flush() assert getattr(caught.value.orig, "sqlstate", None) == "23514" assert await _success_facts(project) == before + + +@pytest.mark.parametrize("corruption", ["missing_member", "pending_root"]) +async def test_native_commit_refuses_incomplete_aggregate_after_real_canonical_stages( + import_source_client, corruption, +): + """Initial custody corruption must roll back both actual canonical Task writes.""" + client = import_source_client + project, batch = await _import(client) + before = await _success_facts(project) + changed = False + + def corrupt_before_flush(session, flush_context, instances): + nonlocal changed + if changed: + return + if corruption == "missing_member": + for row in list(session.new): + if isinstance(row, TaskBatchTransitionMember) and row.row_index == 1: + # Remove the initial INSERT; an UPDATE/DELETE guard cannot + # mask missing complete-member commit closure. + session.expunge(row) + changed = True + else: + for row in list(session.dirty): + if isinstance(row, TaskBatchTransitionReceipt) and row.status == "committed": + # Preserve the valid pending declaration without writing an + # invalid state shape. Deferred closure must reject commit. + session.expire(row) + changed = True + + event.listen(Session, "before_flush", corrupt_before_flush) + try: + refused = await client.post( + _path(project, batch, "screen"), headers=auth_headers(), + json={"reason": "Complete canonical stages before native refusal"}, + ) + assert changed, "the intended final aggregate INSERT/completion was not reached" + assert refused.status_code == 503 and refused.json()["error"]["retryable"] is True, refused.text + assert await _success_facts(project) == before + finally: + event.remove(Session, "before_flush", corrupt_before_flush) + + +@pytest.mark.parametrize("table", ["task_batch_transition_receipts", "task_batch_transition_members"]) +@pytest.mark.parametrize("operation", ["update", "delete", "truncate"]) +async def test_committed_aggregate_custody_refuses_direct_sql_mutation( + import_source_client, table, operation, +): + """Retained aggregate facts refuse mutation and each table owns a TRUNCATE guard.""" + client = import_source_client + project, batch = await _import(client) + key, payload = auth_headers(), {"reason": "Immutable aggregate success"} + result = await client.post(_path(project, batch, "screen"), headers=key, json=payload) + assert result.status_code == 200, result.text + async with db_session.get_session_factory()() as session, session.begin(): + snapshot = text(f"select to_jsonb(t) from {table} t order by id") + before = list(await session.scalars(snapshot)) + assert before + if operation == "truncate": + assert await session.scalar(text( + "select count(*) from pg_trigger where tgrelid=cast(:table as regclass) " + "and not tgisinternal and (tgtype & 32)=32 and (tgtype & 1)=0 and tgenabled='O'" + ), {"table": table}) == 1, "each aggregate table needs its own enabled statement guard" + update = { + "task_batch_transition_receipts": "reason='changed retained decision'", + "task_batch_transition_members": "task_idempotency_key=:new_key", + }[table] + statement = { + "update": f"update {table} set {update}", + "delete": f"delete from {table}", + "truncate": f"truncate {table} cascade", + }[operation] + with pytest.raises(DBAPIError): + async with session.begin_nested(): + await session.execute(text(statement), {"new_key": uuid4()}) + assert list(await session.scalars(snapshot)) == before + replay = await client.post(_path(project, batch, "screen"), headers=key, json=payload) + assert replay.status_code == 200 and replay.json() == result.json(), replay.text From f2c904edcc3b0abda65c3b81f687a219318ac635 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 14:49:14 +0100 Subject: [PATCH 029/283] test(checkers): register default material consumers --- .commitrail/changes/pilot04-workstream-default-checker.md | 4 ++++ backend/tests/test_artifact_architecture.py | 2 ++ 2 files changed, 6 insertions(+) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index ad6b408d9..308cbf903 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -35,6 +35,9 @@ one clean cutover. The merged external runtime is intentionally unselected. material-read capability. - Focused tests under `backend/tests/checkers/default/` for every positive, negative, infrastructure and warning boundary. +- The existing checker custody-consumer inventory in + `backend/tests/test_artifact_architecture.py` for the two new same-owner + materialization-contract consumers. - The minimum test-lane and behavior-owner metadata needed to run the new tests and assign the two new modules exactly once. - `docs/architecture_checker_framework.md` and the exact PILOT-04 checker rows @@ -124,6 +127,7 @@ introduced here. | Default behavior and actual ART callback | `pytest -q tests/checkers/default/test_contract.py tests/checkers/default/test_execution.py` | 25 passed | Component remains deliberately unselected | | Test-lane ownership and focused behavior | `pytest -q tests/checkers/default/test_contract.py tests/checkers/default/test_execution.py tests/test_ci_lane_catalogue.py` | 71 passed | Hosted full-suite evidence follows in the draft PR | | Public module boundary | `pytest -q tests/architecture/test_module_boundaries.py::test_repository_matches_the_protected_module_boundary tests/architecture/test_module_boundaries.py::test_art_implements_checker_consumer_ports_without_a_public_cycle` | 2 passed | Existing catalogues retain their recorded debt until cutover | +| Closed materialization consumer inventory | `pytest -q tests/test_artifact_architecture.py::test_checker_custody_ports_have_exact_owner_and_art_consumers` | Passed | The inventory still rejects every unregistered owner or ART consumer | | Behavior-owner partition | `python -m scripts.behavior_ownership validate` | Passed | Hosted evidence still validates the exact merge tree | ## Reconciliation diff --git a/backend/tests/test_artifact_architecture.py b/backend/tests/test_artifact_architecture.py index 9f5783cc9..e6e4b35ca 100644 --- a/backend/tests/test_artifact_architecture.py +++ b/backend/tests/test_artifact_architecture.py @@ -649,6 +649,8 @@ def test_checker_custody_ports_have_exact_owner_and_art_consumers() -> None: "app/adapters/artifacts/__init__.py", "app/modules/artifacts/post_submit_materialization.py", "app/modules/artifacts/post_submit_selection.py", + "app/modules/checkers/api/default_checker.py", + "app/modules/checkers/default_checker.py", "app/modules/checkers/execution.py", }, } From dd7957e2a9d237948dac912c9082f7c413a100ca Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 15:49:46 +0100 Subject: [PATCH 030/283] Bind selected MCP union snapshot to reconciled backend head --- mcp_server/contracts/authorization_context_get.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mcp_server/contracts/authorization_context_get.json b/mcp_server/contracts/authorization_context_get.json index 1032f09ca..434d62b14 100644 --- a/mcp_server/contracts/authorization_context_get.json +++ b/mcp_server/contracts/authorization_context_get.json @@ -543,7 +543,7 @@ "schema_version": 1, "source": { "action_id": "actor.authorization_context.read", - "backend_git_sha": "3eb281df518ed0d7f12a6e8eaa4ada29e7e15c87", + "backend_git_sha": "b6a56caa19d45c0850aba4241b3f3f626da244d1", "method": "GET", "openapi_version": "3.1.0", "path": "/api/v1/actors/me/authorization-context" From 253b4fcb59baa2ba9e74025f8a6e833d76394abf Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 15:53:35 +0100 Subject: [PATCH 031/283] Pin bulk partial-advance refusal to canonical replay conflict --- backend/tests/tasks/test_task_batch_transitions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/tests/tasks/test_task_batch_transitions.py b/backend/tests/tasks/test_task_batch_transitions.py index 6bb957a48..471db584c 100644 --- a/backend/tests/tasks/test_task_batch_transitions.py +++ b/backend/tests/tasks/test_task_batch_transitions.py @@ -151,7 +151,7 @@ async def fail_after_second_write(commands, prepared, decision): assert advanced.status_code == 200, advanced.text before = await _success_facts(project) replay = await client.post(_path(project, batch, "screen"), headers=key, json=payload) - assert replay.status_code in {403, 409}, replay.text + assert replay.status_code == 409 and replay.json()["error"]["code"] == "task_replay_state_changed", replay.text assert await _success_facts(project) == before From a3fd2bbff1de4808dbf64835640a1c3fec8230ff Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 16:02:00 +0100 Subject: [PATCH 032/283] feat: install atomic task import custody --- backend/alembic/env.py | 3 +- .../versions/0034_task_import_batches.py | 538 ++++++++++++++++++ backend/tests/conftest.py | 8 +- backend/tests/test_alembic.py | 2 +- 4 files changed, 548 insertions(+), 3 deletions(-) create mode 100644 backend/alembic/versions/0034_task_import_batches.py diff --git a/backend/alembic/env.py b/backend/alembic/env.py index 59e3aee9c..524bd5a04 100644 --- a/backend/alembic/env.py +++ b/backend/alembic/env.py @@ -21,7 +21,7 @@ target_metadata = Base.metadata _BASELINE_REVISION = "0001_uuid7_v01" -_CURRENT_HEAD_REVISION = "0033_contribution_reads" +_CURRENT_HEAD_REVISION = "0034_task_import_batches" _RECREATE_GUIDANCE = ( "Workstream v0.1 requires a fresh database; recreate this database before " "running the 0001_uuid7_v01 migration" @@ -86,6 +86,7 @@ def do_run_migrations(connection: Connection) -> None: ("0030_routing_outcomes",), ("0031_task_import_source",), ("0032_checker_remediation",), + ("0033_contribution_reads",), (_CURRENT_HEAD_REVISION,), ): raise RuntimeError(_RECREATE_GUIDANCE) diff --git a/backend/alembic/versions/0034_task_import_batches.py b/backend/alembic/versions/0034_task_import_batches.py new file mode 100644 index 000000000..fb8a2820a --- /dev/null +++ b/backend/alembic/versions/0034_task_import_batches.py @@ -0,0 +1,538 @@ +"""Install atomic JSON-to-DRAFT Task import custody.""" + +from alembic import op +import sqlalchemy as sa +from sqlalchemy.dialects import postgresql + + +revision = "0034_task_import_batches" +down_revision = "0033_contribution_reads" +branch_labels = None +depends_on = None + + +_TABLES = ( + "task_import_batches", + "task_import_batch_members", + "task_import_batch_command_receipts", +) + + +def _definition(table: str, name: str) -> str: + return op.get_bind().execute(sa.text( + "select pg_catalog.pg_get_constraintdef(oid) from pg_catalog.pg_constraint " + "where conrelid=cast(:table as regclass) and conname=:name" + ), {"table": f"public.{table}", "name": name}).scalar_one() + + +def _replace_constraint(table: str, name: str, definition: str) -> None: + op.execute(f"alter table public.{table} drop constraint {name}") + op.execute(f"alter table public.{table} add constraint {name} {definition}") + + +def _replace_function(signature: str, old: str, new: str) -> None: + body = op.get_bind().execute(sa.text( + "select pg_catalog.pg_get_functiondef(cast(:signature as regprocedure))" + ), {"signature": signature}).scalar_one() + if body.count(old) != 1: + raise RuntimeError(f"atomic task import function shape changed: {signature}") + op.execute(body.replace(old, new)) + + +def _extend_audit_contract() -> None: + name = "ck_audit_events_authorization_action_evidence" + definition = _definition("audit_events", name) + anchor = ( + "(((action_id)::text = 'project.task.create'::text) AND " + "((permission_id)::text = 'project.task.manage'::text))" + ) + additions = " OR ".join( + "(((action_id)::text = " + f"'{action}'::text) AND ((permission_id)::text = 'project.task.manage'::text))" + for action in ("project.task.import", "project.task.import_batch.read") + ) + if definition.count(anchor) != 2 or "project.task.import_batch.read" in definition: + raise RuntimeError("atomic task import audit action constraint shape changed") + _replace_constraint("audit_events", name, definition.replace(anchor, anchor + " OR " + additions)) + + name = "ck_audit_events_authority_privacy_bounds" + definition = _definition("audit_events", name) + if "'task_import_batch'::character varying" in definition: + raise RuntimeError("atomic task import audit target constraint already changed") + resource_start = definition.index("resource_type IS NULL") + target_start = definition.index("target_ref_kind IS NULL") + addition = "('task_import_batch'::character varying)::text, " + for start in sorted((resource_start, target_start), reverse=True): + index = definition.index("ARRAY[", start) + len("ARRAY[") + definition = definition[:index] + addition + definition[index:] + _replace_constraint("audit_events", name, definition) + + +def _alter_tasks() -> None: + duplicate = op.get_bind().execute(sa.text( + "select project_id, external_task_id, count(*) from public.workstream_tasks " + "where external_task_id is not null group by project_id, external_task_id " + "having count(*) > 1 order by project_id, external_task_id limit 1" + )).first() + if duplicate is not None: + raise RuntimeError( + "cannot install atomic task import uniqueness with retained duplicate " + f"project/external_task_id facts: {duplicate[0]}/{duplicate[1]}" + ) + op.alter_column( + "workstream_tasks", "difficulty", schema="public", + existing_type=sa.String(50), type_=sa.String(80), existing_nullable=True, + ) + op.create_unique_constraint( + "uq_workstream_tasks_project_external_id", + "workstream_tasks", ["project_id", "external_task_id"], schema="public", + ) + _replace_function( + "public.guard_task_management_audit()", + "payload->>'source_type' in ('manual','markdown_import','csv_import')", + "payload->>'source_type' in ('manual','markdown_import','csv_import','json_import')", + ) + + +def _create_tables() -> None: + op.create_table( + "task_import_batches", + sa.Column("id", sa.Uuid(), nullable=False), + sa.Column("project_id", sa.Uuid(), nullable=False), + sa.Column("source_id", sa.Uuid(), nullable=False), + sa.Column("creation_command_receipt_id", sa.Uuid(), nullable=False), + sa.Column("sha256", sa.String(71), nullable=False), + sa.Column("byte_count", sa.BigInteger(), nullable=False), + sa.Column("media_type", sa.String(255), nullable=False), + sa.Column("schema_version", sa.String(80), nullable=False), + sa.Column("mapping_version", sa.String(80), nullable=False), + sa.Column("manifest_digest", sa.String(71), nullable=False), + sa.Column("row_count", sa.Integer(), nullable=False), + sa.Column("metadata_label", sa.String(255), nullable=True), + sa.Column("actor_profile_id", sa.Uuid(), nullable=False), + sa.Column("identity_link_id", sa.Uuid(), nullable=False), + sa.Column("authorization_decision_id", sa.Uuid(), nullable=True), + sa.Column("status", sa.String(16), nullable=False), + sa.Column("response", postgresql.JSONB(), nullable=True), + sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.text("now()"), nullable=False), + sa.Column("committed_at", sa.DateTime(timezone=True), nullable=True), + sa.Column("source_operation_identity", sa.String(71), nullable=False), + sa.Column("put_attempt_id", sa.Uuid(), nullable=True), + sa.Column("content_id", sa.Uuid(), nullable=True), + sa.Column("replica_id", sa.Uuid(), nullable=True), + sa.Column("verification_job_id", sa.Uuid(), nullable=True), + sa.Column("verification_generation", sa.BigInteger(), nullable=True), + sa.Column("verification_receipt_id", sa.Uuid(), nullable=True), + sa.Column("operation_receipt_id", sa.Uuid(), nullable=True), + sa.Column("observation_receipt_id", sa.Uuid(), nullable=True), + sa.PrimaryKeyConstraint("id", name="pk_task_import_batches"), + sa.UniqueConstraint("project_id", "sha256", "byte_count", name="uq_task_import_batch_file"), + sa.UniqueConstraint("id", "project_id", name="uq_task_import_batch_project"), + sa.UniqueConstraint("creation_command_receipt_id", name="uq_task_import_batch_creation_command"), + sa.ForeignKeyConstraint(["project_id"], ["public.projects.id"], ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), + sa.ForeignKeyConstraint(["actor_profile_id"], ["public.actor_profiles.id"], ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), + sa.ForeignKeyConstraint(["identity_link_id", "actor_profile_id"], ["public.actor_identity_links.id", "public.actor_identity_links.actor_profile_id"], name="fk_task_import_batch_actor_link", ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), + sa.ForeignKeyConstraint(["authorization_decision_id"], ["public.audit_events.id"], ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), + sa.ForeignKeyConstraint(["source_id", "project_id", "sha256", "byte_count", "media_type"], ["public.artifact_task_import_sources.id", "public.artifact_task_import_sources.project_id", "public.artifact_task_import_sources.sha256", "public.artifact_task_import_sources.byte_count", "public.artifact_task_import_sources.media_type"], name="fk_task_import_batch_source", ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), + sa.ForeignKeyConstraint(["put_attempt_id"], ["public.artifact_put_attempts.id"], ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), + sa.ForeignKeyConstraint(["content_id"], ["public.artifact_contents.id"], ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), + sa.ForeignKeyConstraint(["replica_id"], ["public.artifact_replicas.id"], ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), + sa.ForeignKeyConstraint(["verification_job_id"], ["public.artifact_verification_jobs.id"], ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), + sa.ForeignKeyConstraint(["verification_receipt_id"], ["public.artifact_verification_receipts.id"], ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), + sa.ForeignKeyConstraint(["operation_receipt_id"], ["public.artifact_operation_receipts.id"], ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), + sa.ForeignKeyConstraint(["observation_receipt_id"], ["public.artifact_put_observation_receipts.id"], ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), + sa.CheckConstraint("(get_byte(uuid_send(id),6)>>4)=7 and (get_byte(uuid_send(id),8)&192)=128", name="ck_task_import_batches_id_uuid7"), + sa.CheckConstraint("sha256 ~ '^sha256:[0-9a-f]{64}$'", name="ck_task_import_batches_source_hash"), + sa.CheckConstraint("source_operation_identity ~ '^sha256:[0-9a-f]{64}$'", name="ck_task_import_batches_source_operation"), + sa.CheckConstraint("manifest_digest ~ '^sha256:[0-9a-f]{64}$'", name="ck_task_import_batches_manifest_hash"), + sa.CheckConstraint("byte_count between 1 and 8388608 and row_count between 1 and 500", name="ck_task_import_batches_bounds"), + sa.CheckConstraint("media_type='application/json' and schema_version='workstream.task_import.v1' and mapping_version='workstream.task_import.draft_mapping.v1'", name="ck_task_import_batches_format"), + sa.CheckConstraint("(status='pending' and response is null and authorization_decision_id is null and committed_at is null) or (status='committed' and response is not null and jsonb_typeof(response::jsonb)='object' and authorization_decision_id is not null and committed_at is not null and put_attempt_id is not null and content_id is not null and replica_id is not null and verification_job_id is not null and verification_generation is not null and verification_generation>0 and verification_receipt_id is not null and ((operation_receipt_id is not null and observation_receipt_id is null) or (operation_receipt_id is null and observation_receipt_id is not null)))", name="ck_task_import_batches_state_shape"), + schema="public", + ) + op.create_table( + "task_import_batch_command_receipts", + sa.Column("id", sa.Uuid(), nullable=False), + sa.Column("actor_profile_id", sa.Uuid(), nullable=False), + sa.Column("identity_link_id", sa.Uuid(), nullable=False), + sa.Column("action_id", sa.String(160), nullable=False), + sa.Column("idempotency_key", sa.Uuid(), nullable=False), + sa.Column("request_digest", sa.String(71), nullable=False), + sa.Column("project_id", sa.Uuid(), nullable=False), + sa.Column("source_id", sa.Uuid(), nullable=False), + sa.Column("sha256", sa.String(71), nullable=False), + sa.Column("byte_count", sa.BigInteger(), nullable=False), + sa.Column("media_type", sa.String(255), nullable=False), + sa.Column("batch_id", sa.Uuid(), nullable=True), + sa.Column("authorization_decision_id", sa.Uuid(), nullable=True), + sa.Column("status", sa.String(16), nullable=False), + sa.Column("response", postgresql.JSONB(), nullable=True), + sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.text("now()"), nullable=False), + sa.Column("committed_at", sa.DateTime(timezone=True), nullable=True), + sa.Column("source_operation_identity", sa.String(71), nullable=False), + sa.Column("put_attempt_id", sa.Uuid(), nullable=True), + sa.Column("content_id", sa.Uuid(), nullable=True), + sa.Column("replica_id", sa.Uuid(), nullable=True), + sa.Column("verification_job_id", sa.Uuid(), nullable=True), + sa.Column("verification_generation", sa.BigInteger(), nullable=True), + sa.Column("verification_receipt_id", sa.Uuid(), nullable=True), + sa.Column("operation_receipt_id", sa.Uuid(), nullable=True), + sa.Column("observation_receipt_id", sa.Uuid(), nullable=True), + sa.PrimaryKeyConstraint("id", name="pk_task_import_batch_command_receipts"), + sa.UniqueConstraint("actor_profile_id", "action_id", "idempotency_key", name="uq_task_import_command_namespace"), + sa.ForeignKeyConstraint(["project_id"], ["public.projects.id"], ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), + sa.ForeignKeyConstraint(["actor_profile_id"], ["public.actor_profiles.id"], ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), + sa.ForeignKeyConstraint(["identity_link_id", "actor_profile_id"], ["public.actor_identity_links.id", "public.actor_identity_links.actor_profile_id"], name="fk_task_import_command_actor_link", ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), + sa.ForeignKeyConstraint(["authorization_decision_id"], ["public.audit_events.id"], ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), + sa.ForeignKeyConstraint(["source_id", "project_id", "sha256", "byte_count", "media_type"], ["public.artifact_task_import_sources.id", "public.artifact_task_import_sources.project_id", "public.artifact_task_import_sources.sha256", "public.artifact_task_import_sources.byte_count", "public.artifact_task_import_sources.media_type"], name="fk_task_import_command_source", ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), + sa.ForeignKeyConstraint(["put_attempt_id"], ["public.artifact_put_attempts.id"], ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), + sa.ForeignKeyConstraint(["content_id"], ["public.artifact_contents.id"], ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), + sa.ForeignKeyConstraint(["replica_id"], ["public.artifact_replicas.id"], ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), + sa.ForeignKeyConstraint(["verification_job_id"], ["public.artifact_verification_jobs.id"], ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), + sa.ForeignKeyConstraint(["verification_receipt_id"], ["public.artifact_verification_receipts.id"], ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), + sa.ForeignKeyConstraint(["operation_receipt_id"], ["public.artifact_operation_receipts.id"], ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), + sa.ForeignKeyConstraint(["observation_receipt_id"], ["public.artifact_put_observation_receipts.id"], ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), + sa.CheckConstraint("(get_byte(uuid_send(id),6)>>4)=7 and (get_byte(uuid_send(id),8)&192)=128", name="ck_task_import_batch_command_receipts_id_uuid7"), + sa.CheckConstraint("action_id='project.task.import'", name="ck_task_import_batch_command_receipts_action"), + sa.CheckConstraint("request_digest ~ '^sha256:[0-9a-f]{64}$'", name="ck_task_import_batch_command_receipts_request_hash"), + sa.CheckConstraint("sha256 ~ '^sha256:[0-9a-f]{64}$' and source_operation_identity ~ '^sha256:[0-9a-f]{64}$'", name="ck_task_import_batch_command_receipts_source_hash"), + sa.CheckConstraint("byte_count between 1 and 8388608 and media_type='application/json'", name="ck_task_import_batch_command_receipts_bounds"), + sa.CheckConstraint("(status='pending' and response is null and authorization_decision_id is null and committed_at is null) or (status='committed' and batch_id is not null and response is not null and jsonb_typeof(response::jsonb)='object' and authorization_decision_id is not null and committed_at is not null and put_attempt_id is not null and content_id is not null and replica_id is not null and verification_job_id is not null and verification_generation is not null and verification_generation>0 and verification_receipt_id is not null and ((operation_receipt_id is not null and observation_receipt_id is null) or (operation_receipt_id is null and observation_receipt_id is not null)))", name="ck_task_import_batch_command_receipts_state_shape"), + schema="public", + ) + op.create_foreign_key( + "fk_task_import_batch_creation_command", "task_import_batches", + "task_import_batch_command_receipts", ["creation_command_receipt_id"], ["id"], + source_schema="public", referent_schema="public", ondelete="RESTRICT", + deferrable=True, initially="DEFERRED", + ) + op.create_foreign_key( + "fk_task_import_command_batch", "task_import_batch_command_receipts", + "task_import_batches", ["batch_id", "project_id"], ["id", "project_id"], + source_schema="public", referent_schema="public", ondelete="RESTRICT", + deferrable=True, initially="DEFERRED", + ) + op.create_table( + "task_import_batch_members", + sa.Column("id", sa.Uuid(), nullable=False), + sa.Column("batch_id", sa.Uuid(), nullable=False), + sa.Column("project_id", sa.Uuid(), nullable=False), + sa.Column("task_id", sa.Uuid(), nullable=False), + sa.Column("row_index", sa.Integer(), nullable=False), + sa.Column("external_task_id", sa.String(200), nullable=False), + sa.Column("row_digest", sa.String(71), nullable=False), + sa.Column("create_idempotency_key", sa.Uuid(), nullable=False), + sa.Column("task_command_receipt_id", sa.Uuid(), nullable=False), + sa.Column("authorization_decision_id", sa.Uuid(), nullable=False), + sa.Column("response", postgresql.JSONB(), nullable=False), + sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.text("now()"), nullable=False), + sa.PrimaryKeyConstraint("id", name="pk_task_import_batch_members"), + sa.UniqueConstraint("task_id", name="uq_task_import_member_task"), + sa.UniqueConstraint("batch_id", "row_index", name="uq_task_import_member_row"), + sa.UniqueConstraint("project_id", "external_task_id", name="uq_task_import_member_external_id"), + sa.UniqueConstraint("task_command_receipt_id", name="uq_task_import_member_creation"), + sa.ForeignKeyConstraint(["batch_id", "project_id"], ["public.task_import_batches.id", "public.task_import_batches.project_id"], name="fk_task_import_member_batch", ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), + sa.ForeignKeyConstraint(["task_id", "project_id"], ["public.workstream_tasks.id", "public.workstream_tasks.project_id"], name="fk_task_import_member_task", ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), + sa.ForeignKeyConstraint(["task_command_receipt_id"], ["public.task_command_receipts.id"], ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), + sa.ForeignKeyConstraint(["authorization_decision_id"], ["public.audit_events.id"], ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), + sa.CheckConstraint("(get_byte(uuid_send(id),6)>>4)=7 and (get_byte(uuid_send(id),8)&192)=128", name="ck_task_import_batch_members_id_uuid7"), + sa.CheckConstraint("row_index between 0 and 499", name="ck_task_import_batch_members_row_index"), + sa.CheckConstraint("row_digest ~ '^sha256:[0-9a-f]{64}$'", name="ck_task_import_batch_members_row_hash"), + sa.CheckConstraint("jsonb_typeof(response::jsonb)='object'", name="ck_task_import_batch_members_response_shape"), + schema="public", + ) + + +def _create_custody_functions() -> None: + op.execute(r""" +create function public.task_import_binding_valid( + source_id uuid, project_id uuid, sha256 text, byte_count bigint, operation_identity text, + put_attempt_id uuid, content_id uuid, replica_id uuid, verification_job_id uuid, + verification_generation bigint, verification_receipt_id uuid, + operation_receipt_id uuid, observation_receipt_id uuid +) returns boolean language sql stable set search_path=pg_catalog,public,pg_temp as $$ + select exists( + select 1 from public.artifact_task_import_sources s + join public.artifact_put_attempts a on a.id=put_attempt_id and a.task_import_source_id=s.id + join public.artifact_replicas r on r.id=replica_id and r.id=a.replica_id + join public.artifact_contents c on c.id=content_id and c.id=r.content_id + join public.artifact_verification_jobs j on j.id=verification_job_id + and j.originating_put_attempt_id=a.id and j.replica_id=r.id + join public.artifact_verification_receipts v on v.id=verification_receipt_id + and v.verification_job_id=j.id and v.outcome='verified' + where s.id=source_id and s.project_id=project_id and s.sha256=sha256 + and s.byte_count=byte_count and s.operation_identity=operation_identity + and a.producer_request_type='task_import_source' and a.logical_role='task_import_source' + and a.project_id=s.project_id and a.sha256=s.sha256 and a.byte_count=s.byte_count + and a.media_type=s.media_type and c.sha256=s.sha256 and c.byte_count=s.byte_count + and r.storage_namespace_id=a.storage_namespace_id + and r.namespace_fingerprint=a.namespace_fingerprint + and v.execution_generation=verification_generation + and v.observed_sha256=s.sha256 and v.observed_byte_count=s.byte_count + and ((operation_receipt_id is not null and observation_receipt_id is null and exists( + select 1 from public.artifact_operation_receipts o where o.id=operation_receipt_id + and o.put_attempt_id=a.id and o.replica_id=r.id and o.request_digest=a.request_digest + and o.provider_object_ref=r.provider_object_ref and o.logical_role='task_import_source' + and o.outcome='stored_pending_verification')) or + (operation_receipt_id is null and observation_receipt_id is not null and exists( + select 1 from public.artifact_put_observation_receipts o where o.id=observation_receipt_id + and o.put_attempt_id=a.id and o.outcome='observed_confirmed' + and o.observed_sha256=s.sha256 and o.expected_sha256=s.sha256 + and o.observed_byte_count=s.byte_count and o.expected_byte_count=s.byte_count))) + ) +$$ +""") + op.execute(r""" +create function public.task_import_binding_digest( + source_id uuid, project_id uuid, sha256 text, byte_count bigint, operation_identity text, + put_attempt_id uuid, content_id uuid, replica_id uuid, verification_job_id uuid, + verification_generation bigint, verification_receipt_id uuid, + operation_receipt_id uuid, observation_receipt_id uuid +) returns text language sql immutable set search_path=pg_catalog,public,pg_temp as $$ + select public.external_checker_registry_digest(pg_catalog.jsonb_build_object( + 'source_id',source_id,'project_id',project_id,'sha256',sha256,'byte_count',byte_count, + 'operation_identity',operation_identity,'put_attempt_id',put_attempt_id,'content_id',content_id, + 'replica_id',replica_id,'verification_job_id',verification_job_id, + 'verification_generation',verification_generation,'verification_receipt_id',verification_receipt_id, + 'operation_receipt_id',operation_receipt_id,'observation_receipt_id',observation_receipt_id)) +$$ +""") + op.execute(r""" +create function public.task_import_authority_valid( + decision_id uuid, action text, batch_id uuid, project_id uuid, source_id uuid, + actor_id uuid, link_id uuid, sha256 text, byte_count bigint, row_count integer, + manifest_digest text, source_binding_digest text, idempotency_key uuid, request_digest text +) returns boolean language sql stable set search_path=pg_catalog,public,pg_temp as $$ + select exists(select 1 from public.audit_events a where a.id=decision_id + and a.event_domain='authority' and a.event_type='SensitiveAuthorizationAllowed' + and a.actor_ref_kind='actor_profile' and a.actor_id=actor_id::text + and a.project_id=project_id and a.action_id=action and a.permission_id='project.task.manage' + and a.resource_type='task_import_batch' and a.resource_id=batch_id::text + and a.target_ref_kind='task_import_batch' and a.target_ref_id=batch_id::text + and a.denial_code is null and a.after_facts::jsonb=pg_catalog.jsonb_build_object( + 'allowed',true,'resource_context_digest',public.external_checker_registry_digest( + pg_catalog.jsonb_build_object('resource_context',pg_catalog.jsonb_build_object( + 'resource_type','task_import_batch','resource_id',batch_id,'scope_project_id',project_id, + 'source_id',source_id,'actor_profile_id',actor_id,'identity_link_id',link_id, + 'sha256',sha256,'byte_count',byte_count,'row_count',row_count, + 'manifest_digest',manifest_digest,'source_binding_digest',source_binding_digest, + 'idempotency_key',idempotency_key,'request_digest',request_digest))))) +$$ +""") + op.execute(r""" +create function public.validate_task_import_batch_custody(target uuid) returns void +language plpgsql set search_path=pg_catalog,public,pg_temp as $$ +declare b public.task_import_batches%rowtype; cmd public.task_import_batch_command_receipts%rowtype; + members integer; manifest jsonb; binding_digest text; +begin + select * into b from public.task_import_batches where id=target; + if not found then return; end if; + if b.status<>'committed' then raise exception 'task import batch cannot remain pending' using errcode='23514'; end if; + select * into cmd from public.task_import_batch_command_receipts where id=b.creation_command_receipt_id; + binding_digest:=public.task_import_binding_digest(b.source_id,b.project_id,b.sha256,b.byte_count, + b.source_operation_identity,b.put_attempt_id,b.content_id,b.replica_id,b.verification_job_id, + b.verification_generation,b.verification_receipt_id,b.operation_receipt_id,b.observation_receipt_id); + if not public.task_import_binding_valid(b.source_id,b.project_id,b.sha256,b.byte_count, + b.source_operation_identity,b.put_attempt_id,b.content_id,b.replica_id,b.verification_job_id, + b.verification_generation,b.verification_receipt_id,b.operation_receipt_id,b.observation_receipt_id) + or cmd.id is null or cmd.batch_id is distinct from b.id or cmd.project_id is distinct from b.project_id + or cmd.actor_profile_id is distinct from b.actor_profile_id or cmd.identity_link_id is distinct from b.identity_link_id + or cmd.source_id is distinct from b.source_id or cmd.response::jsonb is distinct from b.response::jsonb + or not public.task_import_authority_valid(b.authorization_decision_id,'project.task.import',b.id,b.project_id, + b.source_id,b.actor_profile_id,b.identity_link_id,b.sha256,b.byte_count,b.row_count,b.manifest_digest, + binding_digest,cmd.idempotency_key,cmd.request_digest) then + raise exception 'task import batch original custody invalid' using errcode='23514'; + end if; + select count(*) into members from public.task_import_batch_members m where m.batch_id=b.id; + if members<>b.row_count or exists( + select 1 from generate_series(0,b.row_count-1) i where not exists( + select 1 from public.task_import_batch_members m where m.batch_id=b.id and m.row_index=i)) then + raise exception 'task import batch membership incomplete' using errcode='23514'; + end if; + if b.response::jsonb->>'batch_id' is distinct from b.id::text + or b.response::jsonb->>'project_id' is distinct from b.project_id::text + or b.response::jsonb->>'source_id' is distinct from b.source_id::text + or b.response::jsonb->>'sha256' is distinct from b.sha256 + or (b.response::jsonb->>'byte_count')::bigint is distinct from b.byte_count + or (b.response::jsonb->>'row_count')::integer is distinct from b.row_count + or b.response::jsonb->>'schema_version' is distinct from b.schema_version + or b.response::jsonb->>'mapping_version' is distinct from b.mapping_version + or b.response::jsonb->'label' is distinct from to_jsonb(b.metadata_label) + or pg_catalog.jsonb_array_length(b.response::jsonb->'tasks')<>b.row_count then + raise exception 'task import batch response custody invalid' using errcode='23514'; + end if; + if exists(select 1 from public.task_import_batch_members m + join public.workstream_tasks t on t.id=m.task_id and t.project_id=m.project_id + join public.task_command_receipts r on r.id=m.task_command_receipt_id + where m.batch_id=b.id and ( + m.project_id is distinct from b.project_id or m.external_task_id is distinct from t.external_task_id + or t.source_type<>'json_import' or t.source_ref is distinct from 'task-import-source:'||b.source_id::text + or t.source_payload_hash is distinct from b.sha256 or t.import_batch_id is distinct from b.id::text + or t.status<>'draft' or t.created_by is distinct from b.actor_profile_id::text + or r.status<>'committed' or r.action_id<>'project.task.create' or r.task_id is distinct from m.task_id + or r.actor_profile_id is distinct from b.actor_profile_id or r.idempotency_key is distinct from m.create_idempotency_key + or r.response is distinct from m.response or m.response::jsonb is distinct from b.response::jsonb->'tasks'->m.row_index + or m.response::jsonb->>'id' is distinct from m.task_id::text + or m.response::jsonb->>'project_id' is distinct from b.project_id::text + or m.response::jsonb->>'external_task_id' is distinct from m.external_task_id + or m.response::jsonb->>'source_type'<>'json_import' + or m.response::jsonb->>'source_ref' is distinct from 'task-import-source:'||b.source_id::text + or m.response::jsonb->>'source_payload_hash' is distinct from b.sha256 + or m.response::jsonb->>'import_batch_id' is distinct from b.id::text + or m.response::jsonb->>'created_by' is distinct from b.actor_profile_id::text + or not exists(select 1 from public.audit_events e where e.id=m.authorization_decision_id + and e.event_domain='authority' and e.event_type='SensitiveAuthorizationAllowed' + and e.action_id='project.task.create' and e.permission_id='project.task.manage' + and e.actor_id=b.actor_profile_id::text and e.project_id=b.project_id) + or not exists(select 1 from public.audit_events e where e.event_type='TaskCreated' + and e.entity_id=m.task_id::text and e.event_payload::jsonb#>>'{references,authorization_decision_id}'=m.authorization_decision_id::text) + )) then raise exception 'task import batch member custody invalid' using errcode='23514'; end if; + select pg_catalog.jsonb_build_object( + 'schema_version',b.schema_version,'metadata',pg_catalog.jsonb_build_object('label',b.metadata_label), + 'tasks',pg_catalog.jsonb_agg(pg_catalog.jsonb_build_object( + 'external_task_id',m.response::jsonb->'external_task_id','title',m.response::jsonb->'title', + 'description',m.response::jsonb->'description','task_type',m.response::jsonb->'task_type', + 'difficulty',m.response::jsonb->'difficulty','skill_tags',m.response::jsonb->'skill_tags', + 'estimated_time_minutes',m.response::jsonb->'estimated_time_minutes', + 'acceptance_criteria',m.response::jsonb->'acceptance_criteria', + 'rejection_criteria',m.response::jsonb->'rejection_criteria') order by m.row_index)) into manifest + from public.task_import_batch_members m where m.batch_id=b.id; + if public.external_checker_registry_digest(manifest) is distinct from b.manifest_digest + or exists(select 1 from public.task_import_batch_members m where m.batch_id=b.id and + m.row_digest is distinct from public.external_checker_registry_digest(pg_catalog.jsonb_build_object( + 'external_task_id',m.response::jsonb->'external_task_id','title',m.response::jsonb->'title', + 'description',m.response::jsonb->'description','task_type',m.response::jsonb->'task_type', + 'difficulty',m.response::jsonb->'difficulty','skill_tags',m.response::jsonb->'skill_tags', + 'estimated_time_minutes',m.response::jsonb->'estimated_time_minutes', + 'acceptance_criteria',m.response::jsonb->'acceptance_criteria', + 'rejection_criteria',m.response::jsonb->'rejection_criteria'))) then + raise exception 'task import batch manifest custody invalid' using errcode='23514'; + end if; +end +$$ +""") + op.execute(r""" +create function public.validate_task_import_command_custody(target uuid) returns void +language plpgsql set search_path=pg_catalog,public,pg_temp as $$ +declare c public.task_import_batch_command_receipts%rowtype; b public.task_import_batches%rowtype; binding_digest text; +begin + select * into c from public.task_import_batch_command_receipts where id=target; + if not found then return; end if; + if c.status<>'committed' then raise exception 'task import command cannot remain pending' using errcode='23514'; end if; + select * into b from public.task_import_batches where id=c.batch_id; + binding_digest:=public.task_import_binding_digest(c.source_id,c.project_id,c.sha256,c.byte_count, + c.source_operation_identity,c.put_attempt_id,c.content_id,c.replica_id,c.verification_job_id, + c.verification_generation,c.verification_receipt_id,c.operation_receipt_id,c.observation_receipt_id); + if b.id is null or c.response::jsonb is distinct from b.response::jsonb + or c.sha256 is distinct from b.sha256 or c.byte_count is distinct from b.byte_count + or not public.task_import_binding_valid(c.source_id,c.project_id,c.sha256,c.byte_count, + c.source_operation_identity,c.put_attempt_id,c.content_id,c.replica_id,c.verification_job_id, + c.verification_generation,c.verification_receipt_id,c.operation_receipt_id,c.observation_receipt_id) + or not public.task_import_authority_valid(c.authorization_decision_id,'project.task.import',b.id,c.project_id, + c.source_id,c.actor_profile_id,c.identity_link_id,c.sha256,c.byte_count,b.row_count,b.manifest_digest, + binding_digest,c.idempotency_key,c.request_digest) then + raise exception 'task import command custody invalid' using errcode='23514'; + end if; + perform public.validate_task_import_batch_custody(b.id); +end +$$ +""") + + +def _create_guards() -> None: + op.execute(r""" +create function public.guard_task_import_batch_mutation() returns trigger +language plpgsql set search_path=pg_catalog,public,pg_temp as $$ +begin + if tg_op='UPDATE' and old.status='pending' and new.status='committed' + and row(new.id,new.project_id,new.source_id,new.creation_command_receipt_id,new.sha256,new.byte_count, + new.media_type,new.schema_version,new.mapping_version,new.manifest_digest,new.row_count,new.metadata_label, + new.actor_profile_id,new.identity_link_id,new.created_at,new.source_operation_identity) + is not distinct from row(old.id,old.project_id,old.source_id,old.creation_command_receipt_id,old.sha256,old.byte_count, + old.media_type,old.schema_version,old.mapping_version,old.manifest_digest,old.row_count,old.metadata_label, + old.actor_profile_id,old.identity_link_id,old.created_at,old.source_operation_identity) then return new; end if; + raise exception 'task import batch custody is immutable' using errcode='55000'; +end +$$ +""") + op.execute(r""" +create function public.guard_task_import_command_mutation() returns trigger +language plpgsql set search_path=pg_catalog,public,pg_temp as $$ +begin + if tg_op='UPDATE' and old.status='pending' and new.status='committed' + and row(new.id,new.actor_profile_id,new.identity_link_id,new.action_id,new.idempotency_key,new.request_digest, + new.project_id,new.source_id,new.sha256,new.byte_count,new.media_type,new.created_at,new.source_operation_identity) + is not distinct from row(old.id,old.actor_profile_id,old.identity_link_id,old.action_id,old.idempotency_key,old.request_digest, + old.project_id,old.source_id,old.sha256,old.byte_count,old.media_type,old.created_at,old.source_operation_identity) then return new; end if; + raise exception 'task import command custody is immutable' using errcode='55000'; +end +$$ +""") + op.execute(r""" +create function public.reject_task_import_member_mutation() returns trigger +language plpgsql set search_path=pg_catalog,public,pg_temp as $$ begin + raise exception 'task import member custody is immutable' using errcode='55000'; end $$ +""") + op.execute(r""" +create function public.reject_task_import_truncate() returns trigger +language plpgsql set search_path=pg_catalog,public,pg_temp as $$ begin + raise exception 'task import custody cannot be truncated' using errcode='55000'; end $$ +""") + op.execute("create trigger task_import_batches_immutable before update or delete on public.task_import_batches for each row execute function public.guard_task_import_batch_mutation()") + op.execute("create trigger task_import_batch_commands_immutable before update or delete on public.task_import_batch_command_receipts for each row execute function public.guard_task_import_command_mutation()") + op.execute("create trigger task_import_batch_members_immutable before update or delete on public.task_import_batch_members for each row execute function public.reject_task_import_member_mutation()") + for table in _TABLES: + op.execute(f"create trigger {table}_no_truncate before truncate on public.{table} for each statement execute function public.reject_task_import_truncate()") + op.execute("create constraint trigger task_import_batch_custody after insert or update on public.task_import_batches deferrable initially deferred for each row execute function public.trigger_validate_task_import_batch()") + op.execute("create constraint trigger task_import_command_custody after insert or update on public.task_import_batch_command_receipts deferrable initially deferred for each row execute function public.trigger_validate_task_import_command()") + op.execute("create constraint trigger task_import_member_custody after insert or update on public.task_import_batch_members deferrable initially deferred for each row execute function public.trigger_validate_task_import_member()") + + +def _create_trigger_wrappers() -> None: + op.execute(r""" +create function public.trigger_validate_task_import_batch() returns trigger +language plpgsql set search_path=pg_catalog,public,pg_temp as $$ begin + perform public.validate_task_import_batch_custody(new.id); return new; end $$ +""") + op.execute(r""" +create function public.trigger_validate_task_import_command() returns trigger +language plpgsql set search_path=pg_catalog,public,pg_temp as $$ begin + perform public.validate_task_import_command_custody(new.id); return new; end $$ +""") + op.execute(r""" +create function public.trigger_validate_task_import_member() returns trigger +language plpgsql set search_path=pg_catalog,public,pg_temp as $$ begin + perform public.validate_task_import_batch_custody(new.batch_id); return new; end $$ +""") + + +def upgrade() -> None: + """Install exact batch, member, replay, ART and AUTH closure.""" + op.execute("set local search_path=pg_catalog,public,pg_temp") + op.execute( + "lock table public.audit_events, public.workstream_tasks, public.task_command_receipts, " + "public.artifact_task_import_sources in access exclusive mode" + ) + _extend_audit_contract() + _alter_tasks() + _create_tables() + _create_custody_functions() + _create_trigger_wrappers() + _create_guards() + + +def downgrade() -> None: + """Refuse removal of retained native import custody.""" + op.execute("set local search_path=pg_catalog,public,pg_temp") + op.execute( + "lock table public.task_import_batches, public.task_import_batch_members, " + "public.task_import_batch_command_receipts in access exclusive mode" + ) + retained = op.get_bind().execute(sa.text( + "select exists(select 1 from public.task_import_batches) or " + "exists(select 1 from public.task_import_batch_members) or " + "exists(select 1 from public.task_import_batch_command_receipts)" + )).scalar_one() + if retained: + raise RuntimeError("cannot downgrade atomic task import with retained custody") + raise RuntimeError("Workstream v0.1 migrations cannot be downgraded; recreate the database") diff --git a/backend/tests/conftest.py b/backend/tests/conftest.py index 423952f0b..2605fc32f 100644 --- a/backend/tests/conftest.py +++ b/backend/tests/conftest.py @@ -23,7 +23,7 @@ DDL_LOCK_DIRECTORY = Path("/tmp") # Match the PostgreSQL 16 engine used by Backend CI. Catalog identity rendering # differs across major versions; regenerate only after comparing actual objects. -EXPECTED_PUBLIC_SCHEMA_SHA256 = "17ebfd0a2d07470ec32623072ecbcaed11fda0f427b480a3b2dbd11a625b9195" +EXPECTED_PUBLIC_SCHEMA_SHA256 = "474899906d9566b7cebc8e50112515899d1e9969f23304a0cd0c7bab8c19d51b" PROTECTED_TEST_TABLES = ( "actor_profile_migration_state", "alembic_version", @@ -130,6 +130,9 @@ "submission_bundle_durable_intents", "submissions", "task_assignments", + "task_import_batch_command_receipts", + "task_import_batch_members", + "task_import_batches", "task_command_receipts", "task_post_submit_routing_manifests", "task_post_submit_routing_requests", @@ -146,6 +149,9 @@ "checker_submission_fences", "checker_results", "task_command_receipts", + "task_import_batch_command_receipts", + "task_import_batch_members", + "task_import_batches", "task_post_submit_routing_manifests", "task_post_submit_routing_requests", "checker_policies", diff --git a/backend/tests/test_alembic.py b/backend/tests/test_alembic.py index e0eeaa478..424429a62 100644 --- a/backend/tests/test_alembic.py +++ b/backend/tests/test_alembic.py @@ -79,7 +79,7 @@ def test_v01_graph_has_one_root_and_head() -> None: script = ScriptDirectory.from_config(config) revisions = list(script.walk_revisions()) - assert [revision.revision for revision in revisions] == [HEAD_REVISION, "0032_checker_remediation", "0031_task_import_source", "0030_routing_outcomes", "0029_external_checker_registry", "0028_lifecycle_transitions", "0027_markdown_guide_media", "0026_task_guide_read", "0025_submission_dispatch", "0024_require_second_review_false", "0023_remove_task_payment_policy", "0022_submission_packet_custody", "0021_submission_manifest", "0020_review_admission_lock_order", "0019_submitter_awards", "0018_task_routing_request", "0017_acceptance_source_contracts", "0016_review_lifecycle_fence", "0015_contribution_awards", "0014_final_acceptance", "0013_review_source", "0012_review_packet", "0011_task_routing_source", "0010_post_submit_authority", "0009_checker_material_lineage", "0008_checker_execution", "0007_checker_output_custody", "0006_history_read_authority", "0005_task_evidence_authority", "0004_task_context_authority", "0003_task_read_authority", "0002_task_queue_authority", BASELINE_REVISION] + assert [revision.revision for revision in revisions] == [HEAD_REVISION, "0033_contribution_reads", "0032_checker_remediation", "0031_task_import_source", "0030_routing_outcomes", "0029_external_checker_registry", "0028_lifecycle_transitions", "0027_markdown_guide_media", "0026_task_guide_read", "0025_submission_dispatch", "0024_require_second_review_false", "0023_remove_task_payment_policy", "0022_submission_packet_custody", "0021_submission_manifest", "0020_review_admission_lock_order", "0019_submitter_awards", "0018_task_routing_request", "0017_acceptance_source_contracts", "0016_review_lifecycle_fence", "0015_contribution_awards", "0014_final_acceptance", "0013_review_source", "0012_review_packet", "0011_task_routing_source", "0010_post_submit_authority", "0009_checker_material_lineage", "0008_checker_execution", "0007_checker_output_custody", "0006_history_read_authority", "0005_task_evidence_authority", "0004_task_context_authority", "0003_task_read_authority", "0002_task_queue_authority", BASELINE_REVISION] assert revisions[-1].down_revision is None assert script.get_heads() == [HEAD_REVISION] From 624e7443aa54eca8b1b3212636a48c78f5a24f23 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 16:14:03 +0100 Subject: [PATCH 033/283] fix: close task import custody gaps --- .../versions/0034_task_import_batches.py | 93 +++++++++++-------- backend/tests/conftest.py | 2 +- 2 files changed, 54 insertions(+), 41 deletions(-) diff --git a/backend/alembic/versions/0034_task_import_batches.py b/backend/alembic/versions/0034_task_import_batches.py index fb8a2820a..466ca1b6b 100644 --- a/backend/alembic/versions/0034_task_import_batches.py +++ b/backend/alembic/versions/0034_task_import_batches.py @@ -246,36 +246,38 @@ def _create_tables() -> None: def _create_custody_functions() -> None: op.execute(r""" create function public.task_import_binding_valid( - source_id uuid, project_id uuid, sha256 text, byte_count bigint, operation_identity text, - put_attempt_id uuid, content_id uuid, replica_id uuid, verification_job_id uuid, - verification_generation bigint, verification_receipt_id uuid, - operation_receipt_id uuid, observation_receipt_id uuid + expected_source_id uuid, expected_project_id uuid, expected_sha256 text, + expected_byte_count bigint, expected_operation_identity text, + expected_put_attempt_id uuid, expected_content_id uuid, expected_replica_id uuid, + expected_verification_job_id uuid, expected_verification_generation bigint, + expected_verification_receipt_id uuid, expected_operation_receipt_id uuid, + expected_observation_receipt_id uuid ) returns boolean language sql stable set search_path=pg_catalog,public,pg_temp as $$ select exists( select 1 from public.artifact_task_import_sources s - join public.artifact_put_attempts a on a.id=put_attempt_id and a.task_import_source_id=s.id - join public.artifact_replicas r on r.id=replica_id and r.id=a.replica_id - join public.artifact_contents c on c.id=content_id and c.id=r.content_id - join public.artifact_verification_jobs j on j.id=verification_job_id + join public.artifact_put_attempts a on a.id=expected_put_attempt_id and a.task_import_source_id=s.id + join public.artifact_replicas r on r.id=expected_replica_id and r.id=a.replica_id + join public.artifact_contents c on c.id=expected_content_id and c.id=r.content_id + join public.artifact_verification_jobs j on j.id=expected_verification_job_id and j.originating_put_attempt_id=a.id and j.replica_id=r.id - join public.artifact_verification_receipts v on v.id=verification_receipt_id + join public.artifact_verification_receipts v on v.id=expected_verification_receipt_id and v.verification_job_id=j.id and v.outcome='verified' - where s.id=source_id and s.project_id=project_id and s.sha256=sha256 - and s.byte_count=byte_count and s.operation_identity=operation_identity + where s.id=expected_source_id and s.project_id=expected_project_id and s.sha256=expected_sha256 + and s.byte_count=expected_byte_count and s.operation_identity=expected_operation_identity and a.producer_request_type='task_import_source' and a.logical_role='task_import_source' and a.project_id=s.project_id and a.sha256=s.sha256 and a.byte_count=s.byte_count and a.media_type=s.media_type and c.sha256=s.sha256 and c.byte_count=s.byte_count and r.storage_namespace_id=a.storage_namespace_id and r.namespace_fingerprint=a.namespace_fingerprint - and v.execution_generation=verification_generation + and v.execution_generation=expected_verification_generation and v.observed_sha256=s.sha256 and v.observed_byte_count=s.byte_count - and ((operation_receipt_id is not null and observation_receipt_id is null and exists( - select 1 from public.artifact_operation_receipts o where o.id=operation_receipt_id + and ((expected_operation_receipt_id is not null and expected_observation_receipt_id is null and exists( + select 1 from public.artifact_operation_receipts o where o.id=expected_operation_receipt_id and o.put_attempt_id=a.id and o.replica_id=r.id and o.request_digest=a.request_digest and o.provider_object_ref=r.provider_object_ref and o.logical_role='task_import_source' and o.outcome='stored_pending_verification')) or - (operation_receipt_id is null and observation_receipt_id is not null and exists( - select 1 from public.artifact_put_observation_receipts o where o.id=observation_receipt_id + (expected_operation_receipt_id is null and expected_observation_receipt_id is not null and exists( + select 1 from public.artifact_put_observation_receipts o where o.id=expected_observation_receipt_id and o.put_attempt_id=a.id and o.outcome='observed_confirmed' and o.observed_sha256=s.sha256 and o.expected_sha256=s.sha256 and o.observed_byte_count=s.byte_count and o.expected_byte_count=s.byte_count))) @@ -284,39 +286,50 @@ def _create_custody_functions() -> None: """) op.execute(r""" create function public.task_import_binding_digest( - source_id uuid, project_id uuid, sha256 text, byte_count bigint, operation_identity text, - put_attempt_id uuid, content_id uuid, replica_id uuid, verification_job_id uuid, - verification_generation bigint, verification_receipt_id uuid, - operation_receipt_id uuid, observation_receipt_id uuid + expected_source_id uuid, expected_project_id uuid, expected_sha256 text, + expected_byte_count bigint, expected_operation_identity text, + expected_put_attempt_id uuid, expected_content_id uuid, expected_replica_id uuid, + expected_verification_job_id uuid, expected_verification_generation bigint, + expected_verification_receipt_id uuid, expected_operation_receipt_id uuid, + expected_observation_receipt_id uuid ) returns text language sql immutable set search_path=pg_catalog,public,pg_temp as $$ select public.external_checker_registry_digest(pg_catalog.jsonb_build_object( - 'source_id',source_id,'project_id',project_id,'sha256',sha256,'byte_count',byte_count, - 'operation_identity',operation_identity,'put_attempt_id',put_attempt_id,'content_id',content_id, - 'replica_id',replica_id,'verification_job_id',verification_job_id, - 'verification_generation',verification_generation,'verification_receipt_id',verification_receipt_id, - 'operation_receipt_id',operation_receipt_id,'observation_receipt_id',observation_receipt_id)) + 'source_id',expected_source_id,'project_id',expected_project_id,'sha256',expected_sha256, + 'byte_count',expected_byte_count,'operation_identity',expected_operation_identity, + 'put_attempt_id',expected_put_attempt_id,'content_id',expected_content_id, + 'replica_id',expected_replica_id,'verification_job_id',expected_verification_job_id, + 'verification_generation',expected_verification_generation, + 'verification_receipt_id',expected_verification_receipt_id, + 'operation_receipt_id',expected_operation_receipt_id, + 'observation_receipt_id',expected_observation_receipt_id)) $$ """) op.execute(r""" create function public.task_import_authority_valid( - decision_id uuid, action text, batch_id uuid, project_id uuid, source_id uuid, - actor_id uuid, link_id uuid, sha256 text, byte_count bigint, row_count integer, - manifest_digest text, source_binding_digest text, idempotency_key uuid, request_digest text + expected_decision_id uuid, expected_action text, expected_batch_id uuid, + expected_project_id uuid, expected_source_id uuid, expected_actor_id uuid, + expected_link_id uuid, expected_sha256 text, expected_byte_count bigint, + expected_row_count integer, expected_manifest_digest text, + expected_source_binding_digest text, expected_idempotency_key uuid, + expected_request_digest text ) returns boolean language sql stable set search_path=pg_catalog,public,pg_temp as $$ - select exists(select 1 from public.audit_events a where a.id=decision_id + select exists(select 1 from public.audit_events a where a.id=expected_decision_id and a.event_domain='authority' and a.event_type='SensitiveAuthorizationAllowed' - and a.actor_ref_kind='actor_profile' and a.actor_id=actor_id::text - and a.project_id=project_id and a.action_id=action and a.permission_id='project.task.manage' - and a.resource_type='task_import_batch' and a.resource_id=batch_id::text - and a.target_ref_kind='task_import_batch' and a.target_ref_id=batch_id::text + and a.actor_ref_kind='actor_profile' and a.actor_id=expected_actor_id::text + and a.project_id=expected_project_id and a.action_id=expected_action + and a.permission_id='project.task.manage' + and a.resource_type='task_import_batch' and a.resource_id=expected_batch_id::text + and a.target_ref_kind='task_import_batch' and a.target_ref_id=expected_batch_id::text and a.denial_code is null and a.after_facts::jsonb=pg_catalog.jsonb_build_object( 'allowed',true,'resource_context_digest',public.external_checker_registry_digest( pg_catalog.jsonb_build_object('resource_context',pg_catalog.jsonb_build_object( - 'resource_type','task_import_batch','resource_id',batch_id,'scope_project_id',project_id, - 'source_id',source_id,'actor_profile_id',actor_id,'identity_link_id',link_id, - 'sha256',sha256,'byte_count',byte_count,'row_count',row_count, - 'manifest_digest',manifest_digest,'source_binding_digest',source_binding_digest, - 'idempotency_key',idempotency_key,'request_digest',request_digest))))) + 'resource_type','task_import_batch','resource_id',expected_batch_id, + 'scope_project_id',expected_project_id,'source_id',expected_source_id, + 'actor_profile_id',expected_actor_id,'identity_link_id',expected_link_id, + 'sha256',expected_sha256,'byte_count',expected_byte_count, + 'row_count',expected_row_count,'manifest_digest',expected_manifest_digest, + 'source_binding_digest',expected_source_binding_digest, + 'idempotency_key',expected_idempotency_key,'request_digest',expected_request_digest))))) $$ """) op.execute(r""" @@ -357,7 +370,7 @@ def _create_custody_functions() -> None: or (b.response::jsonb->>'row_count')::integer is distinct from b.row_count or b.response::jsonb->>'schema_version' is distinct from b.schema_version or b.response::jsonb->>'mapping_version' is distinct from b.mapping_version - or b.response::jsonb->'label' is distinct from to_jsonb(b.metadata_label) + or b.response::jsonb->'label' is distinct from coalesce(to_jsonb(b.metadata_label),'null'::jsonb) or pg_catalog.jsonb_array_length(b.response::jsonb->'tasks')<>b.row_count then raise exception 'task import batch response custody invalid' using errcode='23514'; end if; @@ -368,7 +381,7 @@ def _create_custody_functions() -> None: m.project_id is distinct from b.project_id or m.external_task_id is distinct from t.external_task_id or t.source_type<>'json_import' or t.source_ref is distinct from 'task-import-source:'||b.source_id::text or t.source_payload_hash is distinct from b.sha256 or t.import_batch_id is distinct from b.id::text - or t.status<>'draft' or t.created_by is distinct from b.actor_profile_id::text + or t.created_by is distinct from b.actor_profile_id::text or r.status<>'committed' or r.action_id<>'project.task.create' or r.task_id is distinct from m.task_id or r.actor_profile_id is distinct from b.actor_profile_id or r.idempotency_key is distinct from m.create_idempotency_key or r.response is distinct from m.response or m.response::jsonb is distinct from b.response::jsonb->'tasks'->m.row_index diff --git a/backend/tests/conftest.py b/backend/tests/conftest.py index 2605fc32f..5542e3a40 100644 --- a/backend/tests/conftest.py +++ b/backend/tests/conftest.py @@ -23,7 +23,7 @@ DDL_LOCK_DIRECTORY = Path("/tmp") # Match the PostgreSQL 16 engine used by Backend CI. Catalog identity rendering # differs across major versions; regenerate only after comparing actual objects. -EXPECTED_PUBLIC_SCHEMA_SHA256 = "474899906d9566b7cebc8e50112515899d1e9969f23304a0cd0c7bab8c19d51b" +EXPECTED_PUBLIC_SCHEMA_SHA256 = "e855665f7f29cbee579fc281fd547309540e475f6513a602c8582743b53fb6ac" PROTECTED_TEST_TABLES = ( "actor_profile_migration_state", "alembic_version", From c9be28c6bc269e4f727c52191713015f9fa09baa Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 16:21:16 +0100 Subject: [PATCH 034/283] fix: compare native task audit identities --- backend/alembic/versions/0034_task_import_batches.py | 2 +- backend/tests/conftest.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/alembic/versions/0034_task_import_batches.py b/backend/alembic/versions/0034_task_import_batches.py index 466ca1b6b..e593205c0 100644 --- a/backend/alembic/versions/0034_task_import_batches.py +++ b/backend/alembic/versions/0034_task_import_batches.py @@ -398,7 +398,7 @@ def _create_custody_functions() -> None: and e.action_id='project.task.create' and e.permission_id='project.task.manage' and e.actor_id=b.actor_profile_id::text and e.project_id=b.project_id) or not exists(select 1 from public.audit_events e where e.event_type='TaskCreated' - and e.entity_id=m.task_id::text and e.event_payload::jsonb#>>'{references,authorization_decision_id}'=m.authorization_decision_id::text) + and e.entity_id=m.task_id and e.event_payload::jsonb#>>'{references,authorization_decision_id}'=m.authorization_decision_id::text) )) then raise exception 'task import batch member custody invalid' using errcode='23514'; end if; select pg_catalog.jsonb_build_object( 'schema_version',b.schema_version,'metadata',pg_catalog.jsonb_build_object('label',b.metadata_label), diff --git a/backend/tests/conftest.py b/backend/tests/conftest.py index 5542e3a40..b4d274756 100644 --- a/backend/tests/conftest.py +++ b/backend/tests/conftest.py @@ -23,7 +23,7 @@ DDL_LOCK_DIRECTORY = Path("/tmp") # Match the PostgreSQL 16 engine used by Backend CI. Catalog identity rendering # differs across major versions; regenerate only after comparing actual objects. -EXPECTED_PUBLIC_SCHEMA_SHA256 = "e855665f7f29cbee579fc281fd547309540e475f6513a602c8582743b53fb6ac" +EXPECTED_PUBLIC_SCHEMA_SHA256 = "3214f37ad2c38eb46b5348f954c43ffd355d98289e36ebb91937dde954e622d6" PROTECTED_TEST_TABLES = ( "actor_profile_migration_state", "alembic_version", From 6359ee0fca3a8b4edca5becc87ac0caab6a73074 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 16:32:25 +0100 Subject: [PATCH 035/283] [PILOT-10] Add fixed-membership contribution export pagination --- .../pilot10-stable-contribution-pagination.md | 97 +++++++++++++ .../app/adapters/contributions/__init__.py | 6 +- backend/app/api/deps/contribution_exports.py | 20 ++- backend/app/api/routes/contributions.py | 13 +- .../app/modules/contributions/api/records.py | 13 +- .../modules/contributions/records/cursors.py | 131 ++++++++++++++++++ .../contributions/records/export_models.py | 61 ++++++++ .../contributions/records/read_facts.py | 15 +- .../contributions/records/read_repository.py | 129 ++++++++++++++--- .../contributions/records/read_service.py | 15 +- .../contributions/exports/test_pagination.py | 114 +++++++++++++++ .../exports/test_source_reads.py | 4 +- .../contributions/test_export_cursors.py | 94 +++++++++++++ .../contributions/test_export_projection.py | 41 +++++- docs/roadmap_status.md | 14 +- docs/spec_contribution_compensation.md | 44 ++++-- 16 files changed, 741 insertions(+), 70 deletions(-) create mode 100644 .commitrail/changes/pilot10-stable-contribution-pagination.md create mode 100644 backend/app/modules/contributions/records/cursors.py create mode 100644 backend/app/modules/contributions/records/export_models.py create mode 100644 backend/tests/contributions/exports/test_pagination.py create mode 100644 backend/tests/contributions/test_export_cursors.py diff --git a/.commitrail/changes/pilot10-stable-contribution-pagination.md b/.commitrail/changes/pilot10-stable-contribution-pagination.md new file mode 100644 index 000000000..bde951b6d --- /dev/null +++ b/.commitrail/changes/pilot10-stable-contribution-pagination.md @@ -0,0 +1,97 @@ +# PILOT-10B — Fixed-membership contribution export pages + +- Initiative: None +- Durable disposition: Planned +- Intended merge outcome: Existing authorized contribution exports traverse more than 1,000 records with signed, expiring cursors and fixed contribution membership. + +## Intent + +Finance, PMs and contributors must export their complete authorized contribution +selection without narrowing filters merely to stay under one response bound. + +## Current behavior + +PILOT-10A exposes JSON/CSV reads through the canonical CON projection and fresh +AUTH in a repeatable-read response transaction. The repository refuses selections +above 1,000 contributions. AUTH's existing signed timestamp/UUID keyset codec +protects other reads; it does not freeze export membership across transactions. + +## Bounded change + +### Allowed + +- CON API/read facts, repository, projection, owner-local export cursor codec and + record model; explicit CON composition and existing export REST dependencies/routes. +- One sole-author native migration and corresponding schema/reset registration, + after coordination with the existing migration owner; no guessed revision. +- Focused contribution projection/cursor/native public-API regression tests, + affected public schema capture, additive CI ownership and current export docs. + +### Not allowed + +- Economic recognition, award definitions, policy custody, acceptance/routing, + fulfillment, new roles/actions, weakening authority or immutable source evidence. +- Importing AUTH-private codec code into CON; parallel old/new export readers; + native migration authored by anyone except the coordinated migration owner. +- Automatic mutation retry, removed CI checks, deployment or merge. + +## Design and decisions + +Extend the existing read operation with bounded page_size and cursor. Each page +retains its complete awards and fresh canonical authority through serialization +and commit. Sign actor, audience, project, normalized filters, format, page size, +original membership snapshot and last timestamp/UUID boundary with the existing +configured pagination secret. Expire cursors after 15 minutes and reject invalid +or cross-query continuation without disclosing facts. JSON exposes next_cursor; +CSV uses X-Workstream-Next-Cursor and X-Workstream-Exported-At headers. + +Native membership uses two CON-private expiring tables: a header bound to actor, +normalized query and a 15-minute export instant, and immutable contribution IDs +with their recorded-time ordering keys. First-page membership capture uses the +same fresh-authorized repeatable-read transaction as canonical projection. +The complete selection is bounded at 100,000 contributions; each page at 1,000. +Headers are sealed before commit; member additions after sealing are refused. +Expired headers/members alone may be removed, in batches of at most 100 during +reads; retained contribution and award records are never changed or deleted. + +A timestamp/UUID watermark does not exclude late commits. Native xid8 snapshot +filtering would also require provenance metadata on economic rows, cutover rules +and cluster/restore identity handling. Focused peer design review selected the +explicit membership list because ordinary native FK-backed data preserves the +selection through restart and logical restore without that extra subsystem. +CLI is a separate bounded PR. + +## Acceptance criteria + +- [ ] Multi-page traversal returns each originally visible selected contribution + once, in timestamp/UUID order, with its complete exact award set. +- [ ] Delayed commits, later/backdated inserts and savepoints do not change membership. +- [ ] Retained data remains readable; new metadata cannot be forged or mutated. +- [ ] Forged/expired/cross-actor/query cursors fail; revoked authority conceals every page. +- [ ] JSON and CSV share identical page membership and stable exported_at. + +## Risk and review routing + +- Risk class: L1 +- Required reviewers: architecture, security, QA, test_delta, documentation. +- Human review focus: native visibility/restore semantics, fresh authority and exact evidence. + +## Evidence + +| Claim | Command or proof | Result | Remaining uncertainty | +|---|---|---|---| +| Current implementation | Inspect canonical CON read and AUTH keyset owner | Existing bounded reader and codec identified | Native membership design needs review | +| Membership/authority | Real PostgreSQL installed-schema public reads, delayed commit and revocation controls | Planned | No native runtime claim yet | +| Cursor validation | Focused tamper, scope, expiry and serialization controls | Planned | Implementation pending | +| Required repository checks | Focused checks plus required hosted CI and independent review | Planned | No readiness claim | + +## Review findings + +Focused peer plan review selected private expiring membership over cluster-local +transaction-ID coupling. Implementation still requires installed-schema proof. + +## Reconciliation + +- Current-source reconciliation: starts from main d47ee1e, including merged PILOT-10A. +- Next usable boundary: separate CLI export PR and the pilot closing drill. +- Remaining risks: native membership mechanism and restore binding not yet frozen. diff --git a/backend/app/adapters/contributions/__init__.py b/backend/app/adapters/contributions/__init__.py index 63dd33462..f762d358d 100644 --- a/backend/app/adapters/contributions/__init__.py +++ b/backend/app/adapters/contributions/__init__.py @@ -72,17 +72,21 @@ def submitter_contribution_participant(session, fence): def contribution_export_service( session: AsyncSession, *, authorization: ContributionReadAuthorizationPort, + cursor_secret: bytes | None, ) -> ContributionExportPort: """Compose one mandatory authorized evidence projection on the caller's snapshot.""" from app.adapters.actors import contribution_actor_label_port from app.adapters.compensation import contribution_award_read_port from app.adapters.reviews import final_acceptance_read_port from app.adapters.tasks import contribution_task_evidence_port + from app.modules.contributions.records.cursors import ContributionCursorCodec from app.modules.contributions.records.read_repository import ContributionReadRepository from app.modules.contributions.records.read_service import ContributionReadService return ContributionReadService( - authorization=authorization, records=ContributionReadRepository(session), + authorization=authorization, records=ContributionReadRepository( + session, cursor_codec=None if cursor_secret is None else ContributionCursorCodec(cursor_secret), + ), awards=contribution_award_read_port(session), acceptances=final_acceptance_read_port(session), tasks=contribution_task_evidence_port(session), actors=contribution_actor_label_port(session), ) diff --git a/backend/app/api/deps/contribution_exports.py b/backend/app/api/deps/contribution_exports.py index 5fc671bf7..4d747a546 100644 --- a/backend/app/api/deps/contribution_exports.py +++ b/backend/app/api/deps/contribution_exports.py @@ -16,10 +16,11 @@ _authorization_context, get_authorization_actor, get_authorization_actor_identity, ) from app.core.api_controls import StructuredHTTPException, request_ids +from app.core.config import decode_pagination_cursor_hmac_secret from app.db.session import get_db_session from app.modules.contributions.api.records import ( ContributionExportPort, ContributionExportResponse, ContributionExportTooLarge, - ContributionExportUnavailable, ContributionReadDenied, ContributionReadRequest, + ContributionExportUnavailable, ContributionReadDenied, ContributionReadRequest, InvalidContributionCursor, ) @@ -36,7 +37,7 @@ def contribution_export_http_error(status: int) -> StructuredHTTPException: """Conceal denied scopes and keep limits/storage errors free of owner facts.""" code, message = { 404: ("contribution_export_not_found", "Contribution evidence unavailable"), - 422: ("contribution_export_too_large", "Contribution export exceeds 1000 records; narrow the filters"), + 422: ("contribution_export_too_large", "Contribution export exceeds 100000 records; narrow the filters"), 503: ("contribution_export_unavailable", "Contribution export unavailable"), }[status] return StructuredHTTPException(status_code=status, detail=code, error_code=code, @@ -53,12 +54,18 @@ async def get_contribution_export_request( context = _authorization_context(resolved, request_id, correlation_id) actor = await get_authorization_actor_identity(resolved) await session.rollback() + secret = request.app.state.settings.pagination_cursor_hmac_secret + cursor_secret = None if secret is None else decode_pagination_cursor_hmac_secret(secret) try: yield ContributionExportRequest(session, contribution_export_service( - session, authorization=contribution_read_authorization(session, context), + session, authorization=contribution_read_authorization(session, context), cursor_secret=cursor_secret, ), actor.actor_profile_id) except ContributionReadDenied as exc: raise contribution_export_http_error(404) from exc + except InvalidContributionCursor as exc: + raise StructuredHTTPException(status_code=422, detail="contribution_export_invalid_cursor", + error_code="contribution_export_invalid_cursor", + error_message="Invalid contribution export cursor") from exc except ContributionExportTooLarge as exc: raise contribution_export_http_error(422) from exc except (ContributionExportUnavailable, SQLAlchemyError, ValidationError, TypeError) as exc: @@ -97,8 +104,11 @@ async def contribution_export_response( raise if selected.output_format == "csv": body = contribution_export_csv(projection) - response = Response(body, media_type="text/csv; charset=utf-8", - headers={"Content-Disposition": 'attachment; filename="contributions.csv"'}) + headers = {"Content-Disposition": 'attachment; filename="contributions.csv"', + "X-Workstream-Exported-At": projection.exported_at.isoformat()} + if projection.next_cursor is not None: + headers["X-Workstream-Next-Cursor"] = projection.next_cursor + response = Response(body, media_type="text/csv; charset=utf-8", headers=headers) else: body = projection.model_dump_json().encode("utf-8") ContributionExportResponse.model_validate_json(body) diff --git a/backend/app/api/routes/contributions.py b/backend/app/api/routes/contributions.py index 89f80ef26..7d9ead179 100644 --- a/backend/app/api/routes/contributions.py +++ b/backend/app/api/routes/contributions.py @@ -17,13 +17,14 @@ _CSV = {"200": {"content": {"text/csv": {"schema": {"type": "string"}}}}} -def _selected(context, audience, project_id, output_format, contribution_type, recorded_from, recorded_before): +def _selected(context, audience, project_id, output_format, contribution_type, recorded_from, recorded_before, + page_size, cursor): """Bind self actor on the server and reject inverted/naive recorded-time filters.""" try: return ContributionReadRequest( audience=audience, actor_profile_id=context.actor_profile_id, project_id=project_id, output_format=output_format, contribution_type=contribution_type, - recorded_from=recorded_from, recorded_before=recorded_before, + recorded_from=recorded_from, recorded_before=recorded_before, page_size=page_size, cursor=cursor, ) except ValidationError as exc: raise StructuredHTTPException(status_code=422, detail="contribution_export_invalid", @@ -38,10 +39,11 @@ async def read_own_contributions( project_id: UUID | None = None, format: Literal["json", "csv"] = "json", contribution_type: Literal["accepted_submission", "completed_review"] | None = None, recorded_from: AwareDatetime | None = None, recorded_before: AwareDatetime | None = None, + page_size: int = 100, cursor: str | None = None, ): - """Return all selected own records, refusing over 1000 instead of truncating.""" + """Return one authorized page of a fixed own-contribution selection.""" return await contribution_export_response(context, _selected( - context, "self", project_id, format, contribution_type, recorded_from, recorded_before, + context, "self", project_id, format, contribution_type, recorded_from, recorded_before, page_size, cursor, )) @@ -53,8 +55,9 @@ async def export_project_contributions( format: Literal["json", "csv"] = "json", contribution_type: Literal["accepted_submission", "completed_review"] | None = None, recorded_from: AwareDatetime | None = None, recorded_before: AwareDatetime | None = None, + page_size: int = 100, cursor: str | None = None, ): """Export one project for covering PM or exact-project Finance authority.""" return await contribution_export_response(context, _selected( - context, "project", project_id, format, contribution_type, recorded_from, recorded_before, + context, "project", project_id, format, contribution_type, recorded_from, recorded_before, page_size, cursor, )) diff --git a/backend/app/modules/contributions/api/records.py b/backend/app/modules/contributions/api/records.py index cc45be3d3..5650ce1b5 100644 --- a/backend/app/modules/contributions/api/records.py +++ b/backend/app/modules/contributions/api/records.py @@ -16,8 +16,12 @@ class ContributionExportUnavailable(RuntimeError): """Canonical evidence or exact current read authority cannot be established.""" +class InvalidContributionCursor(ValueError): + """Signed continuation is malformed, expired or belongs to another query.""" + + class ContributionExportTooLarge(ValueError): - """The complete selection exceeds the fixed limit; no partial export is valid.""" + """The complete selection exceeds the membership bound; no partial export is valid.""" class ContributionReadDenied(RuntimeError): @@ -35,6 +39,8 @@ class ContributionReadRequest(BaseModel): contribution_type: ContributionType | None = None recorded_from: AwareDatetime | None = None recorded_before: AwareDatetime | None = None + page_size: int = Field(default=100, ge=1, le=MAX_EXPORT_CONTRIBUTIONS) + cursor: str | None = Field(default=None, min_length=1, max_length=4096, pattern=r"^[A-Za-z0-9_-]+$") @field_validator("recorded_from", "recorded_before") @classmethod @@ -132,15 +138,16 @@ def validate_source_and_awards(self) -> Self: class ContributionExportResponse(BaseModel): - """The complete bounded selection from one repeatable-read request transaction.""" + """One bounded fixed-membership page from a fresh authorized read transaction.""" model_config = _STRICT exported_at: AwareDatetime + next_cursor: str | None = Field(default=None, min_length=1, max_length=4096, pattern=r"^[A-Za-z0-9_-]+$") items: tuple[ContributionRecordView, ...] = Field(max_length=MAX_EXPORT_CONTRIBUTIONS) @model_validator(mode="after") def validate_unique_order(self) -> Self: - """Stable display order does not claim a cursor or business commit order.""" + """Stable key order is required for traversal and conveys no business commit order.""" keys = [(item.recorded_at, item.contribution_id) for item in self.items] if keys != sorted(keys) or len({item.contribution_id for item in self.items}) != len(keys): raise ValueError("contribution export order or identity differs") diff --git a/backend/app/modules/contributions/records/cursors.py b/backend/app/modules/contributions/records/cursors.py new file mode 100644 index 000000000..92cfb6cde --- /dev/null +++ b/backend/app/modules/contributions/records/cursors.py @@ -0,0 +1,131 @@ +"""CON-owned signed continuation of one expiring contribution membership export.""" + +import base64 +import binascii +from dataclasses import dataclass +from datetime import UTC, datetime +import hashlib +import hmac +import json +import re +from uuid import UUID + +from app.core.hashing import canonical_json_hash +from app.modules.contributions.api.records import ContributionReadRequest, InvalidContributionCursor + +MAX_CURSOR_BYTES = 4096 +_CURSOR = re.compile(r"^[A-Za-z0-9_-]+$") +_FIELDS = {"v", "q", "export", "at", "expires", "last_at", "last_id"} + + +@dataclass(frozen=True) +class ContributionCursor: + """Verified scope and position; current read authority is still mandatory.""" + + export_id: UUID + exported_at: datetime + expires_at: datetime + last_recorded_at: datetime + last_contribution_id: UUID + + +def contribution_query_digest(request: ContributionReadRequest) -> str: + """Bind normalized actor, audience, filters, format and page size, excluding position.""" + return canonical_json_hash({ + "domain": "contribution-export-membership-v1", + "query": request.model_dump(mode="json", exclude={"cursor"}), + }) + + +def _json(value) -> bytes: + return json.dumps(value, sort_keys=True, separators=(",", ":"), + ensure_ascii=True, allow_nan=False).encode("ascii") + + +def _encode(value: bytes) -> str: + return base64.urlsafe_b64encode(value).decode("ascii").rstrip("=") + + +def _decode(value: str) -> bytes: + if not isinstance(value, str) or not value or len(value) > MAX_CURSOR_BYTES or not _CURSOR.fullmatch(value): + raise InvalidContributionCursor("Invalid contribution export cursor") + decoded = base64.b64decode(value + "=" * (-len(value) % 4), altchars=b"-_", validate=True) + if _encode(decoded) != value: + raise InvalidContributionCursor("Invalid contribution export cursor") + return decoded + + +def _unique(pairs): + result = {} + for key, value in pairs: + if key in result: + raise InvalidContributionCursor("Invalid contribution export cursor") + result[key] = value + return result + + +def _time(value: datetime) -> str: + if value.tzinfo is None or value.utcoffset() is None: + raise ValueError("Export cursor requires aware timestamps") + return value.astimezone(UTC).isoformat(timespec="microseconds").replace("+00:00", "Z") + + +def _parse_time(value: str) -> datetime: + if not isinstance(value, str) or not value.endswith("Z"): + raise InvalidContributionCursor("Invalid contribution export cursor") + parsed = datetime.fromisoformat(value[:-1] + "+00:00") + if _time(parsed) != value: + raise InvalidContributionCursor("Invalid contribution export cursor") + return parsed + + +def _uuid(value: str) -> UUID: + parsed = UUID(value) + if str(parsed) != value: + raise InvalidContributionCursor("Invalid contribution export cursor") + return parsed + + +class ContributionCursorCodec: + """Use the existing configured pagination HMAC secret with a distinct domain.""" + + def __init__(self, secret: bytes) -> None: + if len(secret) != 32: + raise ValueError("Invalid pagination cursor HMAC secret") + self._secret = bytes(secret) + + def encode(self, state: ContributionCursor, *, query_digest: str) -> str: + """Emit canonical bounded signed state; no bearer credential is embedded.""" + payload = {"v": 1, "q": query_digest, "export": str(state.export_id), + "at": _time(state.exported_at), "expires": _time(state.expires_at), + "last_at": _time(state.last_recorded_at), "last_id": str(state.last_contribution_id)} + signature = hmac.new(self._secret, _json(payload), hashlib.sha256).digest() + token = _encode(_json({"p": payload, "s": _encode(signature)})) + if len(token) > MAX_CURSOR_BYTES: + raise ValueError("Export cursor exceeds its bound") + return token + + def decode(self, value: str, *, query_digest: str, now: datetime) -> ContributionCursor: + """Verify all signed fields before any membership lookup; reject expiry exactly.""" + try: + envelope = json.loads(_decode(value), object_pairs_hook=_unique) + if not isinstance(envelope, dict) or set(envelope) != {"p", "s"}: + raise ValueError() + payload = envelope["p"] + if not isinstance(payload, dict) or set(payload) != _FIELDS or type(payload["v"]) is not int or payload["v"] != 1: + raise ValueError() + expected = hmac.new(self._secret, _json(payload), hashlib.sha256).digest() + if not hmac.compare_digest(expected, _decode(envelope["s"])) or not hmac.compare_digest(payload["q"], query_digest): + raise ValueError() + state = ContributionCursor( + export_id=_uuid(payload["export"]), exported_at=_parse_time(payload["at"]), + expires_at=_parse_time(payload["expires"]), last_recorded_at=_parse_time(payload["last_at"]), + last_contribution_id=_uuid(payload["last_id"]), + ) + if not state.exported_at <= now < state.expires_at or ( + state.expires_at - state.exported_at + ).total_seconds() != 900: + raise ValueError() + return state + except (ValueError, TypeError, KeyError, UnicodeError, binascii.Error, OverflowError): + raise InvalidContributionCursor("Invalid contribution export cursor") from None diff --git a/backend/app/modules/contributions/records/export_models.py b/backend/app/modules/contributions/records/export_models.py new file mode 100644 index 000000000..6fa5d87d2 --- /dev/null +++ b/backend/app/modules/contributions/records/export_models.py @@ -0,0 +1,61 @@ +"""Expiring private membership, separate from retained economic contribution facts.""" + +from datetime import datetime +from uuid import UUID + +from sqlalchemy import Boolean, CheckConstraint, DateTime, ForeignKey, Integer, String, Uuid +from sqlalchemy.orm import Mapped, mapped_column + +from app.db.base import Base + + +class ContributionExportMembership(Base): + """One bounded export selection; it grants no authority on later reads.""" + + __tablename__ = "contribution_export_memberships" + __table_args__ = ( + CheckConstraint("(get_byte(uuid_send(id), 6) >> 4) = 7 and (get_byte(uuid_send(id), 8) & 192) = 128", + name="id_uuid7"), + CheckConstraint("query_digest ~ '^sha256:[0-9a-f]{64}$'", name="query_digest"), + CheckConstraint("expires_at = exported_at + interval '15 minutes'", name="expiry"), + CheckConstraint("member_count between 0 and 100000", name="member_count"), + CheckConstraint("audience in ('self','project') and (audience != 'project' or project_id is not null)", + name="audience"), + CheckConstraint("output_format in ('json','csv')", name="output_format"), + CheckConstraint("page_size between 1 and 1000", name="page_size"), + CheckConstraint("contribution_type is null or contribution_type in ('accepted_submission','completed_review')", + name="contribution_type"), + CheckConstraint("recorded_from is null or recorded_before is null or recorded_from < recorded_before", + name="recorded_interval"), + ) + id: Mapped[UUID] = mapped_column(Uuid(), primary_key=True) + actor_profile_id: Mapped[str] = mapped_column( + Uuid(as_uuid=False), ForeignKey("actor_profiles.id", ondelete="RESTRICT"), nullable=False, + ) + audience: Mapped[str] = mapped_column(String(16), nullable=False) + project_id: Mapped[str | None] = mapped_column( + Uuid(as_uuid=False), ForeignKey("projects.id", ondelete="RESTRICT"), + ) + output_format: Mapped[str] = mapped_column(String(4), nullable=False) + page_size: Mapped[int] = mapped_column(Integer, nullable=False) + contribution_type: Mapped[str | None] = mapped_column(String(32)) + recorded_from: Mapped[datetime | None] = mapped_column(DateTime(timezone=True)) + recorded_before: Mapped[datetime | None] = mapped_column(DateTime(timezone=True)) + member_count: Mapped[int] = mapped_column(Integer, nullable=False) + sealed: Mapped[bool] = mapped_column(Boolean, nullable=False) + query_digest: Mapped[str] = mapped_column(String(71), nullable=False) + exported_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False) + expires_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False, index=True) + + +class ContributionExportMember(Base): + """Immutable originally visible identity and its source ordering timestamp.""" + + __tablename__ = "contribution_export_members" + export_id: Mapped[UUID] = mapped_column( + Uuid(), ForeignKey("contribution_export_memberships.id", ondelete="CASCADE"), primary_key=True, + ) + contribution_id: Mapped[UUID] = mapped_column( + Uuid(), ForeignKey("contribution_records.id", ondelete="RESTRICT"), primary_key=True, + ) + recorded_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False) diff --git a/backend/app/modules/contributions/records/read_facts.py b/backend/app/modules/contributions/records/read_facts.py index 0e240ea15..4a3f13bca 100644 --- a/backend/app/modules/contributions/records/read_facts.py +++ b/backend/app/modules/contributions/records/read_facts.py @@ -44,9 +44,18 @@ def validate_frozen_set(self) -> Self: return self +class ContributionReadPage(BaseModel): + """One complete page with its original export instant and verified continuation.""" + + model_config = _STRICT + records: tuple[ContributionReadFacts, ...] = Field(max_length=1000) + exported_at: AwareDatetime + next_cursor: str | None = None + + class ContributionReadRepositoryPort(Protocol): - """Load at most the complete fixed-limit set; never silently truncate.""" + """Load a bounded page from one fixed selection; never silently truncate.""" - async def read(self, request: ContributionReadRequest) -> tuple[ContributionReadFacts, ...]: - """Pre-filter audience/project/date/type before the over-limit probe.""" + async def read(self, request: ContributionReadRequest) -> ContributionReadPage: + """Pre-filter before membership capture and load only the selected page.""" ... diff --git a/backend/app/modules/contributions/records/read_repository.py b/backend/app/modules/contributions/records/read_repository.py index f10280a1c..ef8771662 100644 --- a/backend/app/modules/contributions/records/read_repository.py +++ b/backend/app/modules/contributions/records/read_repository.py @@ -1,12 +1,13 @@ """Canonical contribution/rule projection, pre-filtered before any response bound.""" +from datetime import timedelta from uuid import UUID -from sqlalchemy import and_, select +from sqlalchemy import and_, delete, func, insert, literal, select, tuple_ from sqlalchemy.ext.asyncio import AsyncSession from app.modules.contributions.api.records import ( - MAX_EXPORT_CONTRIBUTIONS, + InvalidContributionCursor, ContributionExportTooLarge, ContributionExportUnavailable, ContributionReadRequest, @@ -15,19 +16,96 @@ ContributionAwardDefinition, ContributionPolicyVersion, ContributionRule, ) from app.modules.contributions.records.models import ContributionRecord -from app.modules.contributions.records.read_facts import ContributionReadFacts, FrozenContributionAward +from app.core.identifiers import new_record_id +from app.modules.contributions.records.cursors import ContributionCursor, ContributionCursorCodec, contribution_query_digest +from app.modules.contributions.records.export_models import ContributionExportMember, ContributionExportMembership +from app.modules.contributions.records.read_facts import ContributionReadFacts, ContributionReadPage, FrozenContributionAward class ContributionReadRepository: """Read immutable facts and frozen terms in the caller's authorized snapshot.""" - def __init__(self, session: AsyncSession) -> None: + def __init__(self, session: AsyncSession, *, cursor_codec: ContributionCursorCodec | None) -> None: """Share transaction ownership; no economic insert/update or commit is exposed.""" self._session = session + self._cursor_codec = cursor_codec - async def read(self, request: ContributionReadRequest) -> tuple[ContributionReadFacts, ...]: - """Probe one excess contribution before loading its complete definition sets.""" + @staticmethod + def _selection(query, request): + """Share original selection with membership capture and canonical page loading.""" + if request.audience == "self": + query = query.where(ContributionRecord.contributor_id == str(request.actor_profile_id)) + if request.project_id is not None: + query = query.where(ContributionRecord.project_id == str(request.project_id)) + if request.contribution_type is not None: + query = query.where(ContributionRecord.contribution_type == request.contribution_type) + if request.recorded_from is not None: + query = query.where(ContributionRecord.created_at >= request.recorded_from) + if request.recorded_before is not None: + query = query.where(ContributionRecord.created_at < request.recorded_before) + return query + + async def _membership(self, request): + """Capture once or prove the signed, sealed original selection after fresh AUTH.""" + now = await self._session.scalar(select(func.clock_timestamp())) + digest = contribution_query_digest(request) + position = None + if request.cursor is not None: + if self._cursor_codec is None: + raise ContributionExportUnavailable("Contribution export pagination unavailable") + position = self._cursor_codec.decode(request.cursor, query_digest=digest, now=now) + header = await self._session.scalar(select(ContributionExportMembership).where( + ContributionExportMembership.id == position.export_id, + ).with_for_update(read=True, key_share=True)) + if header is None or not header.sealed or ( + header.actor_profile_id, header.query_digest, header.exported_at, header.expires_at, + header.audience, header.project_id, header.output_format, header.page_size, + header.contribution_type, header.recorded_from, header.recorded_before, + ) != (str(request.actor_profile_id), digest, position.exported_at, position.expires_at, + request.audience, None if request.project_id is None else str(request.project_id), + request.output_format, request.page_size, request.contribution_type, + request.recorded_from, request.recorded_before): + raise InvalidContributionCursor("Invalid contribution export cursor") + return header, position + selected = self._selection(select(ContributionRecord.id, ContributionRecord.created_at), request) + count = await self._session.scalar(select(func.count()).select_from(selected.limit(100001).subquery())) + if count > 100000: + raise ContributionExportTooLarge("Contribution export exceeds 100000 records; narrow the filters") + if count > request.page_size and self._cursor_codec is None: + raise ContributionExportUnavailable("Contribution export pagination unavailable") + # Private expired membership only. Current page headers are protected by + # key-share locks; economic records are never targets of this cleanup. + expired = select(ContributionExportMembership.id).where( + ContributionExportMembership.expires_at <= now, + ).order_by(ContributionExportMembership.expires_at, ContributionExportMembership.id).limit(100) + expired_ids = tuple(await self._session.scalars(expired.with_for_update(skip_locked=True))) + if expired_ids: + await self._session.execute(delete(ContributionExportMembership).where( + ContributionExportMembership.id.in_(expired_ids), + )) + header = ContributionExportMembership( + id=new_record_id(), actor_profile_id=str(request.actor_profile_id), query_digest=digest, + exported_at=now, expires_at=now + timedelta(minutes=15), member_count=count, sealed=False, + audience=request.audience, project_id=None if request.project_id is None else str(request.project_id), + output_format=request.output_format, page_size=request.page_size, + contribution_type=request.contribution_type, recorded_from=request.recorded_from, + recorded_before=request.recorded_before, + ) + self._session.add(header) + await self._session.flush() + capture = self._selection(select(literal(header.id), ContributionRecord.id, + ContributionRecord.created_at), request) + await self._session.execute(insert(ContributionExportMember).from_select( + ["export_id", "contribution_id", "recorded_at"], capture, + )) + header.sealed = True + await self._session.flush() + return header, position + + async def read(self, request: ContributionReadRequest) -> ContributionReadPage: + """Read complete award definitions for a bounded original-membership page.""" request = ContributionReadRequest.model_validate(request) + header, position = await self._membership(request) query = select(ContributionRecord, ContributionPolicyVersion.version_number, ContributionRule.id, ContributionRule.compensation_mode).outerjoin( ContributionPolicyVersion, @@ -38,23 +116,27 @@ async def read(self, request: ContributionReadRequest) -> tuple[ContributionRead ContributionRule.project_id == ContributionRecord.project_id, ContributionRule.contribution_type == ContributionRecord.contribution_type, )) - if request.audience == "self": - query = query.where(ContributionRecord.contributor_id == str(request.actor_profile_id)) - if request.project_id is not None: - query = query.where(ContributionRecord.project_id == str(request.project_id)) - if request.contribution_type is not None: - query = query.where(ContributionRecord.contribution_type == request.contribution_type) - if request.recorded_from is not None: - query = query.where(ContributionRecord.created_at >= request.recorded_from) - if request.recorded_before is not None: - query = query.where(ContributionRecord.created_at < request.recorded_before) + query = self._selection(query, request).join(ContributionExportMember, and_( + ContributionExportMember.contribution_id == ContributionRecord.id, + ContributionExportMember.recorded_at == ContributionRecord.created_at, + ContributionExportMember.export_id == header.id, + )) + if position is not None: + query = query.where(tuple_(ContributionRecord.created_at, ContributionRecord.id) > + tuple_(position.last_recorded_at, position.last_contribution_id)) rows = (await self._session.execute(query.order_by( ContributionRecord.created_at, ContributionRecord.id, - ).limit(MAX_EXPORT_CONTRIBUTIONS + 1))).all() - if len(rows) > MAX_EXPORT_CONTRIBUTIONS: - raise ContributionExportTooLarge("Contribution export exceeds 1000 records; narrow the filters") + ).limit(request.page_size + 1))).all() + more = len(rows) > request.page_size + rows = rows[:request.page_size] + next_cursor = None + if more: + last = rows[-1][0] + next_cursor = self._cursor_codec.encode(ContributionCursor( + header.id, header.exported_at, header.expires_at, last.created_at, last.id, + ), query_digest=header.query_digest) if not rows: - return () + return ContributionReadPage(records=(), exported_at=header.exported_at, next_cursor=None) if any(version is None or rule is None or mode is None for _, version, rule, mode in rows): raise ContributionExportUnavailable("Contribution evidence unavailable") rule_ids = {rule for _, _, rule, _ in rows} @@ -67,8 +149,11 @@ async def read(self, request: ContributionReadRequest) -> tuple[ContributionRead id=definition.id, instrument=definition.instrument_type, unit=definition.unit_code, quantity=definition.quantity, )) - return tuple(self._facts(row, version, mode, tuple(by_rule[rule])) - for row, version, rule, mode in rows) + return ContributionReadPage( + records=tuple(self._facts(row, version, mode, tuple(by_rule[rule])) + for row, version, rule, mode in rows), + exported_at=header.exported_at, next_cursor=next_cursor, + ) @staticmethod def _facts(row, version, mode, definitions) -> ContributionReadFacts: diff --git a/backend/app/modules/contributions/records/read_service.py b/backend/app/modules/contributions/records/read_service.py index 5de02b519..de0eb0c13 100644 --- a/backend/app/modules/contributions/records/read_service.py +++ b/backend/app/modules/contributions/records/read_service.py @@ -1,7 +1,5 @@ """One authorized canonical evidence projection shared by JSON and CSV.""" -from datetime import UTC, datetime - from pydantic import ValidationError from app.modules.actors.api.contribution_labels import ( @@ -10,7 +8,6 @@ from app.modules.compensation.api.award_reads import ContributionAwardReadPort from app.modules.compensation.api.awards import CompensationAwardFacts from app.modules.contributions.api.records import ( - MAX_EXPORT_CONTRIBUTIONS, ContributionAwardView, ContributionExportResponse, ContributionExportTooLarge, ContributionExportUnavailable, ContributionReadAuthorizationPort, @@ -21,7 +18,7 @@ ContributionTaskSourceFacts, ContributionTaskSourceReadPort, ) from app.modules.contributions.records.read_facts import ( - ContributionReadFacts, ContributionReadRepositoryPort, + ContributionReadFacts, ContributionReadPage, ContributionReadRepositoryPort, ) @@ -56,10 +53,10 @@ async def read(self, request: ContributionReadRequest) -> ContributionExportResp request = ContributionReadRequest.model_validate(request) await self._authorization.authorize(request) try: - records = tuple(ContributionReadFacts.model_validate(row) - for row in await self._records.read(request)) - if len(records) > MAX_EXPORT_CONTRIBUTIONS: - raise ContributionExportTooLarge("Contribution export exceeds 1000 records; narrow the filters") + page = ContributionReadPage.model_validate(await self._records.read(request)) + records = tuple(ContributionReadFacts.model_validate(row) for row in page.records) + if len(records) > request.page_size: + raise ContributionExportUnavailable("Contribution page exceeds its authorized bound") for record in records: self._require_selected(record, request) record_ids = {record.id for record in records} @@ -96,7 +93,7 @@ async def read(self, request: ContributionReadRequest) -> ContributionExportResp actors[record.contributor_id], acceptances.get((record.project_id, record.source_final_acceptance_id)), ) for record in records) - return ContributionExportResponse(exported_at=datetime.now(UTC), items=items) + return ContributionExportResponse(exported_at=page.exported_at, items=items, next_cursor=page.next_cursor) except ContributionExportTooLarge: raise except (ValidationError, ValueError, TypeError) as exc: diff --git a/backend/tests/contributions/exports/test_pagination.py b/backend/tests/contributions/exports/test_pagination.py new file mode 100644 index 000000000..eaf8f00e1 --- /dev/null +++ b/backend/tests/contributions/exports/test_pagination.py @@ -0,0 +1,114 @@ +"""Real public pages freeze visible membership and reauthorize continuation.""" + +import asyncio + +from sqlalchemy import func, select, text + +from app.core.identifiers import new_record_id +from app.modules.contributions.records.export_models import ContributionExportMembership +from app.modules.authorization.repository import AdminAuthorizationRepository +from tests.contributions.records.support import authorized_submitter_source +from tests.tasks.post_submit_routing.support import completed_sibling_source +from tests.tasks.post_submit_routing.outcome_support import apply_outcome, invoked_completion +from .support import export_path + + +async def sibling_ready(h): + """Use real Submission/checker completion and authorized acceptance inputs.""" + sibling = await completed_sibling_source(h) + async with h.factory() as session, session.begin(): + await session.execute(text( + "UPDATE public.task_assignments SET accepted_at=clock_timestamp() " + "WHERE id=:id AND accepted_at IS NULL" + ), {"id": sibling.request.assignment_id}) + sibling.envelope = await invoked_completion(sibling) + return sibling + + +async def test_public_pages_exclude_pre_snapshot_uncommitted_record_after_it_commits( + tmp_path, auth_database_env, admin_access, live_acceptance_lifecycle, monkeypatch, +): + async with authorized_submitter_source(tmp_path, auth_database_env, paid=True) as h: + signed_access = admin_access.signed + reader = admin_access.target + path = export_path(h.submitter_record.project_id) + grant = await signed_access.grant(admin_access.admin, reader, role="project_manager", + project_id=h.submitter_record.project_id) + second = await sibling_ready(h) + async with h.factory() as session, session.begin(): + second_outcome = await apply_outcome(session, second, 2) + late = await sibling_ready(h) + established, proceed = asyncio.Event(), asyncio.Event() + original = AdminAuthorizationRepository.lock_project + name = "pilot10-fixed-membership-first" + + async def before_project_lock(repository, project_id): + if asyncio.current_task().get_name() == name: + assert await repository._session.scalar(text("SHOW transaction_isolation")) == "repeatable read" + established.set() + await proceed.wait() + return await original(repository, project_id) + + # Use project read so the existing AUTH locks establish the RR snapshot + # before waiting for the producer's project lock. The producer already + # inserted its real record before the first export starts. + monkeypatch.setattr(AdminAuthorizationRepository, "lock_project", before_project_lock) + async with h.factory() as producer: + await producer.begin() + late_outcome = await apply_outcome(producer, late, 2) + task = asyncio.create_task(signed_access.client.get( + path, params={"page_size": 1}, headers=reader.headers, + ), name=name) + try: + await asyncio.wait_for(established.wait(), 30) + await producer.commit() + proceed.set() + first = await asyncio.wait_for(task, 30) + finally: + proceed.set() + if not task.done(): + task.cancel() + await asyncio.gather(task, return_exceptions=True) + assert first.status_code == 200, first.text + cursor = first.json()["next_cursor"] + assert cursor is not None + for changed in ({"page_size": 2}, {"format": "csv"}, {"contribution_type": "completed_review"}): + invalid = await signed_access.client.get( + path, params={"page_size": 1, "cursor": cursor} | changed, headers=reader.headers, + ) + assert invalid.status_code == 422, invalid.text + assert invalid.json()["error"]["code"] == "contribution_export_invalid_cursor" + other = await signed_access.actor("other-membership-reader") + await signed_access.grant(admin_access.admin, other, role="project_manager", + project_id=h.submitter_record.project_id) + crossed = await signed_access.client.get( + path, params={"page_size": 1, "cursor": cursor}, headers=other.headers, + ) + assert crossed.status_code == 422, crossed.text + next_page = await signed_access.client.get( + path, params={"page_size": 1, "cursor": cursor}, headers=reader.headers, + ) + assert next_page.status_code == 200, next_page.text + assert next_page.json()["next_cursor"] is None + assert next_page.json()["exported_at"] == first.json()["exported_at"] + ids = [row["contribution_id"] for page in (first, next_page) for row in page.json()["items"]] + assert set(ids) == {str(h.submitter_record.id), str(second_outcome.economic.contribution_record_id)} + assert str(late_outcome.economic.contribution_record_id) not in ids + assert all(len(row["awards"]) == 2 for page in (first, next_page) for row in page.json()["items"]) + fresh = await signed_access.client.get(path, headers=reader.headers) + assert fresh.status_code == 200 + assert {row["contribution_id"] for row in fresh.json()["items"]} == set(ids) | { + str(late_outcome.economic.contribution_record_id), + } + async with h.factory() as session: + assert await session.scalar(select(func.count()).select_from(ContributionExportMembership)) >= 2 + revoked = await signed_access.client.post( + f"/api/v1/admin-role-grants/{grant}/revoke", + headers=admin_access.admin.headers | {"Idempotency-Key": str(new_record_id())}, + json={"reason": "Reauthorize every contribution continuation"}, + ) + assert revoked.status_code == 200, revoked.text + denied = await signed_access.client.get( + path, params={"page_size": 1, "cursor": cursor}, headers=reader.headers, + ) + assert denied.status_code == 404, denied.text diff --git a/backend/tests/contributions/exports/test_source_reads.py b/backend/tests/contributions/exports/test_source_reads.py index 41839ed3a..19f90647c 100644 --- a/backend/tests/contributions/exports/test_source_reads.py +++ b/backend/tests/contributions/exports/test_source_reads.py @@ -21,9 +21,11 @@ async def test_projection_reads_actual_immutable_source_and_complete_awards( await session.connection(execution_options={"isolation_level": "REPEATABLE READ"}) before = {table: await rows(session, table) for table in ("contribution_records", "compensation_awards", "final_acceptances")} - record, = await ContributionReadRepository(session).read(ContributionReadRequest( + page = await ContributionReadRepository(session, cursor_codec=None).read(ContributionReadRequest( audience="self", actor_profile_id=h.actor_context.actor_profile_id, )) + record, = page.records + assert page.next_cursor is None assert record.id == h.submitter_record.id assert record.source_final_acceptance_id == h.acceptance.id assert {definition.instrument for definition in record.award_definitions} == set(instruments) diff --git a/backend/tests/contributions/test_export_cursors.py b/backend/tests/contributions/test_export_cursors.py new file mode 100644 index 000000000..9d7a9b1be --- /dev/null +++ b/backend/tests/contributions/test_export_cursors.py @@ -0,0 +1,94 @@ +"""Continuation cannot expand actor/query scope or outlive one export.""" + +import base64 +from datetime import UTC, datetime, timedelta +import json + +import pytest + +from app.core.identifiers import new_record_id +from app.modules.contributions.api.records import ContributionReadRequest +from app.modules.contributions.records.cursors import ( + ContributionCursor, ContributionCursorCodec, InvalidContributionCursor, contribution_query_digest, +) + +NOW = datetime(2026, 10, 11, 16, tzinfo=UTC) +SECRET = b"a" * 32 + + +def selected(): + return ContributionReadRequest(audience="self", actor_profile_id=new_record_id()) + + +def state(): + return ContributionCursor(new_record_id(), NOW, NOW + timedelta(minutes=15), + NOW - timedelta(days=1), new_record_id()) + + +def test_cursor_roundtrip_retains_exact_membership_position_and_scope(): + codec, request, position = ContributionCursorCodec(SECRET), selected(), state() + digest = contribution_query_digest(request) + token = codec.encode(position, query_digest=digest) + assert len(token) < 4096 + assert codec.decode(token, query_digest=digest, now=NOW) == position + assert contribution_query_digest(request.model_copy(update={"cursor": token})) == digest + + +@pytest.mark.parametrize("field,value", [ + ("actor_profile_id", new_record_id()), ("audience", "project"), + ("project_id", new_record_id()), ("output_format", "csv"), ("page_size", 1), + ("contribution_type", "completed_review"), ("recorded_from", NOW), + ("recorded_before", NOW), +]) +def test_cursor_cannot_cross_actor_audience_filters_or_output(field, value): + codec, request = ContributionCursorCodec(SECRET), selected() + token = codec.encode(state(), query_digest=contribution_query_digest(request)) + other = request.model_copy(update={field: value}) + with pytest.raises(InvalidContributionCursor): + codec.decode(token, query_digest=contribution_query_digest(other), now=NOW) + + +@pytest.mark.parametrize("elapsed", [-1, 900, 901]) +def test_cursor_rejects_future_origin_or_expiry(elapsed): + codec, request = ContributionCursorCodec(SECRET), selected() + digest = contribution_query_digest(request) + token = codec.encode(state(), query_digest=digest) + with pytest.raises(InvalidContributionCursor): + codec.decode(token, query_digest=digest, now=NOW + timedelta(seconds=elapsed)) + + +@pytest.mark.parametrize("mutation", ["payload", "signature", "duplicate", "extra", "boolean_version"]) +def test_forged_envelopes_are_refused_without_echoing_input(mutation): + codec, request = ContributionCursorCodec(SECRET), selected() + digest = contribution_query_digest(request) + token = codec.encode(state(), query_digest=digest) + envelope = json.loads(base64.urlsafe_b64decode(token + "=" * (-len(token) % 4))) + if mutation == "payload": + envelope["p"]["export"] = str(new_record_id()) + elif mutation == "signature": + envelope["s"] = "A" * 43 + elif mutation == "extra": + envelope["extra"] = True + elif mutation == "boolean_version": + envelope["p"]["v"] = True + raw = json.dumps(envelope) + if mutation == "duplicate": + raw = raw.replace('"v": 1', '"v": 1, "v": 1') + forged = base64.urlsafe_b64encode(raw.encode()).decode().rstrip("=") + with pytest.raises(InvalidContributionCursor) as error: + codec.decode(forged, query_digest=digest, now=NOW) + assert str(error.value) == "Invalid contribution export cursor" + + +@pytest.mark.parametrize("value", ["", "x" * 4097, "abc=", "abc.def", "abc\n", "💰", "a"]) +def test_malformed_or_unbounded_cursor_is_refused(value): + with pytest.raises(InvalidContributionCursor): + ContributionCursorCodec(SECRET).decode(value, query_digest="irrelevant", now=NOW) + + +def test_signing_key_rotation_refuses_old_cursor(): + request = selected() + digest = contribution_query_digest(request) + token = ContributionCursorCodec(SECRET).encode(state(), query_digest=digest) + with pytest.raises(InvalidContributionCursor): + ContributionCursorCodec(b"b" * 32).decode(token, query_digest=digest, now=NOW) diff --git a/backend/tests/contributions/test_export_projection.py b/backend/tests/contributions/test_export_projection.py index d0a9e26a8..958d4151f 100644 --- a/backend/tests/contributions/test_export_projection.py +++ b/backend/tests/contributions/test_export_projection.py @@ -13,7 +13,7 @@ from app.modules.contributions.api.records import ( ContributionExportTooLarge, ContributionExportUnavailable, ContributionReadRequest, ) -from app.modules.contributions.records.read_facts import ContributionReadFacts, FrozenContributionAward +from app.modules.contributions.records.read_facts import ContributionReadFacts, ContributionReadPage, FrozenContributionAward from app.modules.contributions.records.read_service import ContributionReadService from app.modules.contributions.api.source_reads import ( ContributionAcceptanceSourceFacts, ContributionTaskSourceFacts, @@ -64,7 +64,7 @@ async def authorize(self, request): async def read(self, request): assert self.authorized, "owner load preceded authority" - return (self.value.record,) + return ContributionReadPage(records=(self.value.record,), exported_at=TIME) async def read_contribution_awards(self, selected): assert selected == (self.value.record.id,) @@ -158,13 +158,15 @@ async def test_faulty_over_limit_loader_cannot_start_owner_projections(): class OverLimit(Ports): async def read(self, request): assert self.authorized - return tuple(self.value.record.model_copy(update={"id": new_record_id()}) - for _ in range(1001)) + return ContributionReadPage(records=(self.value.record,), exported_at=TIME).model_copy( + update={"records": tuple(self.value.record.model_copy(update={"id": new_record_id()}) + for _ in range(1001))}, + ) async def read_contribution_awards(self, selected): pytest.fail("over-limit loader started owner projections") - with pytest.raises(ContributionExportTooLarge): + with pytest.raises(ContributionExportUnavailable): await service(OverLimit(value)).read(request(value)) @@ -223,3 +225,32 @@ async def test_human_acceptance_review_reference_does_not_replace_contribution_s assert item.acceptance_review_id == review_id assert item.source_review_id is item.source_review_lease_id is None assert item.source_final_acceptance_id == value.acceptance.id + + +async def test_projection_preserves_original_export_time_and_next_cursor(): + value = facts() + + class Continued(Ports): + async def read(self, request): + assert self.authorized + return ContributionReadPage(records=(self.value.record,), exported_at=TIME, + next_cursor="signed_continuation") + + response = await service(Continued(value)).read(request(value)) + assert response.exported_at == TIME + assert response.next_cursor == "signed_continuation" + + +async def test_page_size_refusal_precedes_loading_other_owners(): + value = facts() + + class FaultyPage(Ports): + async def read(self, request): + assert self.authorized + return ContributionReadPage(records=(self.value.record, self.value.record), exported_at=TIME) + + async def read_contribution_awards(self, selected): + pytest.fail("faulty oversized page loaded other owner facts") + + with pytest.raises(ContributionExportUnavailable): + await service(FaultyPage(value)).read(request(value).model_copy(update={"page_size": 1})) diff --git a/docs/roadmap_status.md b/docs/roadmap_status.md index 63bb8b16d..84e56d889 100644 --- a/docs/roadmap_status.md +++ b/docs/roadmap_status.md @@ -18,7 +18,8 @@ requests are the transient view of work currently under review. Bounded contribution evidence reads expose existing immutable work and award facts to the current human or authorized project exporter. They do not activate recognition writers, complete the public contribution journey or assert payment. -CLI consumption and fixed-membership pagination remain separate work. +Fixed-membership signed pagination extends those same authorized reads; CLI +consumption remains separate work. ## Product Goal @@ -274,7 +275,7 @@ cannot be reused as post-submission review-gate evidence. See the | Review queue and lease | **Hidden persistence foundation** | Queue/admission idempotency and ReviewLease/preference persistence; complete unavailable REV action/principal catalogue and typed AUTH contracts; ART-07A1 metadata-only packet contract and REV-03B immutable normalized packet persistence with live ingest custody; REV-04A Review/finding/resolution and completed request storage | Future resolver proof; canonical admission from `allow_review`; claim/lease/packet authority; lease copies the Submission-stamped policy version with no CON lookup | | Review decision and revision | **Hidden acceptance core; runtime planned** | Review/revision policy identities and mutation authority, with `requires_second_review` fixed false through typed and database boundaries; REV-04A immutable Review storage; REV-04B source storage; REV-04C hidden source-neutral FinalAcceptance/TASK/CON participant; approved same-task revision-rebase semantics | ARCH-04E2-B supplies mandatory source AUTH and complete database/audit/outbox closure for hidden automated outcomes. Human decision authority/composition, revision preparation, replay and recovery remain | | Contribution and compensation truth | **Hidden shared participant plus public policy administration** | ContributionPolicyVersion persistence; lifecycle-audit participant; adapter bindings; public Finance policy administration; REV-04B shared acceptance source storage; CON-03C immutable ContributionRecord/CompensationAward storage; obsolete guide-keyed payment storage and task-local payment fields removed; CON-07 source-neutral submitter participant and complete award sets; REV-04C composes it with FinalAcceptance/TASK effects in the caller transaction; 04F2 checker remediation creates no contribution or award | ARCH-04E2-B supplies exact routing authority/evidence, complete-set database closure and audit/outbox under REV-12A4A. Hidden B8 completion delivery is implemented; replacement/recovery and live composition remain before production consumption. Only actual Reviews create reviewer records. Obligation/root/ordinal custody remains deferred until fulfillment activation; no public recognition or fulfillment route is live | -| Contribution evidence reads | **Public bounded backend reads** | PILOT-10A exposes current human self-read and one-project JSON/CSV export for covering Project Managers or exact-project Finance Authorities; one fresh repeatable-read response with one narrowly bounded serialization-conflict retry and fresh authority, complete zero/one/two immutable awards, exact decimals, recorded-time filters and formula-neutralized CSV; 1,000-contribution maximum refuses excess without truncation | CLI consumption and stable fixed-membership paginated list remain separate; no recognition mutation, fulfillment, payout or deployed-service claim | +| Contribution evidence reads | **Public bounded backend reads** | PILOT-10A exposes current human self-read and one-project JSON/CSV export for covering Project Managers or exact-project Finance Authorities; one fresh repeatable-read response with one narrowly bounded serialization-conflict retry and fresh authority, complete zero/one/two immutable awards, exact decimals, recorded-time filters and formula-neutralized CSV; fixed membership up to 100,000 contributions and signed 15-minute continuation with up to 1,000 contributions per page | CLI consumption remains separate; no recognition mutation, fulfillment, payout or deployed-service claim | | Fulfillment, reconciliation, and audit | **Planned** | Shared audit foundations, provider-neutral adapter convention, AUTH-OUTBOX-02 live dispatcher authority, retained phase audit decisions, Celery delivery/recovery scans and CON-02B custody | Feature-specific handlers and authority, conditional award fulfillment, callbacks, idempotent recovery, reconciliation, bounded operational reads, and release controls | | Runtime diagnostics | **Implemented foundation** | Closed structured logging, explicit API/Celery tracing, bounded metrics, safe correlation and optional typed OTLP export | Restrict broker publishers; configure and secure collector/log access, egress, encryption and finite deletion; prove diagnostics during the release drill; no deployed monitoring claim | | Frontend and pilot | **Local runtime foundation; product pilot planned** | Checkout-isolated Docker Compose API, prefork Celery process, beat, PostgreSQL, Redis and MinIO stack with local Flow-HMAC identities, existing authority bootstrap/grants, configurable loopback ports and project-scoped state; a pinned offline sample image build and separate oracle were proved under gVisor; React + Vite + TypeScript stack decision | Implement the external launcher/checker images and benchmark a representative task before choosing production limits; complete provider-backed guide compilation and activated-guide scoped task-denial proof on the base stack, implement only stable backed frontend surfaces, run the real internal pilot, repair findings, and complete release drills; Docker Desktop/macOS runtime proof remains | @@ -954,8 +955,8 @@ v0.1 is not ready until all of the following are true: - Fulfillment and recovery are idempotent, observable, reconcilable, and safe under durable-job, provider, transaction, and unknown-commit failures. - Contribution evidence reads retain complete source/award identities with fresh - self or project authority, one response snapshot and explicit over-limit refusal. - CLI access and fixed-membership pagination remain later bounded work; exported + self or project authority, one fresh response snapshot and fixed-membership + signed pagination. CLI access remains later bounded work; exported award quantities are earned facts, not proof of external payment. - Configure secured diagnostic collection with bounded retention and access, and prove API/Celery correlation, privacy and collector-outage behavior in @@ -1084,9 +1085,12 @@ remaining trace sequence is: - Review/revision: REV packet/schema foundations may proceed independently, but live admission starts after `ARCH-04E`; the first live Review commit also requires the atomic CON decision participant on the delivered CON-03C storage. +- [PILOT-10B's fixed-membership pagination](../.commitrail/changes/pilot10-stable-contribution-pagination.md) + extends existing authorized evidence reads without economic mutation. - [PILOT-10A's bounded read/export record](../.commitrail/changes/pilot10-contribution-award-export.md) distinguishes public evidence reads from hidden recognition and deferred - fulfillment. The [canonical read contract](spec_contribution_compensation.md#bounded-contribution-evidence-reads) + fulfillment. Fixed-membership signed pagination extends the same read owner; + CLI consumption remains separately scoped. The [canonical read contract](spec_contribution_compensation.md#bounded-contribution-evidence-reads) defines scope, limits, exact quantities, time semantics and CSV safeguards. For implementation ownership and exact contracts, contributors can follow diff --git a/docs/spec_contribution_compensation.md b/docs/spec_contribution_compensation.md index ba8329b63..9debdac97 100644 --- a/docs/spec_contribution_compensation.md +++ b/docs/spec_contribution_compensation.md @@ -989,12 +989,33 @@ errors are not retried; a second 40001 remains unavailable. This bounded read recovery does not retry product mutations. Export reads mutate no recognition or economic facts. -The maximum is 1,000 selected contributions. Filters apply before the repository -probes the 1,001st row; excess selection returns 422 +The complete fixed membership is bounded at 100,000 selected contributions. +Each response accepts `page_size` (1–1,000, default 100) and optional `cursor`. +Filters apply before membership capture; excess selection returns 422 `contribution_export_too_large` with no partial export. Empty selections succeed. -Rows sort by `(recorded_at, contribution_id)` for display, not commit order. -There is no continuation cursor or snapshot retained across requests. Fixed -membership pagination and CLI consumption remain separate implementation work. +Rows sort by `(recorded_at, contribution_id)`, not business commit order. + +The first response captures its visible selected contribution identities in +CON-private, expiring native membership rows, separate from retained economic +facts. Native guards require sealing the complete member set before commit and +refuse subsequent additions or changes. Later commits, even from transactions +already in progress at capture, cannot enter the original selection. Every page +reapplies the selected actor/project/type/time filters and fresh canonical AUTH; +stored membership confers no read authority. Source display labels may reflect +the fresh page snapshot; contribution membership and economic facts are fixed. + +JSON returns `exported_at`, `items` and `next_cursor` (null on the final page). +CSV returns `X-Workstream-Exported-At` and, when another page exists, +`X-Workstream-Next-Cursor`. The export instant is identical on every page. +Signed cursors bind the original member set, actor, audience, project, normalized +filters, output format, page size, expiry and last ordering key. Change none of +those selections during traversal. Cursors expire after 15 minutes; malformed, +forged, expired or mismatched continuation returns 422 +`contribution_export_invalid_cursor`. Restart an export for a fresh selection. +The existing `WORKSTREAM_PAGINATION_CURSOR_HMAC_SECRET` is required for +continuation; an unavailable key refuses pagination rather than inventing one. +Expired private membership alone is cleaned in bounded batches, never retained +contributions, awards or audits. CLI consumption is a separate bounded change. CSV uses the same validated projection, quotes every UTF-8 cell and retains one row for an unpaid contribution or one row per award (at most 2,000 data rows). @@ -1183,11 +1204,11 @@ repository; all communication is through typed ports. Contribution and award reads use PostgreSQL canonical truth directly. They do not depend on ART, optional evidence, provider availability, balances, or -settlement ledgers. The public contribution reads use the bounded single-response -contract above, with no continuation cursor, exact self/project scope, -pre-filtering, and concealment. Stable fixed-membership pagination remains later -issue #497 work. Provider references, credentials, and secret routes are never -returned. +settlement ledgers. The public contribution reads use the bounded fixed-membership +page contract above, with signed expiring continuation, exact self/project scope, +pre-filtering and fresh authorization/concealment on every page. CLI consumption +remains separately scoped issue #497 work. Provider references, credentials and +secret routes are never returned. CP05A exposes only ContributionPolicy administration, using the existing CP05 Finance authority and caller-owned transaction. Under the project-scoped @@ -1305,7 +1326,8 @@ not wait for contribution/award persistence or REV decisions. PILOT-10's bounded reads consume existing immutable CON/award facts after their own exact AUTH/audit activation and snapshot proof. They do not wait for CON-08B fulfillment or the historical CON-10A ordering below. The later fixed-membership -list and CLI remain separately scoped under issue 497. +list extends those reads without changing economic facts; CLI remains separately +scoped under issue 497. ```text CON-01 -> CON-02A From 839b5356fd2559e89c532be86d7782e3b900f0a7 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 16:38:10 +0100 Subject: [PATCH 036/283] [PILOT-10] Register export membership in the canonical CON model graph --- .../pilot10-stable-contribution-pagination.md | 6 +- .../contributions/records/export_models.py | 61 ------------------- .../modules/contributions/records/models.py | 54 +++++++++++++++- .../contributions/records/read_repository.py | 2 +- .../contributions/exports/test_pagination.py | 2 +- .../test_export_model_registry.py | 26 ++++++++ 6 files changed, 86 insertions(+), 65 deletions(-) delete mode 100644 backend/app/modules/contributions/records/export_models.py create mode 100644 backend/tests/contributions/test_export_model_registry.py diff --git a/.commitrail/changes/pilot10-stable-contribution-pagination.md b/.commitrail/changes/pilot10-stable-contribution-pagination.md index bde951b6d..a41e29097 100644 --- a/.commitrail/changes/pilot10-stable-contribution-pagination.md +++ b/.commitrail/changes/pilot10-stable-contribution-pagination.md @@ -88,7 +88,11 @@ CLI is a separate bounded PR. ## Review findings Focused peer plan review selected private expiring membership over cluster-local -transaction-ID coupling. Implementation still requires installed-schema proof. +transaction-ID coupling. Source review reproduced missing canonical-only model +registration in a fresh process. Membership declarations now live in CON's +existing registered records/models.py; the separate declaration module was +removed, with a fresh-process regression preserving native FK compilation. +Implementation still requires installed-schema proof. ## Reconciliation diff --git a/backend/app/modules/contributions/records/export_models.py b/backend/app/modules/contributions/records/export_models.py deleted file mode 100644 index 6fa5d87d2..000000000 --- a/backend/app/modules/contributions/records/export_models.py +++ /dev/null @@ -1,61 +0,0 @@ -"""Expiring private membership, separate from retained economic contribution facts.""" - -from datetime import datetime -from uuid import UUID - -from sqlalchemy import Boolean, CheckConstraint, DateTime, ForeignKey, Integer, String, Uuid -from sqlalchemy.orm import Mapped, mapped_column - -from app.db.base import Base - - -class ContributionExportMembership(Base): - """One bounded export selection; it grants no authority on later reads.""" - - __tablename__ = "contribution_export_memberships" - __table_args__ = ( - CheckConstraint("(get_byte(uuid_send(id), 6) >> 4) = 7 and (get_byte(uuid_send(id), 8) & 192) = 128", - name="id_uuid7"), - CheckConstraint("query_digest ~ '^sha256:[0-9a-f]{64}$'", name="query_digest"), - CheckConstraint("expires_at = exported_at + interval '15 minutes'", name="expiry"), - CheckConstraint("member_count between 0 and 100000", name="member_count"), - CheckConstraint("audience in ('self','project') and (audience != 'project' or project_id is not null)", - name="audience"), - CheckConstraint("output_format in ('json','csv')", name="output_format"), - CheckConstraint("page_size between 1 and 1000", name="page_size"), - CheckConstraint("contribution_type is null or contribution_type in ('accepted_submission','completed_review')", - name="contribution_type"), - CheckConstraint("recorded_from is null or recorded_before is null or recorded_from < recorded_before", - name="recorded_interval"), - ) - id: Mapped[UUID] = mapped_column(Uuid(), primary_key=True) - actor_profile_id: Mapped[str] = mapped_column( - Uuid(as_uuid=False), ForeignKey("actor_profiles.id", ondelete="RESTRICT"), nullable=False, - ) - audience: Mapped[str] = mapped_column(String(16), nullable=False) - project_id: Mapped[str | None] = mapped_column( - Uuid(as_uuid=False), ForeignKey("projects.id", ondelete="RESTRICT"), - ) - output_format: Mapped[str] = mapped_column(String(4), nullable=False) - page_size: Mapped[int] = mapped_column(Integer, nullable=False) - contribution_type: Mapped[str | None] = mapped_column(String(32)) - recorded_from: Mapped[datetime | None] = mapped_column(DateTime(timezone=True)) - recorded_before: Mapped[datetime | None] = mapped_column(DateTime(timezone=True)) - member_count: Mapped[int] = mapped_column(Integer, nullable=False) - sealed: Mapped[bool] = mapped_column(Boolean, nullable=False) - query_digest: Mapped[str] = mapped_column(String(71), nullable=False) - exported_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False) - expires_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False, index=True) - - -class ContributionExportMember(Base): - """Immutable originally visible identity and its source ordering timestamp.""" - - __tablename__ = "contribution_export_members" - export_id: Mapped[UUID] = mapped_column( - Uuid(), ForeignKey("contribution_export_memberships.id", ondelete="CASCADE"), primary_key=True, - ) - contribution_id: Mapped[UUID] = mapped_column( - Uuid(), ForeignKey("contribution_records.id", ondelete="RESTRICT"), primary_key=True, - ) - recorded_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False) diff --git a/backend/app/modules/contributions/records/models.py b/backend/app/modules/contributions/records/models.py index 51cbd2a23..10b0355c1 100644 --- a/backend/app/modules/contributions/records/models.py +++ b/backend/app/modules/contributions/records/models.py @@ -3,7 +3,7 @@ from datetime import datetime from uuid import UUID -from sqlalchemy import CheckConstraint, DateTime, ForeignKey, String, UniqueConstraint, Uuid, text +from sqlalchemy import Boolean, CheckConstraint, DateTime, ForeignKey, Integer, String, UniqueConstraint, Uuid, text from sqlalchemy.orm import Mapped, mapped_column from app.db.base import Base @@ -65,3 +65,55 @@ class ContributionRecord(Base): created_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), nullable=False, server_default=text("clock_timestamp()") ) + + +class ContributionExportMembership(Base): + """One bounded export selection; it grants no authority on later reads.""" + + __tablename__ = "contribution_export_memberships" + __table_args__ = ( + CheckConstraint("(get_byte(uuid_send(id), 6) >> 4) = 7 and (get_byte(uuid_send(id), 8) & 192) = 128", + name="id_uuid7"), + CheckConstraint("query_digest ~ '^sha256:[0-9a-f]{64}$'", name="query_digest"), + CheckConstraint("expires_at = exported_at + interval '15 minutes'", name="expiry"), + CheckConstraint("member_count between 0 and 100000", name="member_count"), + CheckConstraint("audience in ('self','project') and (audience != 'project' or project_id is not null)", + name="audience"), + CheckConstraint("output_format in ('json','csv')", name="output_format"), + CheckConstraint("page_size between 1 and 1000", name="page_size"), + CheckConstraint("contribution_type is null or contribution_type in ('accepted_submission','completed_review')", + name="contribution_type"), + CheckConstraint("recorded_from is null or recorded_before is null or recorded_from < recorded_before", + name="recorded_interval"), + ) + id: Mapped[UUID] = mapped_column(Uuid(), primary_key=True) + actor_profile_id: Mapped[str] = mapped_column( + Uuid(as_uuid=False), ForeignKey("actor_profiles.id", ondelete="RESTRICT"), nullable=False, + ) + audience: Mapped[str] = mapped_column(String(16), nullable=False) + project_id: Mapped[str | None] = mapped_column( + Uuid(as_uuid=False), ForeignKey("projects.id", ondelete="RESTRICT"), + ) + output_format: Mapped[str] = mapped_column(String(4), nullable=False) + page_size: Mapped[int] = mapped_column(Integer, nullable=False) + contribution_type: Mapped[str | None] = mapped_column(String(32)) + recorded_from: Mapped[datetime | None] = mapped_column(DateTime(timezone=True)) + recorded_before: Mapped[datetime | None] = mapped_column(DateTime(timezone=True)) + member_count: Mapped[int] = mapped_column(Integer, nullable=False) + sealed: Mapped[bool] = mapped_column(Boolean, nullable=False) + query_digest: Mapped[str] = mapped_column(String(71), nullable=False) + exported_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False) + expires_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False, index=True) + + +class ContributionExportMember(Base): + """Immutable originally visible identity and its source ordering timestamp.""" + + __tablename__ = "contribution_export_members" + export_id: Mapped[UUID] = mapped_column( + Uuid(), ForeignKey("contribution_export_memberships.id", ondelete="CASCADE"), primary_key=True, + ) + contribution_id: Mapped[UUID] = mapped_column( + Uuid(), ForeignKey("contribution_records.id", ondelete="RESTRICT"), primary_key=True, + ) + recorded_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False) diff --git a/backend/app/modules/contributions/records/read_repository.py b/backend/app/modules/contributions/records/read_repository.py index ef8771662..7e82d17c3 100644 --- a/backend/app/modules/contributions/records/read_repository.py +++ b/backend/app/modules/contributions/records/read_repository.py @@ -18,7 +18,7 @@ from app.modules.contributions.records.models import ContributionRecord from app.core.identifiers import new_record_id from app.modules.contributions.records.cursors import ContributionCursor, ContributionCursorCodec, contribution_query_digest -from app.modules.contributions.records.export_models import ContributionExportMember, ContributionExportMembership +from app.modules.contributions.records.models import ContributionExportMember, ContributionExportMembership from app.modules.contributions.records.read_facts import ContributionReadFacts, ContributionReadPage, FrozenContributionAward diff --git a/backend/tests/contributions/exports/test_pagination.py b/backend/tests/contributions/exports/test_pagination.py index eaf8f00e1..ccef117ac 100644 --- a/backend/tests/contributions/exports/test_pagination.py +++ b/backend/tests/contributions/exports/test_pagination.py @@ -5,7 +5,7 @@ from sqlalchemy import func, select, text from app.core.identifiers import new_record_id -from app.modules.contributions.records.export_models import ContributionExportMembership +from app.modules.contributions.records.models import ContributionExportMembership from app.modules.authorization.repository import AdminAuthorizationRepository from tests.contributions.records.support import authorized_submitter_source from tests.tasks.post_submit_routing.support import completed_sibling_source diff --git a/backend/tests/contributions/test_export_model_registry.py b/backend/tests/contributions/test_export_model_registry.py new file mode 100644 index 000000000..01e957de5 --- /dev/null +++ b/backend/tests/contributions/test_export_model_registry.py @@ -0,0 +1,26 @@ +"""Canonical-only process discovery must include private export membership custody.""" + +from pathlib import Path +import subprocess +import sys + + +def test_export_membership_is_registered_without_loading_its_read_repository(): + code = ''' +import sys +import app.db.models +from app.db.base import Base +from sqlalchemy.schema import CreateTable +from sqlalchemy.dialects.postgresql import dialect +assert "app.modules.contributions.records.read_repository" not in sys.modules +for name in ("contribution_export_memberships", "contribution_export_members"): + assert name in Base.metadata.tables, name + table = Base.metadata.tables[name] + assert table.foreign_keys + for foreign_key in table.foreign_keys: + assert foreign_key.column is not None + assert str(CreateTable(table).compile(dialect=dialect())) +''' + result = subprocess.run([sys.executable, "-c", code], cwd=Path(__file__).resolve().parents[2], + capture_output=True, text=True, timeout=60) + assert result.returncode == 0, result.stdout + result.stderr From c173db1726fc0dae98e6784a64e61d895aa28952 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 16:50:11 +0100 Subject: [PATCH 037/283] [PILOT-10] Bound public continuation and retain exact CI ownership --- .ci/behavior-ownership/partition.v1.json | 6 ++++- .../pilot10-stable-contribution-pagination.md | 5 ++-- README.md | 8 +++++++ backend/app/api/routes/contributions.py | 20 ++++++++++++---- .../modules/contributions/records/models.py | 5 +++- backend/scripts/test_lane_catalogue.py | 3 +++ .../contributions/exports/test_pagination.py | 24 +++++++++++++++++++ 7 files changed, 63 insertions(+), 8 deletions(-) diff --git a/.ci/behavior-ownership/partition.v1.json b/.ci/behavior-ownership/partition.v1.json index 31a05198b..d912acc9b 100644 --- a/.ci/behavior-ownership/partition.v1.json +++ b/.ci/behavior-ownership/partition.v1.json @@ -1104,6 +1104,10 @@ "group": "lifecycle", "target": "backend/app/modules/contributions/records/csv.py" }, + { + "group": "lifecycle", + "target": "backend/app/modules/contributions/records/cursors.py" + }, { "group": "lifecycle", "target": "backend/app/modules/contributions/records/models.py" @@ -1889,7 +1893,7 @@ "target": "backend/scripts/validate_test_lane_evidence.py" } ], - "authority_digest": "f735dc65412c3c09d4d06ff704d5a44d885385dd42d2cb06dddc9c4492e21675", + "authority_digest": "6284baec6963567f6e4fe22b9f8eafacbbe7c8174544cd4d36235ea3e7b4927d", "protected_base_commit": "7676ce4347db0c9694962a9b587a20765e16eac6", "schema": "workstream.behavior-ownership-partition.v1" } diff --git a/.commitrail/changes/pilot10-stable-contribution-pagination.md b/.commitrail/changes/pilot10-stable-contribution-pagination.md index a41e29097..f4a1c13f6 100644 --- a/.commitrail/changes/pilot10-stable-contribution-pagination.md +++ b/.commitrail/changes/pilot10-stable-contribution-pagination.md @@ -22,6 +22,7 @@ protects other reads; it does not freeze export membership across transactions. - CON API/read facts, repository, projection, owner-local export cursor codec and record model; explicit CON composition and existing export REST dependencies/routes. +- Read indexes for existing CON actor/project ordering and private membership ordering. - One sole-author native migration and corresponding schema/reset registration, after coordination with the existing migration owner; no guessed revision. - Focused contribution projection/cursor/native public-API regression tests, @@ -80,9 +81,9 @@ CLI is a separate bounded PR. | Claim | Command or proof | Result | Remaining uncertainty | |---|---|---|---| -| Current implementation | Inspect canonical CON read and AUTH keyset owner | Existing bounded reader and codec identified | Native membership design needs review | +| Current implementation | Inspect canonical CON read and AUTH keyset owner | Existing read extended; peer selected expiring native membership | Installed native implementation pending | | Membership/authority | Real PostgreSQL installed-schema public reads, delayed commit and revocation controls | Planned | No native runtime claim yet | -| Cursor validation | Focused tamper, scope, expiry and serialization controls | Planned | Implementation pending | +| Cursor/projection validation | Focused cursor, exact projection, CSV and canonical-only model discovery | 68 pass; independent scope/expiry mutants fail intended assertions | No native membership claim | | Required repository checks | Focused checks plus required hosted CI and independent review | Planned | No readiness claim | ## Review findings diff --git a/README.md b/README.md index e08cbaf4a..52be3a175 100644 --- a/README.md +++ b/README.md @@ -221,6 +221,14 @@ composition remain before public intake and the first real end-to-end drill. Active work stays on that first contribution path. Live human review/revision, reviewer participation and fulfillment delivery follow separately. +Current human contributors can read their own contribution evidence at +`GET /api/v1/actors/me/contributions`; covering Project Managers and exact-project +Finance Authorities can export it at +`GET /api/v1/projects/{project_id}/contributions/export`. JSON and CSV share +complete exact award facts and signed, 15-minute fixed-membership pagination. +Use the returned cursor with unchanged filters, format and page size; authorization +is checked on every page. See the [contribution evidence contract](docs/spec_contribution_compensation.md#bounded-contribution-evidence-reads) +for limits and continuation details. These are earned facts, not proof of payment. Contribution evidence remains the input for a separately implemented future reputation projection. Frontend product work follows stable and tested backend contracts for the surface it consumes. diff --git a/backend/app/api/routes/contributions.py b/backend/app/api/routes/contributions.py index 7d9ead179..cdda6b785 100644 --- a/backend/app/api/routes/contributions.py +++ b/backend/app/api/routes/contributions.py @@ -3,7 +3,7 @@ from typing import Annotated, Literal from uuid import UUID -from fastapi import APIRouter, Depends +from fastapi import APIRouter, Depends, Query from pydantic import AwareDatetime, ValidationError from app.api.deps.contribution_exports import ( @@ -14,7 +14,15 @@ router = APIRouter(tags=["contributions"]) _ERRORS = {status: {"model": ApiErrorResponse} for status in (404, 422, 503)} -_CSV = {"200": {"content": {"text/csv": {"schema": {"type": "string"}}}}} +_CSV = {"200": { + "content": {"text/csv": {"schema": {"type": "string"}}}, + "headers": { + "X-Workstream-Exported-At": {"description": "CSV original export instant, identical on every page", + "schema": {"type": "string", "format": "date-time"}}, + "X-Workstream-Next-Cursor": {"description": "CSV continuation; absent on the final page", + "schema": {"type": "string", "maxLength": 4096}}, + }, +}} def _selected(context, audience, project_id, output_format, contribution_type, recorded_from, recorded_before, @@ -39,7 +47,9 @@ async def read_own_contributions( project_id: UUID | None = None, format: Literal["json", "csv"] = "json", contribution_type: Literal["accepted_submission", "completed_review"] | None = None, recorded_from: AwareDatetime | None = None, recorded_before: AwareDatetime | None = None, - page_size: int = 100, cursor: str | None = None, + page_size: Annotated[int, Query(ge=1, le=1000)] = 100, + cursor: Annotated[str | None, Query(min_length=1, max_length=4096, + pattern=r"^[A-Za-z0-9_-]+$")] = None, ): """Return one authorized page of a fixed own-contribution selection.""" return await contribution_export_response(context, _selected( @@ -55,7 +65,9 @@ async def export_project_contributions( format: Literal["json", "csv"] = "json", contribution_type: Literal["accepted_submission", "completed_review"] | None = None, recorded_from: AwareDatetime | None = None, recorded_before: AwareDatetime | None = None, - page_size: int = 100, cursor: str | None = None, + page_size: Annotated[int, Query(ge=1, le=1000)] = 100, + cursor: Annotated[str | None, Query(min_length=1, max_length=4096, + pattern=r"^[A-Za-z0-9_-]+$")] = None, ): """Export one project for covering PM or exact-project Finance authority.""" return await contribution_export_response(context, _selected( diff --git a/backend/app/modules/contributions/records/models.py b/backend/app/modules/contributions/records/models.py index 10b0355c1..c1dfcb180 100644 --- a/backend/app/modules/contributions/records/models.py +++ b/backend/app/modules/contributions/records/models.py @@ -3,7 +3,7 @@ from datetime import datetime from uuid import UUID -from sqlalchemy import Boolean, CheckConstraint, DateTime, ForeignKey, Integer, String, UniqueConstraint, Uuid, text +from sqlalchemy import Boolean, CheckConstraint, DateTime, ForeignKey, Index, Integer, String, UniqueConstraint, Uuid, text from sqlalchemy.orm import Mapped, mapped_column from app.db.base import Base @@ -30,6 +30,8 @@ class ContributionRecord(Base): CheckConstraint("artifact_hash ~ '^sha256:[0-9a-f]{64}$'", name="artifact_hash"), UniqueConstraint("source_review_id"), UniqueConstraint("source_final_acceptance_id"), + Index("ix_contribution_records_self_export", "contributor_id", "created_at", "id"), + Index("ix_contribution_records_project_export", "project_id", "created_at", "id"), ) id: Mapped[UUID] = mapped_column(Uuid(), primary_key=True) @@ -110,6 +112,7 @@ class ContributionExportMember(Base): """Immutable originally visible identity and its source ordering timestamp.""" __tablename__ = "contribution_export_members" + __table_args__ = (Index("ix_contribution_export_members_order", "export_id", "recorded_at", "contribution_id"),) export_id: Mapped[UUID] = mapped_column( Uuid(), ForeignKey("contribution_export_memberships.id", ondelete="CASCADE"), primary_key=True, ) diff --git a/backend/scripts/test_lane_catalogue.py b/backend/scripts/test_lane_catalogue.py index 41f0830c4..a7b4a3c36 100644 --- a/backend/scripts/test_lane_catalogue.py +++ b/backend/scripts/test_lane_catalogue.py @@ -261,12 +261,15 @@ class TestLane: PROJECT_MODULES = ( "tests/contributions/test_export_csv.py", "tests/contributions/test_export_projection.py", + "tests/contributions/test_export_cursors.py", + "tests/contributions/test_export_model_registry.py", "tests/authorization/test_contribution_read_scope.py", "tests/authorization/test_contribution_read_kernel.py", "tests/contributions/exports/test_source_reads.py", "tests/contributions/exports/test_public_reads.py", "tests/contributions/exports/test_failures.py", "tests/contributions/exports/test_concurrency.py", + "tests/contributions/exports/test_pagination.py", # Atomic submission composition shares the existing multi-owner project lanes; # task C and schema are close to their cap on the merged baseline. "tests/tasks/evaluation_delivery/test_custody.py", diff --git a/backend/tests/contributions/exports/test_pagination.py b/backend/tests/contributions/exports/test_pagination.py index ccef117ac..9ec6938f8 100644 --- a/backend/tests/contributions/exports/test_pagination.py +++ b/backend/tests/contributions/exports/test_pagination.py @@ -1,6 +1,8 @@ """Real public pages freeze visible membership and reauthorize continuation.""" import asyncio +import csv +from io import StringIO from sqlalchemy import func, select, text @@ -85,6 +87,11 @@ async def before_project_lock(repository, project_id): path, params={"page_size": 1, "cursor": cursor}, headers=other.headers, ) assert crossed.status_code == 422, crossed.text + ungranted = await signed_access.actor("ungranted-membership-reader") + concealed = await signed_access.client.get( + path, params={"page_size": 1, "cursor": cursor}, headers=ungranted.headers, + ) + assert concealed.status_code == 404, concealed.text next_page = await signed_access.client.get( path, params={"page_size": 1, "cursor": cursor}, headers=reader.headers, ) @@ -100,6 +107,23 @@ async def before_project_lock(repository, project_id): assert {row["contribution_id"] for row in fresh.json()["items"]} == set(ids) | { str(late_outcome.economic.contribution_record_id), } + csv_rows, csv_origin, csv_cursor = [], None, None + for page_number in range(3): + params = {"page_size": 1, "format": "csv"} + if csv_cursor is not None: + params["cursor"] = csv_cursor + csv_page = await signed_access.client.get(path, params=params, headers=reader.headers) + assert csv_page.status_code == 200, csv_page.text + if csv_origin is None: + csv_origin = csv_page.headers["X-Workstream-Exported-At"] + assert csv_page.headers["X-Workstream-Exported-At"] == csv_origin + csv_rows.extend(csv.DictReader(StringIO(csv_page.text, newline=""))) + csv_cursor = csv_page.headers.get("X-Workstream-Next-Cursor") + assert (csv_cursor is None) is (page_number == 2) + assert {row["contribution_id"] for row in csv_rows} == { + row["contribution_id"] for row in fresh.json()["items"] + } + assert len(csv_rows) == 6 async with h.factory() as session: assert await session.scalar(select(func.count()).select_from(ContributionExportMembership)) >= 2 revoked = await signed_access.client.post( From 2e14c4bb43566caf54f63d687cd03dcf4e9f7339 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 16:52:48 +0100 Subject: [PATCH 038/283] [PILOT-10] Reconcile pagination in the current capability diagram --- docs/roadmap_status.md | 3 ++- docs/spec_contribution_compensation.md | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/roadmap_status.md b/docs/roadmap_status.md index 84e56d889..e8a92f278 100644 --- a/docs/roadmap_status.md +++ b/docs/roadmap_status.md @@ -864,7 +864,8 @@ Delivered foundations (not a claim of full public integration) PILOT-10A public bounded evidence reads over existing immutable CON/awards active human self or covering PM / exact-project Finance -> JSON or CSV - no recognition writer or fulfillment dependency; CLI/pagination remain + PILOT-10B fixed membership + signed expiring pages, fresh authority each page + no recognition writer or fulfillment dependency; CLI remains Remaining integration PILOT-02 separately scoped atomic DRAFT import -> explicit batch screen/release diff --git a/docs/spec_contribution_compensation.md b/docs/spec_contribution_compensation.md index 9debdac97..2e90067d0 100644 --- a/docs/spec_contribution_compensation.md +++ b/docs/spec_contribution_compensation.md @@ -1325,7 +1325,7 @@ not wait for contribution/award persistence or REV decisions. PILOT-10's bounded reads consume existing immutable CON/award facts after their own exact AUTH/audit activation and snapshot proof. They do not wait for CON-08B -fulfillment or the historical CON-10A ordering below. The later fixed-membership +fulfillment or the historical CON-10A ordering below. The fixed-membership list extends those reads without changing economic facts; CLI remains separately scoped under issue 497. From 6d315a41e7511906793da4cbb86ee2d697066576 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 16:58:50 +0100 Subject: [PATCH 039/283] feat: install batch transition custody --- backend/alembic/env.py | 3 +- .../versions/0035_task_batch_transitions.py | 456 ++++++++++++++++++ backend/tests/conftest.py | 6 +- backend/tests/test_alembic.py | 2 +- 4 files changed, 464 insertions(+), 3 deletions(-) create mode 100644 backend/alembic/versions/0035_task_batch_transitions.py diff --git a/backend/alembic/env.py b/backend/alembic/env.py index 524bd5a04..23b87417a 100644 --- a/backend/alembic/env.py +++ b/backend/alembic/env.py @@ -21,7 +21,7 @@ target_metadata = Base.metadata _BASELINE_REVISION = "0001_uuid7_v01" -_CURRENT_HEAD_REVISION = "0034_task_import_batches" +_CURRENT_HEAD_REVISION = "0035_task_batch_transitions" _RECREATE_GUIDANCE = ( "Workstream v0.1 requires a fresh database; recreate this database before " "running the 0001_uuid7_v01 migration" @@ -87,6 +87,7 @@ def do_run_migrations(connection: Connection) -> None: ("0031_task_import_source",), ("0032_checker_remediation",), ("0033_contribution_reads",), + ("0034_task_import_batches",), (_CURRENT_HEAD_REVISION,), ): raise RuntimeError(_RECREATE_GUIDANCE) diff --git a/backend/alembic/versions/0035_task_batch_transitions.py b/backend/alembic/versions/0035_task_batch_transitions.py new file mode 100644 index 000000000..b03008297 --- /dev/null +++ b/backend/alembic/versions/0035_task_batch_transitions.py @@ -0,0 +1,456 @@ +"""Install immutable aggregate custody for complete native batch transitions.""" + +from alembic import op +import sqlalchemy as sa +from sqlalchemy.dialects import postgresql + + +revision = "0035_task_batch_transitions" +down_revision = "0034_task_import_batches" +branch_labels = None +depends_on = None + + +_TABLES = ("task_batch_transition_receipts", "task_batch_transition_members") + + +def _replace_function(signature: str, old: str, new: str) -> None: + body = ( + op.get_bind() + .execute( + sa.text("select pg_catalog.pg_get_functiondef(cast(:signature as regprocedure))"), + {"signature": signature}, + ) + .scalar_one() + ) + if body.count(old) != 1: + raise RuntimeError(f"bulk transition predecessor function shape changed: {signature}") + op.execute(body.replace(old, new)) + + +def _create_tables() -> None: + op.create_table( + "task_batch_transition_receipts", + sa.Column("id", sa.Uuid(), nullable=False), + sa.Column("actor_profile_id", sa.Uuid(), nullable=False), + sa.Column("identity_link_id", sa.Uuid(), nullable=False), + sa.Column("action_id", sa.String(160), nullable=False), + sa.Column("idempotency_key", sa.Uuid(), nullable=False), + sa.Column("request_digest", sa.String(71), nullable=False), + sa.Column("reason", sa.Text(), nullable=True), + sa.Column("project_id", sa.Uuid(), nullable=False), + sa.Column("batch_id", sa.Uuid(), nullable=False), + sa.Column("manifest_digest", sa.String(71), nullable=False), + sa.Column("membership_digest", sa.String(71), nullable=False), + sa.Column("row_count", sa.Integer(), nullable=False), + sa.Column("status", sa.String(16), nullable=False), + sa.Column("response", postgresql.JSONB(none_as_null=True), nullable=True), + sa.Column( + "created_at", + sa.DateTime(timezone=True), + server_default=sa.text("now()"), + nullable=False, + ), + sa.Column("committed_at", sa.DateTime(timezone=True), nullable=True), + sa.PrimaryKeyConstraint("id"), + sa.ForeignKeyConstraint( + ["actor_profile_id"], + ["public.actor_profiles.id"], + ondelete="RESTRICT", + deferrable=True, + initially="DEFERRED", + ), + sa.ForeignKeyConstraint( + ["identity_link_id", "actor_profile_id"], + ["public.actor_identity_links.id", "public.actor_identity_links.actor_profile_id"], + name="fk_task_batch_transition_actor_link", + ondelete="RESTRICT", + deferrable=True, + initially="DEFERRED", + ), + sa.ForeignKeyConstraint( + ["batch_id", "project_id"], + ["public.task_import_batches.id", "public.task_import_batches.project_id"], + name="fk_task_batch_transition_batch", + ondelete="RESTRICT", + deferrable=True, + initially="DEFERRED", + ), + sa.UniqueConstraint( + "actor_profile_id", + "action_id", + "idempotency_key", + name="uq_task_batch_transition_namespace", + ), + sa.UniqueConstraint("id", "project_id", "batch_id", name="uq_task_batch_transition_parent"), + sa.CheckConstraint( + "(get_byte(uuid_send(id),6)>>4)=7 and (get_byte(uuid_send(id),8)&192)=128", + name="ck_task_batch_transition_receipts_id_uuid7", + ), + sa.CheckConstraint( + "action_id in ('project.task.screen','project.task.release')", + name="ck_task_batch_transition_receipts_action", + ), + sa.CheckConstraint( + "request_digest ~ '^sha256:[0-9a-f]{64}$' and manifest_digest ~ '^sha256:[0-9a-f]{64}$' and membership_digest ~ '^sha256:[0-9a-f]{64}$'", + name="ck_task_batch_transition_receipts_digests", + ), + sa.CheckConstraint( + "row_count between 1 and 500", name="ck_task_batch_transition_receipts_bounds" + ), + sa.CheckConstraint( + "reason is null or length(reason)<=4000", + name="ck_task_batch_transition_receipts_reason_bounds", + ), + sa.CheckConstraint( + "action_id<>'project.task.release' or (reason is not null and length(btrim(reason))>0)", + name="ck_task_batch_transition_receipts_release_reason", + ), + sa.CheckConstraint( + "(status='pending' and response is null and committed_at is null) or (status='committed' and response is not null and jsonb_typeof(response)='object' and committed_at is not null)", + name="ck_task_batch_transition_receipts_state_shape", + ), + schema="public", + ) + op.create_table( + "task_batch_transition_members", + sa.Column("id", sa.Uuid(), nullable=False), + sa.Column("transition_receipt_id", sa.Uuid(), nullable=False), + sa.Column("project_id", sa.Uuid(), nullable=False), + sa.Column("batch_id", sa.Uuid(), nullable=False), + sa.Column("native_member_id", sa.Uuid(), nullable=False), + sa.Column("task_id", sa.Uuid(), nullable=False), + sa.Column("row_index", sa.Integer(), nullable=False), + sa.Column("task_idempotency_key", sa.Uuid(), nullable=False), + sa.Column("task_command_receipt_id", sa.Uuid(), nullable=False), + sa.Column("authorization_decision_id", sa.Uuid(), nullable=False), + sa.Column( + "created_at", + sa.DateTime(timezone=True), + server_default=sa.text("now()"), + nullable=False, + ), + sa.PrimaryKeyConstraint("id"), + sa.ForeignKeyConstraint( + ["transition_receipt_id", "project_id", "batch_id"], + [ + "public.task_batch_transition_receipts.id", + "public.task_batch_transition_receipts.project_id", + "public.task_batch_transition_receipts.batch_id", + ], + name="fk_task_batch_transition_member_parent", + ondelete="RESTRICT", + deferrable=True, + initially="DEFERRED", + ), + sa.ForeignKeyConstraint( + ["native_member_id"], + ["public.task_import_batch_members.id"], + ondelete="RESTRICT", + deferrable=True, + initially="DEFERRED", + ), + sa.ForeignKeyConstraint( + ["task_id", "project_id"], + ["public.workstream_tasks.id", "public.workstream_tasks.project_id"], + name="fk_task_batch_transition_member_task", + ondelete="RESTRICT", + deferrable=True, + initially="DEFERRED", + ), + sa.ForeignKeyConstraint( + ["task_command_receipt_id"], + ["public.task_command_receipts.id"], + ondelete="RESTRICT", + deferrable=True, + initially="DEFERRED", + ), + sa.ForeignKeyConstraint( + ["authorization_decision_id"], + ["public.audit_events.id"], + ondelete="RESTRICT", + deferrable=True, + initially="DEFERRED", + ), + sa.UniqueConstraint( + "transition_receipt_id", "row_index", name="uq_task_batch_transition_member_row" + ), + sa.UniqueConstraint( + "transition_receipt_id", + "native_member_id", + name="uq_task_batch_transition_member_native", + ), + sa.UniqueConstraint( + "transition_receipt_id", "task_id", name="uq_task_batch_transition_member_task" + ), + sa.UniqueConstraint( + "task_command_receipt_id", name="uq_task_batch_transition_member_command" + ), + sa.CheckConstraint( + "(get_byte(uuid_send(id),6)>>4)=7 and (get_byte(uuid_send(id),8)&192)=128", + name="ck_task_batch_transition_members_id_uuid7", + ), + sa.CheckConstraint( + "row_index between 0 and 499", name="ck_task_batch_transition_members_row_index" + ), + schema="public", + ) + + +def _alter_command_receipts() -> None: + op.add_column( + "task_command_receipts", + sa.Column("batch_transition_receipt_id", sa.Uuid(), nullable=True), + schema="public", + ) + op.create_foreign_key( + "fk_task_command_batch_transition", + "task_command_receipts", + "task_batch_transition_receipts", + ["batch_transition_receipt_id"], + ["id"], + source_schema="public", + referent_schema="public", + ondelete="RESTRICT", + deferrable=True, + initially="DEFERRED", + ) + op.create_check_constraint( + "ck_task_command_receipts_task_command_batch_transition_action", + "task_command_receipts", + "batch_transition_receipt_id is null or action_id in ('project.task.screen','project.task.release')", + schema="public", + ) + op.create_index( + "ix_task_command_receipts_batch_transition_receipt_id", + "task_command_receipts", + ["batch_transition_receipt_id"], + schema="public", + ) + _replace_function( + "public.protect_task_command_receipt()", + "NEW.request_digest, NEW.task_id, NEW.created_at)", + "NEW.request_digest, NEW.batch_transition_receipt_id, NEW.task_id, NEW.created_at)", + ) + _replace_function( + "public.protect_task_command_receipt()", + "OLD.request_digest, OLD.task_id, OLD.created_at)", + "OLD.request_digest, OLD.batch_transition_receipt_id, OLD.task_id, OLD.created_at)", + ) + + +def _create_custody() -> None: + op.execute(r""" +create function public.validate_task_batch_transition_custody(p_receipt_id uuid) returns boolean +language plpgsql set search_path=pg_catalog,public,pg_temp as $$ +declare b public.task_batch_transition_receipts%rowtype; expected_membership text; + expected_request text; expected_response jsonb; expected_event text; +begin + select * into b from public.task_batch_transition_receipts where id=p_receipt_id; + if not found then return false; end if; + if b.status<>'committed' or b.response is null or b.committed_at is null then return false; end if; + if not exists(select 1 from public.task_import_batches source where source.id=b.batch_id + and source.project_id=b.project_id and source.status='committed' + and source.manifest_digest=b.manifest_digest and source.row_count=b.row_count) then return false; end if; + + select public.external_checker_registry_digest(jsonb_build_object('members',coalesce(jsonb_agg( + jsonb_build_object('member_id',n.id::text,'task_id',n.task_id::text,'row_index',n.row_index, + 'external_task_id',n.external_task_id,'row_digest',n.row_digest, + 'create_idempotency_key',n.create_idempotency_key::text, + 'task_command_receipt_id',n.task_command_receipt_id::text, + 'authorization_decision_id',n.authorization_decision_id::text) + order by n.row_index),'[]'::jsonb))) into expected_membership + from public.task_import_batch_members n where n.batch_id=b.batch_id; + expected_request := public.external_checker_registry_digest(jsonb_build_object( + 'project_id',b.project_id::text,'batch_id',b.batch_id::text, + 'operation',b.action_id,'reason',to_jsonb(b.reason))); + if b.membership_digest<>expected_membership or b.request_digest<>expected_request then return false; end if; + + if (select count(*) from public.task_import_batch_members where batch_id=b.batch_id)<>b.row_count + or (select count(*) from public.task_batch_transition_members where transition_receipt_id=b.id)<>b.row_count + or (select count(*) from public.task_command_receipts + where batch_transition_receipt_id=b.id)<>b.row_count + or exists(select 1 from public.task_import_batch_members n + left join public.task_batch_transition_members m + on m.transition_receipt_id=b.id and m.native_member_id=n.id + where n.batch_id=b.batch_id and (m.id is null or m.project_id<>n.project_id + or m.batch_id<>n.batch_id or m.task_id<>n.task_id or m.row_index<>n.row_index)) + or exists(select 1 from public.task_batch_transition_members m + left join public.task_import_batch_members n on n.id=m.native_member_id + where m.transition_receipt_id=b.id and (n.id is null or n.batch_id<>b.batch_id)) then return false; end if; + if exists(select 1 from public.task_command_receipts c + left join public.task_batch_transition_members m + on m.transition_receipt_id=b.id and m.task_command_receipt_id=c.id + where c.batch_transition_receipt_id=b.id and m.id is null) then return false; end if; + + expected_event := case b.action_id when 'project.task.screen' then 'TaskScreened' else 'TaskReleased' end; + if exists(select 1 from public.task_batch_transition_members m + join public.task_import_batch_members n on n.id=m.native_member_id + left join public.task_command_receipts c on c.id=m.task_command_receipt_id + left join public.audit_events d on d.id=m.authorization_decision_id + where m.transition_receipt_id=b.id and ( + m.project_id<>b.project_id or m.batch_id<>b.batch_id or m.task_id<>n.task_id + or m.row_index<>n.row_index or m.task_idempotency_key<>c.idempotency_key + or c.id is null or c.batch_transition_receipt_id is distinct from b.id or c.task_id<>m.task_id + or c.actor_profile_id::text<>b.actor_profile_id::text or c.action_id<>b.action_id + or c.status<>'committed' or c.response is null or c.locked_context_hash is null + or c.request_digest<>public.external_checker_registry_digest(jsonb_build_object( + 'task_id',m.task_id::text,'reason',to_jsonb(b.reason), + 'batch_transition_receipt_id',b.id::text)) + or c.response::jsonb->>'id' is distinct from m.task_id::text + or c.response::jsonb->>'project_id' is distinct from b.project_id::text + or c.response::jsonb->>'status' is distinct from case b.action_id + when 'project.task.screen' then 'screening' else 'ready' end + or nullif(c.response::jsonb->>'locked_guide_version','') is null + or not coalesce((c.response::jsonb->>'locked_contribution_policy_version_id') + ~ '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$',false) + or d.id is null or d.event_domain is distinct from 'authority' + or d.event_type is distinct from 'SensitiveAuthorizationAllowed' + or d.action_id is distinct from b.action_id + or d.permission_id is distinct from 'project.task.manage' + or d.actor_id is distinct from b.actor_profile_id::text + or d.project_id is distinct from b.project_id + or d.resource_type is distinct from 'project' + or d.resource_id is distinct from b.project_id::text or d.denial_code is not null + or d.after_facts::jsonb is distinct from jsonb_build_object('allowed',true,'resource_context_digest',d.after_facts::jsonb->'resource_context_digest') + or not coalesce((d.after_facts::jsonb->>'resource_context_digest') + ~ '^sha256:[0-9a-f]{64}$',false) + or not exists(select 1 from public.audit_events e where e.entity_id=m.task_id + and e.event_type=expected_event and e.actor_id=b.actor_profile_id::text + and e.event_payload::jsonb#>>'{references,project_id}'=b.project_id::text + and e.event_payload::jsonb#>>'{references,task_id}'=m.task_id::text + and e.event_payload::jsonb#>>'{references,authorization_decision_id}'=m.authorization_decision_id::text + and e.event_payload::jsonb#>>'{manager_authority_facts,resource_id}'=m.task_id::text + and e.event_payload::jsonb#>>'{manager_authority_facts,scope_project_id}'=b.project_id::text + and e.event_payload::jsonb#>>'{manager_authority_facts,idempotency_key}'=c.idempotency_key::text + and e.event_payload::jsonb#>>'{manager_authority_facts,request_digest}'=c.request_digest + and e.event_payload::jsonb#>>'{manager_authority_facts,identity_link_id}'=b.identity_link_id::text + and e.event_payload::jsonb#>>'{manager_authority_facts,locked_context_hash}'=c.locked_context_hash + and e.event_payload::jsonb->>'authorization_resource_digest' + =d.after_facts::jsonb->>'resource_context_digest' + and e.event_payload::jsonb->>'locked_guide_version'=c.response::jsonb->>'locked_guide_version' + and e.event_payload::jsonb->>'locked_contribution_policy_version_id' + =c.response::jsonb->>'locked_contribution_policy_version_id') + )) then return false; end if; + + select jsonb_build_object('project_id',b.project_id::text,'batch_id',b.batch_id::text, + 'operation',case b.action_id when 'project.task.screen' then 'screen' else 'release' end, + 'row_count',b.row_count,'tasks',coalesce(jsonb_agg(jsonb_build_object( + 'task_id',m.task_id::text,'row_index',m.row_index,'status',c.response::jsonb->>'status', + 'locked_guide_version',c.response::jsonb->>'locked_guide_version', + 'locked_contribution_policy_version_id',c.response::jsonb->>'locked_contribution_policy_version_id', + 'locked_context_hash',c.locked_context_hash) order by m.row_index),'[]'::jsonb)) + into expected_response + from public.task_batch_transition_members m + join public.task_command_receipts c on c.id=m.task_command_receipt_id + where m.transition_receipt_id=b.id; + return b.response=expected_response; +exception when others then return false; +end $$ +""") + op.execute(r""" +create function public.trigger_validate_task_batch_transition() returns trigger +language plpgsql set search_path=pg_catalog,public,pg_temp as $$ begin + if not public.validate_task_batch_transition_custody(new.id) then + raise exception 'task batch transition custody mismatch' using errcode='23514'; + end if; return new; end $$ +""") + op.execute(r""" +create function public.trigger_validate_task_batch_transition_member() returns trigger +language plpgsql set search_path=pg_catalog,public,pg_temp as $$ begin + if not public.validate_task_batch_transition_custody(new.transition_receipt_id) then + raise exception 'task batch transition member custody mismatch' using errcode='23514'; + end if; return new; end $$ +""") + op.execute(r""" +create function public.trigger_validate_task_batch_command_root() returns trigger +language plpgsql set search_path=pg_catalog,public,pg_temp as $$ begin + if new.batch_transition_receipt_id is not null + and not public.validate_task_batch_transition_custody(new.batch_transition_receipt_id) then + raise exception 'task batch transition command custody mismatch' using errcode='23514'; + end if; return new; end $$ +""") + op.execute( + "create constraint trigger task_batch_transition_custody after insert or update on public.task_batch_transition_receipts deferrable initially deferred for each row execute function public.trigger_validate_task_batch_transition()" + ) + op.execute( + "create constraint trigger task_batch_transition_member_custody after insert or update on public.task_batch_transition_members deferrable initially deferred for each row execute function public.trigger_validate_task_batch_transition_member()" + ) + op.execute( + "create constraint trigger task_batch_transition_command_custody after insert or update of batch_transition_receipt_id,status,response,locked_context_hash on public.task_command_receipts deferrable initially deferred for each row execute function public.trigger_validate_task_batch_command_root()" + ) + + +def _create_guards() -> None: + op.execute(r""" +create function public.guard_task_batch_transition_receipt() returns trigger +language plpgsql set search_path=pg_catalog,public,pg_temp as $$ begin + if tg_op='TRUNCATE' then raise exception 'task batch transition receipts cannot be truncated' using errcode='55000'; end if; + if tg_op='DELETE' then raise exception 'task batch transition receipts are immutable' using errcode='55000'; end if; + if new is not distinct from old then return new; end if; + if old.status<>'pending' or new.status<>'committed' + or row(new.id,new.actor_profile_id,new.identity_link_id,new.action_id,new.idempotency_key, + new.request_digest,new.reason,new.project_id,new.batch_id,new.manifest_digest, + new.membership_digest,new.row_count,new.created_at) + is distinct from + row(old.id,old.actor_profile_id,old.identity_link_id,old.action_id,old.idempotency_key, + old.request_digest,old.reason,old.project_id,old.batch_id,old.manifest_digest, + old.membership_digest,old.row_count,old.created_at) + or old.response is not null or old.committed_at is not null + or new.response is null or new.committed_at is null then + raise exception 'task batch transition receipt is immutable' using errcode='23514'; + end if; return new; end $$ +""") + op.execute(r""" +create function public.reject_task_batch_transition_member_mutation() returns trigger +language plpgsql set search_path=pg_catalog,public,pg_temp as $$ begin + raise exception 'task batch transition members are immutable' using errcode='55000'; end $$ +""") + op.execute( + "create trigger task_batch_transition_receipt_immutable before update or delete on public.task_batch_transition_receipts for each row execute function public.guard_task_batch_transition_receipt()" + ) + op.execute( + "create trigger task_batch_transition_receipt_no_truncate before truncate on public.task_batch_transition_receipts for each statement execute function public.guard_task_batch_transition_receipt()" + ) + op.execute( + "create trigger task_batch_transition_member_immutable before update or delete on public.task_batch_transition_members for each row execute function public.reject_task_batch_transition_member_mutation()" + ) + op.execute( + "create trigger task_batch_transition_member_no_truncate before truncate on public.task_batch_transition_members for each statement execute function public.reject_task_batch_transition_member_mutation()" + ) + + +def upgrade() -> None: + """Install exact aggregate-to-member-to-command transition custody.""" + op.execute("set local search_path=pg_catalog,public,pg_temp") + op.execute( + "lock table public.task_command_receipts, public.task_import_batches, " + "public.task_import_batch_members, public.audit_events in access exclusive mode" + ) + _create_tables() + _alter_command_receipts() + _create_custody() + _create_guards() + + +def downgrade() -> None: + """Refuse removal of retained aggregate transition custody.""" + op.execute("set local search_path=pg_catalog,public,pg_temp") + op.execute( + "lock table public.task_batch_transition_receipts, public.task_batch_transition_members, " + "public.task_command_receipts in access exclusive mode" + ) + retained = ( + op.get_bind() + .execute( + sa.text( + "select exists(select 1 from public.task_batch_transition_receipts) or " + "exists(select 1 from public.task_batch_transition_members) or " + "exists(select 1 from public.task_command_receipts where batch_transition_receipt_id is not null)" + ) + ) + .scalar_one() + ) + if retained: + raise RuntimeError("cannot downgrade batch transitions with retained custody") + raise RuntimeError("Workstream v0.1 migrations cannot be downgraded; recreate the database") diff --git a/backend/tests/conftest.py b/backend/tests/conftest.py index b4d274756..35d51dfbd 100644 --- a/backend/tests/conftest.py +++ b/backend/tests/conftest.py @@ -23,7 +23,7 @@ DDL_LOCK_DIRECTORY = Path("/tmp") # Match the PostgreSQL 16 engine used by Backend CI. Catalog identity rendering # differs across major versions; regenerate only after comparing actual objects. -EXPECTED_PUBLIC_SCHEMA_SHA256 = "3214f37ad2c38eb46b5348f954c43ffd355d98289e36ebb91937dde954e622d6" +EXPECTED_PUBLIC_SCHEMA_SHA256 = "df7f21433c311c1feade4abce146023110080764cef66482f37b5ddc76c51db3" PROTECTED_TEST_TABLES = ( "actor_profile_migration_state", "alembic_version", @@ -133,6 +133,8 @@ "task_import_batch_command_receipts", "task_import_batch_members", "task_import_batches", + "task_batch_transition_members", + "task_batch_transition_receipts", "task_command_receipts", "task_post_submit_routing_manifests", "task_post_submit_routing_requests", @@ -152,6 +154,8 @@ "task_import_batch_command_receipts", "task_import_batch_members", "task_import_batches", + "task_batch_transition_members", + "task_batch_transition_receipts", "task_post_submit_routing_manifests", "task_post_submit_routing_requests", "checker_policies", diff --git a/backend/tests/test_alembic.py b/backend/tests/test_alembic.py index 424429a62..71e70d15b 100644 --- a/backend/tests/test_alembic.py +++ b/backend/tests/test_alembic.py @@ -79,7 +79,7 @@ def test_v01_graph_has_one_root_and_head() -> None: script = ScriptDirectory.from_config(config) revisions = list(script.walk_revisions()) - assert [revision.revision for revision in revisions] == [HEAD_REVISION, "0033_contribution_reads", "0032_checker_remediation", "0031_task_import_source", "0030_routing_outcomes", "0029_external_checker_registry", "0028_lifecycle_transitions", "0027_markdown_guide_media", "0026_task_guide_read", "0025_submission_dispatch", "0024_require_second_review_false", "0023_remove_task_payment_policy", "0022_submission_packet_custody", "0021_submission_manifest", "0020_review_admission_lock_order", "0019_submitter_awards", "0018_task_routing_request", "0017_acceptance_source_contracts", "0016_review_lifecycle_fence", "0015_contribution_awards", "0014_final_acceptance", "0013_review_source", "0012_review_packet", "0011_task_routing_source", "0010_post_submit_authority", "0009_checker_material_lineage", "0008_checker_execution", "0007_checker_output_custody", "0006_history_read_authority", "0005_task_evidence_authority", "0004_task_context_authority", "0003_task_read_authority", "0002_task_queue_authority", BASELINE_REVISION] + assert [revision.revision for revision in revisions] == [HEAD_REVISION, "0034_task_import_batches", "0033_contribution_reads", "0032_checker_remediation", "0031_task_import_source", "0030_routing_outcomes", "0029_external_checker_registry", "0028_lifecycle_transitions", "0027_markdown_guide_media", "0026_task_guide_read", "0025_submission_dispatch", "0024_require_second_review_false", "0023_remove_task_payment_policy", "0022_submission_packet_custody", "0021_submission_manifest", "0020_review_admission_lock_order", "0019_submitter_awards", "0018_task_routing_request", "0017_acceptance_source_contracts", "0016_review_lifecycle_fence", "0015_contribution_awards", "0014_final_acceptance", "0013_review_source", "0012_review_packet", "0011_task_routing_source", "0010_post_submit_authority", "0009_checker_material_lineage", "0008_checker_execution", "0007_checker_output_custody", "0006_history_read_authority", "0005_task_evidence_authority", "0004_task_context_authority", "0003_task_read_authority", "0002_task_queue_authority", BASELINE_REVISION] assert revisions[-1].down_revision is None assert script.get_heads() == [HEAD_REVISION] From e12220d10926a0b432a91c2ad4b4d7bae95b4f11 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 17:04:52 +0100 Subject: [PATCH 040/283] [PILOT-10] Register pagination tests and cursor ownership --- .commitrail/changes/pilot10-stable-contribution-pagination.md | 2 +- backend/scripts/behavior_ownership.py | 4 ++++ backend/tests/test_ci_lane_catalogue.py | 3 +++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/.commitrail/changes/pilot10-stable-contribution-pagination.md b/.commitrail/changes/pilot10-stable-contribution-pagination.md index f4a1c13f6..4f4e185c8 100644 --- a/.commitrail/changes/pilot10-stable-contribution-pagination.md +++ b/.commitrail/changes/pilot10-stable-contribution-pagination.md @@ -84,7 +84,7 @@ CLI is a separate bounded PR. | Current implementation | Inspect canonical CON read and AUTH keyset owner | Existing read extended; peer selected expiring native membership | Installed native implementation pending | | Membership/authority | Real PostgreSQL installed-schema public reads, delayed commit and revocation controls | Planned | No native runtime claim yet | | Cursor/projection validation | Focused cursor, exact projection, CSV and canonical-only model discovery | 68 pass; independent scope/expiry mutants fail intended assertions | No native membership claim | -| Required repository checks | Focused checks plus required hosted CI and independent review | Planned | No readiness claim | +| Required repository checks | CI lane catalogue and behavior ownership tests; Ruff; changed Markdown links | 203 pass after additive registration repair; lint and links pass | Full hosted/native proof pending; no readiness claim | ## Review findings diff --git a/backend/scripts/behavior_ownership.py b/backend/scripts/behavior_ownership.py index 9f22189b0..456918e70 100644 --- a/backend/scripts/behavior_ownership.py +++ b/backend/scripts/behavior_ownership.py @@ -650,6 +650,9 @@ "backend/app/modules/artifacts/task_guide_documents.py", "backend/app/modules/tasks/api/guide_documents.py", }) +PILOT_10_PAGINATION_TARGETS = frozenset({ + "backend/app/modules/contributions/records/cursors.py", +}) PILOT_02A_IMPORT_SOURCE_TARGETS = frozenset({ "backend/app/modules/artifacts/api/task_import_source.py", "backend/app/api/routes/artifact_task_import_sources.py", @@ -907,6 +910,7 @@ def _validate_additive_partition_transition( | TASK_COMMAND_REPLAY_TARGETS | PILOT_13_GUIDE_READ_TARGETS | PILOT_02A_IMPORT_SOURCE_TARGETS + | PILOT_10_PAGINATION_TARGETS ) expected_additions = (approved_additions & additions) - set(trusted_targets) if POL_03A_DECLARATIVE_MODEL_TARGET in additions: diff --git a/backend/tests/test_ci_lane_catalogue.py b/backend/tests/test_ci_lane_catalogue.py index edc121752..82d3318e0 100644 --- a/backend/tests/test_ci_lane_catalogue.py +++ b/backend/tests/test_ci_lane_catalogue.py @@ -122,12 +122,15 @@ def test_measured_hotspots_have_explicit_semantic_owners() -> None: | { "tests/contributions/test_export_csv.py", "tests/contributions/test_export_projection.py", + "tests/contributions/test_export_cursors.py", + "tests/contributions/test_export_model_registry.py", "tests/authorization/test_contribution_read_scope.py", "tests/authorization/test_contribution_read_kernel.py", "tests/contributions/exports/test_source_reads.py", "tests/contributions/exports/test_public_reads.py", "tests/contributions/exports/test_failures.py", "tests/contributions/exports/test_concurrency.py", + "tests/contributions/exports/test_pagination.py", "tests/tasks/evaluation_delivery/test_custody.py", "tests/tasks/evaluation_delivery/test_delivery.py", "tests/tasks/evaluation_delivery/test_isolation.py", From 04f6a24faaf42898d3213326de0e9062dfd3f907 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 17:06:23 +0100 Subject: [PATCH 041/283] [PILOT-10] Exercise sealed export guards alongside real pagination --- .../pilot10-stable-contribution-pagination.md | 5 +- .../contributions/exports/test_pagination.py | 53 ++++++++++++++++++- 2 files changed, 56 insertions(+), 2 deletions(-) diff --git a/.commitrail/changes/pilot10-stable-contribution-pagination.md b/.commitrail/changes/pilot10-stable-contribution-pagination.md index 4f4e185c8..63521b276 100644 --- a/.commitrail/changes/pilot10-stable-contribution-pagination.md +++ b/.commitrail/changes/pilot10-stable-contribution-pagination.md @@ -93,7 +93,10 @@ transaction-ID coupling. Source review reproduced missing canonical-only model registration in a fresh process. Membership declarations now live in CON's existing registered records/models.py; the separate declaration module was removed, with a fresh-process regression preserving native FK compilation. -Implementation still requires installed-schema proof. +Prepared public regression now includes direct installed-guard checks for sealed +append, header/member mutation, premature deletion and deferred unsealed commit. +These collect successfully but are not runtime proof until the native migration +is installed. Implementation still requires installed-schema proof. ## Reconciliation diff --git a/backend/tests/contributions/exports/test_pagination.py b/backend/tests/contributions/exports/test_pagination.py index 9ec6938f8..6bbbef11e 100644 --- a/backend/tests/contributions/exports/test_pagination.py +++ b/backend/tests/contributions/exports/test_pagination.py @@ -2,12 +2,15 @@ import asyncio import csv + +import pytest from io import StringIO from sqlalchemy import func, select, text +from sqlalchemy.exc import IntegrityError from app.core.identifiers import new_record_id -from app.modules.contributions.records.models import ContributionExportMembership +from app.modules.contributions.records.models import ContributionExportMembership, ContributionExportMember from app.modules.authorization.repository import AdminAuthorizationRepository from tests.contributions.records.support import authorized_submitter_source from tests.tasks.post_submit_routing.support import completed_sibling_source @@ -72,6 +75,54 @@ async def before_project_lock(repository, project_id): task.cancel() await asyncio.gather(task, return_exceptions=True) assert first.status_code == 200, first.text + # The installed guards must protect the original selection even when a + # later real contribution now exists and would match the same query. + async with h.factory() as session: + membership = await session.scalar(select(ContributionExportMembership).where( + ContributionExportMembership.actor_profile_id == str(reader.id), + ContributionExportMembership.project_id == h.submitter_record.project_id, + ContributionExportMembership.page_size == 1, + ).order_by(ContributionExportMembership.exported_at.desc()).limit(1)) + assert membership is not None and membership.sealed and membership.member_count == 2 + export_id = membership.id + assert await session.scalar(select(func.count()).select_from(ContributionExportMember).where( + ContributionExportMember.export_id == export_id, + )) == 2 + for statement, parameters in ( + ("UPDATE contribution_export_memberships SET page_size=2 WHERE id=:export", {}), + ("DELETE FROM contribution_export_memberships WHERE id=:export", {}), + ("UPDATE contribution_export_members SET recorded_at=recorded_at + interval '1 second' " + "WHERE export_id=:export", {}), + ("DELETE FROM contribution_export_members WHERE export_id=:export", {}), + ("INSERT INTO contribution_export_members (export_id, contribution_id, recorded_at) " + "SELECT :export, id, created_at FROM contribution_records WHERE id=:late", + {"late": late_outcome.economic.contribution_record_id}), + ): + async with h.factory() as session: + with pytest.raises(IntegrityError) as rejected: + async with session.begin(): + await session.execute(text(statement), {"export": export_id} | parameters) + assert rejected.value.orig.sqlstate == "23514" + async with h.factory() as session: + assert await session.scalar(select(func.count()).select_from(ContributionExportMember).where( + ContributionExportMember.export_id == export_id, + )) == 2 + async with h.factory() as session: + await session.begin() + await session.execute(text( + "INSERT INTO contribution_export_memberships " + "(id, actor_profile_id, audience, project_id, output_format, page_size, " + "contribution_type, recorded_from, recorded_before, member_count, sealed, " + "query_digest, exported_at, expires_at) " + "SELECT :new, actor_profile_id, audience, project_id, output_format, page_size, " + "contribution_type, recorded_from, recorded_before, 3, false, " + "query_digest, exported_at, expires_at " + "FROM contribution_export_memberships WHERE id=:export" + ), {"new": new_record_id(), "export": export_id}) + with pytest.raises(IntegrityError) as unsealed: + await session.commit() + assert unsealed.value.orig.sqlstate == "23514" + await session.rollback() cursor = first.json()["next_cursor"] assert cursor is not None for changed in ({"page_size": 2}, {"format": "csv"}, {"contribution_type": "completed_review"}): From 05f265e9e019c05128ae987ac801497a25e6bf41 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 17:11:45 +0100 Subject: [PATCH 042/283] [PILOT-10] Prove expired nonempty export cleanup preserves source facts --- .../pilot10-stable-contribution-pagination.md | 5 ++-- .../contributions/exports/test_pagination.py | 27 +++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/.commitrail/changes/pilot10-stable-contribution-pagination.md b/.commitrail/changes/pilot10-stable-contribution-pagination.md index 63521b276..b53da8294 100644 --- a/.commitrail/changes/pilot10-stable-contribution-pagination.md +++ b/.commitrail/changes/pilot10-stable-contribution-pagination.md @@ -94,12 +94,13 @@ registration in a fresh process. Membership declarations now live in CON's existing registered records/models.py; the separate declaration module was removed, with a fresh-process regression preserving native FK compilation. Prepared public regression now includes direct installed-guard checks for sealed -append, header/member mutation, premature deletion and deferred unsealed commit. +append, header/member mutation, premature deletion, deferred unsealed commit, +and public cleanup of a nonempty expired private selection. These collect successfully but are not runtime proof until the native migration is installed. Implementation still requires installed-schema proof. ## Reconciliation -- Current-source reconciliation: starts from main d47ee1e, including merged PILOT-10A. +- Current-source reconciliation: started from main d47ee1e; reconciled main e31e1777 after PR #539 merged. - Next usable boundary: separate CLI export PR and the pilot closing drill. - Remaining risks: native membership mechanism and restore binding not yet frozen. diff --git a/backend/tests/contributions/exports/test_pagination.py b/backend/tests/contributions/exports/test_pagination.py index 6bbbef11e..af762c146 100644 --- a/backend/tests/contributions/exports/test_pagination.py +++ b/backend/tests/contributions/exports/test_pagination.py @@ -153,8 +153,35 @@ async def before_project_lock(repository, project_id): assert set(ids) == {str(h.submitter_record.id), str(second_outcome.economic.contribution_record_id)} assert str(late_outcome.economic.contribution_record_id) not in ids assert all(len(row["awards"]) == 2 for page in (first, next_page) for row in page.json()["items"]) + # Construct only private expiry metadata around the same real immutable + # facts; no economic row or clock is changed. The next public first page + # must remove this nonempty expired selection through its native cascade. + expired_id = new_record_id() + async with h.factory() as session, session.begin(): + await session.execute(text( + "INSERT INTO contribution_export_memberships " + "(id, actor_profile_id, audience, project_id, output_format, page_size, " + "contribution_type, recorded_from, recorded_before, member_count, sealed, " + "query_digest, exported_at, expires_at) " + "SELECT :new, actor_profile_id, audience, project_id, output_format, page_size, " + "contribution_type, recorded_from, recorded_before, 3, false, query_digest, " + "exported_at - interval '16 minutes', expires_at - interval '16 minutes' " + "FROM contribution_export_memberships WHERE id=:export" + ), {"new": expired_id, "export": export_id}) + await session.execute(text( + "INSERT INTO contribution_export_members (export_id, contribution_id, recorded_at) " + "SELECT :export, id, created_at FROM contribution_records WHERE project_id=:project" + ), {"export": expired_id, "project": h.submitter_record.project_id}) + await session.execute(text( + "UPDATE contribution_export_memberships SET sealed=true WHERE id=:export" + ), {"export": expired_id}) fresh = await signed_access.client.get(path, headers=reader.headers) assert fresh.status_code == 200 + async with h.factory() as session: + assert await session.get(ContributionExportMembership, expired_id) is None + assert await session.scalar(select(func.count()).select_from(ContributionExportMember).where( + ContributionExportMember.export_id == expired_id, + )) == 0 assert {row["contribution_id"] for row in fresh.json()["items"]} == set(ids) | { str(late_outcome.economic.contribution_record_id), } From ff34fb7c4e49396cdd09fdf1d7f957a8277610c3 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 17:12:47 +0100 Subject: [PATCH 043/283] [PILOT-10] Compare retained economic facts across export cleanup --- backend/tests/contributions/exports/test_pagination.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/backend/tests/contributions/exports/test_pagination.py b/backend/tests/contributions/exports/test_pagination.py index af762c146..384207950 100644 --- a/backend/tests/contributions/exports/test_pagination.py +++ b/backend/tests/contributions/exports/test_pagination.py @@ -12,7 +12,7 @@ from app.core.identifiers import new_record_id from app.modules.contributions.records.models import ContributionExportMembership, ContributionExportMember from app.modules.authorization.repository import AdminAuthorizationRepository -from tests.contributions.records.support import authorized_submitter_source +from tests.contributions.records.support import authorized_submitter_source, rows from tests.tasks.post_submit_routing.support import completed_sibling_source from tests.tasks.post_submit_routing.outcome_support import apply_outcome, invoked_completion from .support import export_path @@ -85,6 +85,9 @@ async def before_project_lock(repository, project_id): ).order_by(ContributionExportMembership.exported_at.desc()).limit(1)) assert membership is not None and membership.sealed and membership.member_count == 2 export_id = membership.id + retained_facts = {table: await rows(session, table) for table in ( + "contribution_records", "compensation_awards", "final_acceptances", + )} assert await session.scalar(select(func.count()).select_from(ContributionExportMember).where( ContributionExportMember.export_id == export_id, )) == 2 @@ -179,6 +182,7 @@ async def before_project_lock(repository, project_id): assert fresh.status_code == 200 async with h.factory() as session: assert await session.get(ContributionExportMembership, expired_id) is None + assert {table: await rows(session, table) for table in retained_facts} == retained_facts assert await session.scalar(select(func.count()).select_from(ContributionExportMember).where( ContributionExportMember.export_id == expired_id, )) == 0 From ddf8ef6bbd0feeeecc8caa134114c16530b8d43e Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 17:15:01 +0100 Subject: [PATCH 044/283] feat: install fixed contribution export pages --- backend/alembic/env.py | 3 +- .../0036_contribution_export_pages.py | 314 ++++++++++++++++++ backend/tests/conftest.py | 6 +- backend/tests/test_alembic.py | 2 +- 4 files changed, 322 insertions(+), 3 deletions(-) create mode 100644 backend/alembic/versions/0036_contribution_export_pages.py diff --git a/backend/alembic/env.py b/backend/alembic/env.py index 23b87417a..627f1ac78 100644 --- a/backend/alembic/env.py +++ b/backend/alembic/env.py @@ -21,7 +21,7 @@ target_metadata = Base.metadata _BASELINE_REVISION = "0001_uuid7_v01" -_CURRENT_HEAD_REVISION = "0035_task_batch_transitions" +_CURRENT_HEAD_REVISION = "0036_contribution_export_pages" _RECREATE_GUIDANCE = ( "Workstream v0.1 requires a fresh database; recreate this database before " "running the 0001_uuid7_v01 migration" @@ -88,6 +88,7 @@ def do_run_migrations(connection: Connection) -> None: ("0032_checker_remediation",), ("0033_contribution_reads",), ("0034_task_import_batches",), + ("0035_task_batch_transitions",), (_CURRENT_HEAD_REVISION,), ): raise RuntimeError(_RECREATE_GUIDANCE) diff --git a/backend/alembic/versions/0036_contribution_export_pages.py b/backend/alembic/versions/0036_contribution_export_pages.py new file mode 100644 index 000000000..090ae20f4 --- /dev/null +++ b/backend/alembic/versions/0036_contribution_export_pages.py @@ -0,0 +1,314 @@ +"""Install private fixed-membership contribution export custody.""" + +from alembic import op + +revision = "0036_contribution_export_pages" +down_revision = "0035_task_batch_transitions" +branch_labels = None +depends_on = None + + +def upgrade() -> None: + op.execute(""" +CREATE INDEX ix_contribution_records_self_export +ON public.contribution_records (contributor_id, created_at, id) +""") + op.execute(""" +CREATE INDEX ix_contribution_records_project_export +ON public.contribution_records (project_id, created_at, id) +""") + op.execute(""" +CREATE TABLE public.contribution_export_memberships ( + id UUID NOT NULL, + actor_profile_id UUID NOT NULL, + audience VARCHAR(16) NOT NULL, + project_id UUID, + output_format VARCHAR(4) NOT NULL, + page_size INTEGER NOT NULL, + contribution_type VARCHAR(32), + recorded_from TIMESTAMP WITH TIME ZONE, + recorded_before TIMESTAMP WITH TIME ZONE, + member_count INTEGER NOT NULL, + sealed BOOLEAN NOT NULL, + query_digest VARCHAR(71) NOT NULL, + exported_at TIMESTAMP WITH TIME ZONE NOT NULL, + expires_at TIMESTAMP WITH TIME ZONE NOT NULL, + CONSTRAINT pk_contribution_export_memberships PRIMARY KEY (id), + CONSTRAINT ck_contribution_export_memberships_id_uuid7 + CHECK ((get_byte(uuid_send(id), 6) >> 4) = 7 + AND (get_byte(uuid_send(id), 8) & 192) = 128), + CONSTRAINT ck_contribution_export_memberships_query_digest + CHECK (query_digest ~ '^sha256:[0-9a-f]{64}$'), + CONSTRAINT ck_contribution_export_memberships_expiry + CHECK (expires_at = exported_at + interval '15 minutes'), + CONSTRAINT ck_contribution_export_memberships_member_count + CHECK (member_count BETWEEN 0 AND 100000), + CONSTRAINT ck_contribution_export_memberships_audience + CHECK (audience IN ('self','project') + AND (audience <> 'project' OR project_id IS NOT NULL)), + CONSTRAINT ck_contribution_export_memberships_output_format + CHECK (output_format IN ('json','csv')), + CONSTRAINT ck_contribution_export_memberships_page_size + CHECK (page_size BETWEEN 1 AND 1000), + CONSTRAINT ck_contribution_export_memberships_contribution_type + CHECK (contribution_type IS NULL + OR contribution_type IN ('accepted_submission','completed_review')), + CONSTRAINT ck_contribution_export_memberships_recorded_interval + CHECK (recorded_from IS NULL OR recorded_before IS NULL + OR recorded_from < recorded_before), + CONSTRAINT fk_contribution_export_memberships_actor_profile_id_act_4609 + FOREIGN KEY(actor_profile_id) REFERENCES public.actor_profiles (id) + ON DELETE RESTRICT, + CONSTRAINT fk_contribution_export_memberships_project_id_projects + FOREIGN KEY(project_id) REFERENCES public.projects (id) + ON DELETE RESTRICT +) +""") + op.execute(""" +CREATE INDEX ix_contribution_export_memberships_expires_at +ON public.contribution_export_memberships (expires_at) +""") + op.execute(""" +CREATE TABLE public.contribution_export_members ( + export_id UUID NOT NULL, + contribution_id UUID NOT NULL, + recorded_at TIMESTAMP WITH TIME ZONE NOT NULL, + CONSTRAINT pk_contribution_export_members + PRIMARY KEY (export_id, contribution_id), + CONSTRAINT fk_contribution_export_members_export_id_contribution_e_3433 + FOREIGN KEY(export_id) REFERENCES public.contribution_export_memberships (id) + ON DELETE CASCADE, + CONSTRAINT fk_contribution_export_members_contribution_id_contribu_5e22 + FOREIGN KEY(contribution_id) REFERENCES public.contribution_records (id) + ON DELETE RESTRICT +) +""") + op.execute(""" +CREATE INDEX ix_contribution_export_members_order +ON public.contribution_export_members (export_id, recorded_at, contribution_id) +""") + op.execute(""" +CREATE FUNCTION public.guard_contribution_export_member() RETURNS trigger +LANGUAGE plpgsql SET search_path=pg_catalog,public,pg_temp AS $$ +DECLARE + export_row public.contribution_export_memberships%ROWTYPE; + contribution_row public.contribution_records%ROWTYPE; +BEGIN + SELECT * INTO export_row + FROM public.contribution_export_memberships + WHERE id=NEW.export_id FOR UPDATE; + IF NOT FOUND OR export_row.sealed THEN + RAISE EXCEPTION 'contribution export membership is not capturing' + USING ERRCODE='23514'; + END IF; + + SELECT * INTO contribution_row + FROM public.contribution_records WHERE id=NEW.contribution_id; + IF NOT FOUND + OR NEW.recorded_at IS DISTINCT FROM contribution_row.created_at + OR (export_row.audience='self' + AND contribution_row.contributor_id IS DISTINCT FROM export_row.actor_profile_id) + OR (export_row.project_id IS NOT NULL + AND contribution_row.project_id IS DISTINCT FROM export_row.project_id) + OR (export_row.contribution_type IS NOT NULL + AND contribution_row.contribution_type IS DISTINCT FROM export_row.contribution_type) + OR (export_row.recorded_from IS NOT NULL + AND contribution_row.created_at < export_row.recorded_from) + OR (export_row.recorded_before IS NOT NULL + AND contribution_row.created_at >= export_row.recorded_before) + THEN + RAISE EXCEPTION 'contribution export member does not match the sealed query' + USING ERRCODE='23514'; + END IF; + RETURN NEW; +END $$ +""") + op.execute(""" +CREATE TRIGGER contribution_export_member_custody +BEFORE INSERT ON public.contribution_export_members +FOR EACH ROW EXECUTE FUNCTION public.guard_contribution_export_member() +""") + op.execute(""" +CREATE FUNCTION public.guard_contribution_export_membership_insert() RETURNS trigger +LANGUAGE plpgsql SET search_path=pg_catalog,public,pg_temp AS $$ +BEGIN + IF NEW.sealed THEN + RAISE EXCEPTION 'contribution export membership must begin unsealed' + USING ERRCODE='23514'; + END IF; + RETURN NEW; +END $$ +""") + op.execute(""" +CREATE TRIGGER contribution_export_membership_insert +BEFORE INSERT ON public.contribution_export_memberships +FOR EACH ROW EXECUTE FUNCTION public.guard_contribution_export_membership_insert() +""") + op.execute(""" +CREATE FUNCTION public.guard_contribution_export_membership_update() RETURNS trigger +LANGUAGE plpgsql SET search_path=pg_catalog,public,pg_temp AS $$ +BEGIN + IF OLD.sealed OR NOT NEW.sealed + OR NEW.id IS DISTINCT FROM OLD.id + OR NEW.actor_profile_id IS DISTINCT FROM OLD.actor_profile_id + OR NEW.audience IS DISTINCT FROM OLD.audience + OR NEW.project_id IS DISTINCT FROM OLD.project_id + OR NEW.output_format IS DISTINCT FROM OLD.output_format + OR NEW.page_size IS DISTINCT FROM OLD.page_size + OR NEW.contribution_type IS DISTINCT FROM OLD.contribution_type + OR NEW.recorded_from IS DISTINCT FROM OLD.recorded_from + OR NEW.recorded_before IS DISTINCT FROM OLD.recorded_before + OR NEW.member_count IS DISTINCT FROM OLD.member_count + OR NEW.query_digest IS DISTINCT FROM OLD.query_digest + OR NEW.exported_at IS DISTINCT FROM OLD.exported_at + OR NEW.expires_at IS DISTINCT FROM OLD.expires_at + THEN + RAISE EXCEPTION 'contribution export membership facts are immutable' + USING ERRCODE='23514'; + END IF; + RETURN NEW; +END $$ +""") + op.execute(""" +CREATE TRIGGER contribution_export_membership_update +BEFORE UPDATE ON public.contribution_export_memberships +FOR EACH ROW EXECUTE FUNCTION public.guard_contribution_export_membership_update() +""") + op.execute(""" +CREATE FUNCTION public.guard_contribution_export_membership_delete() RETURNS trigger +LANGUAGE plpgsql SET search_path=pg_catalog,public,pg_temp AS $$ +BEGIN + IF OLD.expires_at > pg_catalog.clock_timestamp() THEN + RAISE EXCEPTION 'active contribution export membership cannot be deleted' + USING ERRCODE='23514'; + END IF; + RETURN OLD; +END $$ +""") + op.execute(""" +CREATE TRIGGER contribution_export_membership_delete +BEFORE DELETE ON public.contribution_export_memberships +FOR EACH ROW EXECUTE FUNCTION public.guard_contribution_export_membership_delete() +""") + op.execute(""" +CREATE FUNCTION public.guard_contribution_export_member_mutation() RETURNS trigger +LANGUAGE plpgsql SET search_path=pg_catalog,public,pg_temp AS $$ +DECLARE + expiry timestamptz; +BEGIN + IF TG_OP='UPDATE' THEN + RAISE EXCEPTION 'contribution export members are immutable' + USING ERRCODE='23514'; + END IF; + SELECT expires_at INTO expiry + FROM public.contribution_export_memberships WHERE id=OLD.export_id; + IF pg_catalog.pg_trigger_depth() <= 1 OR expiry IS NOT NULL THEN + RAISE EXCEPTION 'contribution export members can be deleted only with an expired parent' + USING ERRCODE='23514'; + END IF; + RETURN OLD; +END $$ +""") + op.execute(""" +CREATE TRIGGER contribution_export_member_mutation +BEFORE UPDATE OR DELETE ON public.contribution_export_members +FOR EACH ROW EXECUTE FUNCTION public.guard_contribution_export_member_mutation() +""") + op.execute(""" +CREATE FUNCTION public.validate_contribution_export_membership(export_uuid uuid) RETURNS void +LANGUAGE plpgsql SET search_path=pg_catalog,public,pg_temp AS $$ +DECLARE + export_row public.contribution_export_memberships%ROWTYPE; + stored_count bigint; + selected_count bigint; +BEGIN + SELECT * INTO export_row + FROM public.contribution_export_memberships WHERE id=export_uuid; + IF NOT FOUND THEN + RETURN; + END IF; + IF NOT export_row.sealed THEN + RAISE EXCEPTION 'contribution export membership must be sealed before commit' + USING ERRCODE='23514'; + END IF; + + SELECT count(*) INTO stored_count + FROM public.contribution_export_members WHERE export_id=export_uuid; + SELECT count(*) INTO selected_count + FROM public.contribution_records c + WHERE (export_row.audience<>'self' OR c.contributor_id=export_row.actor_profile_id) + AND (export_row.project_id IS NULL OR c.project_id=export_row.project_id) + AND (export_row.contribution_type IS NULL + OR c.contribution_type=export_row.contribution_type) + AND (export_row.recorded_from IS NULL OR c.created_at>=export_row.recorded_from) + AND (export_row.recorded_before IS NULL OR c.created_at'self' OR c.contributor_id=export_row.actor_profile_id) + AND (export_row.project_id IS NULL OR c.project_id=export_row.project_id) + AND (export_row.contribution_type IS NULL + OR c.contribution_type=export_row.contribution_type) + AND (export_row.recorded_from IS NULL OR c.created_at>=export_row.recorded_from) + AND (export_row.recorded_before IS NULL OR c.created_at None: + connection = op.get_bind() + retained = connection.exec_driver_sql( + "SELECT EXISTS (SELECT 1 FROM public.contribution_export_memberships) " + "OR EXISTS (SELECT 1 FROM public.contribution_export_members)" + ).scalar_one() + if retained: + raise RuntimeError( + "0036_contribution_export_pages cannot be downgraded while retained " + "contribution export custody exists" + ) + raise RuntimeError( + "Workstream v0.1 migrations cannot be downgraded; recreate the database" + ) diff --git a/backend/tests/conftest.py b/backend/tests/conftest.py index 35d51dfbd..b7d287eb3 100644 --- a/backend/tests/conftest.py +++ b/backend/tests/conftest.py @@ -23,7 +23,7 @@ DDL_LOCK_DIRECTORY = Path("/tmp") # Match the PostgreSQL 16 engine used by Backend CI. Catalog identity rendering # differs across major versions; regenerate only after comparing actual objects. -EXPECTED_PUBLIC_SCHEMA_SHA256 = "df7f21433c311c1feade4abce146023110080764cef66482f37b5ddc76c51db3" +EXPECTED_PUBLIC_SCHEMA_SHA256 = "6b698d4bca1e7a9351df2a5a64928c7823831cacd4b0a68c5f2c012d0a165f21" PROTECTED_TEST_TABLES = ( "actor_profile_migration_state", "alembic_version", @@ -113,6 +113,8 @@ "review_admission_idempotency_records", "final_acceptances", "contribution_records", + "contribution_export_members", + "contribution_export_memberships", "compensation_awards", "reviews", "review_findings", @@ -166,6 +168,8 @@ "compensation_adapter_binding_lifecycle_events", "contribution_policy_lifecycle_events", "contribution_policy_transition_custody", + "contribution_export_members", + "contribution_export_memberships", "guide_mutation_idempotency_records", "guide_sufficiency_reports", "guide_sufficiency_report_source_usages", diff --git a/backend/tests/test_alembic.py b/backend/tests/test_alembic.py index 71e70d15b..078d3377a 100644 --- a/backend/tests/test_alembic.py +++ b/backend/tests/test_alembic.py @@ -79,7 +79,7 @@ def test_v01_graph_has_one_root_and_head() -> None: script = ScriptDirectory.from_config(config) revisions = list(script.walk_revisions()) - assert [revision.revision for revision in revisions] == [HEAD_REVISION, "0034_task_import_batches", "0033_contribution_reads", "0032_checker_remediation", "0031_task_import_source", "0030_routing_outcomes", "0029_external_checker_registry", "0028_lifecycle_transitions", "0027_markdown_guide_media", "0026_task_guide_read", "0025_submission_dispatch", "0024_require_second_review_false", "0023_remove_task_payment_policy", "0022_submission_packet_custody", "0021_submission_manifest", "0020_review_admission_lock_order", "0019_submitter_awards", "0018_task_routing_request", "0017_acceptance_source_contracts", "0016_review_lifecycle_fence", "0015_contribution_awards", "0014_final_acceptance", "0013_review_source", "0012_review_packet", "0011_task_routing_source", "0010_post_submit_authority", "0009_checker_material_lineage", "0008_checker_execution", "0007_checker_output_custody", "0006_history_read_authority", "0005_task_evidence_authority", "0004_task_context_authority", "0003_task_read_authority", "0002_task_queue_authority", BASELINE_REVISION] + assert [revision.revision for revision in revisions] == [HEAD_REVISION, "0035_task_batch_transitions", "0034_task_import_batches", "0033_contribution_reads", "0032_checker_remediation", "0031_task_import_source", "0030_routing_outcomes", "0029_external_checker_registry", "0028_lifecycle_transitions", "0027_markdown_guide_media", "0026_task_guide_read", "0025_submission_dispatch", "0024_require_second_review_false", "0023_remove_task_payment_policy", "0022_submission_packet_custody", "0021_submission_manifest", "0020_review_admission_lock_order", "0019_submitter_awards", "0018_task_routing_request", "0017_acceptance_source_contracts", "0016_review_lifecycle_fence", "0015_contribution_awards", "0014_final_acceptance", "0013_review_source", "0012_review_packet", "0011_task_routing_source", "0010_post_submit_authority", "0009_checker_material_lineage", "0008_checker_execution", "0007_checker_output_custody", "0006_history_read_authority", "0005_task_evidence_authority", "0004_task_context_authority", "0003_task_read_authority", "0002_task_queue_authority", BASELINE_REVISION] assert revisions[-1].down_revision is None assert script.get_heads() == [HEAD_REVISION] From 7453a0d8c5664cfd486872a381899f3755393004 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 17:18:47 +0100 Subject: [PATCH 045/283] docs: reconcile default checker current base --- .commitrail/changes/pilot04-workstream-default-checker.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 308cbf903..d59060049 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -123,7 +123,7 @@ introduced here. | Claim | Command or proof | Result | Remaining uncertainty | |---|---|---|---| -| Current owner map | Source inspection of ART inspection/manifest/change owners, both current catalogues and the merged external runtime | Complete and reconciled through main `3cf40503691ab05533247a6a80bb2cff84c54721` | Policy binding, live pre-admission orchestration, post cutover and catalogue removal remain later slices | +| Current owner map | Source inspection of ART inspection/manifest/change owners, both current catalogues and the merged external runtime | Complete and reconciled through main `e31e1777c47b794b1d4d8240192608e4fff4f536` | Policy binding, live pre-admission orchestration, post cutover and catalogue removal remain later slices | | Default behavior and actual ART callback | `pytest -q tests/checkers/default/test_contract.py tests/checkers/default/test_execution.py` | 25 passed | Component remains deliberately unselected | | Test-lane ownership and focused behavior | `pytest -q tests/checkers/default/test_contract.py tests/checkers/default/test_execution.py tests/test_ci_lane_catalogue.py` | 71 passed | Hosted full-suite evidence follows in the draft PR | | Public module boundary | `pytest -q tests/architecture/test_module_boundaries.py::test_repository_matches_the_protected_module_boundary tests/architecture/test_module_boundaries.py::test_art_implements_checker_consumer_ports_without_a_public_cycle` | 2 passed | Existing catalogues retain their recorded debt until cutover | @@ -134,7 +134,7 @@ introduced here. - Current-source reconciliation: Started from merged PR #528 at `e77c48b1086c95cc4c2fc05bdf2fdcffdce52494` and reconciled additively with - current main `3cf40503691ab05533247a6a80bb2cff84c54721`. + current main `e31e1777c47b794b1d4d8240192608e4fff4f536`. - Next usable boundary: Bind approved external policy identities and compose the default plus every required project pre-image before the existing atomic Submission operation. From 957da893d11a832012027e6db467090ccae2fb8e Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 17:25:30 +0100 Subject: [PATCH 046/283] [PILOT-10] Preserve invalid cursor refusal through evidence projection --- .../pilot10-stable-contribution-pagination.md | 7 ++++++- .../contributions/records/read_service.py | 4 ++-- .../contributions/test_export_projection.py | 17 ++++++++++++++++- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/.commitrail/changes/pilot10-stable-contribution-pagination.md b/.commitrail/changes/pilot10-stable-contribution-pagination.md index b53da8294..4e427d1c0 100644 --- a/.commitrail/changes/pilot10-stable-contribution-pagination.md +++ b/.commitrail/changes/pilot10-stable-contribution-pagination.md @@ -97,7 +97,12 @@ Prepared public regression now includes direct installed-guard checks for sealed append, header/member mutation, premature deletion, deferred unsealed commit, and public cleanup of a nonempty expired private selection. These collect successfully but are not runtime proof until the native migration -is installed. Implementation still requires installed-schema proof. +is installed. First composed native run at 97e8b1cd installed 0036 and passed direct guard +assertions, then reproduced invalid-cursor reclassification (503 instead of 422). +Database, role and MinIO cleanup all passed. Preserve InvalidContributionCursor +through the projection service; an owner-port regression checks propagation +without loading award evidence. Full native rerun remains required. +Implementation still requires installed-schema proof. ## Reconciliation diff --git a/backend/app/modules/contributions/records/read_service.py b/backend/app/modules/contributions/records/read_service.py index de0eb0c13..127fb6d27 100644 --- a/backend/app/modules/contributions/records/read_service.py +++ b/backend/app/modules/contributions/records/read_service.py @@ -9,7 +9,7 @@ from app.modules.compensation.api.awards import CompensationAwardFacts from app.modules.contributions.api.records import ( ContributionAwardView, ContributionExportResponse, ContributionExportTooLarge, - ContributionExportUnavailable, + ContributionExportUnavailable, InvalidContributionCursor, ContributionReadAuthorizationPort, ContributionReadRequest, ContributionRecordView, ) @@ -94,7 +94,7 @@ async def read(self, request: ContributionReadRequest) -> ContributionExportResp acceptances.get((record.project_id, record.source_final_acceptance_id)), ) for record in records) return ContributionExportResponse(exported_at=page.exported_at, items=items, next_cursor=page.next_cursor) - except ContributionExportTooLarge: + except (ContributionExportTooLarge, InvalidContributionCursor): raise except (ValidationError, ValueError, TypeError) as exc: raise ContributionExportUnavailable("Contribution evidence unavailable") from exc diff --git a/backend/tests/contributions/test_export_projection.py b/backend/tests/contributions/test_export_projection.py index 958d4151f..991f0a947 100644 --- a/backend/tests/contributions/test_export_projection.py +++ b/backend/tests/contributions/test_export_projection.py @@ -11,7 +11,7 @@ from app.modules.compensation.api.awards import CompensationAwardFacts from app.modules.compensation.api.instruments import CompensationInstrumentType from app.modules.contributions.api.records import ( - ContributionExportTooLarge, ContributionExportUnavailable, ContributionReadRequest, + ContributionExportTooLarge, ContributionExportUnavailable, ContributionReadRequest, InvalidContributionCursor, ) from app.modules.contributions.records.read_facts import ContributionReadFacts, ContributionReadPage, FrozenContributionAward from app.modules.contributions.records.read_service import ContributionReadService @@ -254,3 +254,18 @@ async def read_contribution_awards(self, selected): with pytest.raises(ContributionExportUnavailable): await service(FaultyPage(value)).read(request(value).model_copy(update={"page_size": 1})) + + +async def test_invalid_cursor_refusal_reaches_public_boundary_without_owner_projections(): + value = facts() + + class InvalidCursor(Ports): + async def read(self, request): + assert self.authorized + raise InvalidContributionCursor("Invalid contribution export cursor") + + async def read_contribution_awards(self, selected): + pytest.fail("invalid cursor loaded award evidence") + + with pytest.raises(InvalidContributionCursor): + await service(InvalidCursor(value)).read(request(value)) From 4574d4498780d646f0adddedc35563986627466b Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 17:43:38 +0100 Subject: [PATCH 047/283] docs: plan full PILOT-04 checker cutover --- .../pilot04-workstream-default-checker.md | 222 +++++++++--------- 1 file changed, 114 insertions(+), 108 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index d59060049..1be111b96 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -1,142 +1,148 @@ -# [PILOT-04] Define The One Workstream Default Checker +# [PILOT-04] Deliver The External Checker Flow End To End - Initiative: None -- Durable disposition: Complete -- Intended merge outcome: Deliver one versioned, unselected Workstream default - checker contract and implementation with exactly four blocking defaults and - warning-only summary and attestation observations. +- Durable disposition: Planned +- Intended merge outcome: Replace both built-in checker catalogues with one + versioned Workstream default checker and immutable digest-pinned project + images, then prove ZIP-to-prechecks-to-Submission-to-post-checks without a + parallel runtime. ## Intent -Issue #491 replaces the built-in pre- and post-submit catalogues with one -Workstream-owned default checker plus digest-pinned project images. The merged -external service can execute project images, but the repository does not yet -have the one default checker whose behavior must precede those images. This -change establishes that executable behavior and its stable result contract -without selecting it in the current intake path. +Issue #491 owns the complete checker cutover. A contributor ZIP must first pass +the one Workstream default checker and every required project pre-submit image. +Only then may the existing caller-owned transaction create an immutable +Submission, move the task to `evaluation_pending`, and retain its durable +initial post-submit dispatch. Post-submit images produce evidence only. ## Current behavior -`backend/app/modules/checkers/pre_submit_execution.py` dispatches the current -versioned pre-submit catalogue. It mixes platform custody checks, project rules, -packet requirements and advisories. The post-submit catalogue separately owns -structural defaults. Both remain active until complete replacement proof permits -one clean cutover. The merged external runtime is intentionally unselected. +This branch contains the normalized external contract, immutable registry, +long-lived Rust service and SDK, typed Unix-socket client, callback-scoped ART +grant, and the exact four-behavior Workstream default checker. Those components +are unselected. Production still uses the older pre/post catalogues. ## Bounded change ### Allowed -- This record. -- `backend/app/modules/checkers/api/default_checker.py` for closed input/result - contracts, stable checker identity and behavior digest. -- `backend/app/modules/checkers/default_checker.py` for the four Workstream - defaults over detached ART/TASK facts and the existing CHECKERS-owned bounded - material-read capability. -- Focused tests under `backend/tests/checkers/default/` for every positive, - negative, infrastructure and warning boundary. -- The existing checker custody-consumer inventory in - `backend/tests/test_artifact_architecture.py` for the two new same-owner - materialization-contract consumers. -- The minimum test-lane and behavior-owner metadata needed to run the new tests - and assign the two new modules exactly once. -- `docs/architecture_checker_framework.md` and the exact PILOT-04 checker rows - in `docs/roadmap_status.md` for the implemented but unselected boundary. +- This record and affected current PILOT-04 architecture, roadmap and owner docs. +- CHECKERS policy contracts, registry reads, default/external execution, + durable attempt/result custody, post routing and composition roots. +- ART preparation, verified-material callback, evidence, admission and + post-submit materialization owners needed by the one selected runtime. +- PROJECT approval persistence and activation readiness for exact registry, + requirement, stage, configuration and resource-limit binding. +- TASK's existing submission composition and CHECKERS dispatch owners only to + compose the already-owned atomic Submission/`evaluation_pending`/outbox + operation after prechecks pass and to route post-submit evidence. +- The intake route and backend/CLI schemas needed for the actual operation. +- One successor migration plus model, Alembic graph, fingerprint, reset + inventory and direct-SQL guards if existing evidence tables cannot retain the + exact external execution and latency facts. Its ordinal follows the actual + single linear predecessor at publication. +- Removal of both obsolete catalogue implementations, callers and obsolete + tests after replacement proof. +- Focused contract, AUTH, custody, replay, concurrency, failure, service, + public API, CLI, PostgreSQL and MinIO tests and their exact CI ownership. ### Not allowed -- No policy binding, guide activation/F-020, external project-image selection, - service composition, public route, CLI or Submission/admission caller wiring. -- No migration, registry mutation, durable run/result/receipt, scheduler, - retry worker, acceptance or routing behavior. -- No deletion, bypass or parallel execution of either current catalogue. No - change to their hashes, policies, active callers or tests. -- No project required-file, project size, forbidden-file or generic rule logic. - No extra blocking Workstream default. Summary and attestation remain warnings. -- No held PILOT-05, PILOT-06 or PILOT-09 work, deployment, merge or issue closure. +- No second scheduler, store, submission lifecycle, acceptance operation, + policy representation, compatibility alias or parallel execution. +- No checker-owned acceptance, Review fabrication, ContributionPolicy change, + payment work, provider-path authority, host socket exposure, or external + execution inside a database transaction. +- No optional summary/attestation blocker. Their absence remains a warning. +- No generic Workstream implementation of project rules; every project + pre/post check is an approved digest-pinned external image. +- No PILOT-05, PILOT-06 or PILOT-09 work, deployment, merge or issue closure. ## Design and decisions -The checker consumes detached owner facts rather than reparsing a ZIP or -inventing storage access: ART's structural inspection, server-computed archive -commitment and canonical semantic manifest, plus TASK/ART canonical predecessor -identity. It reads bytes only through the existing CHECKERS-owned callback-scoped -material capability, recomputes the manifest identity and rechecks every file -digest. The existing ART sealed-tree projection satisfies that capability without -a CHECKERS-to-ART dependency or any path/storage authority. Unsafe contributor -archives become the one archive-safety finding; storage-integrity and timeout -failures remain recoverable infrastructure outcomes. Exact material/manifest -disagreement also fails as infrastructure instead of blaming the contributor. - -The result always has four ordered blocking slots: archive safety, received -identity, high-confidence secrets and task-rule-aware unchanged resubmission. -An evaluated slot is `passed` or `failed`; a slot unavailable after an unsafe -archive is `not_run`. Warning-only summary and attestation observations are -separate closed values. Findings retain only stable categories and counts, not -matched bytes or contributor text. - -The checker has a code-owned version and canonical behavior digest. Its manifest -contains the exact four check identities, warning identities, and each secret -signature's category, executable regex source and flags. The implementation -compiles from that same canonical constant, so detector changes alter the -behavior digest and golden contract proof. This is a Workstream implementation -that changes only with a deploy; project rules remain external images. - -This component is unselected. A later bounded cutover will bind approved -external policy entries, execute every required pre-image through the merged -service, and invoke the existing caller-owned atomic Submission operation only -after this checker and all required project checks pass. Both catalogues are -removed only after complete pre/post replacement proof; no parallel runtime is -introduced here. +Approval resolves every project binding to an immutable phase-specific registry +row and persists its row ID, entry digest, platform image manifest digest, +schemas, configuration and resource ceilings under the locked policy hash. +Runtime never selects a latest version or trusts a proposal string as authority. + +ART computes and verifies received bytes and the canonical file manifest before +external execution. Its callback grant maps one sealed read-only workspace into +the Rust service and expires on completion, timeout, disconnect or cancellation. +The Workstream checker implements exactly archive safety, server-owned receipt +and manifest identity, high-confidence secret detection and task-rule-aware +unchanged-resubmission refusal. Missing summary/attestation yields warnings. +Every required project pre image then runs in locked order. Work failures retain +bounded findings, create no Submission or dispatch, consume no contributor +attempt and leave the task `in_progress`. Infrastructure outcomes are +recoverable and are not contributor-failure facts. + +External work remains outside database transactions. After every required +precheck passes, the caller opens one root and invokes the existing TASK +submission composition operation, which consumes the exact admission while +atomically creating Submission, advancing to `evaluation_pending`, reserving +the initial evaluation and appending the dispatch event. Post workers resolve +only locked entries, read immutable Submission material through ART and persist +normalized evidence; they cannot accept work. + +Activation refuses any required capability suggestion without an exact +requirement/stage binding to a registered digest-pinned image in the same +approved generation. Registration alone, wrong project/stage/requirement, or a +stale approval does not clear F-020. Existing false-policy and warning- +acknowledgment guards remain. + +The old pre/post catalogues are removed in the same final change after every +production caller and required proof uses the selected runtime. ## Acceptance criteria -- [x] The result contract admits exactly four ordered blocking checks and only - the closed warning-only summary/attestation observations. -- [x] Valid safe ZIP custody, recomputed manifest identity, no high-confidence - secret and first/changed work pass all four defaults. -- [x] Malformed, encrypted, unsafe, colliding or platform-limit archives return - one bounded archive finding and do not expose material to later checks. -- [x] Stored-byte/manifest disagreement, inspection timeout/integrity failure or - stale/unavailable predecessor facts are infrastructure outcomes, never work - findings or silent passes. -- [x] Exact private-key, cloud-credential and API-token signatures fail without - retaining matched content; representative near misses pass. -- [x] Exact archive or semantic-manifest replay fails unless the canonical task - rules/predecessor changed, with parity against the canonical owner semantics. -- [x] Empty summary and attestation add warnings only and never change the four - blocking verdicts. -- [x] Existing catalogue identities, hashes and execution tests remain unchanged; - no production composition selects the new checker. +- [ ] Approval binds the default behavior digest and every project binding to + an exact immutable registry row, phase, image, schemas, configuration and + limits; substitutions and stale approvals fail closed. +- [ ] Activation enforces exact F-020 requirement/stage/generation coverage and + retains false-policy and warning-acknowledgment guards. +- [ ] ART verifies server receipt identity and a bounded safe manifest before + any project image reads material. +- [ ] The default checker runs exactly four blockers; absent summary and + attestation remain warning-only. +- [ ] Every required pre image passes before admission consumption. Work + findings create no Submission/dispatch and keep the task `in_progress`; + infrastructure failures remain recoverable and consume no attempt. +- [ ] Passing preparation invokes the existing caller-owned atomic operation + and commits Submission, `evaluation_pending` and initial dispatch together. +- [ ] Required post images consume immutable Submission custody, persist + normalized evidence and never decide acceptance. +- [ ] Timeout, cancellation, crash/restart, changed policy/material, + cross-project access and duplicate delivery cannot create partial effects; + latency and queue/execution lineage are retained. +- [ ] Both obsolete catalogues, implementations, callers and obsolete tests are + removed without a fallback or parallel runtime. +- [ ] A real PostgreSQL 16, MinIO and Rust-service journey proves pass, work + failure, infrastructure/retry and post-dispatch paths with cleanup. ## Risk and review routing - Risk class: L1 -- Required reviewers: architecture, security, reuse_dedup, qa, test_delta, - documentation, product_ops, ci_integrity -- Human review focus: Exact four-default boundary, high-confidence pattern - precision, contributor-vs-infrastructure classification, reuse of ART custody - and predecessor ownership, bounded secret-free results, and absence of a - parallel active execution path. +- Required reviewers: architecture, security, authorization, product_ops, + reuse_dedup, qa, test_delta, documentation, ci_integrity +- Human review focus: Locked policy/registry custody, TASK-before-CHECKERS + ordering, all-pre-before-Submission, transaction boundaries, grant lifetime, + work-versus-infrastructure outcomes, replay, F-020, post non-acceptance and + complete catalogue removal. ## Evidence | Claim | Command or proof | Result | Remaining uncertainty | |---|---|---|---| -| Current owner map | Source inspection of ART inspection/manifest/change owners, both current catalogues and the merged external runtime | Complete and reconciled through main `e31e1777c47b794b1d4d8240192608e4fff4f536` | Policy binding, live pre-admission orchestration, post cutover and catalogue removal remain later slices | -| Default behavior and actual ART callback | `pytest -q tests/checkers/default/test_contract.py tests/checkers/default/test_execution.py` | 25 passed | Component remains deliberately unselected | -| Test-lane ownership and focused behavior | `pytest -q tests/checkers/default/test_contract.py tests/checkers/default/test_execution.py tests/test_ci_lane_catalogue.py` | 71 passed | Hosted full-suite evidence follows in the draft PR | -| Public module boundary | `pytest -q tests/architecture/test_module_boundaries.py::test_repository_matches_the_protected_module_boundary tests/architecture/test_module_boundaries.py::test_art_implements_checker_consumer_ports_without_a_public_cycle` | 2 passed | Existing catalogues retain their recorded debt until cutover | -| Closed materialization consumer inventory | `pytest -q tests/test_artifact_architecture.py::test_checker_custody_ports_have_exact_owner_and_art_consumers` | Passed | The inventory still rejects every unregistered owner or ART consumer | -| Behavior-owner partition | `python -m scripts.behavior_ownership validate` | Passed | Hosted evidence still validates the exact merge tree | +| Existing component custody | Prior PR538 default, Rust service/SDK, ART callback and contract reviews | Passed at recorded component heads | Final selected flow/current-main integration pending | +| Owner/caller trace | PROJECT approval/activation, ART preparation/admission, TASK composition and CHECKERS dispatch | In progress | Persistence delta and migration ordinal await actual linear predecessor | +| End-to-end replacement | Real PostgreSQL/MinIO/Rust public and worker journey | Not run | Implementation incomplete | ## Reconciliation -- Current-source reconciliation: Started from merged PR #528 at - `e77c48b1086c95cc4c2fc05bdf2fdcffdce52494` and reconciled additively with - current main `e31e1777c47b794b1d4d8240192608e4fff4f536`. -- Next usable boundary: Bind approved external policy identities and compose the - default plus every required project pre-image before the existing atomic - Submission operation. -- Remaining risks: No caller selects this component in this change; whole-issue - acceptance, F-020 and both-catalogue removal remain open. +- Current-source reconciliation: implementation starts at PR538 head + `7453a0d8c5664cfd486872a381899f3755393004`; final publication will reconcile + actual merged `main` and intervening owners. +- Next usable boundary: full selected checker journey; no component-only merge. +- Remaining risks: exact durable external pre-attempt/result projection may + require a successor migration. Numbering and fingerprints resolve only + against the actual linear graph; no competing ordinal is reserved here. From ef7fac0679a67baf88ad55538e56884558d0c05a Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 17:48:44 +0100 Subject: [PATCH 048/283] docs: close PILOT-04 cutover planning gaps --- .../pilot04-workstream-default-checker.md | 33 ++++++++++++++++--- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 1be111b96..f313cbed3 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -36,7 +36,11 @@ are unselected. Production still uses the older pre/post catalogues. - TASK's existing submission composition and CHECKERS dispatch owners only to compose the already-owned atomic Submission/`evaluation_pending`/outbox operation after prechecks pass and to route post-submit evidence. -- The intake route and backend/CLI schemas needed for the actual operation. +- The minimum existing hidden preparation-to-Submission composition needed to + prove PILOT-04. PILOT-12 retains assignment-bound upload intent, contributor + REST/CLI intake and requirements-read surfaces. The existing hidden command + stops rejecting absent summary/attestation so the default checker can retain + warning-only observations; this does not publish the PILOT-12 surface. - One successor migration plus model, Alembic graph, fingerprint, reset inventory and direct-SQL guards if existing evidence tables cannot retain the exact external execution and latency facts. Its ordinal follows the actual @@ -92,6 +96,23 @@ acknowledgment guards remain. The old pre/post catalogues are removed in the same final change after every production caller and required proof uses the selected runtime. +Retained approvals, locked guides, evidence and completed runs are never +rewritten or deleted. Historical decoders remain narrowly scoped to immutable +old evidence. An unresolved old-catalogue queue item or locked guide fails +closed and requires an authorized recompile/reapproval transition; it is never +silently run through a new image. This retained-data reader is not an executable +compatibility runtime. + +Pre execution uses a durable lease/generation fence. One root reserves the +exact prepared-generation, policy, registry and request identities, commits, +then the ART callback and external service execute without a database +transaction. A fresh root locks TASK currentness before CHECKERS attempt state, +verifies lease/generation and material/result/isolation identities, and appends +the immutable outcome or marks a recoverable infrastructure result. Expired +leases may be reclaimed under the same locks; a crashed process-local grant is +never serialized or resumed. Queue/read-current/reserve, completion, replay and +acknowledgment all acquire TASK custody before CHECKERS state, including the +retained intermediate-wait regression. ## Acceptance criteria @@ -114,6 +135,9 @@ production caller and required proof uses the selected runtime. - [ ] Timeout, cancellation, crash/restart, changed policy/material, cross-project access and duplicate delivery cannot create partial effects; latency and queue/execution lineage are retained. +- [ ] Retained old evidence remains readable without rewriting hashes; unresolved + old execution cannot cross into the new runtime and requires authorized policy + transition. - [ ] Both obsolete catalogues, implementations, callers and obsolete tests are removed without a fallback or parallel runtime. - [ ] A real PostgreSQL 16, MinIO and Rust-service journey proves pass, work @@ -125,9 +149,10 @@ production caller and required proof uses the selected runtime. - Required reviewers: architecture, security, authorization, product_ops, reuse_dedup, qa, test_delta, documentation, ci_integrity - Human review focus: Locked policy/registry custody, TASK-before-CHECKERS - ordering, all-pre-before-Submission, transaction boundaries, grant lifetime, - work-versus-infrastructure outcomes, replay, F-020, post non-acceptance and - complete catalogue removal. + ordering for read-current/reserve/enqueue/complete/replay/acknowledge, + all-pre-before-Submission, transaction boundaries, durable pre lease and + process-local grant lifetime, work-versus-infrastructure outcomes, retained + history, F-020, post non-acceptance and complete catalogue removal. ## Evidence From 64570ce67e1a51cde9d0eb9ee02b4f782033d42c Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 17:50:54 +0100 Subject: [PATCH 049/283] docs: bind PILOT-04 crash and activation recovery --- .../pilot04-workstream-default-checker.md | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index f313cbed3..09fd44cef 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -109,10 +109,14 @@ then the ART callback and external service execute without a database transaction. A fresh root locks TASK currentness before CHECKERS attempt state, verifies lease/generation and material/result/isolation identities, and appends the immutable outcome or marks a recoverable infrastructure result. Expired -leases may be reclaimed under the same locks; a crashed process-local grant is -never serialized or resumed. Queue/read-current/reserve, completion, replay and -acknowledgment all acquire TASK custody before CHECKERS state, including the -retained intermediate-wait regression. +leases are finalized as infrastructure failures under the same locks. Because +pre-Submission prepared bytes and the grant are deliberately process-local, a +restart never reconstructs them from a DTO or path: retry requires a fresh +upload, a fresh server-computed byte/manifest identity and a new attempt +generation while retaining the failed attempt. A grant is never serialized or +resumed. Queue/read-current/reserve, completion, replay and acknowledgment all +acquire TASK custody before CHECKERS state, including the retained +intermediate-wait regression. ## Acceptance criteria @@ -121,6 +125,9 @@ retained intermediate-wait regression. limits; substitutions and stale approvals fail closed. - [ ] Activation enforces exact F-020 requirement/stage/generation coverage and retains false-policy and warning-acknowledgment guards. +- [ ] F-020 recovery is proven by register -> recompile -> approve -> activate + in one current generation; registration alone and wrong generation, stage, + requirement, registry digest or stale approval remain blocked. - [ ] ART verifies server receipt identity and a bounded safe manifest before any project image reads material. - [ ] The default checker runs exactly four blockers; absent summary and @@ -134,7 +141,8 @@ retained intermediate-wait regression. normalized evidence and never decide acceptance. - [ ] Timeout, cancellation, crash/restart, changed policy/material, cross-project access and duplicate delivery cannot create partial effects; - latency and queue/execution lineage are retained. + latency and queue/execution lineage are retained, and restart requires fresh + server-verified uploaded material rather than a reconstructed scratch handle. - [ ] Retained old evidence remains readable without rewriting hashes; unresolved old execution cannot cross into the new runtime and requires authorized policy transition. From 805bc486e41cd8378bf0ae5f386f92a8caf0ac79 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 18:12:14 +0100 Subject: [PATCH 050/283] feat: lock external checker policy bindings --- backend/app/adapters/checkers/__init__.py | 7 + backend/app/interfaces/project_agents.py | 18 +- backend/app/modules/checkers/api/external.py | 5 + .../modules/checkers/api/external_policy.py | 262 ++++++++++++++++++ .../app/modules/checkers/external_registry.py | 81 +++++- .../projects/guide_activation/service.py | 39 ++- .../guide_compilation/approval_custody.py | 9 +- .../guide_compilation/proposal_approval.py | 71 ++--- .../guide_compilation/proposal_service.py | 4 + .../tests/checkers/external/test_policy.py | 153 ++++++++++ .../test_requirement_dispositions.py | 18 +- .../test_capability_growth.py | 22 +- 12 files changed, 611 insertions(+), 78 deletions(-) create mode 100644 backend/app/modules/checkers/api/external_policy.py create mode 100644 backend/tests/checkers/external/test_policy.py diff --git a/backend/app/adapters/checkers/__init__.py b/backend/app/adapters/checkers/__init__.py index 976e3d2e4..48f993f54 100644 --- a/backend/app/adapters/checkers/__init__.py +++ b/backend/app/adapters/checkers/__init__.py @@ -74,6 +74,13 @@ def configured_external_checker_execution_factory(settings): ) +def external_checker_registry_reader(session): + """Resolve immutable metadata for trusted approval and execution owners.""" + from app.modules.checkers.external_registry import ExternalCheckerRegistryReader + + return ExternalCheckerRegistryReader(session) + + class _ExecutionRequest(Protocol): plan: Any commitment: Any diff --git a/backend/app/interfaces/project_agents.py b/backend/app/interfaces/project_agents.py index 595471321..7b2884ed8 100644 --- a/backend/app/interfaces/project_agents.py +++ b/backend/app/interfaces/project_agents.py @@ -266,9 +266,9 @@ class AtomicGuideRequirement(BaseModel): disposition: RequirementDisposition = Field(description=( "Use human_review for work assigned to an authorized human reviewer. " "Use a capability gap only for required unsupported automated evaluation. " - "Any guide_blocker, pre_submit_capability_gap or post_submit_capability_gap " - "requires guide_blocked and no artifact policy. Exact supported binding " - "proposals may remain as catalogue-match evidence without being projected." + "A guide_blocker requires guide_blocked and no artifact policy. Capability " + "gaps remain explicit activation blockers while the manager reviews the " + "available exact bindings in a warning-ready proposal." )) platform_coverage: PlatformCoverageRef | None = None evidence_refs: tuple[GuideEvidenceRef, ...] = Field( @@ -593,15 +593,13 @@ def _validate_capability_suggestions( def _validate_status_consistency(result: ProjectGuideCompilationResult) -> None: """Require ready and blocked status to match findings and dispositions.""" has_blocker = any(finding.severity == "blocking_gap" for finding in result.findings) or any( - requirement.disposition - in { - RequirementDisposition.GUIDE_BLOCKER, - RequirementDisposition.PRE_SUBMIT_CAPABILITY_GAP, - RequirementDisposition.POST_SUBMIT_CAPABILITY_GAP, - } + requirement.disposition is RequirementDisposition.GUIDE_BLOCKER for requirement in result.requirements ) - has_warning = any(finding.severity == "warning" for finding in result.findings) + has_warning = ( + any(finding.severity == "warning" for finding in result.findings) + or bool(result.capability_suggestions) + ) if result.status == "guide_blocked" and not has_blocker: raise ValueError("blocked compilation requires blocking evidence") if result.status != "guide_blocked" and has_blocker: diff --git a/backend/app/modules/checkers/api/external.py b/backend/app/modules/checkers/api/external.py index 0a0f0cb61..48cd706a1 100644 --- a/backend/app/modules/checkers/api/external.py +++ b/backend/app/modules/checkers/api/external.py @@ -310,6 +310,11 @@ async def read_exact( ) -> ExternalCheckerRegistryEntry: """Read one exact immutable entry without selecting a latest version.""" + async def read_identity( + self, *, capability_id: str, capability_version: str, phase: ExternalCheckerPhase + ) -> ExternalCheckerRegistryEntry: + """Resolve the one immutable registered phase identity during approval.""" + class ExternalCheckerMaterial(ExternalCheckerValue): """One verified read-only material identity without provider coordinates.""" diff --git a/backend/app/modules/checkers/api/external_policy.py b/backend/app/modules/checkers/api/external_policy.py new file mode 100644 index 000000000..0b668a730 --- /dev/null +++ b/backend/app/modules/checkers/api/external_policy.py @@ -0,0 +1,262 @@ +"""Locked external-checker policies compiled from approved guide bindings.""" + +from __future__ import annotations + +from typing import Literal, Self + +from pydantic import BaseModel, ConfigDict, Field, JsonValue, model_validator + +from app.core.hashing import canonical_json_hash +from app.interfaces.project_agents import ( + PostSubmissionBindingProposal, + PreSubmissionBindingProposal, + ProjectGuideCompilationResult, + RequirementDisposition, +) +from app.modules.checkers.api.default_checker import ( + WORKSTREAM_DEFAULT_BEHAVIOR_SHA256, + WORKSTREAM_DEFAULT_CHECKER_ID, + WORKSTREAM_DEFAULT_CHECKER_VERSION, +) +from app.modules.checkers.api.external import ( + ExternalCheckerPhase, + ExternalCheckerRegistryEntry, + ExternalCheckerRegistryPort, + external_checker_json_hash, +) + + +class ExternalCheckerPolicyError(ValueError): + """Reject incomplete, stale or phase-substituted locked checker policy.""" + + +class _PolicyValue(BaseModel): + model_config = ConfigDict(extra="forbid", frozen=True, revalidate_instances="always") + + +class LockedExternalCheckerBinding(_PolicyValue): + """One requirement bound to an exact immutable registry publication.""" + + requirement_id: str = Field(min_length=1, max_length=100) + stage: ExternalCheckerPhase + registry: ExternalCheckerRegistryEntry + configuration: dict[str, JsonValue] + configuration_sha256: str = Field(pattern=r"^sha256:[0-9a-f]{64}$") + + @model_validator(mode="after") + def validate_binding(self) -> Self: + if self.registry.phase != self.stage: + raise ExternalCheckerPolicyError("checker binding phase mismatch") + self.registry.configuration_schema.validate_instance(self.configuration) + if self.configuration_sha256 != external_checker_json_hash(self.configuration): + raise ExternalCheckerPolicyError("checker binding configuration mismatch") + return self + + +class LockedWorkstreamDefault(_PolicyValue): + """Code-owned default identity included in every approved pre policy.""" + + checker_id: Literal[WORKSTREAM_DEFAULT_CHECKER_ID] = WORKSTREAM_DEFAULT_CHECKER_ID + checker_version: Literal[WORKSTREAM_DEFAULT_CHECKER_VERSION] = ( + WORKSTREAM_DEFAULT_CHECKER_VERSION + ) + behavior_sha256: str = Field( + default=WORKSTREAM_DEFAULT_BEHAVIOR_SHA256, + pattern=r"^sha256:[0-9a-f]{64}$", + ) + + @model_validator(mode="after") + def validate_behavior(self) -> Self: + """Bind the locked identity to the executable code-owned manifest.""" + if self.behavior_sha256 != WORKSTREAM_DEFAULT_BEHAVIOR_SHA256: + raise ExternalCheckerPolicyError("default checker behavior mismatch") + return self + + +class LockedExternalPreSubmitPolicy(_PolicyValue): + """One default followed by every required project pre-submit image.""" + + schema_version: Literal["external_pre_submit_policy.v1"] = ( + "external_pre_submit_policy.v1" + ) + workstream_default: LockedWorkstreamDefault = Field( + default_factory=LockedWorkstreamDefault + ) + entries: tuple[LockedExternalCheckerBinding, ...] + policy_sha256: str = Field(pattern=r"^sha256:[0-9a-f]{64}$") + + @model_validator(mode="after") + def validate_policy(self) -> Self: + _validate_entries(self.entries, "pre_submit") + if self.policy_sha256 != canonical_json_hash( + self.model_dump(mode="json", exclude={"policy_sha256"}) + ): + raise ExternalCheckerPolicyError("pre-submit policy digest mismatch") + return self + + +class LockedExternalPostSubmitPolicy(_PolicyValue): + """Every required post-submit image; checkers retain no acceptance authority.""" + + schema_version: Literal["external_post_submit_policy.v1"] = ( + "external_post_submit_policy.v1" + ) + entries: tuple[LockedExternalCheckerBinding, ...] + policy_sha256: str = Field(pattern=r"^sha256:[0-9a-f]{64}$") + + @model_validator(mode="after") + def validate_policy(self) -> Self: + _validate_entries(self.entries, "post_submit") + if self.policy_sha256 != canonical_json_hash( + self.model_dump(mode="json", exclude={"policy_sha256"}) + ): + raise ExternalCheckerPolicyError("post-submit policy digest mismatch") + return self + + +class LockedExternalCheckerPolicies(_PolicyValue): + """Complete approval-time pre/post policy custody for one guide generation.""" + + schema_version: Literal["external_checker_policies.v1"] = ( + "external_checker_policies.v1" + ) + pre_submit: LockedExternalPreSubmitPolicy + post_submit: LockedExternalPostSubmitPolicy + policies_sha256: str = Field(pattern=r"^sha256:[0-9a-f]{64}$") + + @model_validator(mode="after") + def validate_policies(self) -> Self: + if self.policies_sha256 != canonical_json_hash( + self.model_dump(mode="json", exclude={"policies_sha256"}) + ): + raise ExternalCheckerPolicyError("checker policies digest mismatch") + return self + + +def _validate_entries( + entries: tuple[LockedExternalCheckerBinding, ...], phase: ExternalCheckerPhase +) -> None: + identities = [ + ( + item.requirement_id, + item.registry.capability_id, + item.registry.capability_version, + ) + for item in entries + ] + if any(item.stage != phase for item in entries) or identities != sorted(identities): + raise ExternalCheckerPolicyError("checker policy order is not canonical") + if len(identities) != len(set(identities)): + raise ExternalCheckerPolicyError("checker policy binding is duplicated") + + +async def compile_external_checker_policies( + result: ProjectGuideCompilationResult, + registry: ExternalCheckerRegistryPort, +) -> tuple[LockedExternalPreSubmitPolicy, LockedExternalPostSubmitPolicy]: + """Resolve every supported binding to exact immutable registry custody.""" + result = ProjectGuideCompilationResult.model_validate(result) + if result.status == "guide_blocked": + raise ExternalCheckerPolicyError("checker capability coverage is incomplete") + requirements = {item.requirement_id: item for item in result.requirements} + if len(requirements) != len(result.requirements): + raise ExternalCheckerPolicyError("checker requirements are duplicated") + pre = await _resolve( + result.pre_submit_bindings, requirements, registry, "pre_submit" + ) + post = await _resolve( + result.post_submit_bindings, requirements, registry, "post_submit" + ) + return _make_policy(LockedExternalPreSubmitPolicy, pre), _make_policy( + LockedExternalPostSubmitPolicy, post + ) + + +async def compile_external_checker_policy_bundle( + result: ProjectGuideCompilationResult, + registry: ExternalCheckerRegistryPort, +) -> LockedExternalCheckerPolicies: + """Lock both execution phases into one immutable approval-time value.""" + pre, post = await compile_external_checker_policies(result, registry) + body = { + "schema_version": "external_checker_policies.v1", + "pre_submit": pre.model_dump(mode="json"), + "post_submit": post.model_dump(mode="json"), + } + return LockedExternalCheckerPolicies( + pre_submit=pre, + post_submit=post, + policies_sha256=canonical_json_hash(body), + ) + + +async def _resolve(bindings, requirements, registry, phase): + expected = ( + RequirementDisposition.SUPPORTED_PRE_SUBMIT + if phase == "pre_submit" + else RequirementDisposition.SUPPORTED_POST_SUBMIT + ) + resolved = [] + for binding in sorted( + bindings, key=lambda item: ( + item.requirement_id, item.capability_id, item.capability_version + ), + ): + if ( + requirements.get(binding.requirement_id) is None + or requirements[binding.requirement_id].disposition is not expected + or binding.stage.value != phase + ): + raise ExternalCheckerPolicyError("checker binding does not cover requirement") + entry = await registry.read_identity( + capability_id=binding.capability_id, + capability_version=binding.capability_version, + phase=phase, + ) + if ( + entry.capability_id != binding.capability_id + or entry.capability_version != binding.capability_version + or entry.phase != phase + ): + raise ExternalCheckerPolicyError("checker registry identity mismatch") + configuration = ( + { + parameter.name: parameter.value + for parameter in binding.parameters + } + if isinstance(binding, PostSubmissionBindingProposal) + else {} + ) + resolved.append( + LockedExternalCheckerBinding( + requirement_id=binding.requirement_id, + stage=phase, + registry=entry, + configuration=configuration, + configuration_sha256=external_checker_json_hash(configuration), + ) + ) + expected_ids = { + item.requirement_id + for item in requirements.values() + if item.disposition is expected + } + if {item.requirement_id for item in resolved} != expected_ids: + raise ExternalCheckerPolicyError("checker requirement coverage is incomplete") + return tuple(resolved) + + +def _make_policy(model, entries): + hash_body = { + "schema_version": model.model_fields["schema_version"].default, + "entries": [item.model_dump(mode="json") for item in entries], + } + if model is LockedExternalPreSubmitPolicy: + default = LockedWorkstreamDefault() + hash_body["workstream_default"] = default.model_dump(mode="json") + return model( + workstream_default=default, + entries=entries, + policy_sha256=canonical_json_hash(hash_body), + ) + return model(entries=entries, policy_sha256=canonical_json_hash(hash_body)) diff --git a/backend/app/modules/checkers/external_registry.py b/backend/app/modules/checkers/external_registry.py index a95e41b71..f5f335dcf 100644 --- a/backend/app/modules/checkers/external_registry.py +++ b/backend/app/modules/checkers/external_registry.py @@ -129,6 +129,63 @@ async def add(self, row: ExternalCheckerRegistryEntryRecord) -> None: await self._session.refresh(row) +class ExternalCheckerRegistryReader: + """Authority-neutral exact metadata reads for trusted policy compilation.""" + + def __init__(self, session: AsyncSession) -> None: + self._session = session + self._repository = ExternalCheckerRegistryRepository(session) + + def _require_root_transaction(self) -> None: + transaction = self._session.sync_session.get_transaction() + if ( + transaction is None + or not transaction.is_active + or self._session.in_nested_transaction() + ): + raise ExternalCheckerRegistryUnavailable( + "external_checker_registry_unavailable" + ) + + async def read_exact( + self, registry_entry_id: UUID, entry_digest: str + ) -> ExternalCheckerRegistryEntry: + self._require_root_transaction() + if type(registry_entry_id) is not UUID or type(entry_digest) is not str: + raise ExternalCheckerRegistryUnavailable( + "external_checker_registry_unavailable" + ) + row = await self._repository.by_exact_id(registry_entry_id) + if row is None or row.entry_digest != entry_digest: + raise ExternalCheckerRegistryUnavailable( + "external_checker_registry_unavailable" + ) + return _row_entry(row) + + async def read_identity( + self, *, capability_id: str, capability_version: str, phase: str + ) -> ExternalCheckerRegistryEntry: + self._require_root_transaction() + if ( + type(capability_id) is not str + or type(capability_version) is not str + or phase not in {"pre_submit", "post_submit"} + ): + raise ExternalCheckerRegistryUnavailable( + "external_checker_registry_unavailable" + ) + row = await self._repository.by_identity( + capability_id=capability_id, + capability_version=capability_version, + phase=phase, + ) + if row is None: + raise ExternalCheckerRegistryUnavailable( + "external_checker_registry_unavailable" + ) + return _row_entry(row) + + class ExternalCheckerRegistryService: """Publish immutable registry metadata without granting execution authority.""" @@ -225,17 +282,19 @@ async def read_exact( self, registry_entry_id: UUID, entry_digest: str ) -> ExternalCheckerRegistryEntry: """Read one exact row; never select a current/latest version.""" - self._require_root_transaction() - if type(registry_entry_id) is not UUID or type(entry_digest) is not str: - raise ExternalCheckerRegistryUnavailable( - "external_checker_registry_unavailable" - ) - row = await self._repository.by_exact_id(registry_entry_id) - if row is None or row.entry_digest != entry_digest: - raise ExternalCheckerRegistryUnavailable( - "external_checker_registry_unavailable" - ) - return _row_entry(row) + return await ExternalCheckerRegistryReader(self._session).read_exact( + registry_entry_id, entry_digest + ) + + async def read_identity( + self, *, capability_id: str, capability_version: str, phase: str + ) -> ExternalCheckerRegistryEntry: + """Resolve the immutable identity during trusted approval compilation.""" + return await ExternalCheckerRegistryReader(self._session).read_identity( + capability_id=capability_id, + capability_version=capability_version, + phase=phase, + ) @staticmethod def _matches_request( diff --git a/backend/app/modules/projects/guide_activation/service.py b/backend/app/modules/projects/guide_activation/service.py index 2de57710b..98bb5a0b7 100644 --- a/backend/app/modules/projects/guide_activation/service.py +++ b/backend/app/modules/projects/guide_activation/service.py @@ -7,6 +7,7 @@ from app.modules.authorization.api import ActorKind from app.modules.checkers.api.pre_submit import EffectivePreSubmissionPlanLineage +from app.modules.checkers.api.external_policy import LockedExternalCheckerPolicies from app.modules.projects.api.guide_activation import ( GuideActivationCommand, GuideActivationFacts, @@ -39,7 +40,8 @@ class GuideActivationService: """AUTH-12H supplies live manager authority; composition without it denies.""" def __init__( - self, session, *, contribution, planner, pre_catalogue, post_catalogue, authorization=None + self, session, *, contribution, planner, pre_catalogue, post_catalogue, + authorization=None, registry=None, ): self.session = session self.authorization = authorization @@ -52,6 +54,11 @@ def __init__( self.projects = ProjectRepository(session) self.replay = GuideMutationRepository(session) self.post = PostPolicyRepository(session) + if registry is None: + from app.modules.checkers.external_registry import ExternalCheckerRegistryReader + + registry = ExternalCheckerRegistryReader(session) + self.registry = registry async def activate( self, command: GuideActivationCommand, *, actor, request_id: UUID @@ -150,7 +157,9 @@ async def activate( GuideActivationBlocked, persisted_items=source_items, ) - self._readiness(command, locked, policy, post_custody, review, revision) + await self._readiness( + command, locked, policy, post_custody, review, revision + ) except ProjectServiceError: raise GuideProposalError("approval_blocked") from None try: @@ -218,9 +227,29 @@ async def activate( await self.replay.complete(record, response_json=receipt.model_dump(mode="json")) return receipt - def _readiness(self, command, locked, policy, post, review, revision): + async def _readiness(self, command, locked, policy, post, review, revision): target, approval = command.target.proposal, locked.view.approval_custody - require_catalogues(target, self.pre_catalogue, self.post_catalogue) + external = ( + approval.operation.effective_pre_submit_plan.get("schema_version") + == "external_checker_policies.v1" + ) + if external: + policies = LockedExternalCheckerPolicies.model_validate( + approval.operation.effective_pre_submit_plan + ) + if policies.pre_submit.model_dump(mode="json") != approval.pre.compiled_bundle: + raise GuideProposalError("approval_blocked") + for binding in (*policies.pre_submit.entries, *policies.post_submit.entries): + current = await self.registry.read_exact( + binding.registry.registry_entry_id, + binding.registry.entry_digest, + ) + if current != binding.registry: + raise GuideProposalError("approval_blocked") + if locked.result.capability_suggestions: + raise GuideProposalError("approval_blocked") + else: + require_catalogues(target, self.pre_catalogue, self.post_catalogue) post.compiled.validate_catalogue(self.post_catalogue) ProjectService(self.session).validate_activation_ready( locked.view.guide, @@ -235,6 +264,8 @@ def _readiness(self, command, locked, policy, post, review, revision): approval_custody=approval, post_policy_custody=post, ) + if external: + return upstream = command.target.upstream plan = self.planner.compile_effective_plan( lineage=EffectivePreSubmissionPlanLineage( diff --git a/backend/app/modules/projects/guide_compilation/approval_custody.py b/backend/app/modules/projects/guide_compilation/approval_custody.py index 1664fe030..85f4627fa 100644 --- a/backend/app/modules/projects/guide_compilation/approval_custody.py +++ b/backend/app/modules/projects/guide_compilation/approval_custody.py @@ -17,6 +17,7 @@ SubmissionPolicyMutationIdempotencyRecord, SubmissionArtifactPolicy, ) +from app.modules.checkers.api.external_policy import LockedExternalCheckerPolicies from .custody_payloads import policy_digest from .models import ProjectGuideProposalApproval @@ -201,7 +202,13 @@ def _require_plan_and_provenance(view, custody, target) -> None: "schema_version": target.pre_catalogue_schema_version, "manifest_sha256": target.pre_catalogue_manifest_hash, } - if ( + if operation.effective_pre_submit_plan.get("schema_version") == "external_checker_policies.v1": + policies = LockedExternalCheckerPolicies.model_validate( + operation.effective_pre_submit_plan + ) + if policies.pre_submit.model_dump(mode="json") != pre.compiled_bundle: + raise ValueError("approved external checker policy mismatch") + elif ( operation.effective_pre_submit_plan.get("lineage") != expected_lineage or operation.effective_pre_submit_plan.get("catalogue") != expected_catalogue ): diff --git a/backend/app/modules/projects/guide_compilation/proposal_approval.py b/backend/app/modules/projects/guide_compilation/proposal_approval.py index 640505711..31e468af8 100644 --- a/backend/app/modules/projects/guide_compilation/proposal_approval.py +++ b/backend/app/modules/projects/guide_compilation/proposal_approval.py @@ -18,9 +18,10 @@ from app.modules.checkers.api.policy_compilation import ( CompiledPreSubmitCheckerPolicy, PreSubmissionPolicyCompilationPort, ) -from app.modules.checkers.api.pre_submit import ( - EffectivePreSubmissionPlanLineage, - EffectivePreSubmissionExecutionPlan, +from app.modules.checkers.api.external import ExternalCheckerRegistryPort +from app.modules.checkers.api.external_policy import ( + LockedExternalCheckerPolicies, + compile_external_checker_policy_bundle, ) from app.modules.projects.api.guide_proposals import ( GuideProposalApprovalReceipt, @@ -65,6 +66,7 @@ async def approve_proposal( pre_capabilities, post_capabilities, planner: PreSubmissionPolicyCompilationPort, + registry: ExternalCheckerRegistryPort, ) -> GuideProposalApprovalReceipt: """Compile and persist in the caller transaction after exact authority closes.""" target = command.target @@ -115,6 +117,7 @@ async def approve_proposal( pre_capabilities, post_capabilities, planner, + registry, ) receipt = outputs.receipt facts = _facts(locator, target, request_digest, receipt, command) @@ -204,7 +207,7 @@ class _CompiledApproval: effective_body: dict compiled: CompiledPreSubmitCheckerPolicy - plan: EffectivePreSubmissionExecutionPlan + policies: LockedExternalCheckerPolicies receipt: GuideProposalApprovalReceipt @@ -217,6 +220,7 @@ async def _compile_approval( pre_capabilities, post_capabilities, planner, + registry, ) -> _CompiledApproval: target = command.target inputs = CompilationRequestInputs( @@ -231,41 +235,22 @@ async def _compile_approval( locked.view.policy.policy_body, ) effective_hash = canonical_json_hash(effective_body) - compiled = planner.compile_policy_bundle( - effective_policy=effective_body, effective_policy_hash=effective_hash, + policies = await compile_external_checker_policy_bundle(locked.result, registry) + external_pre = policies.pre_submit + compiled = CompiledPreSubmitCheckerPolicy( + compiler_version="external_checker_policy.v1", + compiled_bundle=external_pre.model_dump(mode="json"), + compiled_bundle_hash=external_pre.policy_sha256, + checker_names=[ + external_pre.workstream_default.checker_id, + *(entry.registry.capability_id for entry in external_pre.entries), + ], + checker_configs={ + entry.requirement_id: entry.configuration + for entry in external_pre.entries + }, ) effective_id, pre_id = new_record_id(), new_record_id() - version = target.guide_version - plan = planner.compile_effective_plan( - lineage=EffectivePreSubmissionPlanLineage( - project_id=target.project_id, - guide_id=target.guide_id, - guide_version=version, - source_snapshot_id=target.source_snapshot_id, - source_snapshot_hash=target.source_snapshot_hash, - effective_policy_id=effective_id, - effective_policy_hash=effective_hash, - pre_submit_policy_id=pre_id, - pre_submit_policy_bundle_hash=compiled.compiled_bundle_hash, - ), - effective_policy=effective_body, - compiled_bundle=compiled.compiled_bundle, - ) - if plan.catalogue_manifest_sha256 != target.pre_catalogue_manifest_hash: - raise GuideProposalError("approval_blocked") - # Catalogue-valid intent is not enforcement: optional policy primitives are - # emitted only when the actual merged policy configures them. CHECKERS owns - # that configuration validation; reconcile selections with its resulting plan. - enforced = { - (entry.definition_id, entry.definition_version) - for entry in plan.entries - if entry.checker_definition_state == "enabled" - } - if any( - (binding.capability_id, binding.capability_version) not in enforced - for binding in locked.result.pre_submit_bindings - ): - raise GuideProposalError("approval_blocked") receipt = GuideProposalApprovalReceipt( operation_id=operation_id, target_digest=target.digest, @@ -274,10 +259,12 @@ async def _compile_approval( effective_policy_hash=effective_hash, pre_submit_policy_id=pre_id, pre_submit_bundle_hash=compiled.compiled_bundle_hash, - effective_pre_submit_plan_hash=plan.plan_sha256, + effective_pre_submit_plan_hash=policies.policies_sha256, acknowledged_warning_hashes=command.acknowledged_warning_hashes, ) - return _CompiledApproval(effective_body, compiled, plan, receipt) + return _CompiledApproval( + effective_body, compiled, policies, receipt + ) async def _persist_approval( @@ -505,7 +492,7 @@ async def _commit_provenance( session, replay_repository, command, actor, outputs, facts, authority, policy, effective, pre ): """Commit the existing reservation and its immutable approval provenance together.""" - target, receipt, plan = command.target, outputs.receipt, outputs.plan + target, receipt = command.target, outputs.receipt operation_id, request_digest = receipt.operation_id, facts.request_digest await replay_repository.complete( operation_id, @@ -538,8 +525,8 @@ async def _commit_provenance( effective_policy_id=effective.id, pre_submit_policy_id=pre.id, approved_policy_output_digest=policy_digest(policy), - effective_pre_submit_plan=plan.as_dict(), - effective_pre_submit_plan_hash=plan.plan_sha256, + effective_pre_submit_plan=outputs.policies.model_dump(mode="json"), + effective_pre_submit_plan_hash=outputs.policies.policies_sha256, prior_approval_operation_id=command.expected_previous_approval_operation_id, actor_profile_id=str(actor.actor_profile_id), identity_link_id=str(actor.identity_link_id), diff --git a/backend/app/modules/projects/guide_compilation/proposal_service.py b/backend/app/modules/projects/guide_compilation/proposal_service.py index 9c3d22313..9ddb8b615 100644 --- a/backend/app/modules/projects/guide_compilation/proposal_service.py +++ b/backend/app/modules/projects/guide_compilation/proposal_service.py @@ -50,6 +50,9 @@ def __init__( self.session = session self.authorization = authorization self.repository = GuideProposalRepository(session) + from app.modules.checkers.external_registry import ExternalCheckerRegistryReader + + self.registry = ExternalCheckerRegistryReader(session) async def review_package( self, @@ -120,6 +123,7 @@ async def approve( pre_capabilities=pre_capabilities, post_capabilities=post_capabilities, planner=planner, + registry=self.registry, ) def _require_transaction(self) -> None: diff --git a/backend/tests/checkers/external/test_policy.py b/backend/tests/checkers/external/test_policy.py new file mode 100644 index 000000000..01f04967e --- /dev/null +++ b/backend/tests/checkers/external/test_policy.py @@ -0,0 +1,153 @@ +"""Approved bindings resolve to exact immutable external registry facts.""" + +from datetime import UTC, datetime +from uuid import uuid4 + +import pytest + +from app.core.identifiers import new_record_id +from app.interfaces.project_agents import ( + AtomicGuideRequirement, + CompilationStage, + PostSubmissionBindingProposal, + PreSubmissionBindingProposal, + RequirementDisposition, +) +from app.modules.checkers.api.external import ( + ExternalCheckerRegistryEntry, + ExternalCheckerRegistryUnavailable, +) +from app.modules.checkers.api.external_policy import ( + ExternalCheckerPolicyError, + LockedWorkstreamDefault, + compile_external_checker_policies, +) +from tests.checkers.external.support import registry_spec +from tests.projects.guide_compilation.helpers import result + + +def _entry(capability_id: str, phase: str) -> ExternalCheckerRegistryEntry: + spec = registry_spec(phase).model_copy(update={"capability_id": capability_id}) + # Revalidate after changing one digest-bound specification field. + spec = type(spec).model_validate(spec.model_dump()) + return ExternalCheckerRegistryEntry( + **spec.model_dump(), + registry_entry_id=new_record_id(), + entry_digest=spec.spec_digest, + registration_operation_id=uuid4(), + registered_by_actor_profile_id=uuid4(), + authorization_decision_event_id=uuid4(), + created_at=datetime.now(UTC), + ) + + +class _Registry: + def __init__(self, entries): + self.entries = { + (entry.capability_id, entry.capability_version, entry.phase): entry + for entry in entries + } + self.calls = [] + + async def read_identity(self, **identity): + self.calls.append(identity) + try: + return self.entries[ + ( + identity["capability_id"], + identity["capability_version"], + identity["phase"], + ) + ] + except KeyError as exc: + raise ExternalCheckerRegistryUnavailable( + "external_checker_registry_unavailable" + ) from exc + + +def _proposal(): + pre = AtomicGuideRequirement( + requirement_id="safe_archive", + statement="Inspect the delivered archive.", + disposition=RequirementDisposition.SUPPORTED_PRE_SUBMIT, + ) + post = AtomicGuideRequirement( + requirement_id="quality_review", + statement="Evaluate the submitted work.", + disposition=RequirementDisposition.SUPPORTED_POST_SUBMIT, + ) + return result().model_copy( + update={ + "requirements": (pre, post), + "pre_submit_bindings": ( + PreSubmissionBindingProposal( + requirement_id=pre.requirement_id, + capability_id="acme.safe_archive", + capability_version="v1.2.3", + stage=CompilationStage.PRE_SUBMIT, + ), + ), + "post_submit_bindings": ( + PostSubmissionBindingProposal( + requirement_id=post.requirement_id, + capability_id="acme.quality_review", + capability_version="v1.2.3", + stage=CompilationStage.POST_SUBMIT, + ), + ), + } + ) + + +@pytest.mark.asyncio +async def test_compilation_locks_exact_phase_registry_entries_and_default(): + entries = (_entry("acme.safe_archive", "pre_submit"), + _entry("acme.quality_review", "post_submit")) + registry = _Registry(entries) + + pre, post = await compile_external_checker_policies(_proposal(), registry) + + assert pre.workstream_default.checker_id == "workstream.default" + assert [(item.requirement_id, item.registry.registry_entry_id) + for item in pre.entries] == [("safe_archive", entries[0].registry_entry_id)] + assert [(item.requirement_id, item.registry.registry_entry_id) + for item in post.entries] == [("quality_review", entries[1].registry_entry_id)] + assert pre.entries[0].configuration == {} + assert post.entries[0].configuration == {} + assert [call["phase"] for call in registry.calls] == ["pre_submit", "post_submit"] + + +@pytest.mark.asyncio +async def test_compilation_refuses_missing_or_wrong_phase_registry_identity(): + proposal = _proposal() + with pytest.raises(ExternalCheckerRegistryUnavailable): + await compile_external_checker_policies(proposal, _Registry(())) + + wrong = _entry("acme.safe_archive", "post_submit") + with pytest.raises(ExternalCheckerRegistryUnavailable): + await compile_external_checker_policies(proposal, _Registry((wrong,))) + + class _SubstitutedRegistry: + async def read_identity(self, **_identity): + return _entry("acme.substituted", "pre_submit") + + with pytest.raises(ExternalCheckerPolicyError, match="identity"): + await compile_external_checker_policies(proposal, _SubstitutedRegistry()) + + +@pytest.mark.asyncio +async def test_compilation_refuses_blocked_capability_coverage(): + proposal = _proposal().model_copy( + update={ + "status": "guide_blocked", + "submission_artifact_policy": None, + "capability_suggestions": (), + } + ) + with pytest.raises(ExternalCheckerPolicyError, match="coverage"): + await compile_external_checker_policies(proposal, _Registry(())) + + +def test_locked_default_refuses_substituted_behavior_digest(): + with pytest.raises(ValueError, match="behavior"): + LockedWorkstreamDefault(behavior_sha256="sha256:" + "0" * 64) diff --git a/backend/tests/checkers/post_submit/test_requirement_dispositions.py b/backend/tests/checkers/post_submit/test_requirement_dispositions.py index e768db40f..de0da34da 100644 --- a/backend/tests/checkers/post_submit/test_requirement_dispositions.py +++ b/backend/tests/checkers/post_submit/test_requirement_dispositions.py @@ -30,9 +30,15 @@ def context(snapshot=None): def proposal(disposition, *, binding=False): gap = disposition == "post_submit_capability_gap" return ProjectGuideCompilationResult( - status="guide_blocked" if gap else "draft_ready", + status="draft_ready_with_warnings" if gap else "draft_ready", agent_version="v1", - submission_artifact_policy=None if gap else _artifact_policy(), + submission_artifact_policy=_artifact_policy(), + findings=({ + "severity": "warning", + "code": "capability.unavailable", + "message": "Required automation is awaiting a registered checker.", + "evidence_refs": (_evidence(),), + },) if gap else (), requirements=( AtomicGuideRequirement( requirement_id="quality", @@ -69,11 +75,11 @@ def test_requirement_disposition_is_preserved(): validate_project_guide_compilation_result(source, gap) assert gap.requirements[0].disposition.value == "post_submit_capability_gap" assert gap.post_submit_bindings == () - ready_gap = gap.model_copy( - update={"status": "draft_ready", "submission_artifact_policy": _artifact_policy()} + blocked_gap = gap.model_copy( + update={"status": "guide_blocked", "submission_artifact_policy": None} ) - with pytest.raises(ValueError, match="ready compilation cannot contain blocking"): - validate_project_guide_compilation_result(source, ready_gap) + with pytest.raises(ValueError, match="blocked compilation requires blocking"): + validate_project_guide_compilation_result(source, blocked_gap) @pytest.mark.parametrize("disposition", ("human_review", "post_submit_capability_gap")) diff --git a/backend/tests/projects/guide_compilation/test_capability_growth.py b/backend/tests/projects/guide_compilation/test_capability_growth.py index bab7c820d..cdeeeece3 100644 --- a/backend/tests/projects/guide_compilation/test_capability_growth.py +++ b/backend/tests/projects/guide_compilation/test_capability_growth.py @@ -47,10 +47,10 @@ def growth_report(*, gaps=True): evidence_refs=refs, )) return result().model_copy(update={ - "status": "guide_blocked" if gaps else "draft_ready", - "submission_artifact_policy": None if gaps else result().submission_artifact_policy, + "status": "draft_ready_with_warnings" if gaps else "draft_ready", + "submission_artifact_policy": result().submission_artifact_policy, "findings": (CompilationFinding( - severity="blocking_gap" if gaps else "info", code="catalogue.coverage", + severity="warning" if gaps else "info", code="catalogue.coverage", message="Required automation is unavailable." if gaps else "All checks are supported.", evidence_refs=refs, ),), @@ -180,7 +180,21 @@ def test_blocked_report_rejects_platform_defaults_as_project_bindings(stage): def test_blocked_handoff_cannot_include_artifact_policy(): - report = growth_report() + report = result().model_copy(update={ + "status": "guide_blocked", + "submission_artifact_policy": None, + "findings": (CompilationFinding( + severity="blocking_gap", code="guide.invalid", + message="The guide cannot define a valid task policy.", + evidence_refs=result().findings[0].evidence_refs, + ),), + "requirements": (AtomicGuideRequirement( + requirement_id="guide_invalid", + statement="The guide must define a valid task policy.", + disposition="guide_blocker", + evidence_refs=result().findings[0].evidence_refs, + ),), + }) validate_project_guide_compilation_result(context(ids()), report) with pytest.raises(ValueError, match="blocked guide cannot publish policy proposals"): validate_project_guide_compilation_result(context(ids()), report.model_copy(update={ From f2525f1bf52a81e2262005e06a077cdf786b1f1a Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 18:19:50 +0100 Subject: [PATCH 051/283] feat: separate pre and post checker material custody --- backend/app/modules/checkers/api/external.py | 74 +++++++++++++-- backend/tests/checkers/external/support.py | 34 +++++++ .../tests/checkers/external/test_contracts.py | 44 +++++---- .../tests/checkers/external/test_runtime.py | 19 ++-- .../run_probe.py | 25 +++--- external_checkers/fixtures/request.json | 2 +- external_checkers/fixtures/result.json | 2 +- .../workstream-checker-sdk/src/lib.rs | 90 +++++++++++++++---- .../workstream-checker-service/src/main.rs | 28 ++++-- 9 files changed, 247 insertions(+), 71 deletions(-) diff --git a/backend/app/modules/checkers/api/external.py b/backend/app/modules/checkers/api/external.py index 48cd706a1..4b5413663 100644 --- a/backend/app/modules/checkers/api/external.py +++ b/backend/app/modules/checkers/api/external.py @@ -316,15 +316,51 @@ async def read_identity( """Resolve the one immutable registered phase identity during approval.""" -class ExternalCheckerMaterial(ExternalCheckerValue): - """One verified read-only material identity without provider coordinates.""" +class PreSubmitExternalCheckerMaterial(ExternalCheckerValue): + """Verified prepared bytes that exist before a Submission or ART binding.""" + phase: Literal["pre_submit"] = "pre_submit" + role: Identifier + prepared_generation_id: UUID = Field(strict=True) + attempt_id: UUID = Field(strict=True) + attempt_request_digest: Sha256 + archive_sha256: Sha256 + archive_byte_count: Annotated[ + StrictInt, Field(ge=0, le=9_223_372_036_854_775_807) + ] + semantic_manifest_sha256: Sha256 + media_type: Annotated[ + StrictStr, Field(min_length=1, max_length=255, pattern=r"^[^\s/]+/[^\s/]+$") + ] + + +class PostSubmitExternalCheckerMaterial(ExternalCheckerValue): + """Verified native Submission and ART ancestry selected for POST execution.""" + + phase: Literal["post_submit"] = "post_submit" role: Identifier + submission_id: UUID = Field(strict=True) + submission_version: Annotated[StrictInt, Field(ge=1)] + binding_id: UUID = Field(strict=True) content_id: UUID = Field(strict=True) replica_id: UUID = Field(strict=True) - sha256: Sha256 + content_sha256: Sha256 byte_count: Annotated[StrictInt, Field(ge=0, le=9_223_372_036_854_775_807)] - media_type: Annotated[StrictStr, Field(min_length=1, max_length=255, pattern=r"^[^\s/]+/[^\s/]+$")] + media_type: Annotated[ + StrictStr, Field(min_length=1, max_length=255, pattern=r"^[^\s/]+/[^\s/]+$") + ] + evidence_id: UUID = Field(strict=True) + verification_receipt_id: UUID = Field(strict=True) + verification_job_id: UUID = Field(strict=True) + verification_generation: Annotated[StrictInt, Field(ge=1)] + namespace_fingerprint: Sha256 + semantic_manifest_sha256: Sha256 + + +ExternalCheckerMaterial = Annotated[ + PreSubmitExternalCheckerMaterial | PostSubmitExternalCheckerMaterial, + Field(discriminator="phase"), +] class PreSubmitExternalCheckerIdentity(ExternalCheckerValue): @@ -377,7 +413,7 @@ class ExternalCheckerExecutionRequest(ExternalCheckerValue): configuration_sha256: Sha256 input: dict[str, JsonValue] input_sha256: Sha256 - materials: tuple[ExternalCheckerMaterial, ...] = Field(max_length=32) + materials: tuple[ExternalCheckerMaterial, ...] = Field(min_length=1, max_length=32) request_digest: Sha256 @model_validator(mode="after") @@ -387,6 +423,34 @@ def validate_request(self) -> Self: raise ExternalCheckerContractError("external checker request phase mismatch") if len({item.role for item in self.materials}) != len(self.materials): raise ExternalCheckerContractError("external checker material role is duplicated") + if any(item.phase != self.identity.phase for item in self.materials): + raise ExternalCheckerContractError("external checker material phase mismatch") + if self.identity.phase == "pre_submit": + for material in self.materials: + if not isinstance(material, PreSubmitExternalCheckerMaterial) or ( + material.prepared_generation_id, + material.attempt_id, + material.attempt_request_digest, + ) != ( + self.identity.prepared_generation_id, + self.identity.attempt_id, + self.identity.attempt_request_digest, + ): + raise ExternalCheckerContractError( + "external checker prepared material identity mismatch" + ) + else: + for material in self.materials: + if not isinstance(material, PostSubmitExternalCheckerMaterial) or ( + material.submission_id, + material.submission_version, + ) != ( + self.identity.submission_id, + self.identity.submission_version, + ): + raise ExternalCheckerContractError( + "external checker submission material identity mismatch" + ) if self.configuration_sha256 != external_checker_json_hash(self.configuration): raise ExternalCheckerContractError( "external checker configuration digest mismatch" diff --git a/backend/tests/checkers/external/support.py b/backend/tests/checkers/external/support.py index 54a64107c..5d7c7a331 100644 --- a/backend/tests/checkers/external/support.py +++ b/backend/tests/checkers/external/support.py @@ -14,7 +14,9 @@ ExternalCheckerRegistrySpec, ExternalCheckerResourceLimits, ExternalCheckerSchema, + PostSubmitExternalCheckerMaterial, PostSubmitExternalCheckerIdentity, + PreSubmitExternalCheckerMaterial, PreSubmitExternalCheckerIdentity, external_checker_json_hash, make_external_checker_registration_request, @@ -111,3 +113,35 @@ def execution_identity(phase: str = "pre_submit"): lease_generation=4, lease_expires_at=datetime.now(timezone.utc) + timedelta(minutes=5), ) + + +def execution_material(identity): + """Build one genuine phase-specific custody value for a test identity.""" + if identity.phase == "pre_submit": + return PreSubmitExternalCheckerMaterial( + role="submission_archive", + prepared_generation_id=identity.prepared_generation_id, + attempt_id=identity.attempt_id, + attempt_request_digest=identity.attempt_request_digest, + archive_sha256=SHA, + archive_byte_count=4, + semantic_manifest_sha256=SHA, + media_type="application/zip", + ) + return PostSubmitExternalCheckerMaterial( + role="submission_archive", + submission_id=identity.submission_id, + submission_version=identity.submission_version, + binding_id=uuid4(), + content_id=uuid4(), + replica_id=uuid4(), + content_sha256=SHA, + byte_count=4, + media_type="application/zip", + evidence_id=uuid4(), + verification_receipt_id=uuid4(), + verification_job_id=uuid4(), + verification_generation=1, + namespace_fingerprint=SHA, + semantic_manifest_sha256=SHA, + ) diff --git a/backend/tests/checkers/external/test_contracts.py b/backend/tests/checkers/external/test_contracts.py index b640f6199..3bf9698c1 100644 --- a/backend/tests/checkers/external/test_contracts.py +++ b/backend/tests/checkers/external/test_contracts.py @@ -14,7 +14,7 @@ RESULT_SCHEMA_ID, ExternalCheckerContractError, ExternalCheckerFinding, - ExternalCheckerMaterial, + PreSubmitExternalCheckerMaterial, ExternalCheckerSchema, external_checker_json_hash, make_external_checker_execution_request, @@ -24,6 +24,7 @@ from tests.checkers.external.support import ( SHA, execution_identity, + execution_material, registry_entry, registry_spec, schema, @@ -121,23 +122,15 @@ def test_registration_request_digest_is_derived_and_substitution_fails() -> None @pytest.mark.parametrize("phase", ["pre_submit", "post_submit"]) def test_execution_request_binds_existing_phase_lineage_and_materials(phase: str) -> None: entry = registry_entry(phase) + identity = execution_identity(phase) request = make_external_checker_execution_request( registry=entry, - identity=execution_identity(phase), + identity=identity, configuration={}, configuration_sha256=external_checker_json_hash({}), input={"task_version": "v3"}, input_sha256=external_checker_json_hash({"task_version": "v3"}), - materials=( - ExternalCheckerMaterial( - role="submission_archive", - content_id=uuid4(), - replica_id=uuid4(), - sha256=SHA, - byte_count=4, - media_type="application/zip", - ), - ), + materials=(execution_material(identity),), ) assert request.identity.phase == phase with pytest.raises(ValidationError, match="input digest mismatch"): @@ -161,35 +154,39 @@ def test_execution_identity_does_not_accept_cross_phase_or_unknown_fields() -> N def test_execution_request_rejects_duplicate_material_roles() -> None: - material = ExternalCheckerMaterial( + identity = execution_identity() + material = PreSubmitExternalCheckerMaterial( role="submission_archive", - content_id=uuid4(), - replica_id=uuid4(), - sha256=SHA, - byte_count=4, + prepared_generation_id=identity.prepared_generation_id, + attempt_id=identity.attempt_id, + attempt_request_digest=identity.attempt_request_digest, + archive_sha256=SHA, + archive_byte_count=4, + semantic_manifest_sha256=SHA, media_type="application/zip", ) with pytest.raises(ValidationError, match="role is duplicated"): make_external_checker_execution_request( registry=registry_entry(), - identity=execution_identity(), + identity=identity, configuration={}, configuration_sha256=external_checker_json_hash({}), input={"task_version": "v3"}, input_sha256=external_checker_json_hash({"task_version": "v3"}), - materials=(material, material.model_copy(update={"content_id": uuid4()})), + materials=(material, material.model_copy(update={"archive_sha256": "sha256:" + "b" * 64})), ) def test_completed_and_infrastructure_results_are_closed_and_request_bound() -> None: + identity = execution_identity() request = make_external_checker_execution_request( registry=registry_entry(), - identity=execution_identity(), + identity=identity, configuration={}, configuration_sha256=external_checker_json_hash({}), input={"task_version": "v3"}, input_sha256=external_checker_json_hash({"task_version": "v3"}), - materials=(), + materials=(execution_material(identity),), ) completed = make_external_checker_execution_result( request_digest=request.request_digest, @@ -248,14 +245,15 @@ def test_completed_and_infrastructure_results_are_closed_and_request_bound() -> infrastructure_failure_code="network_error", ) + bounded_identity = execution_identity() bounded_request = make_external_checker_execution_request( registry=registry_entry(maximum_output_bytes=256), - identity=execution_identity(), + identity=bounded_identity, configuration={}, configuration_sha256=external_checker_json_hash({}), input={"task_version": "v3"}, input_sha256=external_checker_json_hash({"task_version": "v3"}), - materials=(), + materials=(execution_material(bounded_identity),), ) oversized_infrastructure = make_external_checker_execution_result( request_digest=bounded_request.request_digest, diff --git a/backend/tests/checkers/external/test_runtime.py b/backend/tests/checkers/external/test_runtime.py index 6b8172a2e..eb5c4f484 100644 --- a/backend/tests/checkers/external/test_runtime.py +++ b/backend/tests/checkers/external/test_runtime.py @@ -44,7 +44,7 @@ ExternalCheckerContractError, ExternalCheckerExecutionRequest, ExternalCheckerExecutionResult, - ExternalCheckerMaterial, + PreSubmitExternalCheckerMaterial, external_checker_json_hash, make_external_checker_execution_request, make_external_checker_execution_result, @@ -60,20 +60,23 @@ async def _stream(value: bytes): def _request(*, identity=None, archive_sha256=SHA, archive_byte_count=4): + identity = identity or execution_identity() return make_external_checker_execution_request( registry=registry_entry(), - identity=identity or execution_identity(), + identity=identity, configuration={}, configuration_sha256=external_checker_json_hash({}), input={"task_version": "v3"}, input_sha256=external_checker_json_hash({"task_version": "v3"}), materials=( - ExternalCheckerMaterial( + PreSubmitExternalCheckerMaterial( role="submission_archive", - content_id=uuid4(), - replica_id=uuid4(), - sha256=archive_sha256, - byte_count=archive_byte_count, + prepared_generation_id=identity.prepared_generation_id, + attempt_id=identity.attempt_id, + attempt_request_digest=identity.attempt_request_digest, + archive_sha256=archive_sha256, + archive_byte_count=archive_byte_count, + semantic_manifest_sha256=SHA, media_type="application/zip", ), ), @@ -90,7 +93,7 @@ def test_shared_rust_fixtures_preserve_python_contract_and_derived_digests(): result.validate_request(request) assert request.configuration == {"threshold": 1e-6} assert request.request_digest == ( - "sha256:81adbc8a7cc0e13b4221ac06ecdd2f95850d6215c3a336d932ad14f8988a70b7" + "sha256:a06707b14348ffe5ef22a55de8d4ec4845c9029da7180d5731fb2c120b5591f3" ) changed = request.model_dump(mode="json") changed["configuration"]["threshold"] = 2e-6 diff --git a/experiments/pilot04_external_checker_runtime/run_probe.py b/experiments/pilot04_external_checker_runtime/run_probe.py index e1e1eae02..d56916919 100644 --- a/experiments/pilot04_external_checker_runtime/run_probe.py +++ b/experiments/pilot04_external_checker_runtime/run_probe.py @@ -34,7 +34,7 @@ ) from app.modules.artifacts.submission_manifest import build_submission_manifest from app.modules.checkers.api.external import ( - ExternalCheckerMaterial, + PreSubmitExternalCheckerMaterial, ExternalCheckerRegistryEntry, ExternalCheckerResourceLimits, ExternalCheckerSchema, @@ -212,17 +212,6 @@ async def run(reference: str, service_binary: Path) -> dict[str, object]: created_at=datetime.now(timezone.utc), ) input_value = {"task_version": "v3"} - materials = ( - ExternalCheckerMaterial( - role="submission_archive", - content_id=uuid4(), - replica_id=uuid4(), - sha256=prepared.commitment.sha256, - byte_count=prepared.commitment.byte_count, - media_type="application/zip", - ), - ) - def request_for(mode: str): identity = PreSubmitExternalCheckerIdentity( project_id=uuid4(), @@ -234,6 +223,18 @@ def request_for(mode: str): effective_plan_sha256="sha256:" + "3" * 64, ) configuration = {"mode": mode} + materials = ( + PreSubmitExternalCheckerMaterial( + role="submission_archive", + prepared_generation_id=identity.prepared_generation_id, + attempt_id=identity.attempt_id, + attempt_request_digest=identity.attempt_request_digest, + archive_sha256=prepared.commitment.sha256, + archive_byte_count=prepared.commitment.byte_count, + semantic_manifest_sha256=manifest.sha256, + media_type="application/zip", + ), + ) return make_external_checker_execution_request( registry=registry, identity=identity, diff --git a/external_checkers/fixtures/request.json b/external_checkers/fixtures/request.json index 634598184..68571145f 100644 --- a/external_checkers/fixtures/request.json +++ b/external_checkers/fixtures/request.json @@ -1 +1 @@ -{"configuration":{"threshold":1e-06},"configuration_sha256":"sha256:3257714092b3dc613247191d82d6da4c22f789929cb50696ebb38a69cc8ef1ff","identity":{"assignment_id":"66666666-6666-4666-8666-666666666666","attempt_id":"88888888-8888-4888-8888-888888888888","attempt_request_digest":"sha256:2222222222222222222222222222222222222222222222222222222222222222","effective_plan_sha256":"sha256:3333333333333333333333333333333333333333333333333333333333333333","phase":"pre_submit","prepared_generation_id":"77777777-7777-4777-8777-777777777777","project_id":"44444444-4444-4444-8444-444444444444","task_id":"55555555-5555-4555-8555-555555555555"},"input":{"task_version":"v3"},"input_sha256":"sha256:7f9f19934f23f43e56d62005ba9fefb8af3a4b42df80103f475187f659ffe6cb","materials":[{"byte_count":14,"content_id":"99999999-9999-4999-8999-999999999999","media_type":"application/zip","replica_id":"aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa","role":"submission_archive","sha256":"sha256:4444444444444444444444444444444444444444444444444444444444444444"}],"registry":{"authorization_decision_event_id":"33333333-3333-4333-8333-333333333333","capability_id":"acme.safe_archive","capability_version":"v1.2.3","configuration_schema":{"document":{"additionalProperties":false,"properties":{"threshold":{"type":"number"}},"required":["threshold"],"type":"object"},"schema_id":"acme.safe_archive.configuration","schema_sha256":"sha256:fd170dacd315270c71f33ff14eb2ae68ae2a6e57b1b6ce494e08e5b63797238b","schema_version":"v1"},"created_at":"2026-10-10T06:00:00Z","entry_digest":"sha256:00603847c6b55dcae9d1f03fed5cc55d0c2f8c05ba02ad35ce1b9eb7b7e0ade2","image_digest":"sha256:1111111111111111111111111111111111111111111111111111111111111111","input_schema":{"document":{"additionalProperties":false,"properties":{"task_version":{"type":"string"}},"required":["task_version"],"type":"object"},"schema_id":"external_checker_pre_submit_input","schema_sha256":"sha256:980c5b0d64a514c4d7e3c0061b99bf2281533296d9376bfdcbdefef3122e4186","schema_version":"v1"},"output_schema":{"document":{"type":"object"},"schema_id":"external_checker_result","schema_sha256":"sha256:a2c799262a3ce3c19ef5cdd983bf3d12b43ab3c426227091b909dcb7054738c0","schema_version":"v1"},"phase":"pre_submit","registered_by_actor_profile_id":"22222222-2222-4222-8222-222222222222","registration_operation_id":"11111111-1111-4111-8111-111111111111","registry_entry_id":"01890f12-3456-789a-8bcd-ef0123456789","resources":{"cpu_millis":500,"deadline_ms":30000,"maximum_output_bytes":32768,"memory_bytes":134217728}},"request_digest":"sha256:81adbc8a7cc0e13b4221ac06ecdd2f95850d6215c3a336d932ad14f8988a70b7","schema_version":"external_checker_request.v1"} +{"configuration":{"threshold":1e-06},"configuration_sha256":"sha256:3257714092b3dc613247191d82d6da4c22f789929cb50696ebb38a69cc8ef1ff","identity":{"assignment_id":"66666666-6666-4666-8666-666666666666","attempt_id":"88888888-8888-4888-8888-888888888888","attempt_request_digest":"sha256:2222222222222222222222222222222222222222222222222222222222222222","effective_plan_sha256":"sha256:3333333333333333333333333333333333333333333333333333333333333333","phase":"pre_submit","prepared_generation_id":"77777777-7777-4777-8777-777777777777","project_id":"44444444-4444-4444-8444-444444444444","task_id":"55555555-5555-4555-8555-555555555555"},"input":{"task_version":"v3"},"input_sha256":"sha256:7f9f19934f23f43e56d62005ba9fefb8af3a4b42df80103f475187f659ffe6cb","materials":[{"archive_byte_count":14,"archive_sha256":"sha256:4444444444444444444444444444444444444444444444444444444444444444","attempt_id":"88888888-8888-4888-8888-888888888888","attempt_request_digest":"sha256:2222222222222222222222222222222222222222222222222222222222222222","media_type":"application/zip","phase":"pre_submit","prepared_generation_id":"77777777-7777-4777-8777-777777777777","role":"submission_archive","semantic_manifest_sha256":"sha256:5555555555555555555555555555555555555555555555555555555555555555"}],"registry":{"authorization_decision_event_id":"33333333-3333-4333-8333-333333333333","capability_id":"acme.safe_archive","capability_version":"v1.2.3","configuration_schema":{"document":{"additionalProperties":false,"properties":{"threshold":{"type":"number"}},"required":["threshold"],"type":"object"},"schema_id":"acme.safe_archive.configuration","schema_sha256":"sha256:fd170dacd315270c71f33ff14eb2ae68ae2a6e57b1b6ce494e08e5b63797238b","schema_version":"v1"},"created_at":"2026-10-10T06:00:00Z","entry_digest":"sha256:00603847c6b55dcae9d1f03fed5cc55d0c2f8c05ba02ad35ce1b9eb7b7e0ade2","image_digest":"sha256:1111111111111111111111111111111111111111111111111111111111111111","input_schema":{"document":{"additionalProperties":false,"properties":{"task_version":{"type":"string"}},"required":["task_version"],"type":"object"},"schema_id":"external_checker_pre_submit_input","schema_sha256":"sha256:980c5b0d64a514c4d7e3c0061b99bf2281533296d9376bfdcbdefef3122e4186","schema_version":"v1"},"output_schema":{"document":{"type":"object"},"schema_id":"external_checker_result","schema_sha256":"sha256:a2c799262a3ce3c19ef5cdd983bf3d12b43ab3c426227091b909dcb7054738c0","schema_version":"v1"},"phase":"pre_submit","registered_by_actor_profile_id":"22222222-2222-4222-8222-222222222222","registration_operation_id":"11111111-1111-4111-8111-111111111111","registry_entry_id":"01890f12-3456-789a-8bcd-ef0123456789","resources":{"cpu_millis":500,"deadline_ms":30000,"maximum_output_bytes":32768,"memory_bytes":134217728}},"request_digest":"sha256:a06707b14348ffe5ef22a55de8d4ec4845c9029da7180d5731fb2c120b5591f3","schema_version":"external_checker_request.v1"} diff --git a/external_checkers/fixtures/result.json b/external_checkers/fixtures/result.json index 71ef47034..282a0f5d5 100644 --- a/external_checkers/fixtures/result.json +++ b/external_checkers/fixtures/result.json @@ -1 +1 @@ -{"findings":[],"infrastructure_failure_code":null,"outcome":"completed","phase":"pre_submit","registry_entry_digest":"sha256:00603847c6b55dcae9d1f03fed5cc55d0c2f8c05ba02ad35ce1b9eb7b7e0ade2","registry_entry_id":"01890f12-3456-789a-8bcd-ef0123456789","request_digest":"sha256:81adbc8a7cc0e13b4221ac06ecdd2f95850d6215c3a336d932ad14f8988a70b7","result_digest":"sha256:7f62c10b491e6761a2bcd4a20ebb07cf13588c24c5b5f48ad9ad0f72d551e8b1","schema_version":"external_checker_result.v1","verdict":"passed"} +{"findings":[],"infrastructure_failure_code":null,"outcome":"completed","phase":"pre_submit","registry_entry_digest":"sha256:00603847c6b55dcae9d1f03fed5cc55d0c2f8c05ba02ad35ce1b9eb7b7e0ade2","registry_entry_id":"01890f12-3456-789a-8bcd-ef0123456789","request_digest":"sha256:a06707b14348ffe5ef22a55de8d4ec4845c9029da7180d5731fb2c120b5591f3","result_digest":"sha256:2fdede489f609ba59017fe8da4a2f7ed31307700eb7663532d9944233d7ab82d","schema_version":"external_checker_result.v1","verdict":"passed"} diff --git a/external_checkers/workstream-checker-sdk/src/lib.rs b/external_checkers/workstream-checker-sdk/src/lib.rs index 729156258..1912a644c 100644 --- a/external_checkers/workstream-checker-sdk/src/lib.rs +++ b/external_checkers/workstream-checker-sdk/src/lib.rs @@ -116,29 +116,87 @@ pub fn parse_request(bytes: &[u8]) -> Result { .get("materials") .and_then(Value::as_array) .ok_or(ContractError("request materials are invalid"))?; - if materials.len() > 32 { + if materials.is_empty() || materials.len() > 32 { return Err(ContractError("request materials are unbounded")); } let mut roles = BTreeSet::new(); for material in materials { - let material = exact_object( - material, - &[ - "role", - "content_id", - "replica_id", - "sha256", - "byte_count", - "media_type", - ], - )?; - if !roles.insert(string(material, "role")?) - || unsigned(material, "byte_count")? > i64::MAX as u64 + let material = material + .as_object() + .ok_or(ContractError("request material is invalid"))?; + if string(material, "phase")? != phase + || !roles.insert(string(material, "role")?) || !string(material, "media_type")?.contains('/') { return Err(ContractError("request material is invalid")); } - digest(material, "sha256")?; + if phase == "pre_submit" { + exact_map( + material, + &[ + "phase", + "role", + "prepared_generation_id", + "attempt_id", + "attempt_request_digest", + "archive_sha256", + "archive_byte_count", + "semantic_manifest_sha256", + "media_type", + ], + )?; + if unsigned(material, "archive_byte_count")? > i64::MAX as u64 { + return Err(ContractError("request material is invalid")); + } + digest(material, "attempt_request_digest")?; + digest(material, "archive_sha256")?; + digest(material, "semantic_manifest_sha256")?; + if string(material, "prepared_generation_id")? + != string(identity, "prepared_generation_id")? + || string(material, "attempt_id")? != string(identity, "attempt_id")? + || digest(material, "attempt_request_digest")? + != digest(identity, "attempt_request_digest")? + { + return Err(ContractError("request material identity differs")); + } + } else { + exact_map( + material, + &[ + "phase", + "role", + "submission_id", + "submission_version", + "binding_id", + "content_id", + "replica_id", + "content_sha256", + "byte_count", + "media_type", + "evidence_id", + "verification_receipt_id", + "verification_job_id", + "verification_generation", + "namespace_fingerprint", + "semantic_manifest_sha256", + ], + )?; + if unsigned(material, "byte_count")? > i64::MAX as u64 + || unsigned(material, "submission_version")? == 0 + || unsigned(material, "verification_generation")? == 0 + { + return Err(ContractError("request material is invalid")); + } + digest(material, "content_sha256")?; + digest(material, "namespace_fingerprint")?; + digest(material, "semantic_manifest_sha256")?; + if string(material, "submission_id")? != string(identity, "submission_id")? + || unsigned(material, "submission_version")? + != unsigned(identity, "submission_version")? + { + return Err(ContractError("request material identity differs")); + } + } } let resources = registry .get("resources") @@ -654,7 +712,7 @@ mod tests { .expect("Python request fixture must satisfy the Rust contract"); assert_eq!( request.request_digest, - "sha256:81adbc8a7cc0e13b4221ac06ecdd2f95850d6215c3a336d932ad14f8988a70b7" + "sha256:a06707b14348ffe5ef22a55de8d4ec4845c9029da7180d5731fb2c120b5591f3" ); let result: Value = serde_json::from_slice(include_bytes!("../../fixtures/result.json")) .expect("result fixture is JSON"); diff --git a/external_checkers/workstream-checker-service/src/main.rs b/external_checkers/workstream-checker-service/src/main.rs index 2676f1e25..2818aea6e 100644 --- a/external_checkers/workstream-checker-service/src/main.rs +++ b/external_checkers/workstream-checker-service/src/main.rs @@ -583,7 +583,9 @@ fn grant_matches_request(manifest: &GrantManifest, request: &ValidatedRequest) - }; let Some(archive) = materials.iter().find_map(|item| { let object = item.as_object()?; - (object.get("role")?.as_str()? == "submission_archive").then_some(object) + (object.get("phase")?.as_str()? == "pre_submit" + && object.get("role")?.as_str()? == "submission_archive") + .then_some(object) }) else { return false; }; @@ -597,8 +599,22 @@ fn grant_matches_request(manifest: &GrantManifest, request: &ValidatedRequest) - .get("attempt_request_digest") .and_then(Value::as_str) == Some(&manifest.attempt_request_digest) - && archive.get("sha256").and_then(Value::as_str) == Some(&manifest.archive_sha256) - && archive.get("byte_count").and_then(Value::as_u64) == Some(manifest.archive_byte_count) + && archive + .get("prepared_generation_id") + .and_then(Value::as_str) + == Some(&manifest.prepared_generation_id) + && archive.get("attempt_id").and_then(Value::as_str) == Some(&manifest.attempt_id) + && archive + .get("attempt_request_digest") + .and_then(Value::as_str) + == Some(&manifest.attempt_request_digest) + && archive.get("archive_sha256").and_then(Value::as_str) == Some(&manifest.archive_sha256) + && archive.get("archive_byte_count").and_then(Value::as_u64) + == Some(manifest.archive_byte_count) + && archive + .get("semantic_manifest_sha256") + .and_then(Value::as_str) + == Some(&manifest.semantic_manifest_sha256) && semantic_manifest_sha256.as_deref() == Some(&manifest.semantic_manifest_sha256) } @@ -1617,11 +1633,11 @@ mod tests { .as_str() .unwrap() .into(), - archive_sha256: request.value["materials"][0]["sha256"] + archive_sha256: request.value["materials"][0]["archive_sha256"] .as_str() .unwrap() .into(), - archive_byte_count: request.value["materials"][0]["byte_count"] + archive_byte_count: request.value["materials"][0]["archive_byte_count"] .as_u64() .unwrap(), semantic_manifest_sha256: String::new(), @@ -1630,6 +1646,8 @@ mod tests { binding_digest: format!("sha256:{}", "9".repeat(64)), }; manifest.semantic_manifest_sha256 = semantic_manifest_hash(&manifest).unwrap(); + request.value["materials"][0]["semantic_manifest_sha256"] = + Value::String(manifest.semantic_manifest_sha256.clone()); assert!(grant_matches_request(&manifest, &request)); for field in 0..6 { let original = ( From 9d3e92bb66c651b0fef3d1ccddac82906c961ae2 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 18:22:43 +0100 Subject: [PATCH 052/283] feat: keep optional packet text warning only --- .../app/api/routes/artifact_submissions.py | 7 +++--- ..._submission_bundle_preparation_recovery.py | 25 +++++++++++++++++++ 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/backend/app/api/routes/artifact_submissions.py b/backend/app/api/routes/artifact_submissions.py index 20e58e69a..62c4fd62c 100644 --- a/backend/app/api/routes/artifact_submissions.py +++ b/backend/app/api/routes/artifact_submissions.py @@ -63,10 +63,9 @@ async def prepare_submission_bundle( ] = None, ) -> SubmissionBundlePreparationResponse | JSONResponse: """Run the hidden continuous ZIP preparation surface; AUTH remains fail closed.""" - if None in (assignment_id, idempotency_key, summary, contributor_attestation): + if None in (assignment_id, idempotency_key): raise HTTPException(status_code=404, detail="Task not found") assert assignment_id is not None and idempotency_key is not None - assert summary is not None and contributor_attestation is not None try: identifiers = ( UUID(task_id), @@ -87,8 +86,8 @@ async def prepare_submission_bundle( assignment_id=identifiers[1], predecessor_submission_id=identifiers[3], idempotency_key=identifiers[2], - summary=summary, - contributor_attestation=contributor_attestation, + summary=summary or "", + contributor_attestation=contributor_attestation or "", media_type=request.headers.get("content-type", ""), byte_source=request.stream(), ) diff --git a/backend/tests/test_submission_bundle_preparation_recovery.py b/backend/tests/test_submission_bundle_preparation_recovery.py index f81fb4922..33f166abf 100644 --- a/backend/tests/test_submission_bundle_preparation_recovery.py +++ b/backend/tests/test_submission_bundle_preparation_recovery.py @@ -27,6 +27,7 @@ SubmissionBundlePreparationRequest, SubmissionBundlePreparationRejected, SubmissionBundlePreparationUnavailable, SubmissionBundlePreparationInfrastructureUnavailable, SubmissionBundlePreparationResult, + SubmissionBundlePreparationStatus, ) from app.modules.checkers.api import ( PreSubmissionExecutionEntryFacts, @@ -221,6 +222,30 @@ async def test_hidden_preparation_maps_context_custody_and_authority_distinctly( assert failure.value.detail == detail +@pytest.mark.asyncio +async def test_hidden_preparation_treats_missing_optional_packet_text_as_warnings() -> None: + """Missing summary and attestation reach PRE as empty warning-only values.""" + command = SimpleNamespace(prepare=AsyncMock(return_value=SubmissionBundlePreparationResult( + put_attempt_id=new_record_id(), admission_id=None, + submission_bundle_preparation_status=SubmissionBundlePreparationStatus.PREPARED, + replayed=False, + ))) + request = Request({ + "type": "http", "method": "POST", "path": "/", + "headers": [(b"content-type", b"application/zip")], + }) + + await prepare_submission_bundle( + task_id=str(new_record_id()), request=request, actor=_actor(), command=command, + assignment_id=str(new_record_id()), idempotency_key=str(new_record_id()), + summary=None, contributor_attestation=None, + ) + + prepared = command.prepare.await_args.args[0] + assert prepared.summary == "" + assert prepared.contributor_attestation == "" + + def _preparation_replay_runtime(prepare_bytes, evidence_id, *, eligible): """Supply bounded ART outcome doubles for command routing proof.""" From 028f5d2250b7b7b7cab73a6edbcac0dea4a10023 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 18:34:49 +0100 Subject: [PATCH 053/283] Bind external post checks to verified ART custody --- .../artifacts/post_submit_materialization.py | 141 ++++++- backend/app/modules/artifacts/preparation.py | 187 +++++++-- .../modules/checkers/api/materialization.py | 22 +- .../tests/test_post_submit_materialization.py | 79 ++++ .../workstream-checker-service/src/main.rs | 390 ++++++++++++++---- 5 files changed, 704 insertions(+), 115 deletions(-) diff --git a/backend/app/modules/artifacts/post_submit_materialization.py b/backend/app/modules/artifacts/post_submit_materialization.py index 7474bcc84..f41ce3803 100644 --- a/backend/app/modules/artifacts/post_submit_materialization.py +++ b/backend/app/modules/artifacts/post_submit_materialization.py @@ -19,6 +19,10 @@ select_post_submission_material, ) from app.modules.artifacts.preparation import ArtifactPreparationService, ArtifactScratchIntegrityError +from app.modules.artifacts.preparation import ( + ExternalMaterialFile, + PostExternalMaterialGrantRequest, +) from app.modules.artifacts.service import ArtifactStorageNamespaceError, ArtifactStorageNamespaceSpec from app.modules.artifacts.submission_archive import ( SealedSubmissionTree, SubmissionArchiveInspector, SubmissionArchiveEntryType, @@ -30,13 +34,24 @@ ExecuteFacts, CurrentExecutionPort, VerifiedMaterialFacts, CheckerExecutionUnavailable, ) from app.modules.tasks.api.submitted_bundle import SubmittedBundlePort, SubmittedBundleUnavailable +from app.modules.checkers.api.external import ( + ExternalCheckerExecutionRequest, + PostSubmitExternalCheckerIdentity, + PostSubmitExternalCheckerMaterial, +) class _MaterialView: """Revoke callback access independently of the private projection lifetime.""" - def __init__(self, tree: SealedSubmissionTree) -> None: + def __init__( + self, tree: SealedSubmissionTree, *, preparation, prepared, workspace, + execution: ExecuteFacts, materialization: MaterializationFacts, media_type: str, + ) -> None: """Wrap the single ART-owned sealed tree without exposing its path.""" self._tree = tree + self._preparation, self._prepared, self._workspace = preparation, prepared, workspace + self._execution, self._materialization = execution, materialization + self._media_type = media_type self._closed = False def close(self) -> None: @@ -61,6 +76,108 @@ def read_file(self, normalized_path: str, *, maximum_bytes: int) -> bytes: self._require_open() return self._tree.read_file(normalized_path, maximum_bytes=maximum_bytes) + def external_checker_grant(self, request: ExternalCheckerExecutionRequest): + """Bind a POST service grant to actual current execution and ART ancestry.""" + self._require_open() + checked = ExternalCheckerExecutionRequest.model_validate(request) + identity = checked.identity + if not isinstance(identity, PostSubmitExternalCheckerIdentity): + raise ArtifactScratchIntegrityError("external POST request identity differs") + execution, facts = self._execution, self._materialization + source = execution.request + lease = execution.lease + reservation = lease.reservation + if ( + identity.project_id != source.project_id + or identity.task_id != source.task_id + or identity.assignment_id != source.assignment_id + or identity.submission_id != source.submission_id + or identity.submission_version != source.submission_version + or identity.evaluation_request_id != source.evaluation_request_id + or identity.evaluation_request_digest != source.request_sha256 + or identity.evaluation_generation != source.evaluation_generation + or identity.attempt_id != reservation.attempt_id + or identity.result_id != reservation.result_id + or identity.lease_id != lease.lease_id + or identity.lease_generation != lease.lease_generation + or identity.lease_expires_at != lease.expires_at + or len(checked.materials) != 1 + or not isinstance(checked.materials[0], PostSubmitExternalCheckerMaterial) + ): + raise ArtifactScratchIntegrityError("external POST execution identity differs") + material = checked.materials[0] + expected = facts.material + if ( + material.submission_id != expected.submission_id + or material.submission_version != expected.submission_version + or material.binding_id != expected.binding_id + or material.content_id != expected.content_id + or material.replica_id != expected.replica_id + or material.content_sha256 != expected.content_sha256 + or material.byte_count != expected.byte_count + or material.evidence_id != facts.evidence_id + or material.verification_receipt_id != facts.verification_receipt_id + or material.verification_job_id != facts.verification_job_id + or material.verification_generation != facts.verification_generation + or material.namespace_fingerprint != facts.namespace_fingerprint + or material.semantic_manifest_sha256 != expected.semantic_manifest_sha256 + ): + raise ArtifactScratchIntegrityError("external POST material identity differs") + entries = self.entries + directories = tuple(item.normalized_path for item in entries if item.entry_type == "directory") + files = tuple(ExternalMaterialFile( + normalized_path=item.normalized_path, byte_count=item.byte_count, + sha256=item.sha256 or "", executable=bool(item.executable), + ) for item in entries if item.entry_type == "file") + lease_expires_at = identity.model_dump(mode="json")["lease_expires_at"] + grant_request = PostExternalMaterialGrantRequest( + request_digest=checked.request_digest, + submission_id=str(identity.submission_id), + submission_version=identity.submission_version, + evaluation_request_id=str(identity.evaluation_request_id), + evaluation_request_digest=identity.evaluation_request_digest, + evaluation_generation=identity.evaluation_generation, + attempt_id=str(identity.attempt_id), result_id=str(identity.result_id), + lease_id=str(identity.lease_id), lease_generation=identity.lease_generation, + lease_expires_at=lease_expires_at, + binding_id=str(material.binding_id), content_id=str(material.content_id), + replica_id=str(material.replica_id), content_sha256=material.content_sha256, + byte_count=material.byte_count, evidence_id=str(material.evidence_id), + verification_receipt_id=str(material.verification_receipt_id), + verification_job_id=str(material.verification_job_id), + verification_generation=material.verification_generation, + namespace_fingerprint=material.namespace_fingerprint, + semantic_manifest_sha256=material.semantic_manifest_sha256, + directories=directories, files=files, + ) + return self._preparation.external_material_grant( + self._prepared, self._workspace, grant_request + ) + + @property + def external_checker_material(self) -> PostSubmitExternalCheckerMaterial: + """Detach the exact verified POST lineage selected before byte access.""" + self._require_open() + facts = self._materialization + material = facts.material + return PostSubmitExternalCheckerMaterial( + role="submission_archive", + submission_id=material.submission_id, + submission_version=material.submission_version, + binding_id=material.binding_id, + content_id=material.content_id, + replica_id=material.replica_id, + content_sha256=material.content_sha256, + byte_count=material.byte_count, + media_type=self._media_type, + evidence_id=facts.evidence_id, + verification_receipt_id=facts.verification_receipt_id, + verification_job_id=facts.verification_job_id, + verification_generation=facts.verification_generation, + namespace_fingerprint=facts.namespace_fingerprint, + semantic_manifest_sha256=material.semantic_manifest_sha256, + ) + def __reduce__(self): """Prevent transfer of a process-local read capability.""" raise TypeError("submission material view is process-local") @@ -68,10 +185,16 @@ def __reduce__(self): class _MaterialProcessor: """Keep async evaluation inside the shared projection and scratch lifetime.""" - def __init__(self, inspector, inspection, request, consumer) -> None: + def __init__( + self, inspector, inspection, request, consumer, *, preparation, prepared, + execution, materialization, media_type, + ) -> None: """Bind one inspection, request and consumer for preparation-owned execution.""" self._inspector, self._inspection = inspector, inspection self._request, self._consumer = request, consumer + self._preparation, self._prepared = preparation, prepared + self._execution, self._materialization = execution, materialization + self._media_type = media_type self._aborted = False self._consumer_task: asyncio.Task[PostSubmissionEvaluationResult] | None = None self._view: _MaterialView | None = None @@ -93,7 +216,11 @@ async def process(self, reader, workspace) -> PostSubmissionEvaluationResult: try: if self._aborted: raise asyncio.CancelledError - self._view = _MaterialView(tree) + self._view = _MaterialView( + tree, preparation=self._preparation, prepared=self._prepared, + workspace=workspace, execution=self._execution, + materialization=self._materialization, media_type=self._media_type, + ) self._consumer_task = asyncio.create_task(self._consumer.evaluate(self._request, self._view)) result = PostSubmissionEvaluationResult.model_validate(await self._consumer_task) result.validate_request(self._request) @@ -195,8 +322,14 @@ async def materialize( for entry in request.structural_input.manifest)) if manifest.sha256 != selected.semantic_manifest_sha256 or supplied_files != expected_files: raise PostSubmissionMaterializationFailure("post_submit_material_manifest_mismatch") + materialization_facts = self._authority_facts(facts, selected) evaluation = await self._preparation._process_prepared_submission( - prepared, _MaterialProcessor(self._inspector, inspection, request, consumer), + prepared, _MaterialProcessor( + self._inspector, inspection, request, consumer, + preparation=self._preparation, prepared=prepared, + execution=facts, materialization=materialization_facts, + media_type=selected.media_type, + ), reserved_bytes=manifest.total_expanded_bytes, maximum_entries=manifest.entry_count, ) finally: diff --git a/backend/app/modules/artifacts/preparation.py b/backend/app/modules/artifacts/preparation.py index af8f00a33..bebd2d62b 100644 --- a/backend/app/modules/artifacts/preparation.py +++ b/backend/app/modules/artifacts/preparation.py @@ -110,6 +110,31 @@ def __post_init__(self) -> None: raise ValueError("external material file identity is invalid") +def _validate_external_material_tree( + directories: tuple[str, ...], files: tuple[ExternalMaterialFile, ...] +) -> None: + """Validate the shared closed path inventory without fabricating phase facts.""" + if ( + type(files) is not tuple + or type(directories) is not tuple + or any(type(item) is not ExternalMaterialFile for item in files) + or any( + type(path) is not str + or not path + or path.startswith("/") + or any(part in {"", ".", ".."} for part in path.split("/")) + or "\x00" in path + for path in directories + ) + or tuple(sorted(directories)) != directories + or len(set(directories)) != len(directories) + or tuple(sorted(files, key=lambda item: item.normalized_path)) != files + or len({item.normalized_path for item in files}) != len(files) + or set(directories) & {item.normalized_path for item in files} + ): + raise ValueError("external material tree is invalid") + + @dataclass(frozen=True, slots=True) class ExternalMaterialGrantRequest: """Exact pre-admission facts bound to one callback-scoped material grant.""" @@ -141,24 +166,125 @@ def __post_init__(self) -> None: ) or type(self.archive_byte_count) is not int or not 0 <= self.archive_byte_count <= HARD_MAXIMUM_ARTIFACT_BYTES - or type(self.files) is not tuple - or type(self.directories) is not tuple - or any(type(item) is not ExternalMaterialFile for item in self.files) + ): + raise ValueError("external material grant request is invalid") + _validate_external_material_tree(self.directories, self.files) + + def manifest_identity(self) -> dict[str, object]: + """Return the exact PRE lineage written into the private grant manifest.""" + return { + "phase": "pre_submit", + "prepared_generation_id": self.prepared_generation_id, + "attempt_id": self.attempt_id, + "attempt_request_digest": self.attempt_request_digest, + "archive_sha256": self.archive_sha256, + "archive_byte_count": self.archive_byte_count, + "semantic_manifest_sha256": self.semantic_manifest_sha256, + } + + +@dataclass(frozen=True, slots=True) +class PostExternalMaterialGrantRequest: + """Exact verified Submission, ART and lease facts for one POST callback.""" + + request_digest: str + submission_id: str + submission_version: int + evaluation_request_id: str + evaluation_request_digest: str + evaluation_generation: int + attempt_id: str + result_id: str + lease_id: str + lease_generation: int + lease_expires_at: str + binding_id: str + content_id: str + replica_id: str + content_sha256: str + byte_count: int + evidence_id: str + verification_receipt_id: str + verification_job_id: str + verification_generation: int + namespace_fingerprint: str + semantic_manifest_sha256: str + directories: tuple[str, ...] + files: tuple[ExternalMaterialFile, ...] + + def __post_init__(self) -> None: + """Reject a partial POST lineage before publishing any scratch path.""" + digests = ( + self.request_digest, + self.evaluation_request_digest, + self.content_sha256, + self.namespace_fingerprint, + self.semantic_manifest_sha256, + ) + identifiers = ( + self.submission_id, + self.evaluation_request_id, + self.attempt_id, + self.result_id, + self.lease_id, + self.binding_id, + self.content_id, + self.replica_id, + self.evidence_id, + self.verification_receipt_id, + self.verification_job_id, + ) + if ( + any(not re.fullmatch(r"sha256:[0-9a-f]{64}", value) for value in digests) or any( - type(path) is not str - or not path - or path.startswith("/") - or any(part in {"", ".", ".."} for part in path.split("/")) - or "\x00" in path - for path in self.directories + not re.fullmatch( + r"[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[89ab][0-9a-f]{3}-[0-9a-f]{12}", + value, + ) + for value in identifiers + ) + or any( + type(value) is not int or value <= 0 + for value in ( + self.submission_version, + self.evaluation_generation, + self.lease_generation, + self.verification_generation, + ) ) - or tuple(sorted(self.directories)) != self.directories - or len(set(self.directories)) != len(self.directories) - or tuple(sorted(self.files, key=lambda item: item.normalized_path)) != self.files - or len({item.normalized_path for item in self.files}) != len(self.files) - or set(self.directories) & {item.normalized_path for item in self.files} + or type(self.byte_count) is not int + or not 0 <= self.byte_count <= HARD_MAXIMUM_ARTIFACT_BYTES + or not self.lease_expires_at.endswith(("Z", "+00:00")) ): - raise ValueError("external material grant request is invalid") + raise ValueError("external POST material grant request is invalid") + _validate_external_material_tree(self.directories, self.files) + + def manifest_identity(self) -> dict[str, object]: + """Return complete POST custody without storage-provider coordinates.""" + return { + "phase": "post_submit", + "submission_id": self.submission_id, + "submission_version": self.submission_version, + "evaluation_request_id": self.evaluation_request_id, + "evaluation_request_digest": self.evaluation_request_digest, + "evaluation_generation": self.evaluation_generation, + "attempt_id": self.attempt_id, + "result_id": self.result_id, + "lease_id": self.lease_id, + "lease_generation": self.lease_generation, + "lease_expires_at": self.lease_expires_at, + "binding_id": self.binding_id, + "content_id": self.content_id, + "replica_id": self.replica_id, + "content_sha256": self.content_sha256, + "byte_count": self.byte_count, + "evidence_id": self.evidence_id, + "verification_receipt_id": self.verification_receipt_id, + "verification_job_id": self.verification_job_id, + "verification_generation": self.verification_generation, + "namespace_fingerprint": self.namespace_fingerprint, + "semantic_manifest_sha256": self.semantic_manifest_sha256, + } @dataclass(frozen=True, slots=True) @@ -579,10 +705,13 @@ def extraction_workspace( def _external_material_grant( self, workspace: Path, - request: ExternalMaterialGrantRequest, + request: ExternalMaterialGrantRequest | PostExternalMaterialGrantRequest, ) -> Iterator[ExternalMaterialGrant]: """Publish one sealed request-bound workspace for the callback lifetime.""" - if type(request) is not ExternalMaterialGrantRequest: + if type(request) not in { + ExternalMaterialGrantRequest, + PostExternalMaterialGrantRequest, + }: raise ValueError("external material grant request is invalid") with self._tracked_operation(): grant = self._publish_external_grant_sync(workspace, request) @@ -594,7 +723,7 @@ def _external_material_grant( def _publish_external_grant_sync( self, workspace: Path, - request: ExternalMaterialGrantRequest, + request: ExternalMaterialGrantRequest | PostExternalMaterialGrantRequest, ) -> ExternalMaterialGrant: """Move the projected tree below a fixed mount and seal its exact manifest.""" try: @@ -684,12 +813,7 @@ def _publish_external_grant_sync( "protocol_version": _EXTERNAL_GRANT_PROTOCOL, "grant_id": grant_id, "request_digest": request.request_digest, - "prepared_generation_id": request.prepared_generation_id, - "attempt_id": request.attempt_id, - "attempt_request_digest": request.attempt_request_digest, - "archive_sha256": request.archive_sha256, - "archive_byte_count": request.archive_byte_count, - "semantic_manifest_sha256": request.semantic_manifest_sha256, + **request.manifest_identity(), "directories": list(observed_directories), "files": list(observed), } @@ -1990,7 +2114,7 @@ def external_material_grant( self, prepared: PreparedArtifact, workspace: Path, - request: ExternalMaterialGrantRequest, + request: ExternalMaterialGrantRequest | PostExternalMaterialGrantRequest, ) -> Iterator[ExternalMaterialGrant]: """Issue one grant from the live prepared source and current callback only.""" if type(prepared) is not PreparedArtifact or prepared._owner is not self: @@ -2002,9 +2126,20 @@ def external_material_grant( or not active.handle_issued or active.stream_claimed or self._external_grant_workspaces.get(binding) != workspace - or request.prepared_generation_id != str(prepared.generation_id) + ): + raise ArtifactScratchIntegrityError("external material provenance differs") + pre_mismatch = type(request) is ExternalMaterialGrantRequest and ( + request.prepared_generation_id != str(prepared.generation_id) or request.archive_sha256 != active.commitment.sha256 or request.archive_byte_count != active.commitment.byte_count + ) + post_mismatch = type(request) is PostExternalMaterialGrantRequest and ( + request.content_sha256 != active.commitment.sha256 + or request.byte_count != active.commitment.byte_count + ) + if ( + pre_mismatch + or post_mismatch ): raise ArtifactScratchIntegrityError("external material provenance differs") with self._manager._external_material_grant(workspace, request) as grant: diff --git a/backend/app/modules/checkers/api/materialization.py b/backend/app/modules/checkers/api/materialization.py index 10812ca4c..d64f85a14 100644 --- a/backend/app/modules/checkers/api/materialization.py +++ b/backend/app/modules/checkers/api/materialization.py @@ -2,7 +2,7 @@ from dataclasses import dataclass from abc import ABC, abstractmethod -from contextlib import AbstractAsyncContextManager +from contextlib import AbstractAsyncContextManager, AbstractContextManager from typing import Literal, Protocol from uuid import UUID @@ -14,6 +14,10 @@ PostSubmissionEvaluationRequest, PostSubmissionEvaluationResult, ) +from app.modules.checkers.api.external import ( + ExternalCheckerExecutionRequest, + PostSubmitExternalCheckerMaterial, +) class PostSubmissionMaterializationUnavailable(RuntimeError): @@ -104,6 +108,22 @@ def entries(self) -> tuple[SubmissionMaterialEntry, ...]: def read_file(self, normalized_path: str, *, maximum_bytes: int) -> bytes: """Read one bounded verified file without filesystem authority.""" + def external_checker_grant( + self, request: ExternalCheckerExecutionRequest + ) -> AbstractContextManager["ExternalCheckerGrantReference"]: + """Issue one request-bound opaque grant for this callback lifetime only.""" + + @property + def external_checker_material(self) -> PostSubmitExternalCheckerMaterial: + """Return detached exact POST custody without provider or path coordinates.""" + + +class ExternalCheckerGrantReference(Protocol): + """Opaque ART grant identity accepted by the trusted service adapter.""" + + grant_id: str + binding_digest: str + class PostSubmissionMaterialConsumer(Protocol): """Evaluate scoped input asynchronously and return detached phase facts.""" diff --git a/backend/tests/test_post_submit_materialization.py b/backend/tests/test_post_submit_materialization.py index f8cf72671..15a6f5858 100644 --- a/backend/tests/test_post_submit_materialization.py +++ b/backend/tests/test_post_submit_materialization.py @@ -1,6 +1,7 @@ """Verified exact Submission input, async lifetime and fail-closed composition.""" import asyncio +import json import pickle from dataclasses import asdict @@ -16,6 +17,13 @@ from tests.post_submit_materialization_helpers import material_fixture from tests.checkers.execution.support import material_execution, service_link_state from app.modules.actors.api import ServiceIdentity +from app.modules.artifacts.preparation import ArtifactScratchIntegrityError +from app.modules.checkers.api.external import ( + PostSubmitExternalCheckerIdentity, + external_checker_json_hash, + make_external_checker_execution_request, +) +from tests.checkers.external.support import registry_entry class Consumer: @@ -42,6 +50,65 @@ async def evaluate(self, request, view): return result(request) +class ExternalGrantConsumer(Consumer): + """Exercise the real POST lineage through ART's callback-scoped grant.""" + + def __init__(self, files, execution): + super().__init__(files) + self.execution = execution + self.grant_path = None + self.manifest = None + + def external_request(self, material, *, identity=None): + source, lease = self.execution.request, self.execution.lease + reservation = lease.reservation + identity = identity or PostSubmitExternalCheckerIdentity( + project_id=source.project_id, + task_id=source.task_id, + assignment_id=source.assignment_id, + submission_id=source.submission_id, + submission_version=source.submission_version, + evaluation_request_id=source.evaluation_request_id, + evaluation_request_digest=source.request_sha256, + evaluation_generation=source.evaluation_generation, + attempt_id=reservation.attempt_id, + result_id=reservation.result_id, + lease_id=lease.lease_id, + lease_generation=lease.lease_generation, + lease_expires_at=lease.expires_at, + ) + return make_external_checker_execution_request( + registry=registry_entry("post_submit"), + identity=identity, + configuration={}, + configuration_sha256=external_checker_json_hash({}), + input={"task_version": "v1"}, + input_sha256=external_checker_json_hash({"task_version": "v1"}), + materials=(material,), + ) + + async def evaluate(self, request, view): + await super().evaluate(request, view) + external_request = self.external_request(view.external_checker_material) + with view.external_checker_grant(external_request) as grant: + self.grant_path = view._workspace.parent / grant.grant_id + self.manifest = json.loads( + (self.grant_path / ".external-checker-grant.json").read_text() + ) + assert self.manifest["phase"] == "post_submit" + assert self.manifest["submission_id"] == str(request.submission_id) + assert self.manifest["request_digest"] == external_request.request_digest + assert self.manifest["binding_digest"] == grant.binding_digest + assert not self.grant_path.exists() + + changed = view.external_checker_material.model_copy( + update={"binding_id": new_record_id()} + ) + with pytest.raises(ArtifactScratchIntegrityError, match="material identity differs"): + view.external_checker_grant(self.external_request(changed)) + return result(request) + + def assert_closed(h, consumer): with pytest.raises(RuntimeError, match="closed"): _ = consumer.view.entries @@ -91,6 +158,18 @@ async def test_exact_materialization_reads_verified_original_and_revokes_view(tm "input_materialization_evidence_id"} +async def test_post_external_grant_binds_native_submission_art_and_lease(tmp_path, isolated_database_env): + async with material_fixture(tmp_path, isolated_database_env) as h: + execution = await material_execution(h) + consumer = ExternalGrantConsumer(h.files, execution) + material = await h.service.materialize(execution, consumer) + assert material.evaluation.outcome == "completed" + assert consumer.manifest["lease_id"] == str(execution.lease.lease_id) + assert consumer.manifest["content_id"] == str(material.content_id) + assert consumer.grant_path is not None and not consumer.grant_path.exists() + assert_closed(h, consumer) + + async def test_revoked_materializer_denies_before_provider_or_scratch(tmp_path, isolated_database_env): async with material_fixture(tmp_path, isolated_database_env) as h: execution = await material_execution(h) diff --git a/external_checkers/workstream-checker-service/src/main.rs b/external_checkers/workstream-checker-service/src/main.rs index 2818aea6e..5367645e0 100644 --- a/external_checkers/workstream-checker-service/src/main.rs +++ b/external_checkers/workstream-checker-service/src/main.rs @@ -76,24 +76,58 @@ struct GrantReference { binding_digest: String, } -#[derive(Debug, Deserialize, Serialize)] +#[derive(Debug, Clone, Deserialize, Serialize)] #[serde(deny_unknown_fields)] struct GrantManifest { protocol_version: String, grant_id: String, request_digest: String, - prepared_generation_id: String, - attempt_id: String, - attempt_request_digest: String, - archive_sha256: String, - archive_byte_count: u64, - semantic_manifest_sha256: String, + #[serde(flatten)] + identity: GrantIdentity, directories: Vec, files: Vec, binding_digest: String, } -#[derive(Debug, Deserialize, Serialize, PartialEq, Eq)] +#[derive(Debug, Clone, Deserialize, Serialize)] +#[serde(tag = "phase", deny_unknown_fields)] +enum GrantIdentity { + #[serde(rename = "pre_submit")] + PreSubmit { + prepared_generation_id: String, + attempt_id: String, + attempt_request_digest: String, + archive_sha256: String, + archive_byte_count: u64, + semantic_manifest_sha256: String, + }, + #[serde(rename = "post_submit")] + PostSubmit { + submission_id: String, + submission_version: u64, + evaluation_request_id: String, + evaluation_request_digest: String, + evaluation_generation: u64, + attempt_id: String, + result_id: String, + lease_id: String, + lease_generation: u64, + lease_expires_at: String, + binding_id: String, + content_id: String, + replica_id: String, + content_sha256: String, + byte_count: u64, + evidence_id: String, + verification_receipt_id: String, + verification_job_id: String, + verification_generation: u64, + namespace_fingerprint: String, + semantic_manifest_sha256: String, + }, +} + +#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)] #[serde(deny_unknown_fields)] struct GrantFile { normalized_path: String, @@ -572,9 +606,6 @@ fn verify_grant( } fn grant_matches_request(manifest: &GrantManifest, request: &ValidatedRequest) -> bool { - if request.phase != "pre_submit" { - return false; - } let Some(identity) = request.value.get("identity").and_then(Value::as_object) else { return false; }; @@ -583,39 +614,124 @@ fn grant_matches_request(manifest: &GrantManifest, request: &ValidatedRequest) - }; let Some(archive) = materials.iter().find_map(|item| { let object = item.as_object()?; - (object.get("phase")?.as_str()? == "pre_submit" + (object.get("phase")?.as_str()? == request.phase && object.get("role")?.as_str()? == "submission_archive") .then_some(object) }) else { return false; }; let semantic_manifest_sha256 = semantic_manifest_hash(manifest).ok(); - identity - .get("prepared_generation_id") - .and_then(Value::as_str) - == Some(&manifest.prepared_generation_id) - && identity.get("attempt_id").and_then(Value::as_str) == Some(&manifest.attempt_id) - && identity - .get("attempt_request_digest") - .and_then(Value::as_str) - == Some(&manifest.attempt_request_digest) - && archive - .get("prepared_generation_id") - .and_then(Value::as_str) - == Some(&manifest.prepared_generation_id) - && archive.get("attempt_id").and_then(Value::as_str) == Some(&manifest.attempt_id) - && archive - .get("attempt_request_digest") - .and_then(Value::as_str) - == Some(&manifest.attempt_request_digest) - && archive.get("archive_sha256").and_then(Value::as_str) == Some(&manifest.archive_sha256) - && archive.get("archive_byte_count").and_then(Value::as_u64) - == Some(manifest.archive_byte_count) - && archive - .get("semantic_manifest_sha256") - .and_then(Value::as_str) - == Some(&manifest.semantic_manifest_sha256) - && semantic_manifest_sha256.as_deref() == Some(&manifest.semantic_manifest_sha256) + match &manifest.identity { + GrantIdentity::PreSubmit { + prepared_generation_id, + attempt_id, + attempt_request_digest, + archive_sha256, + archive_byte_count, + semantic_manifest_sha256: expected_manifest, + } => { + request.phase == "pre_submit" + && identity + .get("prepared_generation_id") + .and_then(Value::as_str) + == Some(prepared_generation_id) + && identity.get("attempt_id").and_then(Value::as_str) == Some(attempt_id) + && identity + .get("attempt_request_digest") + .and_then(Value::as_str) + == Some(attempt_request_digest) + && archive + .get("prepared_generation_id") + .and_then(Value::as_str) + == Some(prepared_generation_id) + && archive.get("attempt_id").and_then(Value::as_str) == Some(attempt_id) + && archive + .get("attempt_request_digest") + .and_then(Value::as_str) + == Some(attempt_request_digest) + && archive.get("archive_sha256").and_then(Value::as_str) == Some(archive_sha256) + && archive.get("archive_byte_count").and_then(Value::as_u64) + == Some(*archive_byte_count) + && archive + .get("semantic_manifest_sha256") + .and_then(Value::as_str) + == Some(expected_manifest) + && semantic_manifest_sha256.as_deref() == Some(expected_manifest) + } + GrantIdentity::PostSubmit { + submission_id, + submission_version, + evaluation_request_id, + evaluation_request_digest, + evaluation_generation, + attempt_id, + result_id, + lease_id, + lease_generation, + lease_expires_at, + binding_id, + content_id, + replica_id, + content_sha256, + byte_count, + evidence_id, + verification_receipt_id, + verification_job_id, + verification_generation, + namespace_fingerprint, + semantic_manifest_sha256: expected_manifest, + } => { + request.phase == "post_submit" + && identity.get("submission_id").and_then(Value::as_str) == Some(submission_id) + && identity.get("submission_version").and_then(Value::as_u64) + == Some(*submission_version) + && identity + .get("evaluation_request_id") + .and_then(Value::as_str) + == Some(evaluation_request_id) + && identity + .get("evaluation_request_digest") + .and_then(Value::as_str) + == Some(evaluation_request_digest) + && identity + .get("evaluation_generation") + .and_then(Value::as_u64) + == Some(*evaluation_generation) + && identity.get("attempt_id").and_then(Value::as_str) == Some(attempt_id) + && identity.get("result_id").and_then(Value::as_str) == Some(result_id) + && identity.get("lease_id").and_then(Value::as_str) == Some(lease_id) + && identity.get("lease_generation").and_then(Value::as_u64) + == Some(*lease_generation) + && identity.get("lease_expires_at").and_then(Value::as_str) + == Some(lease_expires_at) + && archive.get("submission_id").and_then(Value::as_str) == Some(submission_id) + && archive.get("submission_version").and_then(Value::as_u64) + == Some(*submission_version) + && archive.get("binding_id").and_then(Value::as_str) == Some(binding_id) + && archive.get("content_id").and_then(Value::as_str) == Some(content_id) + && archive.get("replica_id").and_then(Value::as_str) == Some(replica_id) + && archive.get("content_sha256").and_then(Value::as_str) == Some(content_sha256) + && archive.get("byte_count").and_then(Value::as_u64) == Some(*byte_count) + && archive.get("evidence_id").and_then(Value::as_str) == Some(evidence_id) + && archive + .get("verification_receipt_id") + .and_then(Value::as_str) + == Some(verification_receipt_id) + && archive.get("verification_job_id").and_then(Value::as_str) + == Some(verification_job_id) + && archive + .get("verification_generation") + .and_then(Value::as_u64) + == Some(*verification_generation) + && archive.get("namespace_fingerprint").and_then(Value::as_str) + == Some(namespace_fingerprint) + && archive + .get("semantic_manifest_sha256") + .and_then(Value::as_str) + == Some(expected_manifest) + && semantic_manifest_sha256.as_deref() == Some(expected_manifest) + } + } } fn semantic_manifest_hash(manifest: &GrantManifest) -> Result { @@ -1621,64 +1737,170 @@ mod tests { protocol_version: GRANT_PROTOCOL.into(), grant_id: "extract_0123456789abcdef0123456789abcdef".into(), request_digest: request.request_digest.clone(), - prepared_generation_id: request.value["identity"]["prepared_generation_id"] - .as_str() - .unwrap() - .into(), - attempt_id: request.value["identity"]["attempt_id"] - .as_str() - .unwrap() - .into(), - attempt_request_digest: request.value["identity"]["attempt_request_digest"] - .as_str() - .unwrap() - .into(), - archive_sha256: request.value["materials"][0]["archive_sha256"] - .as_str() - .unwrap() - .into(), - archive_byte_count: request.value["materials"][0]["archive_byte_count"] - .as_u64() - .unwrap(), - semantic_manifest_sha256: String::new(), + identity: GrantIdentity::PreSubmit { + prepared_generation_id: request.value["identity"]["prepared_generation_id"] + .as_str() + .unwrap() + .into(), + attempt_id: request.value["identity"]["attempt_id"] + .as_str() + .unwrap() + .into(), + attempt_request_digest: request.value["identity"]["attempt_request_digest"] + .as_str() + .unwrap() + .into(), + archive_sha256: request.value["materials"][0]["archive_sha256"] + .as_str() + .unwrap() + .into(), + archive_byte_count: request.value["materials"][0]["archive_byte_count"] + .as_u64() + .unwrap(), + semantic_manifest_sha256: String::new(), + }, directories: Vec::new(), files: Vec::new(), binding_digest: format!("sha256:{}", "9".repeat(64)), }; - manifest.semantic_manifest_sha256 = semantic_manifest_hash(&manifest).unwrap(); + let semantic = semantic_manifest_hash(&manifest).unwrap(); + let GrantIdentity::PreSubmit { + semantic_manifest_sha256, + .. + } = &mut manifest.identity + else { + unreachable!() + }; + *semantic_manifest_sha256 = semantic; request.value["materials"][0]["semantic_manifest_sha256"] = - Value::String(manifest.semantic_manifest_sha256.clone()); + Value::String(semantic_manifest_sha256.clone()); assert!(grant_matches_request(&manifest, &request)); for field in 0..6 { - let original = ( - manifest.prepared_generation_id.clone(), - manifest.attempt_id.clone(), - manifest.attempt_request_digest.clone(), - manifest.archive_sha256.clone(), - manifest.archive_byte_count, - manifest.semantic_manifest_sha256.clone(), - ); - match field { - 0 => { - manifest.prepared_generation_id = "00000000-0000-4000-8000-000000000000".into() + let original = manifest.identity.clone(); + if let GrantIdentity::PreSubmit { + prepared_generation_id, + attempt_id, + attempt_request_digest, + archive_sha256, + archive_byte_count, + semantic_manifest_sha256, + } = &mut manifest.identity + { + match field { + 0 => *prepared_generation_id = "00000000-0000-4000-8000-000000000000".into(), + 1 => *attempt_id = "00000000-0000-4000-8000-000000000000".into(), + 2 => *attempt_request_digest = format!("sha256:{}", "8".repeat(64)), + 3 => *archive_sha256 = format!("sha256:{}", "8".repeat(64)), + 4 => *archive_byte_count += 1, + _ => *semantic_manifest_sha256 = format!("sha256:{}", "8".repeat(64)), } - 1 => manifest.attempt_id = "00000000-0000-4000-8000-000000000000".into(), - 2 => manifest.attempt_request_digest = format!("sha256:{}", "8".repeat(64)), - 3 => manifest.archive_sha256 = format!("sha256:{}", "8".repeat(64)), - 4 => manifest.archive_byte_count += 1, - _ => manifest.semantic_manifest_sha256 = format!("sha256:{}", "8".repeat(64)), } assert!(!grant_matches_request(&manifest, &request)); - ( - manifest.prepared_generation_id, - manifest.attempt_id, - manifest.attempt_request_digest, - manifest.archive_sha256, - manifest.archive_byte_count, - manifest.semantic_manifest_sha256, - ) = original; + manifest.identity = original; } request.phase = "post_submit".into(); assert!(!grant_matches_request(&manifest, &request)); } + + #[test] + fn grant_lineage_matches_every_normalized_post_submit_fact() { + let digest = |byte: char| format!("sha256:{}", byte.to_string().repeat(64)); + let id = |byte: char| format!("{0}{0}{0}{0}{0}{0}{0}{0}-0000-4000-8000-000000000000", byte); + let identity = serde_json::json!({ + "phase": "post_submit", "project_id": id('1'), "task_id": id('2'), + "assignment_id": id('3'), "submission_id": id('4'), "submission_version": 2, + "evaluation_request_id": id('5'), "evaluation_request_digest": digest('5'), + "evaluation_generation": 3, "attempt_id": id('6'), "result_id": id('7'), + "lease_id": id('8'), "lease_generation": 4, + "lease_expires_at": "2026-10-11T12:00:00+00:00" + }); + let material = serde_json::json!({ + "phase": "post_submit", "role": "submission_archive", + "submission_id": identity["submission_id"], "submission_version": 2, + "binding_id": id('9'), "content_id": "aaaaaaaa-0000-4000-8000-000000000000", + "replica_id": "bbbbbbbb-0000-4000-8000-000000000000", + "content_sha256": digest('c'), "byte_count": 0, "media_type": "application/zip", + "evidence_id": "cccccccc-0000-4000-8000-000000000000", + "verification_receipt_id": "dddddddd-0000-4000-8000-000000000000", + "verification_job_id": "eeeeeeee-0000-4000-8000-000000000000", + "verification_generation": 5, "namespace_fingerprint": digest('d'), + "semantic_manifest_sha256": "" + }); + let mut manifest = GrantManifest { + protocol_version: GRANT_PROTOCOL.into(), + grant_id: "extract_0123456789abcdef0123456789abcdef".into(), + request_digest: digest('f'), + identity: GrantIdentity::PostSubmit { + submission_id: identity["submission_id"].as_str().unwrap().into(), + submission_version: 2, + evaluation_request_id: identity["evaluation_request_id"].as_str().unwrap().into(), + evaluation_request_digest: digest('5'), + evaluation_generation: 3, + attempt_id: identity["attempt_id"].as_str().unwrap().into(), + result_id: identity["result_id"].as_str().unwrap().into(), + lease_id: identity["lease_id"].as_str().unwrap().into(), + lease_generation: 4, + lease_expires_at: identity["lease_expires_at"].as_str().unwrap().into(), + binding_id: material["binding_id"].as_str().unwrap().into(), + content_id: material["content_id"].as_str().unwrap().into(), + replica_id: material["replica_id"].as_str().unwrap().into(), + content_sha256: digest('c'), + byte_count: 0, + evidence_id: material["evidence_id"].as_str().unwrap().into(), + verification_receipt_id: material["verification_receipt_id"] + .as_str() + .unwrap() + .into(), + verification_job_id: material["verification_job_id"].as_str().unwrap().into(), + verification_generation: 5, + namespace_fingerprint: digest('d'), + semantic_manifest_sha256: String::new(), + }, + directories: Vec::new(), + files: Vec::new(), + binding_digest: digest('9'), + }; + let semantic = semantic_manifest_hash(&manifest).unwrap(); + let GrantIdentity::PostSubmit { + semantic_manifest_sha256, + .. + } = &mut manifest.identity + else { + unreachable!() + }; + *semantic_manifest_sha256 = semantic.clone(); + let mut material = material; + material["semantic_manifest_sha256"] = Value::String(semantic); + let request = ValidatedRequest { + value: serde_json::json!({"identity": identity, "materials": [material]}), + request_digest: manifest.request_digest.clone(), + registry_entry_id: id('f'), + registry_entry_digest: digest('1'), + image_digest: digest('2'), + phase: "post_submit".into(), + cpu_millis: 1, + memory_bytes: 1, + deadline_ms: 100, + maximum_output_bytes: 256, + }; + assert!(grant_matches_request(&manifest, &request)); + + let original = manifest.identity.clone(); + if let GrantIdentity::PostSubmit { + verification_generation, + .. + } = &mut manifest.identity + { + *verification_generation += 1; + } + assert!(!grant_matches_request(&manifest, &request)); + manifest.identity = original; + manifest.files.push(GrantFile { + normalized_path: "foreign.txt".into(), + byte_count: 0, + sha256: digest('a'), + executable: false, + }); + assert!(!grant_matches_request(&manifest, &request)); + } } From 2648bf1872183c470222e13ea6bfbf8f75aafa36 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 18:39:51 +0100 Subject: [PATCH 054/283] [PILOT-04] Run prechecks outside database roots --- .../pilot04-workstream-default-checker.md | 1 + .../modules/artifacts/pre_submit_attempts.py | 15 +++++ .../artifacts/submission_materialization.py | 27 +++++++-- backend/tests/pre_submit_test_helpers.py | 9 ++- .../test_pre_submit_attempt_contracts.py | 58 ++++++++++++++++++- 5 files changed, 102 insertions(+), 8 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 09fd44cef..2c94bee70 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -167,6 +167,7 @@ intermediate-wait regression. | Claim | Command or proof | Result | Remaining uncertainty | |---|---|---|---| | Existing component custody | Prior PR538 default, Rust service/SDK, ART callback and contract reviews | Passed at recorded component heads | Final selected flow/current-main integration pending | +| PRE transaction boundary | `pytest -q` for invalid claim controls and `test_checker_processor_starts_only_after_authority_transaction_commits`, plus Ruff on the four affected files | 5 passed; processor construction is refused while the authority root is active and reached only after it commits | Durable lease/generation schema and selected external sequence remain pending | | Owner/caller trace | PROJECT approval/activation, ART preparation/admission, TASK composition and CHECKERS dispatch | In progress | Persistence delta and migration ordinal await actual linear predecessor | | End-to-end replacement | Real PostgreSQL/MinIO/Rust public and worker journey | Not run | Implementation incomplete | diff --git a/backend/app/modules/artifacts/pre_submit_attempts.py b/backend/app/modules/artifacts/pre_submit_attempts.py index 3a337fee6..22fe00254 100644 --- a/backend/app/modules/artifacts/pre_submit_attempts.py +++ b/backend/app/modules/artifacts/pre_submit_attempts.py @@ -142,6 +142,21 @@ async def consume( self._started = True await self._reserved(session) + def require_execution( + self, + session: AsyncSession, + request: PreparedBundleMaterializationRequest, + ) -> None: + """Require the committed claim outside a database transaction.""" + if ( + session is not self._session + or session.in_transaction() + or not self._started + or self._execution is not None + or replace(request, prepared_authorization=None) != self._request + ): + raise PreSubmitEvidenceConflict("pre_submit_attempt_claim_invalid") + def finish(self, execution: PreSubmitExecutionResult) -> None: """Retain the exact owner-issued result object for final persistence.""" if not self._started or self._execution is not None: diff --git a/backend/app/modules/artifacts/submission_materialization.py b/backend/app/modules/artifacts/submission_materialization.py index bc24cd504..e26f1cdd5 100644 --- a/backend/app/modules/artifacts/submission_materialization.py +++ b/backend/app/modules/artifacts/submission_materialization.py @@ -232,13 +232,13 @@ def __init__( raise ValueError("pre-submit materializer storage scheme is invalid") self._storage_scheme = storage_scheme - async def materialize_prepared_bundle( + async def authorize_prepared_bundle( self, request: PreparedBundleMaterializationRequest, *, claim: PreSubmitAttemptClaim, - ) -> PreSubmitExecutionResult: - """Consume fixed-service authority before any byte or workspace access.""" + ) -> None: + """Consume fixed-service authority and the durable claim in its short root.""" if type(claim) is not PreSubmitAttemptClaim: raise PreSubmitEvidenceConflict("pre_submit_attempt_claim_invalid") facts = self._authority_facts(request) @@ -247,6 +247,17 @@ async def materialize_prepared_bundle( facts=facts, ) await claim.consume(self._session, request) + + async def materialize_prepared_bundle( + self, + request: PreparedBundleMaterializationRequest, + *, + claim: PreSubmitAttemptClaim, + ) -> PreSubmitExecutionResult: + """Execute only after the authority root commits; no external work holds DB locks.""" + if type(claim) is not PreSubmitAttemptClaim: + raise PreSubmitEvidenceConflict("pre_submit_attempt_claim_invalid") + claim.require_execution(self._session, request) processor = self._checker_execution.build( PreSubmitCheckerExecutionRequest( plan=request.effective_plan, @@ -492,6 +503,7 @@ async def execute_reserved( if self._session.in_transaction(): raise RuntimeError("pre-submit execution requires a transaction-free session") claim = await self._attempts.committed_claim(reservation) + authorized_request = None async with self._session.begin(): await self._lock_authorized_context(request, preparation_request) handle = await self._materialization.prepare_authorization( @@ -502,9 +514,14 @@ async def execute_reserved( effective_plan=request.effective_plan, idempotency_key=preparation_request.idempotency_key, ) - execution = await self._materialization.materialize_prepared_bundle( - replace(request, prepared_authorization=handle), claim=claim, + authorized_request = replace(request, prepared_authorization=handle) + await self._materialization.authorize_prepared_bundle( + authorized_request, claim=claim, ) + assert authorized_request is not None + execution = await self._materialization.materialize_prepared_bundle( + replace(authorized_request, prepared_authorization=None), claim=claim, + ) async with self._session.begin(): await self._session.execute(text("set transaction isolation level read committed")) values = self._input(request, preparation_request) diff --git a/backend/tests/pre_submit_test_helpers.py b/backend/tests/pre_submit_test_helpers.py index 5eb7c04fd..273c730ad 100644 --- a/backend/tests/pre_submit_test_helpers.py +++ b/backend/tests/pre_submit_test_helpers.py @@ -32,14 +32,19 @@ async def materialize_member_fixture(service, request): claim._request = replace(request, prepared_authorization=None) claim._started, claim._execution = False, None claim._session = service._session - service._session.in_transaction = lambda: True + in_transaction = True + service._session.in_transaction = lambda: in_transaction service._session.in_nested_transaction = lambda: False service._session.scalar = AsyncMock(return_value=SimpleNamespace( status="reserved", evidence_set_id=None, claim_nonce=str(claim._nonce), request_digest=claim.request_digest, prepared_generation_id=str(request.prepared_artifact.generation_id), )) - return await service.materialize_prepared_bundle(request, claim=claim) + await service.authorize_prepared_bundle(request, claim=claim) + in_transaction = False + return await service.materialize_prepared_bundle( + replace(request, prepared_authorization=None), claim=claim + ) async def execute_evidence_workflow(workflow, request, *, preparation_request): diff --git a/backend/tests/test_pre_submit_attempt_contracts.py b/backend/tests/test_pre_submit_attempt_contracts.py index b5e4f5dc1..743ab44b0 100644 --- a/backend/tests/test_pre_submit_attempt_contracts.py +++ b/backend/tests/test_pre_submit_attempt_contracts.py @@ -167,7 +167,7 @@ async def test_invalid_attempt_claim_never_builds_processor_or_opens_workspace( }[claim_kind] try: with pytest.raises(PreSubmitEvidenceConflict, match="pre_submit_attempt_claim_invalid"): - await service.materialize_prepared_bundle(request, claim=claim) + await service.authorize_prepared_bundle(request, claim=claim) processor_build.assert_not_called() preparation._process_prepared_submission.assert_not_awaited() assert list((tmp_path / "scratch" / "workspaces").iterdir()) == [] @@ -176,6 +176,62 @@ async def test_invalid_attempt_claim_never_builds_processor_or_opens_workspace( manager.close() +@pytest.mark.asyncio +async def test_checker_processor_starts_only_after_authority_transaction_commits( + tmp_path, +) -> None: + request, _inspector, manager, _preparation, catalogue = await _request(tmp_path) + transaction = True + reservation = SimpleNamespace( + status="reserved", + evidence_set_id=None, + claim_nonce=None, + request_digest="sha256:" + "1" * 64, + prepared_generation_id=str(request.prepared_artifact.generation_id), + ) + session = SimpleNamespace( + in_transaction=lambda: transaction, + in_nested_transaction=lambda: False, + scalar=AsyncMock(return_value=reservation), + ) + claim = _claim(request, session) + reservation.claim_nonce = str(claim._nonce) + processor_build = Mock( + side_effect=RuntimeError("processor reached after authority transaction") + ) + service = PreparedBundleMaterializationService( + session=session, + authorization=SimpleNamespace(consume=AsyncMock()), + preparation=SimpleNamespace(_process_prepared_submission=AsyncMock()), + checker_execution=SimpleNamespace( + catalogue_manifest_sha256=catalogue.manifest_sha256, + build=processor_build, + ), + storage_scheme="s3", + ) + try: + await service.authorize_prepared_bundle(request, claim=claim) + with pytest.raises( + PreSubmitEvidenceConflict, match="pre_submit_attempt_claim_invalid" + ): + await service.materialize_prepared_bundle( + replace(request, prepared_authorization=None), claim=claim + ) + processor_build.assert_not_called() + + transaction = False + with pytest.raises( + RuntimeError, match="processor reached after authority transaction" + ): + await service.materialize_prepared_bundle( + replace(request, prepared_authorization=None), claim=claim + ) + processor_build.assert_called_once() + finally: + await request.prepared_artifact.close() + manager.close() + + @pytest.mark.parametrize("missing_field", ("metadata_json", "checker_order")) async def test_completed_replay_rejects_missing_result_metadata_before_capability( missing_field: str, From fe792de43096d6e000482797af5d24227db1c453 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 18:51:51 +0100 Subject: [PATCH 055/283] [PILOT-04] Select verified pre-submit checker sequence --- .../pilot04-workstream-default-checker.md | 7 +- backend/app/adapters/checkers/__init__.py | 73 ++++ .../artifacts/post_submit_materialization.py | 4 +- .../artifacts/submission_materialization.py | 160 ++++++- backend/app/modules/checkers/api/__init__.py | 10 + .../checkers/api/selected_pre_submit.py | 111 +++++ .../checkers/selected_pre_submit_execution.py | 228 ++++++++++ .../app/modules/projects/api/locked_policy.py | 4 + .../projects/locked_policy_projection.py | 3 + .../external/test_selected_pre_submit.py | 394 ++++++++++++++++++ .../test_default_pre_submit_execution.py | 18 +- 11 files changed, 1002 insertions(+), 10 deletions(-) create mode 100644 backend/app/modules/checkers/api/selected_pre_submit.py create mode 100644 backend/app/modules/checkers/selected_pre_submit_execution.py create mode 100644 backend/tests/checkers/external/test_selected_pre_submit.py diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 2c94bee70..2fa703319 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -19,8 +19,10 @@ initial post-submit dispatch. Post-submit images produce evidence only. This branch contains the normalized external contract, immutable registry, long-lived Rust service and SDK, typed Unix-socket client, callback-scoped ART -grant, and the exact four-behavior Workstream default checker. Those components -are unselected. Production still uses the older pre/post catalogues. +grant, and the exact four-behavior Workstream default checker. The selected PRE +processor now runs the default before each locked external image over one +genuine prepared-ART callback, but its durable result and admission caller are +not selected yet. Production still uses the older pre/post catalogues. ## Bounded change @@ -168,6 +170,7 @@ intermediate-wait regression. |---|---|---|---| | Existing component custody | Prior PR538 default, Rust service/SDK, ART callback and contract reviews | Passed at recorded component heads | Final selected flow/current-main integration pending | | PRE transaction boundary | `pytest -q` for invalid claim controls and `test_checker_processor_starts_only_after_authority_transaction_commits`, plus Ruff on the four affected files | 5 passed; processor construction is refused while the authority root is active and reached only after it commits | Durable lease/generation schema and selected external sequence remain pending | +| Selected PRE callback | `pytest -q backend/tests/checkers/external/test_selected_pre_submit.py`; Ruff and `git diff --check` on the affected files | 4 passed; exact default runs first, a real high-confidence secret prevents every external invocation, locked external pass/fail is retained, and the genuine request-bound ART grant completes cleanup with one bounded owned mount | Durable persistence, admission composition, crash recovery and native service journey remain pending | | Owner/caller trace | PROJECT approval/activation, ART preparation/admission, TASK composition and CHECKERS dispatch | In progress | Persistence delta and migration ordinal await actual linear predecessor | | End-to-end replacement | Real PostgreSQL/MinIO/Rust public and worker journey | Not run | Implementation incomplete | diff --git a/backend/app/adapters/checkers/__init__.py b/backend/app/adapters/checkers/__init__.py index 48f993f54..7320f4fbc 100644 --- a/backend/app/adapters/checkers/__init__.py +++ b/backend/app/adapters/checkers/__init__.py @@ -42,6 +42,11 @@ DefaultPreSubmissionExecutionInput, EffectivePreSubmissionProcessor, ) +from app.modules.checkers.api.external import ( + PreSubmitExternalCheckerIdentity, + PreSubmitExternalCheckerMaterial, +) +from app.modules.checkers.selected_pre_submit_execution import SelectedPreSubmitProcessor def external_checker_execution_factory( @@ -74,6 +79,17 @@ def configured_external_checker_execution_factory(settings): ) +def selected_pre_submit_checker_execution(*, settings, archive_inspector): + """Compose the sole selected PRE runtime from the configured Rust service.""" + execution = configured_external_checker_execution_factory(settings).create( + EXTERNAL_CHECKER_PROVIDER_KEY + ) + return SelectedPreSubmitCheckerExecutionAdapter( + archive_inspector=archive_inspector, + external_execution=execution, + ) + + def external_checker_registry_reader(session): """Resolve immutable metadata for trusted approval and execution owners.""" from app.modules.checkers.external_registry import ExternalCheckerRegistryReader @@ -83,6 +99,8 @@ def external_checker_registry_reader(session): class _ExecutionRequest(Protocol): plan: Any + task_id: Any + assignment_id: Any commitment: Any inspection: Any manifest: Any @@ -139,6 +157,61 @@ def build(self, request: _ExecutionRequest) -> _PublicFactsCheckerProcessor: ) +class SelectedPreSubmitCheckerExecutionAdapter: + """Build the selected default-plus-external PRE processor from exact ART facts.""" + + def __init__(self, *, archive_inspector, external_execution) -> None: + self._archive_inspector = archive_inspector + self._external_execution = external_execution + + def build(self, request: _ExecutionRequest) -> SelectedPreSubmitProcessor: + """Reject any incomplete pre-admission identity before projecting bytes.""" + policy = getattr(request, "external_policy", None) + default_input = getattr(request, "default_checker_input", None) + attempt_id = getattr(request, "attempt_id", None) + attempt_request_digest = getattr(request, "attempt_request_digest", None) + grants = getattr(request, "external_grants", None) + if ( + policy is None + or default_input is None + or attempt_id is None + or attempt_request_digest is None + or grants is None + ): + raise PreSubmissionInfrastructureUnavailableError( + "external_pre_submit_context_unavailable" + ) + identity = PreSubmitExternalCheckerIdentity( + project_id=request.plan.lineage.project_id, + task_id=request.task_id, + assignment_id=request.assignment_id, + prepared_generation_id=request.prepared_generation_id, + attempt_id=attempt_id, + attempt_request_digest=attempt_request_digest, + effective_plan_sha256=policy.policy_sha256, + ) + material = PreSubmitExternalCheckerMaterial( + role="submission_archive", + prepared_generation_id=request.prepared_generation_id, + attempt_id=attempt_id, + attempt_request_digest=attempt_request_digest, + archive_sha256=request.commitment.sha256, + archive_byte_count=request.commitment.byte_count, + semantic_manifest_sha256=request.manifest.sha256, + media_type="application/zip", + ) + return SelectedPreSubmitProcessor( + archive_inspector=self._archive_inspector, + inspection=request.inspection, + policy=policy, + default_input=default_input, + identity=identity, + material=material, + grants=grants, + execution=self._external_execution, + ) + + def project_guide_pre_submission_catalogue() -> PreSubmissionCapabilityProjection: """Compose the canonical immutable pre-submit capabilities for guide setup.""" return project_guide_pre_submission_capabilities(build_pre_submission_checker_catalogue()) diff --git a/backend/app/modules/artifacts/post_submit_materialization.py b/backend/app/modules/artifacts/post_submit_materialization.py index f41ce3803..2239b360a 100644 --- a/backend/app/modules/artifacts/post_submit_materialization.py +++ b/backend/app/modules/artifacts/post_submit_materialization.py @@ -330,7 +330,9 @@ async def materialize( execution=facts, materialization=materialization_facts, media_type=selected.media_type, ), - reserved_bytes=manifest.total_expanded_bytes, maximum_entries=manifest.entry_count, + reserved_bytes=manifest.total_expanded_bytes, + # ART's external grant adds one owned mount around the tree. + maximum_entries=manifest.entry_count + 1, ) finally: if prepared is not None: diff --git a/backend/app/modules/artifacts/submission_materialization.py b/backend/app/modules/artifacts/submission_materialization.py index e26f1cdd5..90383af90 100644 --- a/backend/app/modules/artifacts/submission_materialization.py +++ b/backend/app/modules/artifacts/submission_materialization.py @@ -2,7 +2,9 @@ from __future__ import annotations +from contextlib import AbstractContextManager, contextmanager from dataclasses import asdict, dataclass, replace +from pathlib import Path from typing import Protocol, final from uuid import UUID @@ -10,9 +12,16 @@ from sqlalchemy.ext.asyncio import AsyncSession from app.core.hashing import canonical_json_hash +from app.interfaces.external_checker_execution import ( + ExternalCheckerMaterialGrant, +) from app.modules.artifacts.api import SubmissionBundlePreparationRequest from app.modules.artifacts.schemas import ArtifactAuthorityDeniedError -from app.modules.artifacts.preparation import ArtifactPreparationService +from app.modules.artifacts.preparation import ( + ArtifactPreparationService, + ExternalMaterialFile, + ExternalMaterialGrantRequest, +) from app.modules.artifacts.sources import PreparedArtifact from app.modules.artifacts.pre_submit_evidence import ( PreSubmitEvidenceInput, @@ -44,6 +53,16 @@ PreSubmissionInfrastructureUnavailableError, SubmissionPacketView, ) +from app.modules.checkers.api.default_checker import ( + WORKSTREAM_DEFAULT_BEHAVIOR_SHA256, + WorkstreamDefaultCheckerInput, +) +from app.modules.checkers.api.external import ( + ExternalCheckerExecutionRequest, + PreSubmitExternalCheckerIdentity, + PreSubmitExternalCheckerMaterial, +) +from app.modules.checkers.api.external_policy import LockedExternalPreSubmitPolicy from app.modules.projects.api import ProjectLockedPolicyContextPort from app.modules.tasks.api import TaskSubmissionContextPort @@ -63,6 +82,8 @@ class PreparedBundleMaterializationRequest: manifest: SubmissionManifest change_gate: SubmissionChangeGateResult packet: SubmissionPacketView + external_policy: LockedExternalPreSubmitPolicy | None = None + default_checker_input: WorkstreamDefaultCheckerInput | None = None @dataclass(frozen=True, slots=True) @@ -70,6 +91,8 @@ class PreSubmitCheckerExecutionRequest: """Exact process-local input supplied to the composition CHECKER adapter.""" plan: EffectivePreSubmissionExecutionPlan + task_id: UUID + assignment_id: UUID commitment: object inspection: SubmissionArchiveInspectionResult manifest: SubmissionManifest @@ -77,6 +100,106 @@ class PreSubmitCheckerExecutionRequest: packet: SubmissionPacketView prepared_generation_id: UUID storage_scheme: str + external_policy: LockedExternalPreSubmitPolicy | None = None + default_checker_input: WorkstreamDefaultCheckerInput | None = None + attempt_id: UUID | None = None + attempt_request_digest: str | None = None + external_grants: "PreSubmitExternalGrantPort | None" = None + + +class PreSubmitExternalGrantPort(Protocol): + """Issue one callback-scoped grant from genuine prepared ART custody.""" + + def issue( + self, + request: ExternalCheckerExecutionRequest, + workspace: Path, + ) -> AbstractContextManager[ExternalCheckerMaterialGrant]: ... + + +class _PreSubmitExternalGrantIssuer: + """Keep private prepared-artifact authority behind a typed callback port.""" + + def __init__( + self, + *, + preparation: ArtifactPreparationService, + prepared: PreparedArtifact, + request: PreparedBundleMaterializationRequest, + claim: PreSubmitAttemptClaim, + ) -> None: + self._preparation = preparation + self._prepared = prepared + self._request = request + self._claim = claim + + @contextmanager + def issue( + self, + request: ExternalCheckerExecutionRequest, + workspace: Path, + ): + """Bind the service grant to exact claim, manifest and prepared bytes.""" + checked = ExternalCheckerExecutionRequest.model_validate(request) + identity = checked.identity + source = self._request + if ( + not isinstance(identity, PreSubmitExternalCheckerIdentity) + or identity.project_id != source.effective_plan.lineage.project_id + or identity.task_id != source.task_id + or identity.assignment_id != source.assignment_id + or identity.prepared_generation_id != source.prepared_artifact.generation_id + or identity.attempt_id != self._claim.attempt_id + or identity.attempt_request_digest != self._claim.request_digest + or len(checked.materials) != 1 + or not isinstance(checked.materials[0], PreSubmitExternalCheckerMaterial) + ): + raise PreSubmitEvidenceConflict("pre_submit_external_request_invalid") + material = checked.materials[0] + commitment = source.prepared_artifact.commitment + if ( + material.prepared_generation_id != source.prepared_artifact.generation_id + or material.attempt_id != self._claim.attempt_id + or material.attempt_request_digest != self._claim.request_digest + or material.archive_sha256 != commitment.sha256 + or material.archive_byte_count != commitment.byte_count + or material.semantic_manifest_sha256 != source.manifest.sha256 + or material.media_type != commitment.media_type + ): + raise PreSubmitEvidenceConflict("pre_submit_external_material_invalid") + directories = tuple( + item.normalized_path + for item in source.manifest.entries + if item.entry_type.value == "directory" + ) + files = tuple( + ExternalMaterialFile( + normalized_path=item.normalized_path, + byte_count=item.byte_count, + sha256=item.sha256 or "", + executable=bool(item.executable), + ) + for item in source.manifest.entries + if item.entry_type.value == "file" + ) + grant_request = ExternalMaterialGrantRequest( + request_digest=checked.request_digest, + prepared_generation_id=str(identity.prepared_generation_id), + attempt_id=str(identity.attempt_id), + attempt_request_digest=identity.attempt_request_digest, + archive_sha256=material.archive_sha256, + archive_byte_count=material.archive_byte_count, + semantic_manifest_sha256=material.semantic_manifest_sha256, + directories=directories, + files=files, + ) + with self._preparation.external_material_grant( + self._prepared, workspace, grant_request + ) as grant: + yield ExternalCheckerMaterialGrant( + grant_id=grant.grant_id, + binding_digest=grant.binding_digest, + ) class PreSubmissionEvaluationPort(Protocol): @@ -261,6 +384,8 @@ async def materialize_prepared_bundle( processor = self._checker_execution.build( PreSubmitCheckerExecutionRequest( plan=request.effective_plan, + task_id=request.task_id, + assignment_id=request.assignment_id, commitment=request.prepared_artifact.commitment, inspection=request.inspection, manifest=request.manifest, @@ -268,6 +393,16 @@ async def materialize_prepared_bundle( packet=request.packet, prepared_generation_id=request.prepared_artifact.generation_id, storage_scheme=self._storage_scheme, + external_policy=request.external_policy, + default_checker_input=request.default_checker_input, + attempt_id=claim.attempt_id, + attempt_request_digest=claim.request_digest, + external_grants=_PreSubmitExternalGrantIssuer( + preparation=self._preparation, + prepared=request.prepared_artifact, + request=request, + claim=claim, + ), ), ) # Intentional friend call: this is the sole authority-gated caller, and @@ -276,7 +411,8 @@ async def materialize_prepared_bundle( request.prepared_artifact, processor, reserved_bytes=request.manifest.total_expanded_bytes, - maximum_entries=request.manifest.entry_count, + # ART's external grant nests the verified tree below one owned mount. + maximum_entries=request.manifest.entry_count + 1, ) execution = PreSubmitExecutionResult( custody=PreSubmitExecutionCustody( @@ -344,6 +480,7 @@ def _authority_facts( checker_policy_id=request.checker_policy_id, prepared_artifact=request.prepared_artifact, effective_plan=plan, + external_policy=request.external_policy, ) if ( request.manifest != request.change_gate.manifest @@ -369,6 +506,7 @@ def _preparation_facts( checker_policy_id: UUID, prepared_artifact: PreparedArtifact, effective_plan: EffectivePreSubmissionExecutionPlan, + external_policy: LockedExternalPreSubmitPolicy | None = None, ) -> PreSubmitMaterializationPreparationFacts: """Build pre-inspection facts from locked lineage and byte commitment.""" plan = effective_plan @@ -379,12 +517,26 @@ def _preparation_facts( if ( submission_artifact_policy_id != plan.lineage.effective_policy_id or checker_policy_id != plan.lineage.pre_submit_policy_id - or plan.catalogue_manifest_sha256 - != self._checker_execution.catalogue_manifest_sha256 + or ( + external_policy is None + and plan.catalogue_manifest_sha256 + != self._checker_execution.catalogue_manifest_sha256 + ) ): raise PreSubmissionInfrastructureUnavailableError( "pre_submission_materialization_context_invalid" ) + if external_policy is not None and ( + external_policy.policy_sha256 + != canonical_json_hash( + external_policy.model_dump(mode="json", exclude={"policy_sha256"}) + ) + or external_policy.workstream_default.behavior_sha256 + != WORKSTREAM_DEFAULT_BEHAVIOR_SHA256 + ): + raise PreSubmissionInfrastructureUnavailableError( + "external_pre_submit_policy_invalid" + ) commitment = prepared_artifact.commitment return PreSubmitMaterializationPreparationFacts( task_id=task_id, diff --git a/backend/app/modules/checkers/api/__init__.py b/backend/app/modules/checkers/api/__init__.py index 640ecce41..f2d393fce 100644 --- a/backend/app/modules/checkers/api/__init__.py +++ b/backend/app/modules/checkers/api/__init__.py @@ -43,6 +43,12 @@ SubmissionPacketView, validate_pre_submission_execution_facts, ) +from app.modules.checkers.api.selected_pre_submit import ( + ExternalPreSubmitIsolationFacts, + ExternalPreSubmitMemberFacts, + SelectedPreSubmitExecutionFacts, + SelectedPreSubmitInfrastructureUnavailable, +) __all__ = ( "ALLOWED_PRE_SUBMIT_STORAGE_SCHEMES", @@ -58,6 +64,10 @@ "PRE_SUBMISSION_RESULT_METADATA_KEYS", "SubmissionPacketView", "validate_pre_submission_execution_facts", + "ExternalPreSubmitIsolationFacts", + "ExternalPreSubmitMemberFacts", + "SelectedPreSubmitExecutionFacts", + "SelectedPreSubmitInfrastructureUnavailable", ) from app.modules.checkers.api.post_submit_catalogue import ( diff --git a/backend/app/modules/checkers/api/selected_pre_submit.py b/backend/app/modules/checkers/api/selected_pre_submit.py new file mode 100644 index 000000000..7f6acfe8d --- /dev/null +++ b/backend/app/modules/checkers/api/selected_pre_submit.py @@ -0,0 +1,111 @@ +"""Closed facts from the selected default-plus-external PRE execution.""" + +from __future__ import annotations + +from dataclasses import dataclass +from uuid import UUID + +from app.modules.checkers.api.default_checker import WorkstreamDefaultCheckerResult +from app.modules.checkers.api.external import ExternalCheckerExecutionResult + + +@dataclass(frozen=True, slots=True) +class ExternalPreSubmitIsolationFacts: + """Observed sandbox identity detached from the trusted service response.""" + + repository: str + platform_manifest_digest: str + platform_manifest_media_type: str + platform_manifest_byte_count: int + operating_system: str + architecture: str + config_image_id: str + runtime: str + isolation_mode: str + sandbox_uid: int + sandbox_gid: int + + +@dataclass(frozen=True, slots=True) +class ExternalPreSubmitMemberFacts: + """One completed required project PRE image in canonical policy order.""" + + order: int + requirement_id: str + registry_entry_id: UUID + registry_entry_digest: str + request_digest: str + result: ExternalCheckerExecutionResult + isolation: ExternalPreSubmitIsolationFacts + + def __post_init__(self) -> None: + if ( + type(self.order) is not int + or self.order < 0 + or not self.requirement_id + or self.result.outcome != "completed" + or self.result.request_digest != self.request_digest + or self.result.registry_entry_id != self.registry_entry_id + or self.result.registry_entry_digest != self.registry_entry_digest + ): + raise ValueError("external PRE member facts are invalid") + + +@dataclass(frozen=True, slots=True) +class SelectedPreSubmitExecutionFacts: + """One default result followed by the executed required external prefix.""" + + policy_sha256: str + workstream_default: WorkstreamDefaultCheckerResult + required_external_count: int + external_members: tuple[ExternalPreSubmitMemberFacts, ...] + eligible: bool + + def __post_init__(self) -> None: + members = self.external_members + if ( + not self.policy_sha256.startswith("sha256:") + or len(self.policy_sha256) != 71 + or type(self.required_external_count) is not int + or self.required_external_count < 0 + or tuple(item.order for item in members) != tuple(range(len(members))) + or len({item.requirement_id for item in members}) != len(members) + or len(members) > self.required_external_count + ): + raise ValueError("selected PRE execution facts are invalid") + external_passed = all(item.result.verdict == "passed" for item in members) + complete = len(members) == self.required_external_count + if self.eligible != ( + self.workstream_default.eligible and complete and external_passed + ): + raise ValueError("selected PRE eligibility differs from required results") + if ( + not self.workstream_default.eligible + and members + or any(item.result.verdict == "failed" for item in members[:-1]) + ): + raise ValueError("selected PRE execution continued after a blocker") + + +class SelectedPreSubmitInfrastructureUnavailable(RuntimeError): + """Retain a recoverable PRE infrastructure category, never a work failure.""" + + def __init__(self, code: str) -> None: + if code not in { + "capacity_exceeded", + "deadline_exceeded", + "material_unavailable", + "implementation_unavailable", + "invalid_output", + }: + raise ValueError("selected PRE infrastructure failure is invalid") + self.code = code + super().__init__(code) + + +__all__ = ( + "ExternalPreSubmitIsolationFacts", + "ExternalPreSubmitMemberFacts", + "SelectedPreSubmitExecutionFacts", + "SelectedPreSubmitInfrastructureUnavailable", +) diff --git a/backend/app/modules/checkers/selected_pre_submit_execution.py b/backend/app/modules/checkers/selected_pre_submit_execution.py new file mode 100644 index 000000000..e71d89a80 --- /dev/null +++ b/backend/app/modules/checkers/selected_pre_submit_execution.py @@ -0,0 +1,228 @@ +"""Selected default-plus-external PRE execution over one ART callback.""" + +from __future__ import annotations + +import asyncio +from dataclasses import asdict + +from app.core.cancellation import await_cancellation_resistant +from app.interfaces.external_checker_execution import ExternalCheckerExecutionAdapter +from app.interfaces.external_services import ( + ExternalServiceProtocolError, + ExternalServiceUnavailableError, +) +from app.modules.artifacts.preparation import ArtifactScratchIntegrityError +from app.modules.artifacts.submission_archive import SealedSubmissionTree +from app.modules.checkers.api.default_checker import WorkstreamDefaultCheckerInput +from app.modules.checkers.api.external import ( + PreSubmitExternalCheckerIdentity, + PreSubmitExternalCheckerMaterial, + external_checker_json_hash, + make_external_checker_execution_request, +) +from app.modules.checkers.api.external_policy import LockedExternalPreSubmitPolicy +from app.modules.checkers.api.materialization import SubmissionMaterialEntry +from app.modules.checkers.api.selected_pre_submit import ( + ExternalPreSubmitIsolationFacts, + ExternalPreSubmitMemberFacts, + SelectedPreSubmitExecutionFacts, + SelectedPreSubmitInfrastructureUnavailable, +) +from app.modules.checkers.default_checker import ( + WorkstreamDefaultCheckerUnavailable, + evaluate_verified_archive, +) + + +class _PreSubmitMaterialView: + """Keep verified reads and the opaque PRE grant inside one ART callback.""" + + def __init__(self, tree, *, grants, workspace) -> None: + self._tree, self._grants, self._workspace = tree, grants, workspace + self._closed = False + + def close(self) -> None: + self._closed = True + + def _require_open(self) -> None: + if self._closed: + raise RuntimeError("pre-submit material view is closed") + + @property + def entries(self) -> tuple[SubmissionMaterialEntry, ...]: + self._require_open() + return tuple( + SubmissionMaterialEntry( + item.normalized_path, + item.entry_type.value, + item.byte_count, + item.sha256, + item.executable, + ) + for item in self._tree.entries + ) + + def read_file(self, normalized_path: str, *, maximum_bytes: int) -> bytes: + self._require_open() + return self._tree.read_file(normalized_path, maximum_bytes=maximum_bytes) + + def external_checker_grant(self, request): + self._require_open() + return self._grants.issue(request, self._workspace) + + +def _input_body( + *, + requirement_id: str, + identity: PreSubmitExternalCheckerIdentity, + material: PreSubmitExternalCheckerMaterial, + value: WorkstreamDefaultCheckerInput, +) -> dict[str, object]: + """Build the one normalized public PRE image input from verified facts.""" + return { + "schema_version": "workstream.external_checker_pre_submit_input.v1", + "requirement_id": requirement_id, + "project_id": str(identity.project_id), + "task_id": str(identity.task_id), + "assignment_id": str(identity.assignment_id), + "archive_sha256": material.archive_sha256, + "archive_byte_count": material.archive_byte_count, + "semantic_manifest_sha256": material.semantic_manifest_sha256, + "manifest": [asdict(item) for item in value.entries], + "packet": { + "summary": value.packet.summary, + "contributor_attestation": value.packet.contributor_attestation, + }, + } + + +class SelectedPreSubmitProcessor: + """Run the default and every required locked external PRE image in order.""" + + def __init__( + self, + *, + archive_inspector, + inspection, + policy: LockedExternalPreSubmitPolicy, + default_input: WorkstreamDefaultCheckerInput, + identity: PreSubmitExternalCheckerIdentity, + material: PreSubmitExternalCheckerMaterial, + grants, + execution: ExternalCheckerExecutionAdapter, + ) -> None: + self._inspector, self._inspection = archive_inspector, inspection + self._policy, self._default_input = policy, default_input + self._identity, self._material = identity, material + self._grants, self._execution = grants, execution + self._aborted = False + self._active: asyncio.Task | None = None + self._view: _PreSubmitMaterialView | None = None + + def abort(self) -> None: + """Revoke callback access and cancel the active default/image invocation.""" + self._aborted = True + if self._view is not None: + self._view.close() + if self._active is not None: + self._active.cancel() + + async def process(self, reader, workspace) -> SelectedPreSubmitExecutionFacts: + """Project once, execute outside DB, and drain ART cleanup before return.""" + projection = self._inspector._projected_tree( + reader, workspace, expected=self._inspection + ) + tree: SealedSubmissionTree = await asyncio.to_thread(projection.__enter__) + try: + if self._aborted: + raise asyncio.CancelledError + self._view = _PreSubmitMaterialView( + tree, grants=self._grants, workspace=workspace + ) + self._active = asyncio.create_task( + asyncio.to_thread( + evaluate_verified_archive, self._default_input, self._view + ) + ) + default = await self._active + members: list[ExternalPreSubmitMemberFacts] = [] + if default.eligible: + for order, binding in enumerate(self._policy.entries): + if self._aborted: + raise asyncio.CancelledError + input_value = _input_body( + requirement_id=binding.requirement_id, + identity=self._identity, + material=self._material, + value=self._default_input, + ) + request = make_external_checker_execution_request( + registry=binding.registry, + identity=self._identity, + configuration=binding.configuration, + configuration_sha256=binding.configuration_sha256, + input=input_value, + input_sha256=external_checker_json_hash(input_value), + materials=(self._material,), + ) + with self._view.external_checker_grant(request) as grant: + self._active = asyncio.create_task( + self._execution.execute(request, grant) + ) + response = await self._active + result = response.result + if result.outcome == "infrastructure_failed": + raise SelectedPreSubmitInfrastructureUnavailable( + result.infrastructure_failure_code or "invalid_output" + ) + if response.isolation is None: + raise SelectedPreSubmitInfrastructureUnavailable("invalid_output") + member = ExternalPreSubmitMemberFacts( + order=order, + requirement_id=binding.requirement_id, + registry_entry_id=binding.registry.registry_entry_id, + registry_entry_digest=binding.registry.entry_digest, + request_digest=request.request_digest, + result=result, + isolation=ExternalPreSubmitIsolationFacts( + **asdict(response.isolation) + ), + ) + members.append(member) + if result.verdict == "failed": + break + eligible = default.eligible and len(members) == len(self._policy.entries) and all( + item.result.verdict == "passed" for item in members + ) + return SelectedPreSubmitExecutionFacts( + policy_sha256=self._policy.policy_sha256, + workstream_default=default, + required_external_count=len(self._policy.entries), + external_members=tuple(members), + eligible=eligible, + ) + except WorkstreamDefaultCheckerUnavailable as exc: + raise SelectedPreSubmitInfrastructureUnavailable("material_unavailable") from exc + except ExternalServiceUnavailableError as exc: + raise SelectedPreSubmitInfrastructureUnavailable( + "implementation_unavailable" + ) from exc + except ExternalServiceProtocolError as exc: + raise SelectedPreSubmitInfrastructureUnavailable("invalid_output") from exc + finally: + if self._view is not None: + self._view.close() + self._active = None + try: + await await_cancellation_resistant( + asyncio.to_thread(projection.__exit__, None, None, None) + ) + except ArtifactScratchIntegrityError: + raise + except Exception: + raise ArtifactScratchIntegrityError( + "pre_submit_projection_cleanup_unconfirmed" + ) from None + + +__all__ = ("SelectedPreSubmitProcessor",) diff --git a/backend/app/modules/projects/api/locked_policy.py b/backend/app/modules/projects/api/locked_policy.py index 3f7436369..3970867ae 100644 --- a/backend/app/modules/projects/api/locked_policy.py +++ b/backend/app/modules/projects/api/locked_policy.py @@ -169,6 +169,7 @@ class ProjectLockedPolicyContextFacts: activation_receipt: GuideActivationReceipt artifact_policy: CanonicalJsonObject compiled_post_submit_policy: CanonicalJsonObject + external_checker_policies: CanonicalJsonObject review_policy: CanonicalJsonObject review_semantics_format: ReviewSemanticsFormat revision_policy: CanonicalJsonObject @@ -200,6 +201,7 @@ def __post_init__(self) -> None: self.compiled_pre_submit_bundle, self.artifact_policy, self.compiled_post_submit_policy, + self.external_checker_policies, self.review_policy, self.revision_policy, ) @@ -251,6 +253,8 @@ def __post_init__(self) -> None: or self.compiled_pre_submit_bundle.sha256 != self.pre_submit_policy_bundle_hash or self.artifact_policy.sha256 != target.artifact_policy_hash or self.compiled_post_submit_policy.sha256 != receipt.command.target.policy_hash + or self.external_checker_policies.sha256 + != receipt.command.target.upstream.effective_pre_submit_plan_hash ): raise ValueError("project locked policy facts differ from activation") require_complete_policy( diff --git a/backend/app/modules/projects/locked_policy_projection.py b/backend/app/modules/projects/locked_policy_projection.py index 5210e4140..b3435bebe 100644 --- a/backend/app/modules/projects/locked_policy_projection.py +++ b/backend/app/modules/projects/locked_policy_projection.py @@ -73,6 +73,9 @@ def complete_context(locked, post_policy, post_custody, receipt, review, revisio activation_receipt=receipt, artifact_policy=CanonicalJsonObject.from_mapping(view.policy.policy_body), compiled_post_submit_policy=CanonicalJsonObject.from_mapping(post_policy.policy_body), + external_checker_policies=CanonicalJsonObject.from_mapping( + approval.operation.effective_pre_submit_plan + ), review_policy=_policy_body("review", review, command.review, view.guide), review_semantics_format=review.semantics_format, revision_policy=_policy_body("revision", revision, command.revision, view.guide), diff --git a/backend/tests/checkers/external/test_selected_pre_submit.py b/backend/tests/checkers/external/test_selected_pre_submit.py new file mode 100644 index 000000000..63ae687eb --- /dev/null +++ b/backend/tests/checkers/external/test_selected_pre_submit.py @@ -0,0 +1,394 @@ +"""Selected default and project PRE images share one verified ART callback.""" + +from __future__ import annotations + +from contextlib import contextmanager +from dataclasses import replace +from types import SimpleNamespace +from unittest.mock import AsyncMock +import pytest + +from app.core.hashing import canonical_json_hash +from app.core.identifiers import new_record_id +from app.interfaces.external_checker_execution import ( + ExternalCheckerExecutionResponse, + ExternalCheckerIsolationReceipt, + ExternalCheckerMaterialGrant, +) +from app.modules.checkers.api.default_checker import WorkstreamDefaultCheckerInput +from app.modules.checkers.api.external import ( + PRE_SUBMIT_INPUT_SCHEMA_ID, + ExternalCheckerRegistryEntry, + ExternalCheckerSchema, + PreSubmitExternalCheckerIdentity, + PreSubmitExternalCheckerMaterial, + external_checker_json_hash, + make_external_checker_execution_result, +) +from app.modules.checkers.api.external_policy import ( + LockedExternalCheckerBinding, + LockedExternalPreSubmitPolicy, + LockedWorkstreamDefault, +) +from app.modules.checkers.api.materialization import SubmissionMaterialEntry +from app.modules.checkers.selected_pre_submit_execution import SelectedPreSubmitProcessor +from app.adapters.checkers import SelectedPreSubmitCheckerExecutionAdapter +from app.modules.artifacts.pre_submit_attempts import PreSubmitAttemptClaim +from app.modules.artifacts.submission_materialization import ( + PreparedBundleMaterializationService, +) +from app.modules.checkers.api.pre_submit import SubmissionPacketView +from tests.checkers.external.support import SHA, registry_entry +from tests.test_default_pre_submit_execution import _request + + +def _open_input_schema() -> ExternalCheckerSchema: + document = {"type": "object"} + return ExternalCheckerSchema( + schema_id=PRE_SUBMIT_INPUT_SCHEMA_ID, + schema_version="v1", + document=document, + schema_sha256=external_checker_json_hash(document), + ) + + +def _policy() -> LockedExternalPreSubmitPolicy: + values = registry_entry().model_dump() + values["input_schema"] = _open_input_schema() + # The immutable entry digest includes the input schema. + spec = { + key: value + for key, value in values.items() + if key + not in { + "registry_entry_id", + "entry_digest", + "registration_operation_id", + "registered_by_actor_profile_id", + "authorization_decision_event_id", + "created_at", + } + } + spec["input_schema"] = values["input_schema"].model_dump(mode="json") + values["entry_digest"] = external_checker_json_hash(spec) + registry = ExternalCheckerRegistryEntry.model_validate(values) + binding = LockedExternalCheckerBinding( + requirement_id="project.archive_rules", + stage="pre_submit", + registry=registry, + configuration={}, + configuration_sha256=external_checker_json_hash({}), + ) + default = LockedWorkstreamDefault() + body = { + "schema_version": "external_pre_submit_policy.v1", + "workstream_default": default.model_dump(mode="json"), + "entries": [binding.model_dump(mode="json")], + } + return LockedExternalPreSubmitPolicy( + workstream_default=default, + entries=(binding,), + policy_sha256=canonical_json_hash(body), + ) + + +class _GrantIssuer: + def __init__(self) -> None: + self.requests = [] + + @contextmanager + def issue(self, request, _workspace): + self.requests.append(request) + yield ExternalCheckerMaterialGrant( + grant_id="extract_" + "a" * 32, + binding_digest="sha256:" + "b" * 64, + ) + + +class _Execution: + def __init__(self, verdict: str) -> None: + self.verdict = verdict + self.requests = [] + + async def execute(self, request, _grant): + self.requests.append(request) + findings = ( + () + if self.verdict == "passed" + else ( + { + "code": "project_rule_failed", + "level": "error", + "message": "Project rule failed.", + }, + ) + ) + result = make_external_checker_execution_result( + request_digest=request.request_digest, + registry_entry_id=request.registry.registry_entry_id, + registry_entry_digest=request.registry.entry_digest, + phase="pre_submit", + outcome="completed", + verdict=self.verdict, + findings=findings, + infrastructure_failure_code=None, + ) + return ExternalCheckerExecutionResponse( + result=result, + isolation=ExternalCheckerIsolationReceipt( + repository="registry.example/workstream/checker", + platform_manifest_digest=request.registry.image_digest, + platform_manifest_media_type=( + "application/vnd.oci.image.manifest.v1+json" + ), + platform_manifest_byte_count=1024, + operating_system="linux", + architecture="amd64", + config_image_id=SHA, + runtime="runsc", + isolation_mode="gvisor", + sandbox_uid=65532, + sandbox_gid=65532, + ), + ) + + +@pytest.mark.asyncio +@pytest.mark.parametrize("verdict,eligible", [("passed", True), ("failed", False)]) +async def test_selected_pre_runs_default_then_locked_external_image( + tmp_path, verdict: str, eligible: bool +) -> None: + request, inspector, manager, preparation, _catalogue = await _request(tmp_path) + policy = _policy() + identity = PreSubmitExternalCheckerIdentity( + project_id=request.effective_plan.lineage.project_id, + task_id=request.task_id, + assignment_id=request.assignment_id, + prepared_generation_id=request.prepared_artifact.generation_id, + attempt_id=new_record_id(), + attempt_request_digest=SHA, + effective_plan_sha256=policy.policy_sha256, + ) + material = PreSubmitExternalCheckerMaterial( + role="submission_archive", + prepared_generation_id=identity.prepared_generation_id, + attempt_id=identity.attempt_id, + attempt_request_digest=identity.attempt_request_digest, + archive_sha256=request.prepared_artifact.commitment.sha256, + archive_byte_count=request.prepared_artifact.commitment.byte_count, + semantic_manifest_sha256=request.manifest.sha256, + media_type="application/zip", + ) + entries = tuple( + SubmissionMaterialEntry( + item.normalized_path, + item.entry_type.value, + item.byte_count, + item.sha256, + item.executable, + ) + for item in request.manifest.entries + ) + default_input = WorkstreamDefaultCheckerInput( + archive_sha256=material.archive_sha256, + archive_byte_count=material.archive_byte_count, + archive_media_type=material.media_type, + semantic_manifest_sha256=material.semantic_manifest_sha256, + entries=entries, + predecessor=None, + predecessor_exists=False, + current_predecessor=None, + current_rules_sha256=request.effective_plan.lineage.pre_submit_policy_bundle_hash, + predecessor_rules_sha256=None, + packet=SubmissionPacketView(summary="", contributor_attestation=""), + ) + grants, execution = _GrantIssuer(), _Execution(verdict) + processor = SelectedPreSubmitProcessor( + archive_inspector=inspector, + inspection=request.inspection, + policy=policy, + default_input=default_input, + identity=identity, + material=material, + grants=grants, + execution=execution, + ) + try: + result = await preparation._process_prepared_submission( + request.prepared_artifact, + processor, + reserved_bytes=request.manifest.total_expanded_bytes, + maximum_entries=request.manifest.entry_count, + ) + assert result.eligible is eligible + assert result.workstream_default.eligible + assert [item.code for item in result.workstream_default.warnings] == [ + "submission_summary_missing", + "submission_attestation_missing", + ] + assert len(result.external_members) == 1 + assert result.external_members[0].result.verdict == verdict + assert len(grants.requests) == len(execution.requests) == 1 + assert grants.requests[0].request_digest == execution.requests[0].request_digest + finally: + await request.prepared_artifact.close() + manager.close() + + +@pytest.mark.asyncio +async def test_selected_pre_default_secret_blocker_precedes_external_image( + tmp_path, +) -> None: + request, inspector, manager, preparation, _catalogue = await _request( + tmp_path, + primary_bytes=b"-----BEGIN OPENSSH PRIVATE KEY-----\nencoded", + ) + policy = _policy() + identity = PreSubmitExternalCheckerIdentity( + project_id=request.effective_plan.lineage.project_id, + task_id=request.task_id, + assignment_id=request.assignment_id, + prepared_generation_id=request.prepared_artifact.generation_id, + attempt_id=new_record_id(), + attempt_request_digest=SHA, + effective_plan_sha256=policy.policy_sha256, + ) + material = PreSubmitExternalCheckerMaterial( + role="submission_archive", + prepared_generation_id=identity.prepared_generation_id, + attempt_id=identity.attempt_id, + attempt_request_digest=identity.attempt_request_digest, + archive_sha256=request.prepared_artifact.commitment.sha256, + archive_byte_count=request.prepared_artifact.commitment.byte_count, + semantic_manifest_sha256=request.manifest.sha256, + media_type="application/zip", + ) + entries = tuple( + SubmissionMaterialEntry( + item.normalized_path, + item.entry_type.value, + item.byte_count, + item.sha256, + item.executable, + ) + for item in request.manifest.entries + ) + execution = _Execution("passed") + grants = _GrantIssuer() + processor = SelectedPreSubmitProcessor( + archive_inspector=inspector, + inspection=request.inspection, + policy=policy, + default_input=WorkstreamDefaultCheckerInput( + archive_sha256=material.archive_sha256, + archive_byte_count=material.archive_byte_count, + archive_media_type=material.media_type, + semantic_manifest_sha256=material.semantic_manifest_sha256, + entries=entries, + predecessor=None, + predecessor_exists=False, + current_predecessor=None, + current_rules_sha256=request.effective_plan.lineage.pre_submit_policy_bundle_hash, + predecessor_rules_sha256=None, + packet=request.packet, + ), + identity=identity, + material=material, + grants=grants, + execution=execution, + ) + try: + result = await preparation._process_prepared_submission( + request.prepared_artifact, + processor, + reserved_bytes=request.manifest.total_expanded_bytes, + maximum_entries=request.manifest.entry_count, + ) + assert result.eligible is False + assert result.workstream_default.checks[2].failure_code == ( + "high_confidence_secret_detected" + ) + assert result.external_members == () + assert grants.requests == [] + assert execution.requests == [] + finally: + await request.prepared_artifact.close() + manager.close() + + +@pytest.mark.asyncio +async def test_selected_factory_uses_request_bound_art_grant(tmp_path) -> None: + request, inspector, manager, preparation, _catalogue = await _request(tmp_path) + policy = _policy() + entries = tuple( + SubmissionMaterialEntry( + item.normalized_path, + item.entry_type.value, + item.byte_count, + item.sha256, + item.executable, + ) + for item in request.manifest.entries + ) + request = replace( + request, + external_policy=policy, + default_checker_input=WorkstreamDefaultCheckerInput( + archive_sha256=request.prepared_artifact.commitment.sha256, + archive_byte_count=request.prepared_artifact.commitment.byte_count, + archive_media_type="application/zip", + semantic_manifest_sha256=request.manifest.sha256, + entries=entries, + predecessor=None, + predecessor_exists=False, + current_predecessor=None, + current_rules_sha256=request.effective_plan.lineage.pre_submit_policy_bundle_hash, + predecessor_rules_sha256=None, + packet=request.packet, + ), + ) + transaction = True + claim = object.__new__(PreSubmitAttemptClaim) + claim.attempt_id, claim._nonce = new_record_id(), new_record_id() + claim.request_digest = SHA + claim._request = replace(request, prepared_authorization=None) + claim._started, claim._execution = False, None + row = SimpleNamespace( + status="reserved", + evidence_set_id=None, + claim_nonce=str(claim._nonce), + request_digest=claim.request_digest, + prepared_generation_id=str(request.prepared_artifact.generation_id), + ) + session = SimpleNamespace( + in_transaction=lambda: transaction, + in_nested_transaction=lambda: False, + scalar=AsyncMock(return_value=row), + ) + claim._session = session + execution = _Execution("passed") + service = PreparedBundleMaterializationService( + session=session, + authorization=SimpleNamespace(consume=AsyncMock()), + preparation=preparation, + checker_execution=SelectedPreSubmitCheckerExecutionAdapter( + archive_inspector=inspector, + external_execution=execution, + ), + storage_scheme="s3", + ) + try: + await service.authorize_prepared_bundle(request, claim=claim) + transaction = False + result = await service.materialize_prepared_bundle( + replace(request, prepared_authorization=None), claim=claim + ) + assert result.checker_facts.eligible is True + assert len(execution.requests) == 1 + assert execution.requests[0].identity.attempt_id == claim.attempt_id + assert execution.requests[0].materials[0].archive_sha256 == ( + request.prepared_artifact.commitment.sha256 + ) + finally: + await request.prepared_artifact.close() + manager.close() diff --git a/backend/tests/test_default_pre_submit_execution.py b/backend/tests/test_default_pre_submit_execution.py index 5acddc857..0750feabb 100644 --- a/backend/tests/test_default_pre_submit_execution.py +++ b/backend/tests/test_default_pre_submit_execution.py @@ -137,7 +137,13 @@ async def test_evidence_workflow_requires_transaction_free_session() -> None: ) -def _archive(path: str = "task.toml", *, extra_path: str | None = None, evidence_path="evidence/results") -> bytes: +def _archive( + path: str = "task.toml", + *, + primary_bytes: bytes = b"[task]\nname='proof'\n", + extra_path: str | None = None, + evidence_path="evidence/results", +) -> bytes: output = BytesIO() with zipfile.ZipFile(output, "w") as archive: @@ -145,7 +151,7 @@ def write(name: str, value: bytes) -> None: entry = zipfile.ZipInfo(name, date_time=(1980, 1, 1, 0, 0, 0)) archive.writestr(entry, value) - write(path, b"[task]\nname='proof'\n") + write(path, primary_bytes) if extra_path is not None: write(extra_path, b"blocked\n") if path != evidence_path: @@ -257,6 +263,7 @@ async def _request( tmp_path: Path, *, path: str = "task.toml", + primary_bytes: bytes = b"[task]\nname='proof'\n", extra_path: str | None = None, catalogue=None, plan=None, @@ -264,7 +271,12 @@ async def _request( ): selected_catalogue = catalogue or build_pre_submission_checker_catalogue() plan = _plan(selected_catalogue) if plan is None else plan - data = _archive(path, extra_path=extra_path, evidence_path=evidence_path) + data = _archive( + path, + primary_bytes=primary_bytes, + extra_path=extra_path, + evidence_path=evidence_path, + ) inspector = SubmissionArchiveInspector(SubmissionArchiveLimits()) manager = ArtifactScratchManager(root=tmp_path / "scratch", limits=_limits()) preparation = ArtifactPreparationService(manager) From dd208d71566e3324e8f5e4d96c34759fbe23a88b Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 18:53:29 +0100 Subject: [PATCH 056/283] [PILOT-04] Carry selected policy into authority --- .../artifacts/submission_materialization.py | 3 +++ .../external/test_selected_pre_submit.py | 17 ++++++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/backend/app/modules/artifacts/submission_materialization.py b/backend/app/modules/artifacts/submission_materialization.py index 90383af90..018c36c41 100644 --- a/backend/app/modules/artifacts/submission_materialization.py +++ b/backend/app/modules/artifacts/submission_materialization.py @@ -452,6 +452,7 @@ async def prepare_authorization( prepared_artifact: PreparedArtifact, effective_plan: EffectivePreSubmissionExecutionPlan, idempotency_key: UUID, + external_policy: LockedExternalPreSubmitPolicy | None = None, ) -> object: """Deny unavailable service authority before inspecting the ZIP.""" facts = self._preparation_facts( @@ -461,6 +462,7 @@ async def prepare_authorization( checker_policy_id=checker_policy_id, prepared_artifact=prepared_artifact, effective_plan=effective_plan, + external_policy=external_policy, ) return await self._authorization.prepare( facts=facts, @@ -665,6 +667,7 @@ async def execute_reserved( prepared_artifact=request.prepared_artifact, effective_plan=request.effective_plan, idempotency_key=preparation_request.idempotency_key, + external_policy=request.external_policy, ) authorized_request = replace(request, prepared_authorization=handle) await self._materialization.authorize_prepared_bundle( diff --git a/backend/tests/checkers/external/test_selected_pre_submit.py b/backend/tests/checkers/external/test_selected_pre_submit.py index 63ae687eb..de4e61fdb 100644 --- a/backend/tests/checkers/external/test_selected_pre_submit.py +++ b/backend/tests/checkers/external/test_selected_pre_submit.py @@ -367,9 +367,13 @@ async def test_selected_factory_uses_request_bound_art_grant(tmp_path) -> None: ) claim._session = session execution = _Execution("passed") + authority = SimpleNamespace( + prepare=AsyncMock(return_value=object()), + consume=AsyncMock(), + ) service = PreparedBundleMaterializationService( session=session, - authorization=SimpleNamespace(consume=AsyncMock()), + authorization=authority, preparation=preparation, checker_execution=SelectedPreSubmitCheckerExecutionAdapter( archive_inspector=inspector, @@ -378,6 +382,17 @@ async def test_selected_factory_uses_request_bound_art_grant(tmp_path) -> None: storage_scheme="s3", ) try: + await service.prepare_authorization( + task_id=request.task_id, + assignment_id=request.assignment_id, + submission_artifact_policy_id=request.submission_artifact_policy_id, + checker_policy_id=request.checker_policy_id, + prepared_artifact=request.prepared_artifact, + effective_plan=request.effective_plan, + idempotency_key=new_record_id(), + external_policy=policy, + ) + assert authority.prepare.await_count == 1 await service.authorize_prepared_bundle(request, claim=claim) transaction = False result = await service.materialize_prepared_bundle( From 249c822e0c907ac0d9226d6b579304e50ea781fc Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 18:59:12 +0100 Subject: [PATCH 057/283] [PILOT-04] Bind unchanged work to the default checker --- .../pilot04-workstream-default-checker.md | 6 +- .../selected_pre_submit_admission.py | 112 ++++++++++++++++++ .../modules/artifacts/submission_manifest.py | 42 ++++++- .../external/test_selected_pre_submit.py | 82 +++++++++++++ backend/tests/test_submission_change_gate.py | 11 ++ 5 files changed, 247 insertions(+), 6 deletions(-) create mode 100644 backend/app/modules/artifacts/selected_pre_submit_admission.py diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 2fa703319..d693623e0 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -22,7 +22,10 @@ long-lived Rust service and SDK, typed Unix-socket client, callback-scoped ART grant, and the exact four-behavior Workstream default checker. The selected PRE processor now runs the default before each locked external image over one genuine prepared-ART callback, but its durable result and admission caller are -not selected yet. Production still uses the older pre/post catalogues. +not selected yet. The admission binder now carries an unchanged byte/manifest +comparison into the default checker with exact predecessor and current locked +rules instead of treating that default behavior as an early ART rejection. +Production still uses the older pre/post catalogues. ## Bounded change @@ -171,6 +174,7 @@ intermediate-wait regression. | Existing component custody | Prior PR538 default, Rust service/SDK, ART callback and contract reviews | Passed at recorded component heads | Final selected flow/current-main integration pending | | PRE transaction boundary | `pytest -q` for invalid claim controls and `test_checker_processor_starts_only_after_authority_transaction_commits`, plus Ruff on the four affected files | 5 passed; processor construction is refused while the authority root is active and reached only after it commits | Durable lease/generation schema and selected external sequence remain pending | | Selected PRE callback | `pytest -q backend/tests/checkers/external/test_selected_pre_submit.py`; Ruff and `git diff --check` on the affected files | 4 passed; exact default runs first, a real high-confidence secret prevents every external invocation, locked external pass/fail is retained, and the genuine request-bound ART grant completes cleanup with one bounded owned mount | Durable persistence, admission composition, crash recovery and native service journey remain pending | +| Selected admission binding | `pytest -q backend/tests/test_submission_change_gate.py backend/tests/checkers/external/test_selected_pre_submit.py`; Ruff and `git diff --check` on the affected files | 11 passed; existing callers retain their exact archive/manifest rejection while the selected binder carries unchanged work plus exact predecessor/current rules into the default checker | The binder is not yet selected by the durable admission caller | | Owner/caller trace | PROJECT approval/activation, ART preparation/admission, TASK composition and CHECKERS dispatch | In progress | Persistence delta and migration ordinal await actual linear predecessor | | End-to-end replacement | Real PostgreSQL/MinIO/Rust public and worker journey | Not run | Implementation incomplete | diff --git a/backend/app/modules/artifacts/selected_pre_submit_admission.py b/backend/app/modules/artifacts/selected_pre_submit_admission.py new file mode 100644 index 000000000..b56c6d8db --- /dev/null +++ b/backend/app/modules/artifacts/selected_pre_submit_admission.py @@ -0,0 +1,112 @@ +"""Bind selected PRE policy and default inputs to locked TASK/PROJECT custody.""" + +from __future__ import annotations + +from dataclasses import dataclass + +from app.core.hashing import canonical_json_hash +from app.modules.artifacts.sources import ArtifactCommitment +from app.modules.artifacts.submission_manifest import ( + SubmissionCanonicalPredecessor, + SubmissionChangeGateResult, + SubmissionManifest, + bind_submission_change, +) +from app.modules.checkers.api.default_checker import ( + WorkstreamDefaultCheckerInput, + WorkstreamDefaultPredecessor, +) +from app.modules.checkers.api.external_policy import ( + LockedExternalCheckerPolicies, + LockedExternalPreSubmitPolicy, +) +from app.modules.checkers.api.materialization import SubmissionMaterialEntry +from app.modules.checkers.api.pre_submit import SubmissionPacketView +from app.modules.projects.api import ProjectLockedPolicyContextFacts +from app.modules.tasks.api import TaskSubmissionContextFacts + + +@dataclass(frozen=True, slots=True) +class SelectedPreSubmitAdmissionContext: + """Exact selected policy, default input and non-deciding change binding.""" + + policy: LockedExternalPreSubmitPolicy + default_input: WorkstreamDefaultCheckerInput + change_gate: SubmissionChangeGateResult + rules_sha256: str + + +def bind_selected_pre_submit_admission( + *, + task: TaskSubmissionContextFacts, + project: ProjectLockedPolicyContextFacts, + commitment: ArtifactCommitment, + manifest: SubmissionManifest, + predecessor: SubmissionCanonicalPredecessor | None, + predecessor_rules_sha256: str | None, + predecessor_exists: bool, + packet: SubmissionPacketView, +) -> SelectedPreSubmitAdmissionContext: + """Bind genuine locked policy and predecessor facts before CHECKER execution.""" + if project.project_id != task.locked_project_context.project_id: + raise ValueError("selected PRE task and project contexts differ") + policies = LockedExternalCheckerPolicies.model_validate_json( + project.external_checker_policies.value + ) + rules_sha256 = canonical_json_hash( + { + "schema_version": "workstream.task_checker_rules.v1", + "task_policy": task.locked_policy.model_dump(mode="json"), + "external_checker_policies_sha256": policies.policies_sha256, + } + ) + default_predecessor = ( + WorkstreamDefaultPredecessor( + submission_id=predecessor.submission_id, + submission_version=predecessor.submission_version, + archive_sha256=predecessor.archive_sha256, + semantic_manifest_sha256=predecessor.semantic_manifest_sha256, + ) + if predecessor is not None + else None + ) + if (predecessor_rules_sha256 is None) != (predecessor is None): + raise ValueError("selected PRE predecessor rules are incomplete") + change_gate = bind_submission_change( + commitment=commitment, + manifest=manifest, + predecessor=predecessor, + predecessor_exists=predecessor_exists, + current_predecessor=predecessor, + ) + entries = tuple( + SubmissionMaterialEntry( + normalized_path=item.normalized_path, + entry_type=item.entry_type.value, + byte_count=item.byte_count, + sha256=item.sha256, + executable=item.executable, + ) + for item in manifest.entries + ) + return SelectedPreSubmitAdmissionContext( + policy=policies.pre_submit, + default_input=WorkstreamDefaultCheckerInput( + archive_sha256=commitment.sha256, + archive_byte_count=commitment.byte_count, + archive_media_type=commitment.media_type, + semantic_manifest_sha256=manifest.sha256, + entries=entries, + predecessor=default_predecessor, + predecessor_exists=predecessor_exists, + current_predecessor=default_predecessor, + current_rules_sha256=rules_sha256, + predecessor_rules_sha256=predecessor_rules_sha256, + packet=packet, + ), + change_gate=change_gate, + rules_sha256=rules_sha256, + ) + + +__all__ = ("SelectedPreSubmitAdmissionContext", "bind_selected_pre_submit_admission") diff --git a/backend/app/modules/artifacts/submission_manifest.py b/backend/app/modules/artifacts/submission_manifest.py index ae39956e4..527e38423 100644 --- a/backend/app/modules/artifacts/submission_manifest.py +++ b/backend/app/modules/artifacts/submission_manifest.py @@ -44,6 +44,7 @@ class SubmissionChangeOutcome(StrEnum): FIRST_SUBMISSION = "first_submission" CHANGED = "changed" + UNCHANGED = "unchanged" @dataclass(frozen=True, slots=True) @@ -240,6 +241,33 @@ def evaluate_submission_change( current_predecessor: SubmissionCanonicalPredecessor | None = None, ) -> SubmissionChangeGateResult: """Compare server-owned identities without performing any durable effect.""" + result = bind_submission_change( + commitment=commitment, + manifest=manifest, + predecessor=predecessor, + predecessor_exists=predecessor_exists, + current_predecessor=current_predecessor, + ) + if result.outcome is SubmissionChangeOutcome.UNCHANGED: + assert predecessor is not None + code = ( + SubmissionChangeFailureCode.ARCHIVE_UNCHANGED + if commitment.sha256 == predecessor.archive_sha256 + else SubmissionChangeFailureCode.MANIFEST_UNCHANGED + ) + raise SubmissionChangeRejectedError(code) + return result + + +def bind_submission_change( + *, + commitment: ArtifactCommitment, + manifest: SubmissionManifest, + predecessor: SubmissionCanonicalPredecessor | None, + predecessor_exists: bool, + current_predecessor: SubmissionCanonicalPredecessor | None = None, +) -> SubmissionChangeGateResult: + """Bind exact predecessor and byte facts without deciding the default check.""" if predecessor is not None and not predecessor_exists: raise ValueError("submission predecessor existence is inconsistent") if predecessor is None: @@ -256,14 +284,18 @@ def evaluate_submission_change( ) if current_predecessor is None or current_predecessor != predecessor: raise SubmissionChangeRejectedError(SubmissionChangeFailureCode.PREDECESSOR_STALE) - if commitment.sha256 == predecessor.archive_sha256: - raise SubmissionChangeRejectedError(SubmissionChangeFailureCode.ARCHIVE_UNCHANGED) - if manifest.sha256 == predecessor.semantic_manifest_sha256: - raise SubmissionChangeRejectedError(SubmissionChangeFailureCode.MANIFEST_UNCHANGED) + unchanged = ( + commitment.sha256 == predecessor.archive_sha256 + or manifest.sha256 == predecessor.semantic_manifest_sha256 + ) return SubmissionChangeGateResult( commitment.sha256, commitment.byte_count, manifest, - SubmissionChangeOutcome.CHANGED, + ( + SubmissionChangeOutcome.UNCHANGED + if unchanged + else SubmissionChangeOutcome.CHANGED + ), predecessor, ) diff --git a/backend/tests/checkers/external/test_selected_pre_submit.py b/backend/tests/checkers/external/test_selected_pre_submit.py index de4e61fdb..05b6038f5 100644 --- a/backend/tests/checkers/external/test_selected_pre_submit.py +++ b/backend/tests/checkers/external/test_selected_pre_submit.py @@ -4,6 +4,7 @@ from contextlib import contextmanager from dataclasses import replace +import json from types import SimpleNamespace from unittest.mock import AsyncMock import pytest @@ -27,6 +28,8 @@ ) from app.modules.checkers.api.external_policy import ( LockedExternalCheckerBinding, + LockedExternalCheckerPolicies, + LockedExternalPostSubmitPolicy, LockedExternalPreSubmitPolicy, LockedWorkstreamDefault, ) @@ -34,6 +37,10 @@ from app.modules.checkers.selected_pre_submit_execution import SelectedPreSubmitProcessor from app.adapters.checkers import SelectedPreSubmitCheckerExecutionAdapter from app.modules.artifacts.pre_submit_attempts import PreSubmitAttemptClaim +from app.modules.artifacts.selected_pre_submit_admission import ( + bind_selected_pre_submit_admission, +) +from app.modules.artifacts.submission_manifest import SubmissionCanonicalPredecessor from app.modules.artifacts.submission_materialization import ( PreparedBundleMaterializationService, ) @@ -92,6 +99,28 @@ def _policy() -> LockedExternalPreSubmitPolicy: ) +def _policies() -> LockedExternalCheckerPolicies: + pre = _policy() + post_body = { + "schema_version": "external_post_submit_policy.v1", + "entries": [], + } + post = LockedExternalPostSubmitPolicy( + entries=(), + policy_sha256=canonical_json_hash(post_body), + ) + body = { + "schema_version": "external_checker_policies.v1", + "pre_submit": pre.model_dump(mode="json"), + "post_submit": post.model_dump(mode="json"), + } + return LockedExternalCheckerPolicies( + pre_submit=pre, + post_submit=post, + policies_sha256=canonical_json_hash(body), + ) + + class _GrantIssuer: def __init__(self) -> None: self.requests = [] @@ -316,6 +345,59 @@ async def test_selected_pre_default_secret_blocker_precedes_external_image( manager.close() +@pytest.mark.asyncio +async def test_selected_admission_binds_unchanged_work_to_current_task_rules( + tmp_path, +) -> None: + request, _inspector, manager, _preparation, _catalogue = await _request(tmp_path) + policies = _policies() + project_id = request.effective_plan.lineage.project_id + task = SimpleNamespace( + locked_project_context=SimpleNamespace(project_id=project_id), + locked_policy=SimpleNamespace( + model_dump=lambda **_kwargs: { + "locked_guide_version": "v1", + "locked_pre_submit_checker_bundle_hash": SHA, + } + ), + ) + project = SimpleNamespace( + project_id=project_id, + external_checker_policies=SimpleNamespace( + value=json.dumps( + policies.model_dump(mode="json"), + sort_keys=True, + separators=(",", ":"), + ) + ), + ) + predecessor = SubmissionCanonicalPredecessor( + submission_id=new_record_id(), + submission_version=1, + archive_sha256=request.prepared_artifact.commitment.sha256, + semantic_manifest_sha256=request.manifest.sha256, + ) + try: + bound = bind_selected_pre_submit_admission( + task=task, + project=project, + commitment=request.prepared_artifact.commitment, + manifest=request.manifest, + predecessor=predecessor, + predecessor_rules_sha256="sha256:" + "d" * 64, + predecessor_exists=True, + packet=request.packet, + ) + assert bound.change_gate.outcome.value == "unchanged" + assert bound.default_input.predecessor is not None + assert bound.default_input.predecessor_rules_sha256 == "sha256:" + "d" * 64 + assert bound.default_input.current_rules_sha256 == bound.rules_sha256 + assert bound.policy.policy_sha256 == policies.pre_submit.policy_sha256 + finally: + await request.prepared_artifact.close() + manager.close() + + @pytest.mark.asyncio async def test_selected_factory_uses_request_bound_art_grant(tmp_path) -> None: request, inspector, manager, preparation, _catalogue = await _request(tmp_path) diff --git a/backend/tests/test_submission_change_gate.py b/backend/tests/test_submission_change_gate.py index 61ba4eb8f..48f7c295c 100644 --- a/backend/tests/test_submission_change_gate.py +++ b/backend/tests/test_submission_change_gate.py @@ -16,6 +16,7 @@ SubmissionChangeFailureCode, SubmissionChangeOutcome, SubmissionChangeRejectedError, + bind_submission_change, build_submission_manifest, evaluate_submission_change, ) @@ -117,6 +118,16 @@ def test_exact_archive_and_semantically_unchanged_reject_distinctly() -> None: current_predecessor=semantic_predecessor, ) + bound = bind_submission_change( + commitment=_commitment(), + manifest=manifest, + predecessor=semantic_predecessor, + predecessor_exists=True, + current_predecessor=semantic_predecessor, + ) + assert bound.outcome is SubmissionChangeOutcome.UNCHANGED + assert bound.predecessor is semantic_predecessor + def test_predecessor_advancement_rejects_stale_selector_before_comparison() -> None: _rejects( From 3cb0a2e5c6c55ea480331cdbe467a82be8e85a58 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 19:10:08 +0100 Subject: [PATCH 058/283] [PILOT-04] Bind durable selected pre-submit results --- .../pilot04-workstream-default-checker.md | 4 + .../checkers/api/selected_pre_submit.py | 148 +++++++++++++++++- .../external/test_selected_pre_submit.py | 34 +++- 3 files changed, 184 insertions(+), 2 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index d693623e0..f079a835b 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -25,6 +25,9 @@ genuine prepared-ART callback, but its durable result and admission caller are not selected yet. The admission binder now carries an unchanged byte/manifest comparison into the default checker with exact predecessor and current locked rules instead of treating that default behavior as an early ART rejection. +The selected result contract now has one canonical digest over the default, +ordered external results and observed isolation, plus a database-timed lease +and terminal latency body suitable for the durable owner. Production still uses the older pre/post catalogues. ## Bounded change @@ -175,6 +178,7 @@ intermediate-wait regression. | PRE transaction boundary | `pytest -q` for invalid claim controls and `test_checker_processor_starts_only_after_authority_transaction_commits`, plus Ruff on the four affected files | 5 passed; processor construction is refused while the authority root is active and reached only after it commits | Durable lease/generation schema and selected external sequence remain pending | | Selected PRE callback | `pytest -q backend/tests/checkers/external/test_selected_pre_submit.py`; Ruff and `git diff --check` on the affected files | 4 passed; exact default runs first, a real high-confidence secret prevents every external invocation, locked external pass/fail is retained, and the genuine request-bound ART grant completes cleanup with one bounded owned mount | Durable persistence, admission composition, crash recovery and native service journey remain pending | | Selected admission binding | `pytest -q backend/tests/test_submission_change_gate.py backend/tests/checkers/external/test_selected_pre_submit.py`; Ruff and `git diff --check` on the affected files | 11 passed; existing callers retain their exact archive/manifest rejection while the selected binder carries unchanged work plus exact predecessor/current rules into the default checker | The binder is not yet selected by the durable admission caller | +| Selected durable result contract | `pytest -q backend/tests/checkers/external/test_selected_pre_submit.py`; Ruff and `git diff --check` on the affected files | 5 passed; canonical result/terminal digests bind the default, ordered external results, isolation, generation lease, outcome and measured queue/execution latency | PostgreSQL reservation, lease and finalize storage remain pending | | Owner/caller trace | PROJECT approval/activation, ART preparation/admission, TASK composition and CHECKERS dispatch | In progress | Persistence delta and migration ordinal await actual linear predecessor | | End-to-end replacement | Real PostgreSQL/MinIO/Rust public and worker journey | Not run | Implementation incomplete | diff --git a/backend/app/modules/checkers/api/selected_pre_submit.py b/backend/app/modules/checkers/api/selected_pre_submit.py index 7f6acfe8d..139fe2d6c 100644 --- a/backend/app/modules/checkers/api/selected_pre_submit.py +++ b/backend/app/modules/checkers/api/selected_pre_submit.py @@ -2,9 +2,13 @@ from __future__ import annotations -from dataclasses import dataclass +from dataclasses import asdict, dataclass +from datetime import datetime +from typing import Literal from uuid import UUID +from app.core.hashing import canonical_json_hash +from app.modules.checkers.api.default_checker import WORKSTREAM_DEFAULT_BEHAVIOR_SHA256 from app.modules.checkers.api.default_checker import WorkstreamDefaultCheckerResult from app.modules.checkers.api.external import ExternalCheckerExecutionResult @@ -86,6 +90,146 @@ def __post_init__(self) -> None: ): raise ValueError("selected PRE execution continued after a blocker") + def canonical_body(self) -> dict[str, object]: + """Return the complete bounded result body retained by the durable owner.""" + return { + "schema_version": "workstream.selected_pre_submit_execution.v1", + "policy_sha256": self.policy_sha256, + "workstream_default": self.workstream_default.model_dump(mode="json"), + "required_external_count": self.required_external_count, + "external_members": [ + { + "order": member.order, + "requirement_id": member.requirement_id, + "registry_entry_id": str(member.registry_entry_id), + "registry_entry_digest": member.registry_entry_digest, + "request_digest": member.request_digest, + "result": member.result.model_dump(mode="json"), + "isolation": asdict(member.isolation), + } + for member in self.external_members + ], + "eligible": self.eligible, + } + + @property + def result_digest(self) -> str: + """Bind every default, project-image and observed-isolation result fact.""" + return canonical_json_hash(self.canonical_body()) + + +@dataclass(frozen=True, slots=True) +class SelectedPreSubmitLeaseFacts: + """Database-timed generation for one genuine pre-admission ART attempt.""" + + attempt_id: UUID + attempt_request_digest: str + prepared_generation_id: UUID + policy_sha256: str + default_behavior_sha256: str + lease_id: UUID + lease_generation: int + lease_expires_at: datetime + + def __post_init__(self) -> None: + """Reject a copied identifier or an unbounded/non-current lease shape.""" + digests = ( + self.attempt_request_digest, + self.policy_sha256, + self.default_behavior_sha256, + ) + if ( + any(type(value) is not UUID for value in ( + self.attempt_id, + self.prepared_generation_id, + self.lease_id, + )) + or any( + type(value) is not str + or len(value) != 71 + or not value.startswith("sha256:") + for value in digests + ) + or self.default_behavior_sha256 != WORKSTREAM_DEFAULT_BEHAVIOR_SHA256 + or type(self.lease_generation) is not int + or self.lease_generation < 1 + or self.lease_expires_at.tzinfo is None + ): + raise ValueError("selected PRE lease facts are invalid") + + +@dataclass(frozen=True, slots=True) +class SelectedPreSubmitTerminalFacts: + """Exact terminal value finalized under a fresh TASK-first transaction.""" + + lease: SelectedPreSubmitLeaseFacts + outcome: Literal["completed", "infrastructure_failed"] + execution: SelectedPreSubmitExecutionFacts | None + infrastructure_failure_code: str | None + queued_at: datetime + started_at: datetime + completed_at: datetime + + def __post_init__(self) -> None: + """Keep work findings separate from recoverable infrastructure outcomes.""" + if type(self.lease) is not SelectedPreSubmitLeaseFacts: + raise ValueError("selected PRE terminal lease is invalid") + if any(value.tzinfo is None for value in ( + self.queued_at, + self.started_at, + self.completed_at, + )) or not (self.queued_at <= self.started_at <= self.completed_at): + raise ValueError("selected PRE terminal timing is invalid") + if self.outcome == "completed": + if ( + type(self.execution) is not SelectedPreSubmitExecutionFacts + or self.infrastructure_failure_code is not None + or self.execution.policy_sha256 != self.lease.policy_sha256 + ): + raise ValueError("selected PRE completed outcome is invalid") + elif ( + self.execution is not None + or self.infrastructure_failure_code not in { + "capacity_exceeded", + "deadline_exceeded", + "material_unavailable", + "implementation_unavailable", + "invalid_output", + } + ): + raise ValueError("selected PRE infrastructure outcome is invalid") + + def canonical_body(self) -> dict[str, object]: + """Return persisted latency, lease and terminal facts without private paths.""" + return { + "schema_version": "workstream.selected_pre_submit_terminal.v1", + "attempt_id": str(self.lease.attempt_id), + "attempt_request_digest": self.lease.attempt_request_digest, + "prepared_generation_id": str(self.lease.prepared_generation_id), + "policy_sha256": self.lease.policy_sha256, + "default_behavior_sha256": self.lease.default_behavior_sha256, + "lease_id": str(self.lease.lease_id), + "lease_generation": self.lease.lease_generation, + "lease_expires_at": self.lease.lease_expires_at.isoformat(), + "outcome": self.outcome, + "execution": self.execution.canonical_body() if self.execution else None, + "infrastructure_failure_code": self.infrastructure_failure_code, + "queued_at": self.queued_at.isoformat(), + "started_at": self.started_at.isoformat(), + "completed_at": self.completed_at.isoformat(), + "queue_latency_ms": int( + (self.started_at - self.queued_at).total_seconds() * 1000 + ), + "execution_latency_ms": int( + (self.completed_at - self.started_at).total_seconds() * 1000 + ), + } + + @property + def terminal_digest(self) -> str: + """Bind the exact terminal body used by replay and admission.""" + return canonical_json_hash(self.canonical_body()) + class SelectedPreSubmitInfrastructureUnavailable(RuntimeError): """Retain a recoverable PRE infrastructure category, never a work failure.""" @@ -108,4 +252,6 @@ def __init__(self, code: str) -> None: "ExternalPreSubmitMemberFacts", "SelectedPreSubmitExecutionFacts", "SelectedPreSubmitInfrastructureUnavailable", + "SelectedPreSubmitLeaseFacts", + "SelectedPreSubmitTerminalFacts", ) diff --git a/backend/tests/checkers/external/test_selected_pre_submit.py b/backend/tests/checkers/external/test_selected_pre_submit.py index 05b6038f5..7dd1d7465 100644 --- a/backend/tests/checkers/external/test_selected_pre_submit.py +++ b/backend/tests/checkers/external/test_selected_pre_submit.py @@ -4,6 +4,7 @@ from contextlib import contextmanager from dataclasses import replace +from datetime import UTC, datetime, timedelta import json from types import SimpleNamespace from unittest.mock import AsyncMock @@ -16,7 +17,10 @@ ExternalCheckerIsolationReceipt, ExternalCheckerMaterialGrant, ) -from app.modules.checkers.api.default_checker import WorkstreamDefaultCheckerInput +from app.modules.checkers.api.default_checker import ( + WORKSTREAM_DEFAULT_BEHAVIOR_SHA256, + WorkstreamDefaultCheckerInput, +) from app.modules.checkers.api.external import ( PRE_SUBMIT_INPUT_SCHEMA_ID, ExternalCheckerRegistryEntry, @@ -34,6 +38,10 @@ LockedWorkstreamDefault, ) from app.modules.checkers.api.materialization import SubmissionMaterialEntry +from app.modules.checkers.api.selected_pre_submit import ( + SelectedPreSubmitLeaseFacts, + SelectedPreSubmitTerminalFacts, +) from app.modules.checkers.selected_pre_submit_execution import SelectedPreSubmitProcessor from app.adapters.checkers import SelectedPreSubmitCheckerExecutionAdapter from app.modules.artifacts.pre_submit_attempts import PreSubmitAttemptClaim @@ -259,6 +267,30 @@ async def test_selected_pre_runs_default_then_locked_external_image( assert result.external_members[0].result.verdict == verdict assert len(grants.requests) == len(execution.requests) == 1 assert grants.requests[0].request_digest == execution.requests[0].request_digest + assert result.result_digest == canonical_json_hash(result.canonical_body()) + now = datetime.now(UTC) + lease = SelectedPreSubmitLeaseFacts( + attempt_id=identity.attempt_id, + attempt_request_digest=identity.attempt_request_digest, + prepared_generation_id=identity.prepared_generation_id, + policy_sha256=policy.policy_sha256, + default_behavior_sha256=WORKSTREAM_DEFAULT_BEHAVIOR_SHA256, + lease_id=new_record_id(), + lease_generation=1, + lease_expires_at=now + timedelta(minutes=2), + ) + terminal = SelectedPreSubmitTerminalFacts( + lease=lease, + outcome="completed", + execution=result, + infrastructure_failure_code=None, + queued_at=now, + started_at=now + timedelta(milliseconds=25), + completed_at=now + timedelta(milliseconds=75), + ) + assert terminal.canonical_body()["queue_latency_ms"] == 25 + assert terminal.canonical_body()["execution_latency_ms"] == 50 + assert terminal.terminal_digest == canonical_json_hash(terminal.canonical_body()) finally: await request.prepared_artifact.close() manager.close() From 2eb4c08a4b9a97dc33c93b224cd3b07b58fb252d Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 19:13:10 +0100 Subject: [PATCH 059/283] [PILOT-04] Run selected post-submit checks over ART custody --- .../pilot04-workstream-default-checker.md | 5 + .../checkers/api/selected_post_submit.py | 124 +++++++++++++ .../selected_post_submit_execution.py | 113 ++++++++++++ .../external/test_selected_post_submit.py | 166 ++++++++++++++++++ 4 files changed, 408 insertions(+) create mode 100644 backend/app/modules/checkers/api/selected_post_submit.py create mode 100644 backend/app/modules/checkers/selected_post_submit_execution.py create mode 100644 backend/tests/checkers/external/test_selected_post_submit.py diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index f079a835b..cb7d4f4c5 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -28,6 +28,10 @@ rules instead of treating that default behavior as an early ART rejection. The selected result contract now has one canonical digest over the default, ordered external results and observed isolation, plus a database-timed lease and terminal latency body suitable for the durable owner. +The selected POST processor consumes only actual Submission and ART material +through the phase-typed callback grant, runs every locked POST image in order, +and returns canonical evidence and observed isolation without any acceptance +or routing authority. Its durable worker and result store are not selected yet. Production still uses the older pre/post catalogues. ## Bounded change @@ -179,6 +183,7 @@ intermediate-wait regression. | Selected PRE callback | `pytest -q backend/tests/checkers/external/test_selected_pre_submit.py`; Ruff and `git diff --check` on the affected files | 4 passed; exact default runs first, a real high-confidence secret prevents every external invocation, locked external pass/fail is retained, and the genuine request-bound ART grant completes cleanup with one bounded owned mount | Durable persistence, admission composition, crash recovery and native service journey remain pending | | Selected admission binding | `pytest -q backend/tests/test_submission_change_gate.py backend/tests/checkers/external/test_selected_pre_submit.py`; Ruff and `git diff --check` on the affected files | 11 passed; existing callers retain their exact archive/manifest rejection while the selected binder carries unchanged work plus exact predecessor/current rules into the default checker | The binder is not yet selected by the durable admission caller | | Selected durable result contract | `pytest -q backend/tests/checkers/external/test_selected_pre_submit.py`; Ruff and `git diff --check` on the affected files | 5 passed; canonical result/terminal digests bind the default, ordered external results, isolation, generation lease, outcome and measured queue/execution latency | PostgreSQL reservation, lease and finalize storage remain pending | +| Selected POST callback | `pytest -q backend/tests/checkers/external/test_selected_post_submit.py`; Ruff and `git diff --check` on the affected files | 3 passed; actual Submission/ART identity reaches every locked POST image through its short-lived grant, work pass/fail remains evidence only, and infrastructure failure stays recoverable | Durable POST reservation/finalization, worker restart and routing composition remain pending | | Owner/caller trace | PROJECT approval/activation, ART preparation/admission, TASK composition and CHECKERS dispatch | In progress | Persistence delta and migration ordinal await actual linear predecessor | | End-to-end replacement | Real PostgreSQL/MinIO/Rust public and worker journey | Not run | Implementation incomplete | diff --git a/backend/app/modules/checkers/api/selected_post_submit.py b/backend/app/modules/checkers/api/selected_post_submit.py new file mode 100644 index 000000000..c8a8c3e12 --- /dev/null +++ b/backend/app/modules/checkers/api/selected_post_submit.py @@ -0,0 +1,124 @@ +"""Closed evidence-only facts from selected external POST images.""" + +from __future__ import annotations + +from dataclasses import asdict, dataclass +from uuid import UUID + +from app.core.hashing import canonical_json_hash +from app.modules.checkers.api.external import ExternalCheckerExecutionResult + + +@dataclass(frozen=True, slots=True) +class ExternalPostSubmitIsolationFacts: + """Observed sandbox identity detached from the trusted service response.""" + + repository: str + platform_manifest_digest: str + platform_manifest_media_type: str + platform_manifest_byte_count: int + operating_system: str + architecture: str + config_image_id: str + runtime: str + isolation_mode: str + sandbox_uid: int + sandbox_gid: int + + +@dataclass(frozen=True, slots=True) +class ExternalPostSubmitMemberFacts: + """One normalized POST image result in exact locked policy order.""" + + order: int + requirement_id: str + registry_entry_id: UUID + registry_entry_digest: str + request_digest: str + result: ExternalCheckerExecutionResult + isolation: ExternalPostSubmitIsolationFacts + + def __post_init__(self) -> None: + if ( + type(self.order) is not int + or self.order < 0 + or not self.requirement_id + or self.result.outcome != "completed" + or self.result.request_digest != self.request_digest + or self.result.registry_entry_id != self.registry_entry_id + or self.result.registry_entry_digest != self.registry_entry_digest + or self.result.phase != "post_submit" + ): + raise ValueError("external POST member facts are invalid") + + +@dataclass(frozen=True, slots=True) +class SelectedPostSubmitExecutionFacts: + """Complete evidence-only result from every locked external POST image.""" + + policy_sha256: str + required_external_count: int + external_members: tuple[ExternalPostSubmitMemberFacts, ...] + + def __post_init__(self) -> None: + members = self.external_members + if ( + type(self.policy_sha256) is not str + or len(self.policy_sha256) != 71 + or not self.policy_sha256.startswith("sha256:") + or type(self.required_external_count) is not int + or self.required_external_count < 0 + or len(members) != self.required_external_count + or tuple(item.order for item in members) != tuple(range(len(members))) + or len({item.requirement_id for item in members}) != len(members) + ): + raise ValueError("selected POST execution facts are invalid") + + def canonical_body(self) -> dict[str, object]: + """Return exact evidence and isolation without any acceptance signal.""" + return { + "schema_version": "workstream.selected_post_submit_execution.v1", + "policy_sha256": self.policy_sha256, + "required_external_count": self.required_external_count, + "external_members": [ + { + "order": member.order, + "requirement_id": member.requirement_id, + "registry_entry_id": str(member.registry_entry_id), + "registry_entry_digest": member.registry_entry_digest, + "request_digest": member.request_digest, + "result": member.result.model_dump(mode="json"), + "isolation": asdict(member.isolation), + } + for member in self.external_members + ], + } + + @property + def result_digest(self) -> str: + """Bind every required image result and observed sandbox fact.""" + return canonical_json_hash(self.canonical_body()) + + +class SelectedPostSubmitInfrastructureUnavailable(RuntimeError): + """Retain a recoverable POST infrastructure category, never a work verdict.""" + + def __init__(self, code: str) -> None: + if code not in { + "capacity_exceeded", + "deadline_exceeded", + "material_unavailable", + "implementation_unavailable", + "invalid_output", + }: + raise ValueError("selected POST infrastructure failure is invalid") + self.code = code + super().__init__(code) + + +__all__ = ( + "ExternalPostSubmitIsolationFacts", + "ExternalPostSubmitMemberFacts", + "SelectedPostSubmitExecutionFacts", + "SelectedPostSubmitInfrastructureUnavailable", +) diff --git a/backend/app/modules/checkers/selected_post_submit_execution.py b/backend/app/modules/checkers/selected_post_submit_execution.py new file mode 100644 index 000000000..4700703fd --- /dev/null +++ b/backend/app/modules/checkers/selected_post_submit_execution.py @@ -0,0 +1,113 @@ +"""Selected external POST execution inside one verified ART callback.""" + +from __future__ import annotations + +from dataclasses import asdict + +from app.interfaces.external_checker_execution import ExternalCheckerExecutionAdapter +from app.interfaces.external_services import ( + ExternalServiceProtocolError, + ExternalServiceUnavailableError, +) +from app.modules.checkers.api.external import ( + PostSubmitExternalCheckerIdentity, + external_checker_json_hash, + make_external_checker_execution_request, +) +from app.modules.checkers.api.external_policy import LockedExternalPostSubmitPolicy +from app.modules.checkers.api.selected_post_submit import ( + ExternalPostSubmitIsolationFacts, + ExternalPostSubmitMemberFacts, + SelectedPostSubmitExecutionFacts, + SelectedPostSubmitInfrastructureUnavailable, +) + + +def _input_body(*, requirement_id, identity, material, entries) -> dict[str, object]: + """Build one normalized POST input from actual Submission and ART custody.""" + return { + "schema_version": "workstream.external_checker_post_submit_input.v1", + "requirement_id": requirement_id, + "project_id": str(identity.project_id), + "task_id": str(identity.task_id), + "assignment_id": str(identity.assignment_id), + "submission_id": str(identity.submission_id), + "submission_version": identity.submission_version, + "content_sha256": material.content_sha256, + "byte_count": material.byte_count, + "semantic_manifest_sha256": material.semantic_manifest_sha256, + "manifest": [asdict(item) for item in entries], + } + + +class SelectedPostSubmitProcessor: + """Run every locked POST image and return evidence without acceptance authority.""" + + def __init__( + self, + *, + policy: LockedExternalPostSubmitPolicy, + identity: PostSubmitExternalCheckerIdentity, + execution: ExternalCheckerExecutionAdapter, + ) -> None: + self._policy = policy + self._identity = identity + self._execution = execution + + async def evaluate(self, _request, material_view) -> SelectedPostSubmitExecutionFacts: + """Execute in policy order while ART owns actual verified POST material.""" + material = material_view.external_checker_material + members: list[ExternalPostSubmitMemberFacts] = [] + try: + for order, binding in enumerate(self._policy.entries): + input_value = _input_body( + requirement_id=binding.requirement_id, + identity=self._identity, + material=material, + entries=material_view.entries, + ) + request = make_external_checker_execution_request( + registry=binding.registry, + identity=self._identity, + configuration=binding.configuration, + configuration_sha256=binding.configuration_sha256, + input=input_value, + input_sha256=external_checker_json_hash(input_value), + materials=(material,), + ) + with material_view.external_checker_grant(request) as grant: + response = await self._execution.execute(request, grant) + result = response.result + if result.outcome == "infrastructure_failed": + raise SelectedPostSubmitInfrastructureUnavailable( + result.infrastructure_failure_code or "invalid_output" + ) + if response.isolation is None: + raise SelectedPostSubmitInfrastructureUnavailable("invalid_output") + members.append( + ExternalPostSubmitMemberFacts( + order=order, + requirement_id=binding.requirement_id, + registry_entry_id=binding.registry.registry_entry_id, + registry_entry_digest=binding.registry.entry_digest, + request_digest=request.request_digest, + result=result, + isolation=ExternalPostSubmitIsolationFacts( + **asdict(response.isolation) + ), + ) + ) + except ExternalServiceUnavailableError as exc: + raise SelectedPostSubmitInfrastructureUnavailable( + "implementation_unavailable" + ) from exc + except ExternalServiceProtocolError as exc: + raise SelectedPostSubmitInfrastructureUnavailable("invalid_output") from exc + return SelectedPostSubmitExecutionFacts( + policy_sha256=self._policy.policy_sha256, + required_external_count=len(self._policy.entries), + external_members=tuple(members), + ) + + +__all__ = ("SelectedPostSubmitProcessor",) diff --git a/backend/tests/checkers/external/test_selected_post_submit.py b/backend/tests/checkers/external/test_selected_post_submit.py new file mode 100644 index 000000000..c2d144415 --- /dev/null +++ b/backend/tests/checkers/external/test_selected_post_submit.py @@ -0,0 +1,166 @@ +"""Selected project POST images consume actual ART custody as evidence only.""" + +from __future__ import annotations + +from contextlib import contextmanager + +import pytest + +from app.core.hashing import canonical_json_hash +from app.interfaces.external_checker_execution import ( + ExternalCheckerExecutionResponse, + ExternalCheckerIsolationReceipt, + ExternalCheckerMaterialGrant, +) +from app.modules.checkers.api.external import ( + POST_SUBMIT_INPUT_SCHEMA_ID, + ExternalCheckerRegistryEntry, + ExternalCheckerSchema, + external_checker_json_hash, + make_external_checker_execution_result, +) +from app.modules.checkers.api.external_policy import ( + LockedExternalCheckerBinding, + LockedExternalPostSubmitPolicy, +) +from app.modules.checkers.api.materialization import SubmissionMaterialEntry +from app.modules.checkers.selected_post_submit_execution import ( + SelectedPostSubmitProcessor, +) +from tests.checkers.external.support import ( + SHA, + execution_identity, + execution_material, + registry_entry, +) + + +def _policy() -> LockedExternalPostSubmitPolicy: + values = registry_entry("post_submit").model_dump() + document = {"type": "object"} + values["input_schema"] = ExternalCheckerSchema( + schema_id=POST_SUBMIT_INPUT_SCHEMA_ID, + schema_version="v1", + document=document, + schema_sha256=external_checker_json_hash(document), + ) + spec = { + key: value + for key, value in values.items() + if key + not in { + "registry_entry_id", + "entry_digest", + "registration_operation_id", + "registered_by_actor_profile_id", + "authorization_decision_event_id", + "created_at", + } + } + spec["input_schema"] = values["input_schema"].model_dump(mode="json") + values["entry_digest"] = external_checker_json_hash(spec) + binding = LockedExternalCheckerBinding( + requirement_id="project.post_evidence", + stage="post_submit", + registry=ExternalCheckerRegistryEntry.model_validate(values), + configuration={}, + configuration_sha256=external_checker_json_hash({}), + ) + body = { + "schema_version": "external_post_submit_policy.v1", + "entries": [binding.model_dump(mode="json")], + } + return LockedExternalPostSubmitPolicy( + entries=(binding,), + policy_sha256=canonical_json_hash(body), + ) + + +class _MaterialView: + def __init__(self, material) -> None: + self.external_checker_material = material + self.entries = ( + SubmissionMaterialEntry("src/main.py", "file", 4, SHA, False), + ) + self.requests = [] + + @contextmanager + def external_checker_grant(self, request): + self.requests.append(request) + yield ExternalCheckerMaterialGrant( + grant_id="extract_" + "a" * 32, + binding_digest="sha256:" + "b" * 64, + ) + + +class _Execution: + def __init__(self, *, outcome="completed", verdict="passed") -> None: + self.outcome, self.verdict = outcome, verdict + self.requests = [] + + async def execute(self, request, _grant): + self.requests.append(request) + infrastructure = self.outcome == "infrastructure_failed" + findings = () if self.verdict == "passed" or infrastructure else ({ + "code": "post_evidence_failed", + "level": "error", + "message": "Post evidence failed.", + },) + result = make_external_checker_execution_result( + request_digest=request.request_digest, + registry_entry_id=request.registry.registry_entry_id, + registry_entry_digest=request.registry.entry_digest, + phase="post_submit", + outcome=self.outcome, + verdict=None if infrastructure else self.verdict, + findings=findings, + infrastructure_failure_code="deadline_exceeded" if infrastructure else None, + ) + return ExternalCheckerExecutionResponse( + result=result, + isolation=None if infrastructure else ExternalCheckerIsolationReceipt( + repository="registry.example/workstream/checker", + platform_manifest_digest=request.registry.image_digest, + platform_manifest_media_type="application/vnd.oci.image.manifest.v1+json", + platform_manifest_byte_count=1024, + operating_system="linux", + architecture="amd64", + config_image_id=SHA, + runtime="runsc", + isolation_mode="gvisor", + sandbox_uid=65532, + sandbox_gid=65532, + ), + ) + + +@pytest.mark.asyncio +@pytest.mark.parametrize("verdict", ["passed", "failed"]) +async def test_selected_post_runs_every_locked_image_without_acceptance(verdict) -> None: + identity = execution_identity("post_submit") + material = execution_material(identity) + view, execution, policy = _MaterialView(material), _Execution(verdict=verdict), _policy() + result = await SelectedPostSubmitProcessor( + policy=policy, + identity=identity, + execution=execution, + ).evaluate(object(), view) + + assert len(result.external_members) == 1 + assert result.external_members[0].result.verdict == verdict + assert result.result_digest == canonical_json_hash(result.canonical_body()) + assert len(view.requests) == len(execution.requests) == 1 + assert view.requests[0].identity.submission_id == identity.submission_id + assert "routing" not in result.canonical_body() + assert "accepted" not in result.canonical_body() + + +@pytest.mark.asyncio +async def test_selected_post_separates_infrastructure_from_work_findings() -> None: + identity = execution_identity("post_submit") + with pytest.raises(RuntimeError, match="deadline_exceeded"): + await SelectedPostSubmitProcessor( + policy=_policy(), + identity=identity, + execution=_Execution(outcome="infrastructure_failed"), + ).evaluate(object(), _MaterialView(execution_material(identity))) From b18a38027296b3de3bdcf33e00aa5ea63397c038 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 19:18:45 +0100 Subject: [PATCH 060/283] [PILOT-04] Bind selected pre-submit reservation facts --- .../pilot04-workstream-default-checker.md | 6 +- .../modules/checkers/api/default_checker.py | 51 ++++++++++ .../checkers/api/selected_pre_submit.py | 92 +++++++++++++++---- .../external/test_selected_pre_submit.py | 17 +++- 4 files changed, 147 insertions(+), 19 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index cb7d4f4c5..2ee953cdb 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -27,7 +27,10 @@ comparison into the default checker with exact predecessor and current locked rules instead of treating that default behavior as an early ART rejection. The selected result contract now has one canonical digest over the default, ordered external results and observed isolation, plus a database-timed lease -and terminal latency body suitable for the durable owner. +and terminal latency body suitable for the durable owner. Its reservation +digest binds the contributor identity, TASK/assignment, genuine ART attempt +and prepared generation, approved policy/default, complete default input and +server-owned archive/manifest identity before the lease is issued. The selected POST processor consumes only actual Submission and ART material through the phase-typed callback grant, runs every locked POST image in order, and returns canonical evidence and observed isolation without any acceptance @@ -183,6 +186,7 @@ intermediate-wait regression. | Selected PRE callback | `pytest -q backend/tests/checkers/external/test_selected_pre_submit.py`; Ruff and `git diff --check` on the affected files | 4 passed; exact default runs first, a real high-confidence secret prevents every external invocation, locked external pass/fail is retained, and the genuine request-bound ART grant completes cleanup with one bounded owned mount | Durable persistence, admission composition, crash recovery and native service journey remain pending | | Selected admission binding | `pytest -q backend/tests/test_submission_change_gate.py backend/tests/checkers/external/test_selected_pre_submit.py`; Ruff and `git diff --check` on the affected files | 11 passed; existing callers retain their exact archive/manifest rejection while the selected binder carries unchanged work plus exact predecessor/current rules into the default checker | The binder is not yet selected by the durable admission caller | | Selected durable result contract | `pytest -q backend/tests/checkers/external/test_selected_pre_submit.py`; Ruff and `git diff --check` on the affected files | 5 passed; canonical result/terminal digests bind the default, ordered external results, isolation, generation lease, outcome and measured queue/execution latency | PostgreSQL reservation, lease and finalize storage remain pending | +| Selected durable request contract | The same five selected-PRE tests plus focused Ruff and `git diff --check` | Passed; the reservation digest covers contributor/link, TASK, assignment, ART attempt/generation, policy/default, exact default input and archive/manifest custody, and the terminal includes that request digest | PostgreSQL ownership and SQL custody remain pending | | Selected POST callback | `pytest -q backend/tests/checkers/external/test_selected_post_submit.py`; Ruff and `git diff --check` on the affected files | 3 passed; actual Submission/ART identity reaches every locked POST image through its short-lived grant, work pass/fail remains evidence only, and infrastructure failure stays recoverable | Durable POST reservation/finalization, worker restart and routing composition remain pending | | Owner/caller trace | PROJECT approval/activation, ART preparation/admission, TASK composition and CHECKERS dispatch | In progress | Persistence delta and migration ordinal await actual linear predecessor | | End-to-end replacement | Real PostgreSQL/MinIO/Rust public and worker journey | Not run | Implementation incomplete | diff --git a/backend/app/modules/checkers/api/default_checker.py b/backend/app/modules/checkers/api/default_checker.py index 1f1d66f55..17bceaade 100644 --- a/backend/app/modules/checkers/api/default_checker.py +++ b/backend/app/modules/checkers/api/default_checker.py @@ -164,6 +164,55 @@ def __post_init__(self) -> None: _require_sha256(self.predecessor_rules_sha256) +def workstream_default_input_body( + value: WorkstreamDefaultCheckerInput, +) -> dict[str, object]: + """Return the exact detached input committed by durable PRE reservation.""" + if type(value) is not WorkstreamDefaultCheckerInput: + raise ValueError("default checker input is invalid") + + def predecessor_body(item: WorkstreamDefaultPredecessor | None): + return ( + None + if item is None + else { + "submission_id": str(item.submission_id), + "submission_version": item.submission_version, + "archive_sha256": item.archive_sha256, + "semantic_manifest_sha256": item.semantic_manifest_sha256, + } + ) + + return { + "schema_version": "workstream.default_checker_input.v1", + "archive_sha256": value.archive_sha256, + "archive_byte_count": value.archive_byte_count, + "archive_media_type": value.archive_media_type, + "semantic_manifest_sha256": value.semantic_manifest_sha256, + "entries": [ + { + "normalized_path": item.normalized_path, + "entry_type": item.entry_type, + "byte_count": item.byte_count, + "sha256": item.sha256, + "executable": item.executable, + } + for item in value.entries + ], + "predecessor": predecessor_body(value.predecessor), + "predecessor_exists": value.predecessor_exists, + "current_predecessor": predecessor_body(value.current_predecessor), + "current_rules_sha256": value.current_rules_sha256, + "predecessor_rules_sha256": value.predecessor_rules_sha256, + "packet_sha256": value.packet.sha256, + } + + +def workstream_default_input_sha256(value: WorkstreamDefaultCheckerInput) -> str: + """Bind every executable default-checker input without private file bytes.""" + return canonical_json_hash(workstream_default_input_body(value)) + + class WorkstreamDefaultCheckerValue(BaseModel): """Strict immutable value emitted by the default checker.""" @@ -272,4 +321,6 @@ def _failure_matches_check( "WorkstreamDefaultFailureCode", "WorkstreamDefaultPredecessor", "WorkstreamDefaultWarning", + "workstream_default_input_body", + "workstream_default_input_sha256", ) diff --git a/backend/app/modules/checkers/api/selected_pre_submit.py b/backend/app/modules/checkers/api/selected_pre_submit.py index 139fe2d6c..6194e63ee 100644 --- a/backend/app/modules/checkers/api/selected_pre_submit.py +++ b/backend/app/modules/checkers/api/selected_pre_submit.py @@ -119,31 +119,45 @@ def result_digest(self) -> str: @dataclass(frozen=True, slots=True) -class SelectedPreSubmitLeaseFacts: - """Database-timed generation for one genuine pre-admission ART attempt.""" +class SelectedPreSubmitReservationFacts: + """Complete durable PRE request reserved before any external work starts.""" + actor_profile_id: UUID + identity_link_id: UUID + project_id: UUID + task_id: UUID + assignment_id: UUID attempt_id: UUID attempt_request_digest: str prepared_generation_id: UUID policy_sha256: str default_behavior_sha256: str - lease_id: UUID - lease_generation: int - lease_expires_at: datetime + default_input_sha256: str + archive_sha256: str + archive_byte_count: int + semantic_manifest_sha256: str def __post_init__(self) -> None: - """Reject a copied identifier or an unbounded/non-current lease shape.""" + """Reject partial authority, material, policy or default-input custody.""" + identifiers = ( + self.actor_profile_id, + self.identity_link_id, + self.project_id, + self.task_id, + self.assignment_id, + self.attempt_id, + self.prepared_generation_id, + ) digests = ( self.attempt_request_digest, self.policy_sha256, self.default_behavior_sha256, + self.default_input_sha256, + self.archive_sha256, + self.semantic_manifest_sha256, ) if ( - any(type(value) is not UUID for value in ( - self.attempt_id, - self.prepared_generation_id, - self.lease_id, - )) + any(type(value) is not UUID for value in identifiers) or any( type(value) is not str or len(value) != 71 @@ -151,6 +165,51 @@ def __post_init__(self) -> None: for value in digests ) or self.default_behavior_sha256 != WORKSTREAM_DEFAULT_BEHAVIOR_SHA256 + or type(self.archive_byte_count) is not int + or self.archive_byte_count < 0 + ): + raise ValueError("selected PRE reservation facts are invalid") + + def canonical_body(self) -> dict[str, object]: + """Bind the actual contributor, task, ART generation, policy and bytes.""" + return { + "schema_version": "workstream.selected_pre_submit_reservation.v1", + "actor_profile_id": str(self.actor_profile_id), + "identity_link_id": str(self.identity_link_id), + "project_id": str(self.project_id), + "task_id": str(self.task_id), + "assignment_id": str(self.assignment_id), + "attempt_id": str(self.attempt_id), + "attempt_request_digest": self.attempt_request_digest, + "prepared_generation_id": str(self.prepared_generation_id), + "policy_sha256": self.policy_sha256, + "default_behavior_sha256": self.default_behavior_sha256, + "default_input_sha256": self.default_input_sha256, + "archive_sha256": self.archive_sha256, + "archive_byte_count": self.archive_byte_count, + "semantic_manifest_sha256": self.semantic_manifest_sha256, + } + + @property + def request_digest(self) -> str: + """Return the immutable request identity used by reserve and replay.""" + return canonical_json_hash(self.canonical_body()) + + +@dataclass(frozen=True, slots=True) +class SelectedPreSubmitLeaseFacts: + """Database-timed generation for one genuine pre-admission ART attempt.""" + + reservation: SelectedPreSubmitReservationFacts + lease_id: UUID + lease_generation: int + lease_expires_at: datetime + + def __post_init__(self) -> None: + """Reject a copied identifier or an unbounded/non-current lease shape.""" + if ( + type(self.reservation) is not SelectedPreSubmitReservationFacts + or type(self.lease_id) is not UUID or type(self.lease_generation) is not int or self.lease_generation < 1 or self.lease_expires_at.tzinfo is None @@ -184,7 +243,8 @@ def __post_init__(self) -> None: if ( type(self.execution) is not SelectedPreSubmitExecutionFacts or self.infrastructure_failure_code is not None - or self.execution.policy_sha256 != self.lease.policy_sha256 + or self.execution.policy_sha256 + != self.lease.reservation.policy_sha256 ): raise ValueError("selected PRE completed outcome is invalid") elif ( @@ -203,11 +263,8 @@ def canonical_body(self) -> dict[str, object]: """Return persisted latency, lease and terminal facts without private paths.""" return { "schema_version": "workstream.selected_pre_submit_terminal.v1", - "attempt_id": str(self.lease.attempt_id), - "attempt_request_digest": self.lease.attempt_request_digest, - "prepared_generation_id": str(self.lease.prepared_generation_id), - "policy_sha256": self.lease.policy_sha256, - "default_behavior_sha256": self.lease.default_behavior_sha256, + "reservation": self.lease.reservation.canonical_body(), + "request_digest": self.lease.reservation.request_digest, "lease_id": str(self.lease.lease_id), "lease_generation": self.lease.lease_generation, "lease_expires_at": self.lease.lease_expires_at.isoformat(), @@ -253,5 +310,6 @@ def __init__(self, code: str) -> None: "SelectedPreSubmitExecutionFacts", "SelectedPreSubmitInfrastructureUnavailable", "SelectedPreSubmitLeaseFacts", + "SelectedPreSubmitReservationFacts", "SelectedPreSubmitTerminalFacts", ) diff --git a/backend/tests/checkers/external/test_selected_pre_submit.py b/backend/tests/checkers/external/test_selected_pre_submit.py index 7dd1d7465..2690ebd57 100644 --- a/backend/tests/checkers/external/test_selected_pre_submit.py +++ b/backend/tests/checkers/external/test_selected_pre_submit.py @@ -20,6 +20,7 @@ from app.modules.checkers.api.default_checker import ( WORKSTREAM_DEFAULT_BEHAVIOR_SHA256, WorkstreamDefaultCheckerInput, + workstream_default_input_sha256, ) from app.modules.checkers.api.external import ( PRE_SUBMIT_INPUT_SCHEMA_ID, @@ -40,6 +41,7 @@ from app.modules.checkers.api.materialization import SubmissionMaterialEntry from app.modules.checkers.api.selected_pre_submit import ( SelectedPreSubmitLeaseFacts, + SelectedPreSubmitReservationFacts, SelectedPreSubmitTerminalFacts, ) from app.modules.checkers.selected_pre_submit_execution import SelectedPreSubmitProcessor @@ -269,12 +271,24 @@ async def test_selected_pre_runs_default_then_locked_external_image( assert grants.requests[0].request_digest == execution.requests[0].request_digest assert result.result_digest == canonical_json_hash(result.canonical_body()) now = datetime.now(UTC) - lease = SelectedPreSubmitLeaseFacts( + reservation = SelectedPreSubmitReservationFacts( + actor_profile_id=new_record_id(), + identity_link_id=new_record_id(), + project_id=identity.project_id, + task_id=identity.task_id, + assignment_id=identity.assignment_id, attempt_id=identity.attempt_id, attempt_request_digest=identity.attempt_request_digest, prepared_generation_id=identity.prepared_generation_id, policy_sha256=policy.policy_sha256, default_behavior_sha256=WORKSTREAM_DEFAULT_BEHAVIOR_SHA256, + default_input_sha256=workstream_default_input_sha256(default_input), + archive_sha256=material.archive_sha256, + archive_byte_count=material.archive_byte_count, + semantic_manifest_sha256=material.semantic_manifest_sha256, + ) + lease = SelectedPreSubmitLeaseFacts( + reservation=reservation, lease_id=new_record_id(), lease_generation=1, lease_expires_at=now + timedelta(minutes=2), @@ -290,6 +304,7 @@ async def test_selected_pre_runs_default_then_locked_external_image( ) assert terminal.canonical_body()["queue_latency_ms"] == 25 assert terminal.canonical_body()["execution_latency_ms"] == 50 + assert terminal.canonical_body()["request_digest"] == reservation.request_digest assert terminal.terminal_digest == canonical_json_hash(terminal.canonical_body()) finally: await request.prepared_artifact.close() From 626281d981151810ad7cd1c029c20f16923982c6 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 19:38:34 +0100 Subject: [PATCH 061/283] [PILOT-04] Own durable selected pre-submit runs --- .../pilot04-workstream-default-checker.md | 9 + .../app/adapters/checkers/external_service.py | 3 +- backend/app/adapters/projects/__init__.py | 7 +- backend/app/db/models.py | 1 + backend/app/interfaces/artifacts.py | 6 + backend/app/modules/artifacts/preparation.py | 8 +- backend/app/modules/checkers/api/external.py | 1 + .../modules/checkers/api/external_policy.py | 31 +- .../checkers/api/selected_pre_submit.py | 4 + backend/app/modules/checkers/models.py | 116 ++++++ .../selected_pre_submit_coordination.py | 330 ++++++++++++++++++ .../checkers/selected_pre_submit_execution.py | 5 +- .../projects/guide_activation/service.py | 9 +- .../guide_compilation/proposal_service.py | 8 +- .../tests/checkers/external/test_policy.py | 21 ++ .../external/test_selected_pre_submit.py | 1 + .../test_selected_pre_submit_coordination.py | 91 +++++ 17 files changed, 630 insertions(+), 21 deletions(-) create mode 100644 backend/app/modules/checkers/selected_pre_submit_coordination.py create mode 100644 backend/tests/checkers/external/test_selected_pre_submit_coordination.py diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 2ee953cdb..ad2d0efdf 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -31,6 +31,14 @@ and terminal latency body suitable for the durable owner. Its reservation digest binds the contributor identity, TASK/assignment, genuine ART attempt and prepared generation, approved policy/default, complete default input and server-owned archive/manifest identity before the lease is issued. +The selected durable owner is now modeled separately from the retained legacy +evidence decoder: its UUIDv7 run identifier is the genuine PRE attempt identity, +so selection does not reserve through or foreign-key to the obsolete invocation +store. The coordinator takes TASK custody before CHECKERS state, issues a +database-timed generation lease, finalizes one terminal body, and mints a +process-local one-use admission capability only for a complete pass. Its +ordered work budget is derived from the default plus each locked image deadline +and service cleanup margin and must fit ART's configured custody deadline. The selected POST processor consumes only actual Submission and ART material through the phase-typed callback grant, runs every locked POST image in order, and returns canonical evidence and observed isolation without any acceptance @@ -187,6 +195,7 @@ intermediate-wait regression. | Selected admission binding | `pytest -q backend/tests/test_submission_change_gate.py backend/tests/checkers/external/test_selected_pre_submit.py`; Ruff and `git diff --check` on the affected files | 11 passed; existing callers retain their exact archive/manifest rejection while the selected binder carries unchanged work plus exact predecessor/current rules into the default checker | The binder is not yet selected by the durable admission caller | | Selected durable result contract | `pytest -q backend/tests/checkers/external/test_selected_pre_submit.py`; Ruff and `git diff --check` on the affected files | 5 passed; canonical result/terminal digests bind the default, ordered external results, isolation, generation lease, outcome and measured queue/execution latency | PostgreSQL reservation, lease and finalize storage remain pending | | Selected durable request contract | The same five selected-PRE tests plus focused Ruff and `git diff --check` | Passed; the reservation digest covers contributor/link, TASK, assignment, ART attempt/generation, policy/default, exact default input and archive/manifest custody, and the terminal includes that request digest | PostgreSQL ownership and SQL custody remain pending | +| Selected durable owner source | `pytest -q` over selected PRE, policy, coordination, PROJECT activation/proposal contracts and architecture module boundaries; focused Ruff | 51 focused/architecture tests passed; the selected run is its own durable attempt identity, TASK locks precede CHECKERS state, one-use admission facts are substitution-resistant, ordered deadlines fit ART custody, and four private module edges were removed through public ports/composition | Native migration, exact AUTH SQL closure, crash reclaim and admission composition remain pending | | Selected POST callback | `pytest -q backend/tests/checkers/external/test_selected_post_submit.py`; Ruff and `git diff --check` on the affected files | 3 passed; actual Submission/ART identity reaches every locked POST image through its short-lived grant, work pass/fail remains evidence only, and infrastructure failure stays recoverable | Durable POST reservation/finalization, worker restart and routing composition remain pending | | Owner/caller trace | PROJECT approval/activation, ART preparation/admission, TASK composition and CHECKERS dispatch | In progress | Persistence delta and migration ordinal await actual linear predecessor | | End-to-end replacement | Real PostgreSQL/MinIO/Rust public and worker journey | Not run | Implementation incomplete | diff --git a/backend/app/adapters/checkers/external_service.py b/backend/app/adapters/checkers/external_service.py index ffa28569a..f1f402bc7 100644 --- a/backend/app/adapters/checkers/external_service.py +++ b/backend/app/adapters/checkers/external_service.py @@ -21,6 +21,7 @@ ExternalServiceUnavailableError, ) from app.modules.checkers.api.external import ( + EXTERNAL_CHECKER_EXECUTION_CLEANUP_MARGIN_MS, MAX_RESULT_BYTES, ExternalCheckerContractError, ExternalCheckerExecutionRequest, @@ -31,7 +32,7 @@ EXTERNAL_CHECKER_PROVIDER_KEY = "unix_socket" _PROTOCOL = "external_checker_service.v1" _MAXIMUM_RESPONSE_BYTES = MAX_RESULT_BYTES + 16_384 -_EXECUTION_OVERHEAD_SECONDS = 60.0 +_EXECUTION_OVERHEAD_SECONDS = EXTERNAL_CHECKER_EXECUTION_CLEANUP_MARGIN_MS / 1000 class UnixSocketExternalCheckerAdapter: diff --git a/backend/app/adapters/projects/__init__.py b/backend/app/adapters/projects/__init__.py index d0b817337..806573e86 100644 --- a/backend/app/adapters/projects/__init__.py +++ b/backend/app/adapters/projects/__init__.py @@ -148,9 +148,12 @@ def project_guide_proposal_service( PostSubmitCatalogue, PreSubmissionPolicyCompilationPort, ]: """Compose the sole proposal owner with explicit authority.""" + from app.adapters.checkers import external_checker_registry_reader from app.modules.projects.guide_compilation.proposal_service import GuideProposalService - return GuideProposalService(session, authorization) + return GuideProposalService( + session, authorization, external_checker_registry_reader(session) + ) def project_guide_correction_dispatch( @@ -209,9 +212,11 @@ def project_guide_activation_port( authorization: GuideActivationAuthorizationPort | None = None, ) -> GuideActivationPort[ActorIdentityFacts]: """Compose canonical activation with explicit CON validation and authority.""" + from app.adapters.checkers import external_checker_registry_reader from app.modules.projects.guide_activation.service import GuideActivationService return GuideActivationService( session, contribution=contribution, planner=planner, pre_catalogue=pre_catalogue, post_catalogue=post_catalogue, authorization=authorization, + registry=external_checker_registry_reader(session), ) diff --git a/backend/app/db/models.py b/backend/app/db/models.py index cf90e66ad..f438ad840 100644 --- a/backend/app/db/models.py +++ b/backend/app/db/models.py @@ -36,6 +36,7 @@ CheckerRun, CheckerSubmissionFence, ExternalCheckerRegistryEntryRecord, + SelectedPreSubmitRun, ) from app.modules.compensation.models import ( # noqa: F401 CompensationAdapterBindingLifecycleEvent, diff --git a/backend/app/interfaces/artifacts.py b/backend/app/interfaces/artifacts.py index ea182332e..de4347a4e 100644 --- a/backend/app/interfaces/artifacts.py +++ b/backend/app/interfaces/artifacts.py @@ -252,6 +252,12 @@ class ArtifactIntegrityError(ArtifactStoreError): category = "integrity" +class ArtifactScratchIntegrityError(ArtifactIntegrityError): + """Raised when private scratch state violates its filesystem contract.""" + + code = "artifact_scratch_integrity_failure" + + class ArtifactRangeInvalidError(ArtifactStoreError): """Raised when a requested range starts past the object end.""" diff --git a/backend/app/modules/artifacts/preparation.py b/backend/app/modules/artifacts/preparation.py index bebd2d62b..0eed9bf90 100644 --- a/backend/app/modules/artifacts/preparation.py +++ b/backend/app/modules/artifacts/preparation.py @@ -23,8 +23,8 @@ from app.interfaces.artifacts import ( ArtifactInputMismatchError, - ArtifactIntegrityError, ArtifactLimitExceededError, + ArtifactScratchIntegrityError, ArtifactStoreUnavailableError, ) from app.core.cancellation import ( @@ -80,12 +80,6 @@ class ArtifactPreparationDeadlineError(ArtifactStoreUnavailableError): code = "artifact_preparation_deadline_exceeded" -class ArtifactScratchIntegrityError(ArtifactIntegrityError): - """Raised when private scratch state violates its filesystem contract.""" - - code = "artifact_scratch_integrity_failure" - - @dataclass(frozen=True, slots=True) class ExternalMaterialFile: """One server-inspected file identity published to an external checker.""" diff --git a/backend/app/modules/checkers/api/external.py b/backend/app/modules/checkers/api/external.py index 4b5413663..52c0b8a8a 100644 --- a/backend/app/modules/checkers/api/external.py +++ b/backend/app/modules/checkers/api/external.py @@ -33,6 +33,7 @@ StrictStr, Field(min_length=1, max_length=50, pattern=r"^[a-z0-9][a-z0-9_.-]*$") ] ExternalCheckerPhase = Literal["pre_submit", "post_submit"] +EXTERNAL_CHECKER_EXECUTION_CLEANUP_MARGIN_MS = 60_000 PRE_SUBMIT_INPUT_SCHEMA_ID = "external_checker_pre_submit_input" POST_SUBMIT_INPUT_SCHEMA_ID = "external_checker_post_submit_input" diff --git a/backend/app/modules/checkers/api/external_policy.py b/backend/app/modules/checkers/api/external_policy.py index 0b668a730..09db92d63 100644 --- a/backend/app/modules/checkers/api/external_policy.py +++ b/backend/app/modules/checkers/api/external_policy.py @@ -9,7 +9,6 @@ from app.core.hashing import canonical_json_hash from app.interfaces.project_agents import ( PostSubmissionBindingProposal, - PreSubmissionBindingProposal, ProjectGuideCompilationResult, RequirementDisposition, ) @@ -19,6 +18,7 @@ WORKSTREAM_DEFAULT_CHECKER_VERSION, ) from app.modules.checkers.api.external import ( + EXTERNAL_CHECKER_EXECUTION_CLEANUP_MARGIN_MS, ExternalCheckerPhase, ExternalCheckerRegistryEntry, ExternalCheckerRegistryPort, @@ -26,6 +26,10 @@ ) +WORKSTREAM_DEFAULT_EXECUTION_BUDGET_MS = 60_000 +MAXIMUM_SELECTED_PRE_EXECUTION_BUDGET_MS = 7_200_000 + + class ExternalCheckerPolicyError(ValueError): """Reject incomplete, stale or phase-substituted locked checker policy.""" @@ -260,3 +264,28 @@ def _make_policy(model, entries): policy_sha256=canonical_json_hash(hash_body), ) return model(entries=entries, policy_sha256=canonical_json_hash(hash_body)) + + +def selected_pre_submit_execution_budget_ms( + policy: LockedExternalPreSubmitPolicy, + *, + artifact_deadline_ms: int, +) -> int: + """Return the exact ordered work budget only when ART can keep custody alive.""" + if ( + type(policy) is not LockedExternalPreSubmitPolicy + or type(artifact_deadline_ms) is not int + or artifact_deadline_ms <= 0 + or artifact_deadline_ms > MAXIMUM_SELECTED_PRE_EXECUTION_BUDGET_MS + ): + raise ExternalCheckerPolicyError("selected PRE execution budget is invalid") + required = WORKSTREAM_DEFAULT_EXECUTION_BUDGET_MS + sum( + binding.registry.resources.deadline_ms + + EXTERNAL_CHECKER_EXECUTION_CLEANUP_MARGIN_MS + for binding in policy.entries + ) + if required > artifact_deadline_ms: + raise ExternalCheckerPolicyError( + "selected PRE execution exceeds ART custody deadline" + ) + return required diff --git a/backend/app/modules/checkers/api/selected_pre_submit.py b/backend/app/modules/checkers/api/selected_pre_submit.py index 6194e63ee..1154efd8a 100644 --- a/backend/app/modules/checkers/api/selected_pre_submit.py +++ b/backend/app/modules/checkers/api/selected_pre_submit.py @@ -136,6 +136,7 @@ class SelectedPreSubmitReservationFacts: archive_sha256: str archive_byte_count: int semantic_manifest_sha256: str + execution_budget_ms: int def __post_init__(self) -> None: """Reject partial authority, material, policy or default-input custody.""" @@ -167,6 +168,8 @@ def __post_init__(self) -> None: or self.default_behavior_sha256 != WORKSTREAM_DEFAULT_BEHAVIOR_SHA256 or type(self.archive_byte_count) is not int or self.archive_byte_count < 0 + or type(self.execution_budget_ms) is not int + or not 100 <= self.execution_budget_ms <= 14_400_000 ): raise ValueError("selected PRE reservation facts are invalid") @@ -188,6 +191,7 @@ def canonical_body(self) -> dict[str, object]: "archive_sha256": self.archive_sha256, "archive_byte_count": self.archive_byte_count, "semantic_manifest_sha256": self.semantic_manifest_sha256, + "execution_budget_ms": self.execution_budget_ms, } @property diff --git a/backend/app/modules/checkers/models.py b/backend/app/modules/checkers/models.py index 35a6d8b86..def68e8c3 100644 --- a/backend/app/modules/checkers/models.py +++ b/backend/app/modules/checkers/models.py @@ -8,6 +8,7 @@ from sqlalchemy import Uuid from sqlalchemy import ( BigInteger, + Boolean, CheckConstraint, DateTime, ForeignKey, @@ -352,3 +353,118 @@ class CheckerSubmissionFence(Base): ) submission_id: Mapped[str] = mapped_column(ForeignKey("submissions.id"), primary_key=True) current_run_id: Mapped[str] = mapped_column(Uuid(as_uuid=False), nullable=False, unique=True) + + +class SelectedPreSubmitRun(Base): + """Durable selected PRE lease and terminal facts before any Submission exists.""" + + __tablename__ = "selected_pre_submit_runs" + __table_args__ = ( + CheckConstraint( + "(get_byte(uuid_send(id), 6) >> 4) = 7 and " + "(get_byte(uuid_send(id), 8) & 192) = 128", + name="id_uuid7", + ), + ForeignKeyConstraint( + ["task_id", "project_id"], + ["workstream_tasks.id", "workstream_tasks.project_id"], + name="fk_selected_pre_run_task_project", + ), + ForeignKeyConstraint( + ["assignment_id", "task_id", "actor_profile_id"], + ["task_assignments.id", "task_assignments.task_id", "task_assignments.contributor_id"], + name="fk_selected_pre_run_assignment", + ), + ForeignKeyConstraint( + ["identity_link_id", "actor_profile_id"], + ["actor_identity_links.id", "actor_identity_links.actor_profile_id"], + name="fk_selected_pre_run_actor_link", + ), + CheckConstraint( + "status in ('queued','running','completed','infrastructure_failed')", + name="status", + ), + CheckConstraint( + "request_digest ~ '^sha256:[0-9a-f]{64}$' and " + "policy_sha256 ~ '^sha256:[0-9a-f]{64}$' and " + "default_behavior_sha256 ~ '^sha256:[0-9a-f]{64}$' and " + "default_input_sha256 ~ '^sha256:[0-9a-f]{64}$' and " + "archive_sha256 ~ '^sha256:[0-9a-f]{64}$' and " + "semantic_manifest_sha256 ~ '^sha256:[0-9a-f]{64}$' and " + "(terminal_digest is null or terminal_digest ~ '^sha256:[0-9a-f]{64}$')", + name="digests", + ), + CheckConstraint("archive_byte_count > 0", name="archive_size"), + CheckConstraint( + "execution_budget_ms between 100 and 14400000", + name="execution_budget", + ), + CheckConstraint("lease_generation >= 0", name="lease_generation"), + CheckConstraint( + "(status='queued' and lease_id is null and lease_expires_at is null " + "and terminal_json is null and terminal_digest is null and eligible is null " + "and started_at is null and completed_at is null " + "and execute_evidence_id is null and finalize_evidence_id is null) or " + "(status='running' and lease_id is not null and lease_generation > 0 " + "and lease_expires_at is not null and terminal_json is null " + "and terminal_digest is null and eligible is null and started_at is not null " + "and completed_at is null " + "and execute_evidence_id is not null and finalize_evidence_id is null) or " + "(status='completed' and lease_id is not null and lease_generation > 0 " + "and lease_expires_at is not null and terminal_json is not null " + "and terminal_digest is not null and eligible is not null " + "and started_at is not null and completed_at is not null " + "and execute_evidence_id is not null and finalize_evidence_id is not null) or " + "(status='infrastructure_failed' and lease_id is not null " + "and lease_generation > 0 and lease_expires_at is not null " + "and terminal_json is not null and terminal_digest is not null " + "and eligible is null and started_at is not null and completed_at is not null " + "and execute_evidence_id is not null and finalize_evidence_id is not null)", + name="lifecycle", + ), + CheckConstraint( + "jsonb_typeof(request_json)='object' and " + "(terminal_json is null or jsonb_typeof(terminal_json)='object')", + name="json_objects", + ), + UniqueConstraint("request_digest", name="request_digest"), + Index("ix_selected_pre_runs_task", "task_id"), + Index("ix_selected_pre_runs_status", "status"), + ) + + id: Mapped[str] = mapped_column(Uuid(as_uuid=False), primary_key=True) + actor_profile_id: Mapped[str] = mapped_column(Uuid(as_uuid=False), nullable=False) + identity_link_id: Mapped[str] = mapped_column(Uuid(as_uuid=False), nullable=False) + project_id: Mapped[str] = mapped_column(Uuid(as_uuid=False), nullable=False) + task_id: Mapped[str] = mapped_column(Uuid(as_uuid=False), nullable=False) + assignment_id: Mapped[str] = mapped_column(Uuid(as_uuid=False), nullable=False) + prepared_generation_id: Mapped[str] = mapped_column(Uuid(as_uuid=False), nullable=False) + request_json: Mapped[dict] = mapped_column(JSONB(), nullable=False) + request_digest: Mapped[str] = mapped_column(String(71), nullable=False) + policy_sha256: Mapped[str] = mapped_column(String(71), nullable=False) + default_behavior_sha256: Mapped[str] = mapped_column(String(71), nullable=False) + default_input_sha256: Mapped[str] = mapped_column(String(71), nullable=False) + archive_sha256: Mapped[str] = mapped_column(String(71), nullable=False) + archive_byte_count: Mapped[int] = mapped_column(BigInteger, nullable=False) + semantic_manifest_sha256: Mapped[str] = mapped_column(String(71), nullable=False) + execution_budget_ms: Mapped[int] = mapped_column(Integer, nullable=False) + status: Mapped[str] = mapped_column(String(32), nullable=False) + lease_id: Mapped[str | None] = mapped_column(Uuid(as_uuid=False)) + lease_generation: Mapped[int] = mapped_column(Integer, nullable=False, default=0) + lease_expires_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True)) + execute_evidence_id: Mapped[str | None] = mapped_column( + Uuid(as_uuid=False), + ForeignKey("audit_events.id", ondelete="RESTRICT"), + ) + finalize_evidence_id: Mapped[str | None] = mapped_column( + Uuid(as_uuid=False), + ForeignKey("audit_events.id", ondelete="RESTRICT"), + ) + terminal_json: Mapped[dict | None] = mapped_column(JSONB()) + terminal_digest: Mapped[str | None] = mapped_column(String(71)) + eligible: Mapped[bool | None] = mapped_column(Boolean) + queued_at: Mapped[datetime] = mapped_column( + DateTime(timezone=True), nullable=False, server_default=text("clock_timestamp()") + ) + started_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True)) + completed_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True)) diff --git a/backend/app/modules/checkers/selected_pre_submit_coordination.py b/backend/app/modules/checkers/selected_pre_submit_coordination.py new file mode 100644 index 000000000..93ecb73fb --- /dev/null +++ b/backend/app/modules/checkers/selected_pre_submit_coordination.py @@ -0,0 +1,330 @@ +"""Durable selected PRE reservation and TASK-first lease/finalization custody.""" + +from __future__ import annotations + +import threading +from dataclasses import dataclass +from datetime import timedelta +from typing import Protocol +from uuid import UUID + +from sqlalchemy import func, select, text +from sqlalchemy.exc import IntegrityError +from sqlalchemy.ext.asyncio import AsyncSession + +from app.core.identifiers import new_record_id +from app.modules.checkers.api.selected_pre_submit import ( + SelectedPreSubmitExecutionFacts, + SelectedPreSubmitLeaseFacts, + SelectedPreSubmitReservationFacts, + SelectedPreSubmitTerminalFacts, +) +from app.modules.checkers.models import SelectedPreSubmitRun + + +class SelectedPreSubmitUnavailable(RuntimeError): + """Conceal absent, foreign, stale, conflicting or already leased PRE custody.""" + + +class SelectedPreSubmitTaskGuard(Protocol): + """TASK owns current contributor/assignment/policy checks before CHECKERS locks.""" + + async def lock_selected_pre_submit_scope( + self, reservation: SelectedPreSubmitReservationFacts + ) -> None: + """Lock and validate exact current TASK scope through caller commit.""" + + +@dataclass(frozen=True, slots=True) +class SelectedPreSubmitCompletion: + """Terminal facts and one process-local capability for immediate admission.""" + + terminal: SelectedPreSubmitTerminalFacts + capability: SelectedPreSubmitAdmissionCapability | None + + +_CAPABILITY_SEAL = object() + + +class SelectedPreSubmitAdmissionCapability: + """One-use completed-pass authority minted inside the finalization root.""" + + __slots__ = ( + "_consumed", + "_owner", + "_seal", + "_lock", + "run_id", + "terminal_digest", + "attempt_id", + "prepared_generation_id", + "archive_sha256", + "semantic_manifest_sha256", + ) + + def __init__(self, *_: object, **__: object) -> None: + raise TypeError("selected PRE admission capabilities are coordinator-issued") + + @classmethod + def _issued( + cls, + *, + owner: SelectedPreSubmitCoordinator, + run_id: UUID, + terminal: SelectedPreSubmitTerminalFacts, + ) -> SelectedPreSubmitAdmissionCapability: + reservation = terminal.lease.reservation + value = object.__new__(cls) + value._owner = owner + value._seal = _CAPABILITY_SEAL + value._lock = threading.Lock() + value._consumed = False + value.run_id = run_id + value.terminal_digest = terminal.terminal_digest + value.attempt_id = reservation.attempt_id + value.prepared_generation_id = reservation.prepared_generation_id + value.archive_sha256 = reservation.archive_sha256 + value.semantic_manifest_sha256 = reservation.semantic_manifest_sha256 + return value + + def consume( + self, + *, + run_id: UUID, + terminal_digest: str, + attempt_id: UUID, + prepared_generation_id: UUID, + archive_sha256: str, + semantic_manifest_sha256: str, + ) -> UUID: + """Consume only for the exact finalized run and still-live prepared bytes.""" + with self._lock: + if ( + self._seal is not _CAPABILITY_SEAL + or self._consumed + or self._owner._capability is not self + or ( + run_id, + terminal_digest, + attempt_id, + prepared_generation_id, + archive_sha256, + semantic_manifest_sha256, + ) + != ( + self.run_id, + self.terminal_digest, + self.attempt_id, + self.prepared_generation_id, + self.archive_sha256, + self.semantic_manifest_sha256, + ) + ): + raise SelectedPreSubmitUnavailable( + "selected_pre_submit_admission_unavailable" + ) + self._consumed = True + self._owner._capability = None + return self.run_id + + +def _require_root(session: AsyncSession) -> None: + transaction = session.sync_session.get_transaction() + if ( + transaction is None + or not transaction.is_active + or session.in_nested_transaction() + ): + raise RuntimeError("selected PRE coordination requires one root transaction") + + +def _matches(row: SelectedPreSubmitRun, facts: SelectedPreSubmitReservationFacts) -> bool: + return ( + row.request_json == facts.canonical_body() + and row.request_digest == facts.request_digest + and row.id == str(facts.attempt_id) + and row.actor_profile_id == str(facts.actor_profile_id) + and row.identity_link_id == str(facts.identity_link_id) + and row.project_id == str(facts.project_id) + and row.task_id == str(facts.task_id) + and row.assignment_id == str(facts.assignment_id) + and row.prepared_generation_id == str(facts.prepared_generation_id) + and row.policy_sha256 == facts.policy_sha256 + and row.default_behavior_sha256 == facts.default_behavior_sha256 + and row.default_input_sha256 == facts.default_input_sha256 + and row.archive_sha256 == facts.archive_sha256 + and row.archive_byte_count == facts.archive_byte_count + and row.semantic_manifest_sha256 == facts.semantic_manifest_sha256 + and row.execution_budget_ms == facts.execution_budget_ms + ) + + +class SelectedPreSubmitCoordinator: + """Reserve, lease and finalize one selected PRE run in caller-owned roots.""" + + def __init__( + self, + session: AsyncSession, + *, + tasks: SelectedPreSubmitTaskGuard, + ) -> None: + self._session = session + self._tasks = tasks + self._capability: SelectedPreSubmitAdmissionCapability | None = None + + async def reserve(self, facts: SelectedPreSubmitReservationFacts) -> UUID: + """Acquire TASK custody before the CHECKERS key and exact request row.""" + _require_root(self._session) + if type(facts) is not SelectedPreSubmitReservationFacts: + raise TypeError("selected PRE reservation facts are invalid") + await self._tasks.lock_selected_pre_submit_scope(facts) + await self._session.execute( + text("select pg_advisory_xact_lock(hashtextextended(:key,0))"), + {"key": "checkers:selected-pre:" + str(facts.attempt_id)}, + ) + row = await self._session.scalar( + select(SelectedPreSubmitRun) + .where(SelectedPreSubmitRun.id == str(facts.attempt_id)) + .with_for_update() + .execution_options(populate_existing=True) + ) + if row is not None: + if not _matches(row, facts): + raise SelectedPreSubmitUnavailable("selected_pre_submit_request_conflict") + return UUID(row.id) + row = SelectedPreSubmitRun( + id=str(facts.attempt_id), + actor_profile_id=str(facts.actor_profile_id), + identity_link_id=str(facts.identity_link_id), + project_id=str(facts.project_id), + task_id=str(facts.task_id), + assignment_id=str(facts.assignment_id), + prepared_generation_id=str(facts.prepared_generation_id), + request_json=facts.canonical_body(), + request_digest=facts.request_digest, + policy_sha256=facts.policy_sha256, + default_behavior_sha256=facts.default_behavior_sha256, + default_input_sha256=facts.default_input_sha256, + archive_sha256=facts.archive_sha256, + archive_byte_count=facts.archive_byte_count, + semantic_manifest_sha256=facts.semantic_manifest_sha256, + execution_budget_ms=facts.execution_budget_ms, + status="queued", + lease_generation=0, + ) + self._session.add(row) + try: + await self._session.flush() + except IntegrityError: + raise SelectedPreSubmitUnavailable("selected_pre_submit_request_conflict") from None + return facts.attempt_id + + async def claim( + self, + *, + run_id: UUID, + facts: SelectedPreSubmitReservationFacts, + execute_evidence_id: UUID, + ) -> SelectedPreSubmitLeaseFacts: + """Issue one database-timed lease after fresh TASK and execute authority.""" + row = await self._lock(run_id=run_id, facts=facts) + if row.status != "queued" or not isinstance(execute_evidence_id, UUID): + raise SelectedPreSubmitUnavailable("selected_pre_submit_lease_unavailable") + now = await self._session.scalar(select(func.clock_timestamp())) + assert now is not None + lease = SelectedPreSubmitLeaseFacts( + reservation=facts, + lease_id=new_record_id(), + lease_generation=row.lease_generation + 1, + lease_expires_at=now + timedelta(milliseconds=facts.execution_budget_ms), + ) + row.lease_id = str(lease.lease_id) + row.lease_generation = lease.lease_generation + row.lease_expires_at = lease.lease_expires_at + row.execute_evidence_id = str(execute_evidence_id) + row.started_at = now + row.status = "running" + await self._session.flush() + return lease + + async def finalize( + self, + *, + run_id: UUID, + lease: SelectedPreSubmitLeaseFacts, + finalize_evidence_id: UUID, + execution: SelectedPreSubmitExecutionFacts | None, + infrastructure_failure_code: str | None, + ) -> SelectedPreSubmitCompletion: + """Fence the lease and persist one exact terminal value under fresh TASK custody.""" + facts = lease.reservation + row = await self._lock(run_id=run_id, facts=facts) + if ( + row.status != "running" + or row.lease_id != str(lease.lease_id) + or row.lease_generation != lease.lease_generation + or row.lease_expires_at != lease.lease_expires_at + or not isinstance(finalize_evidence_id, UUID) + ): + raise SelectedPreSubmitUnavailable("selected_pre_submit_finalization_unavailable") + completed_at = await self._session.scalar(select(func.clock_timestamp())) + assert completed_at is not None and row.started_at is not None + if execution is not None and completed_at > lease.lease_expires_at: + raise SelectedPreSubmitUnavailable("selected_pre_submit_lease_expired") + outcome = "completed" if execution is not None else "infrastructure_failed" + terminal = SelectedPreSubmitTerminalFacts( + lease=lease, + outcome=outcome, + execution=execution, + infrastructure_failure_code=infrastructure_failure_code, + queued_at=row.queued_at, + started_at=row.started_at, + completed_at=completed_at, + ) + row.status = outcome + row.terminal_json = terminal.canonical_body() + row.terminal_digest = terminal.terminal_digest + row.eligible = execution.eligible if execution is not None else None + row.finalize_evidence_id = str(finalize_evidence_id) + row.completed_at = completed_at + await self._session.flush() + capability = ( + SelectedPreSubmitAdmissionCapability._issued( + owner=self, run_id=run_id, terminal=terminal + ) + if execution is not None and execution.eligible + else None + ) + self._capability = capability + return SelectedPreSubmitCompletion(terminal=terminal, capability=capability) + + async def _lock( + self, *, run_id: UUID, facts: SelectedPreSubmitReservationFacts + ) -> SelectedPreSubmitRun: + _require_root(self._session) + if not isinstance(run_id, UUID) or type(facts) is not SelectedPreSubmitReservationFacts: + raise SelectedPreSubmitUnavailable("selected_pre_submit_run_unavailable") + await self._tasks.lock_selected_pre_submit_scope(facts) + row = await self._session.scalar( + select(SelectedPreSubmitRun) + .where( + SelectedPreSubmitRun.id == str(run_id), + SelectedPreSubmitRun.project_id == str(facts.project_id), + SelectedPreSubmitRun.task_id == str(facts.task_id), + SelectedPreSubmitRun.assignment_id == str(facts.assignment_id), + ) + .with_for_update() + .execution_options(populate_existing=True) + ) + if row is None or not _matches(row, facts): + raise SelectedPreSubmitUnavailable("selected_pre_submit_run_unavailable") + return row + + +__all__ = ( + "SelectedPreSubmitAdmissionCapability", + "SelectedPreSubmitCompletion", + "SelectedPreSubmitCoordinator", + "SelectedPreSubmitTaskGuard", + "SelectedPreSubmitUnavailable", +) diff --git a/backend/app/modules/checkers/selected_pre_submit_execution.py b/backend/app/modules/checkers/selected_pre_submit_execution.py index e71d89a80..a79f9d16d 100644 --- a/backend/app/modules/checkers/selected_pre_submit_execution.py +++ b/backend/app/modules/checkers/selected_pre_submit_execution.py @@ -6,13 +6,12 @@ from dataclasses import asdict from app.core.cancellation import await_cancellation_resistant +from app.interfaces.artifacts import ArtifactScratchIntegrityError from app.interfaces.external_checker_execution import ExternalCheckerExecutionAdapter from app.interfaces.external_services import ( ExternalServiceProtocolError, ExternalServiceUnavailableError, ) -from app.modules.artifacts.preparation import ArtifactScratchIntegrityError -from app.modules.artifacts.submission_archive import SealedSubmissionTree from app.modules.checkers.api.default_checker import WorkstreamDefaultCheckerInput from app.modules.checkers.api.external import ( PreSubmitExternalCheckerIdentity, @@ -132,7 +131,7 @@ async def process(self, reader, workspace) -> SelectedPreSubmitExecutionFacts: projection = self._inspector._projected_tree( reader, workspace, expected=self._inspection ) - tree: SealedSubmissionTree = await asyncio.to_thread(projection.__enter__) + tree = await asyncio.to_thread(projection.__enter__) try: if self._aborted: raise asyncio.CancelledError diff --git a/backend/app/modules/projects/guide_activation/service.py b/backend/app/modules/projects/guide_activation/service.py index 98bb5a0b7..59cefbd18 100644 --- a/backend/app/modules/projects/guide_activation/service.py +++ b/backend/app/modules/projects/guide_activation/service.py @@ -8,6 +8,7 @@ from app.modules.authorization.api import ActorKind from app.modules.checkers.api.pre_submit import EffectivePreSubmissionPlanLineage from app.modules.checkers.api.external_policy import LockedExternalCheckerPolicies +from app.modules.checkers.api.external import ExternalCheckerRegistryPort from app.modules.projects.api.guide_activation import ( GuideActivationCommand, GuideActivationFacts, @@ -41,7 +42,7 @@ class GuideActivationService: def __init__( self, session, *, contribution, planner, pre_catalogue, post_catalogue, - authorization=None, registry=None, + authorization=None, registry: ExternalCheckerRegistryPort | None = None, ): self.session = session self.authorization = authorization @@ -54,10 +55,6 @@ def __init__( self.projects = ProjectRepository(session) self.replay = GuideMutationRepository(session) self.post = PostPolicyRepository(session) - if registry is None: - from app.modules.checkers.external_registry import ExternalCheckerRegistryReader - - registry = ExternalCheckerRegistryReader(session) self.registry = registry async def activate( @@ -234,6 +231,8 @@ async def _readiness(self, command, locked, policy, post, review, revision): == "external_checker_policies.v1" ) if external: + if self.registry is None: + raise GuideProposalError("approval_blocked") policies = LockedExternalCheckerPolicies.model_validate( approval.operation.effective_pre_submit_plan ) diff --git a/backend/app/modules/projects/guide_compilation/proposal_service.py b/backend/app/modules/projects/guide_compilation/proposal_service.py index 9ddb8b615..6da362815 100644 --- a/backend/app/modules/projects/guide_compilation/proposal_service.py +++ b/backend/app/modules/projects/guide_compilation/proposal_service.py @@ -33,6 +33,7 @@ from app.modules.checkers.api.pre_submit_catalogue import PreSubmissionCapabilityProjection from app.modules.checkers.api.post_submit_catalogue import PostSubmitCatalogue from app.modules.checkers.api.policy_compilation import PreSubmissionPolicyCompilationPort +from app.modules.checkers.api.external import ExternalCheckerRegistryPort from app.modules.projects.api.guide_proposal_package import GuideProposalReviewPackage from .proposal_repository import GuideProposalRepository @@ -46,13 +47,12 @@ def __init__( self, session: AsyncSession, authorization: GuideProposalAuthorizationPort, + registry: ExternalCheckerRegistryPort | None = None, ) -> None: self.session = session self.authorization = authorization self.repository = GuideProposalRepository(session) - from app.modules.checkers.external_registry import ExternalCheckerRegistryReader - - self.registry = ExternalCheckerRegistryReader(session) + self.registry = registry async def review_package( self, @@ -112,6 +112,8 @@ async def approve( from .proposal_approval import approve_proposal self._require_transaction() + if self.registry is None: + raise GuideProposalError("proposal_unavailable") async with self._bounded_errors(): return await approve_proposal( self.session, diff --git a/backend/tests/checkers/external/test_policy.py b/backend/tests/checkers/external/test_policy.py index 01f04967e..c81c1ffca 100644 --- a/backend/tests/checkers/external/test_policy.py +++ b/backend/tests/checkers/external/test_policy.py @@ -21,6 +21,7 @@ ExternalCheckerPolicyError, LockedWorkstreamDefault, compile_external_checker_policies, + selected_pre_submit_execution_budget_ms, ) from tests.checkers.external.support import registry_spec from tests.projects.guide_compilation.helpers import result @@ -151,3 +152,23 @@ async def test_compilation_refuses_blocked_capability_coverage(): def test_locked_default_refuses_substituted_behavior_digest(): with pytest.raises(ValueError, match="behavior"): LockedWorkstreamDefault(behavior_sha256="sha256:" + "0" * 64) + + +@pytest.mark.asyncio +async def test_selected_pre_budget_binds_ordered_deadlines_to_art_custody(): + pre, _ = await compile_external_checker_policies( + _proposal(), + _Registry( + ( + _entry("acme.safe_archive", "pre_submit"), + _entry("acme.quality_review", "post_submit"), + ) + ), + ) + assert selected_pre_submit_execution_budget_ms( + pre, artifact_deadline_ms=150_000 + ) == 150_000 + with pytest.raises(ExternalCheckerPolicyError, match="exceeds ART"): + selected_pre_submit_execution_budget_ms( + pre, artifact_deadline_ms=149_999 + ) diff --git a/backend/tests/checkers/external/test_selected_pre_submit.py b/backend/tests/checkers/external/test_selected_pre_submit.py index 2690ebd57..76f5b6965 100644 --- a/backend/tests/checkers/external/test_selected_pre_submit.py +++ b/backend/tests/checkers/external/test_selected_pre_submit.py @@ -286,6 +286,7 @@ async def test_selected_pre_runs_default_then_locked_external_image( archive_sha256=material.archive_sha256, archive_byte_count=material.archive_byte_count, semantic_manifest_sha256=material.semantic_manifest_sha256, + execution_budget_ms=120_000, ) lease = SelectedPreSubmitLeaseFacts( reservation=reservation, diff --git a/backend/tests/checkers/external/test_selected_pre_submit_coordination.py b/backend/tests/checkers/external/test_selected_pre_submit_coordination.py new file mode 100644 index 000000000..3ad164fa9 --- /dev/null +++ b/backend/tests/checkers/external/test_selected_pre_submit_coordination.py @@ -0,0 +1,91 @@ +"""Selected PRE durable ownership stays exact before native migration proof.""" + +from __future__ import annotations + +from types import SimpleNamespace + +import pytest +from sqlalchemy.dialects import postgresql +from sqlalchemy.schema import CreateTable + +from app.core.identifiers import new_record_id +from app.modules.checkers.api.default_checker import WORKSTREAM_DEFAULT_BEHAVIOR_SHA256 +from app.modules.checkers.api.selected_pre_submit import ( + SelectedPreSubmitReservationFacts, +) +from app.modules.checkers.models import SelectedPreSubmitRun +from app.modules.checkers.selected_pre_submit_coordination import ( + SelectedPreSubmitAdmissionCapability, + SelectedPreSubmitUnavailable, +) +from tests.checkers.external.support import SHA + + +def _reservation() -> SelectedPreSubmitReservationFacts: + return SelectedPreSubmitReservationFacts( + actor_profile_id=new_record_id(), + identity_link_id=new_record_id(), + project_id=new_record_id(), + task_id=new_record_id(), + assignment_id=new_record_id(), + attempt_id=new_record_id(), + attempt_request_digest=SHA, + prepared_generation_id=new_record_id(), + policy_sha256="sha256:" + "1" * 64, + default_behavior_sha256=WORKSTREAM_DEFAULT_BEHAVIOR_SHA256, + default_input_sha256="sha256:" + "2" * 64, + archive_sha256="sha256:" + "3" * 64, + archive_byte_count=1024, + semantic_manifest_sha256="sha256:" + "4" * 64, + execution_budget_ms=120_000, + ) + + +def test_selected_pre_model_compiles_complete_owner_and_authority_custody() -> None: + sql = str( + CreateTable(SelectedPreSubmitRun.__table__).compile( + dialect=postgresql.dialect() + ) + ) + for value in ( + "fk_selected_pre_run_task_project", + "fk_selected_pre_run_assignment", + "execute_evidence_id", + "finalize_evidence_id", + "execution_budget_ms", + ): + assert value in sql + assert "pre_submit_execution_attempts" not in sql + + +def test_selected_pre_admission_capability_is_exact_and_single_use() -> None: + reservation = _reservation() + owner = SimpleNamespace(_capability=None) + run_id = new_record_id() + terminal = SimpleNamespace( + lease=SimpleNamespace(reservation=reservation), + terminal_digest="sha256:" + "5" * 64, + ) + capability = SelectedPreSubmitAdmissionCapability._issued( + owner=owner, + run_id=run_id, + terminal=terminal, + ) + owner._capability = capability + values = { + "run_id": run_id, + "terminal_digest": terminal.terminal_digest, + "attempt_id": reservation.attempt_id, + "prepared_generation_id": reservation.prepared_generation_id, + "archive_sha256": reservation.archive_sha256, + "semantic_manifest_sha256": reservation.semantic_manifest_sha256, + } + with pytest.raises( + SelectedPreSubmitUnavailable, match="selected_pre_submit_admission_unavailable" + ): + capability.consume( + **(values | {"semantic_manifest_sha256": "sha256:" + "6" * 64}) + ) + assert capability.consume(**values) == run_id + with pytest.raises(SelectedPreSubmitUnavailable): + capability.consume(**values) From 7134dd98d743f3be5b1f2269ae6880f05c9a9c9d Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 19:41:07 +0100 Subject: [PATCH 062/283] [PILOT-04] Issue selected PRE execution authority --- .../artifacts/submission_materialization.py | 83 +++++++++++++++++++ .../checkers/api/selected_pre_submit.py | 14 +++- .../selected_pre_submit_coordination.py | 78 +++++++++++++++++ .../test_selected_pre_submit_coordination.py | 31 +++++++ 4 files changed, 205 insertions(+), 1 deletion(-) diff --git a/backend/app/modules/artifacts/submission_materialization.py b/backend/app/modules/artifacts/submission_materialization.py index 018c36c41..5baa74504 100644 --- a/backend/app/modules/artifacts/submission_materialization.py +++ b/backend/app/modules/artifacts/submission_materialization.py @@ -56,6 +56,7 @@ from app.modules.checkers.api.default_checker import ( WORKSTREAM_DEFAULT_BEHAVIOR_SHA256, WorkstreamDefaultCheckerInput, + workstream_default_input_body, ) from app.modules.checkers.api.external import ( ExternalCheckerExecutionRequest, @@ -63,6 +64,11 @@ PreSubmitExternalCheckerMaterial, ) from app.modules.checkers.api.external_policy import LockedExternalPreSubmitPolicy +from app.modules.checkers.api.selected_pre_submit import ( + SelectedPreSubmitExecutionAuthority, + SelectedPreSubmitExecutionFacts, + SelectedPreSubmitLeaseFacts, +) from app.modules.projects.api import ProjectLockedPolicyContextPort from app.modules.tasks.api import TaskSubmissionContextPort @@ -117,6 +123,14 @@ def issue( ) -> AbstractContextManager[ExternalCheckerMaterialGrant]: ... +@dataclass(frozen=True, slots=True) +class _SelectedGrantClaim: + """Minimum genuine selected-run identity required by the ART grant issuer.""" + + attempt_id: UUID + request_digest: str + + class _PreSubmitExternalGrantIssuer: """Keep private prepared-artifact authority behind a typed callback port.""" @@ -427,6 +441,75 @@ async def materialize_prepared_bundle( claim.finish(execution) return execution + async def materialize_selected_pre_submit( + self, + request: PreparedBundleMaterializationRequest, + *, + run_id: UUID, + lease: SelectedPreSubmitLeaseFacts, + execution_authority: SelectedPreSubmitExecutionAuthority, + ) -> SelectedPreSubmitExecutionFacts: + """Execute the committed selected lease without the legacy invocation store.""" + if self._session.in_transaction(): + raise RuntimeError("selected pre-submit execution requires no transaction") + checked = execution_authority.consume(run_id=run_id, lease=lease) + reservation = checked.reservation + commitment = request.prepared_artifact.commitment + if ( + run_id != reservation.attempt_id + or request.task_id != reservation.task_id + or request.assignment_id != reservation.assignment_id + or request.prepared_artifact.generation_id + != reservation.prepared_generation_id + or request.external_policy is None + or request.external_policy.policy_sha256 != reservation.policy_sha256 + or request.default_checker_input is None + or canonical_json_hash( + workstream_default_input_body(request.default_checker_input) + ) + != reservation.default_input_sha256 + or commitment.sha256 != reservation.archive_sha256 + or commitment.byte_count != reservation.archive_byte_count + or request.manifest.sha256 != reservation.semantic_manifest_sha256 + ): + raise PreSubmitEvidenceConflict("selected_pre_submit_execution_invalid") + processor = self._checker_execution.build( + PreSubmitCheckerExecutionRequest( + plan=request.effective_plan, + task_id=request.task_id, + assignment_id=request.assignment_id, + commitment=commitment, + inspection=request.inspection, + manifest=request.manifest, + change_gate=request.change_gate, + packet=request.packet, + prepared_generation_id=request.prepared_artifact.generation_id, + storage_scheme=self._storage_scheme, + external_policy=request.external_policy, + default_checker_input=request.default_checker_input, + attempt_id=run_id, + attempt_request_digest=reservation.request_digest, + external_grants=_PreSubmitExternalGrantIssuer( + preparation=self._preparation, + prepared=request.prepared_artifact, + request=request, + claim=_SelectedGrantClaim( + attempt_id=run_id, + request_digest=reservation.request_digest, + ), + ), + ) + ) + result = await self._preparation._process_prepared_submission( + request.prepared_artifact, + processor, + reserved_bytes=request.manifest.total_expanded_bytes, + maximum_entries=request.manifest.entry_count + 1, + ) + if type(result) is not SelectedPreSubmitExecutionFacts: + raise PreSubmitEvidenceConflict("selected_pre_submit_execution_invalid") + return result + async def authorize_inspected(self, request: PreparedBundleMaterializationRequest) -> None: """Authorize inspected custody for reservation without invoking checker members.""" await self._authorization.consume( diff --git a/backend/app/modules/checkers/api/selected_pre_submit.py b/backend/app/modules/checkers/api/selected_pre_submit.py index 1154efd8a..db299d071 100644 --- a/backend/app/modules/checkers/api/selected_pre_submit.py +++ b/backend/app/modules/checkers/api/selected_pre_submit.py @@ -4,7 +4,7 @@ from dataclasses import asdict, dataclass from datetime import datetime -from typing import Literal +from typing import Literal, Protocol from uuid import UUID from app.core.hashing import canonical_json_hash @@ -221,6 +221,18 @@ def __post_init__(self) -> None: raise ValueError("selected PRE lease facts are invalid") +class SelectedPreSubmitExecutionAuthority(Protocol): + """Process-local capability for one committed durable PRE lease.""" + + def consume( + self, + *, + run_id: UUID, + lease: SelectedPreSubmitLeaseFacts, + ) -> SelectedPreSubmitLeaseFacts: + """Return the exact lease once, or refuse stale/substituted execution.""" + + @dataclass(frozen=True, slots=True) class SelectedPreSubmitTerminalFacts: """Exact terminal value finalized under a fresh TASK-first transaction.""" diff --git a/backend/app/modules/checkers/selected_pre_submit_coordination.py b/backend/app/modules/checkers/selected_pre_submit_coordination.py index 93ecb73fb..ba1c553b1 100644 --- a/backend/app/modules/checkers/selected_pre_submit_coordination.py +++ b/backend/app/modules/checkers/selected_pre_submit_coordination.py @@ -128,6 +128,54 @@ def consume( return self.run_id +class SelectedPreSubmitExecutionCapability: + """One-use authority for the committed lease's process-local ART callback.""" + + __slots__ = ("_consumed", "_owner", "_seal", "_lock", "run_id", "lease") + + def __init__(self, *_: object, **__: object) -> None: + raise TypeError("selected PRE execution capabilities are coordinator-issued") + + @classmethod + def _issued( + cls, + *, + owner: SelectedPreSubmitCoordinator, + run_id: UUID, + lease: SelectedPreSubmitLeaseFacts, + ) -> SelectedPreSubmitExecutionCapability: + value = object.__new__(cls) + value._owner = owner + value._seal = _CAPABILITY_SEAL + value._lock = threading.Lock() + value._consumed = False + value.run_id = run_id + value.lease = lease + return value + + def consume( + self, + *, + run_id: UUID, + lease: SelectedPreSubmitLeaseFacts, + ) -> SelectedPreSubmitLeaseFacts: + """Consume only for the exact committed run generation and request facts.""" + with self._lock: + if ( + self._seal is not _CAPABILITY_SEAL + or self._consumed + or self._owner._execution_capability is not self + or run_id != self.run_id + or lease != self.lease + ): + raise SelectedPreSubmitUnavailable( + "selected_pre_submit_execution_unavailable" + ) + self._consumed = True + self._owner._execution_capability = None + return self.lease + + def _require_root(session: AsyncSession) -> None: transaction = session.sync_session.get_transaction() if ( @@ -171,6 +219,7 @@ def __init__( self._session = session self._tasks = tasks self._capability: SelectedPreSubmitAdmissionCapability | None = None + self._execution_capability: SelectedPreSubmitExecutionCapability | None = None async def reserve(self, facts: SelectedPreSubmitReservationFacts) -> UUID: """Acquire TASK custody before the CHECKERS key and exact request row.""" @@ -247,6 +296,34 @@ async def claim( await self._session.flush() return lease + async def committed_execution( + self, + *, + run_id: UUID, + lease: SelectedPreSubmitLeaseFacts, + ) -> SelectedPreSubmitExecutionCapability: + """Mint execution authority only after a fresh root observes the committed lease.""" + if self._session.in_transaction(): + raise RuntimeError("selected PRE execution requires a committed lease") + async with self._session.begin(): + row = await self._lock(run_id=run_id, facts=lease.reservation) + if ( + row.status != "running" + or row.lease_id != str(lease.lease_id) + or row.lease_generation != lease.lease_generation + or row.lease_expires_at != lease.lease_expires_at + ): + raise SelectedPreSubmitUnavailable( + "selected_pre_submit_execution_unavailable" + ) + capability = SelectedPreSubmitExecutionCapability._issued( + owner=self, + run_id=run_id, + lease=lease, + ) + self._execution_capability = capability + return capability + async def finalize( self, *, @@ -325,6 +402,7 @@ async def _lock( "SelectedPreSubmitAdmissionCapability", "SelectedPreSubmitCompletion", "SelectedPreSubmitCoordinator", + "SelectedPreSubmitExecutionCapability", "SelectedPreSubmitTaskGuard", "SelectedPreSubmitUnavailable", ) diff --git a/backend/tests/checkers/external/test_selected_pre_submit_coordination.py b/backend/tests/checkers/external/test_selected_pre_submit_coordination.py index 3ad164fa9..fbb89bdd1 100644 --- a/backend/tests/checkers/external/test_selected_pre_submit_coordination.py +++ b/backend/tests/checkers/external/test_selected_pre_submit_coordination.py @@ -11,11 +11,13 @@ from app.core.identifiers import new_record_id from app.modules.checkers.api.default_checker import WORKSTREAM_DEFAULT_BEHAVIOR_SHA256 from app.modules.checkers.api.selected_pre_submit import ( + SelectedPreSubmitLeaseFacts, SelectedPreSubmitReservationFacts, ) from app.modules.checkers.models import SelectedPreSubmitRun from app.modules.checkers.selected_pre_submit_coordination import ( SelectedPreSubmitAdmissionCapability, + SelectedPreSubmitExecutionCapability, SelectedPreSubmitUnavailable, ) from tests.checkers.external.support import SHA @@ -89,3 +91,32 @@ def test_selected_pre_admission_capability_is_exact_and_single_use() -> None: assert capability.consume(**values) == run_id with pytest.raises(SelectedPreSubmitUnavailable): capability.consume(**values) + + +def test_selected_pre_execution_capability_is_exact_and_single_use() -> None: + from datetime import UTC, datetime + + reservation = _reservation() + lease = SelectedPreSubmitLeaseFacts( + reservation=reservation, + lease_id=new_record_id(), + lease_generation=1, + lease_expires_at=datetime.now(UTC), + ) + owner = SimpleNamespace(_execution_capability=None) + capability = SelectedPreSubmitExecutionCapability._issued( + owner=owner, + run_id=reservation.attempt_id, + lease=lease, + ) + owner._execution_capability = capability + with pytest.raises( + SelectedPreSubmitUnavailable, match="selected_pre_submit_execution_unavailable" + ): + capability.consume(run_id=new_record_id(), lease=lease) + assert capability.consume( + run_id=reservation.attempt_id, + lease=lease, + ) == lease + with pytest.raises(SelectedPreSubmitUnavailable): + capability.consume(run_id=reservation.attempt_id, lease=lease) From 08a30cafcffc2cb0a5748e0fb5d74c4eb201b079 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 19:46:37 +0100 Subject: [PATCH 063/283] [PILOT-04] Execute selected PRE across short roots --- .../pilot04-workstream-default-checker.md | 6 + .../selected_pre_submit_execution.py | 88 +++++++++ .../checkers/api/selected_pre_submit.py | 177 ++++++++++++++++++ .../selected_pre_submit_coordination.py | 37 ++-- .../test_selected_pre_submit_coordination.py | 41 ++++ .../test_selected_pre_submit_service.py | 172 +++++++++++++++++ 6 files changed, 506 insertions(+), 15 deletions(-) create mode 100644 backend/app/modules/artifacts/selected_pre_submit_execution.py create mode 100644 backend/tests/checkers/external/test_selected_pre_submit_service.py diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index ad2d0efdf..aadc401c8 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -39,6 +39,11 @@ database-timed generation lease, finalizes one terminal body, and mints a process-local one-use admission capability only for a complete pass. Its ordered work budget is derived from the default plus each locked image deadline and service cleanup margin and must fit ART's configured custody deadline. +The selected execution workflow now prepares fixed-service authority before +TASK/CHECKERS locks, commits the database-timed lease before exposing material, +executes through one exact process-local ART capability with no transaction +open, then uses a distinct short root to authorize and finalize the exact result +or one closed recoverable infrastructure outcome. The selected POST processor consumes only actual Submission and ART material through the phase-typed callback grant, runs every locked POST image in order, and returns canonical evidence and observed isolation without any acceptance @@ -196,6 +201,7 @@ intermediate-wait regression. | Selected durable result contract | `pytest -q backend/tests/checkers/external/test_selected_pre_submit.py`; Ruff and `git diff --check` on the affected files | 5 passed; canonical result/terminal digests bind the default, ordered external results, isolation, generation lease, outcome and measured queue/execution latency | PostgreSQL reservation, lease and finalize storage remain pending | | Selected durable request contract | The same five selected-PRE tests plus focused Ruff and `git diff --check` | Passed; the reservation digest covers contributor/link, TASK, assignment, ART attempt/generation, policy/default, exact default input and archive/manifest custody, and the terminal includes that request digest | PostgreSQL ownership and SQL custody remain pending | | Selected durable owner source | `pytest -q` over selected PRE, policy, coordination, PROJECT activation/proposal contracts and architecture module boundaries; focused Ruff | 51 focused/architecture tests passed; the selected run is its own durable attempt identity, TASK locks precede CHECKERS state, one-use admission facts are substitution-resistant, ordered deadlines fit ART custody, and four private module edges were removed through public ports/composition | Native migration, exact AUTH SQL closure, crash reclaim and admission composition remain pending | +| Selected lease execution boundary | `pytest -q backend/tests/checkers/external/test_selected_pre_submit_coordination.py backend/tests/checkers/external/test_selected_pre_submit_service.py backend/tests/checkers/external/test_selected_pre_submit.py backend/tests/architecture/test_module_boundaries.py`; focused Ruff | 49 passed; fixed-service preparation precedes owner locks, the lease commits before material execution, execution occurs with no root open, and exact lease/result digests are consumed in a separate finalization root | Concrete AUTH registration, native SQL custody and live admission selection remain pending | | Selected POST callback | `pytest -q backend/tests/checkers/external/test_selected_post_submit.py`; Ruff and `git diff --check` on the affected files | 3 passed; actual Submission/ART identity reaches every locked POST image through its short-lived grant, work pass/fail remains evidence only, and infrastructure failure stays recoverable | Durable POST reservation/finalization, worker restart and routing composition remain pending | | Owner/caller trace | PROJECT approval/activation, ART preparation/admission, TASK composition and CHECKERS dispatch | In progress | Persistence delta and migration ordinal await actual linear predecessor | | End-to-end replacement | Real PostgreSQL/MinIO/Rust public and worker journey | Not run | Implementation incomplete | diff --git a/backend/app/modules/artifacts/selected_pre_submit_execution.py b/backend/app/modules/artifacts/selected_pre_submit_execution.py new file mode 100644 index 000000000..b0d817eb9 --- /dev/null +++ b/backend/app/modules/artifacts/selected_pre_submit_execution.py @@ -0,0 +1,88 @@ +"""Selected PRE lease execution across short authority and owner transactions.""" + +from __future__ import annotations + +from sqlalchemy.ext.asyncio import AsyncSession + +from app.modules.artifacts.submission_materialization import ( + PreparedBundleMaterializationRequest, + PreparedBundleMaterializationService, +) +from app.modules.checkers.api.selected_pre_submit import ( + SelectedPreSubmitAuthorityPort, + SelectedPreSubmitCompletion, + SelectedPreSubmitCoordinationPort, + SelectedPreSubmitExecutionFacts, + SelectedPreSubmitFinalizeFacts, + SelectedPreSubmitInfrastructureUnavailable, + SelectedPreSubmitReservationFacts, +) + + +class SelectedPreSubmitExecutionService: + """Claim, execute and finalize one selected run without holding a DB root.""" + + def __init__( + self, + *, + session: AsyncSession, + coordinator: SelectedPreSubmitCoordinationPort, + authority: SelectedPreSubmitAuthorityPort, + materialization: PreparedBundleMaterializationService, + ) -> None: + self._session = session + self._coordinator = coordinator + self._authority = authority + self._materialization = materialization + + async def execute( + self, + *, + reservation: SelectedPreSubmitReservationFacts, + materialization: PreparedBundleMaterializationRequest, + ) -> SelectedPreSubmitCompletion: + """Use short claim/finalize roots around one process-local ART execution.""" + run_id = reservation.attempt_id + async with self._session.begin(): + # Preparing the fixed principal precedes CHECKERS' TASK/run locks. + async with self._authority.prepare_execution(reservation) as prepared: + lease = await self._coordinator.claim( + run_id=run_id, + facts=reservation, + authority=prepared, + ) + + execution: SelectedPreSubmitExecutionFacts | None = None + infrastructure_failure_code: str | None = None + try: + capability = await self._coordinator.committed_execution( + run_id=run_id, lease=lease + ) + execution = await self._materialization.materialize_selected_pre_submit( + materialization, + run_id=run_id, + lease=lease, + execution_authority=capability, + ) + except SelectedPreSubmitInfrastructureUnavailable as exc: + infrastructure_failure_code = exc.code + + finalize_facts = SelectedPreSubmitFinalizeFacts( + lease=lease, + execution=execution, + infrastructure_failure_code=infrastructure_failure_code, + ) + async with self._session.begin(): + async with self._authority.prepare_finalization( + finalize_facts + ) as prepared: + return await self._coordinator.finalize( + run_id=run_id, + lease=lease, + authority=prepared, + execution=execution, + infrastructure_failure_code=infrastructure_failure_code, + ) + + +__all__ = ("SelectedPreSubmitExecutionService",) diff --git a/backend/app/modules/checkers/api/selected_pre_submit.py b/backend/app/modules/checkers/api/selected_pre_submit.py index db299d071..a7e610640 100644 --- a/backend/app/modules/checkers/api/selected_pre_submit.py +++ b/backend/app/modules/checkers/api/selected_pre_submit.py @@ -4,6 +4,7 @@ from dataclasses import asdict, dataclass from datetime import datetime +from contextlib import AbstractAsyncContextManager from typing import Literal, Protocol from uuid import UUID @@ -233,6 +234,173 @@ def consume( """Return the exact lease once, or refuse stale/substituted execution.""" +class SelectedPreSubmitAdmissionAuthority(Protocol): + """Process-local authority for immediate selected admission.""" + + def consume( + self, + *, + run_id: UUID, + terminal_digest: str, + attempt_id: UUID, + prepared_generation_id: UUID, + archive_sha256: str, + semantic_manifest_sha256: str, + ) -> UUID: + """Consume only for the exact pass and still-live prepared bytes.""" + + +@dataclass(frozen=True, slots=True) +class SelectedPreSubmitExecuteFacts: + """Exact committed lease consumed by the fixed PRE executor.""" + + lease: SelectedPreSubmitLeaseFacts + + def __post_init__(self) -> None: + if type(self.lease) is not SelectedPreSubmitLeaseFacts: + raise ValueError("selected PRE execute facts are invalid") + + @property + def facts_digest(self) -> str: + """Bind reservation, lease generation and database expiry.""" + return canonical_json_hash( + { + "schema_version": "workstream.selected_pre_submit_execute.v1", + "reservation": self.lease.reservation.canonical_body(), + "lease_id": str(self.lease.lease_id), + "lease_generation": self.lease.lease_generation, + "lease_expires_at": self.lease.lease_expires_at.isoformat(), + } + ) + + +@dataclass(frozen=True, slots=True) +class SelectedPreSubmitFinalizeFacts: + """Deterministic terminal input consumed before database-timed finalization.""" + + lease: SelectedPreSubmitLeaseFacts + execution: SelectedPreSubmitExecutionFacts | None + infrastructure_failure_code: str | None + + def __post_init__(self) -> None: + if type(self.lease) is not SelectedPreSubmitLeaseFacts: + raise ValueError("selected PRE finalize lease is invalid") + if (self.execution is None) == (self.infrastructure_failure_code is None): + raise ValueError("selected PRE finalize outcome is invalid") + if self.execution is not None: + if type(self.execution) is not SelectedPreSubmitExecutionFacts: + raise ValueError("selected PRE finalize execution is invalid") + if self.execution.policy_sha256 != self.lease.reservation.policy_sha256: + raise ValueError("selected PRE finalize policy is invalid") + else: + SelectedPreSubmitInfrastructureUnavailable( + self.infrastructure_failure_code or "" + ) + + @property + def facts_digest(self) -> str: + """Bind the lease to either exact results or one closed infrastructure code.""" + return canonical_json_hash( + { + "schema_version": "workstream.selected_pre_submit_finalize.v1", + "execute_facts_digest": SelectedPreSubmitExecuteFacts( + self.lease + ).facts_digest, + "execution": ( + self.execution.canonical_body() + if self.execution is not None + else None + ), + "infrastructure_failure_code": self.infrastructure_failure_code, + } + ) + + +@dataclass(frozen=True, slots=True) +class SelectedPreSubmitAuthorityEvidence: + """One retained AUTH decision bound to exact phase facts.""" + + evidence_id: UUID + facts_digest: str + + def __post_init__(self) -> None: + if ( + type(self.evidence_id) is not UUID + or len(self.facts_digest) != 71 + or not self.facts_digest.startswith("sha256:") + ): + raise ValueError("selected PRE authority evidence is invalid") + + +class PreparedSelectedPreSubmitExecution(Protocol): + """Transaction-bound fixed-service execution authority.""" + + async def consume( + self, facts: SelectedPreSubmitExecuteFacts + ) -> SelectedPreSubmitAuthorityEvidence: + """Consume the exact committed lease once.""" + + +class PreparedSelectedPreSubmitFinalization(Protocol): + """Transaction-bound fixed-service finalization authority.""" + + async def consume( + self, facts: SelectedPreSubmitFinalizeFacts + ) -> SelectedPreSubmitAuthorityEvidence: + """Consume the exact result or infrastructure outcome once.""" + + +class SelectedPreSubmitAuthorityPort(Protocol): + """Prepare separate execute and finalize authority before owner locks.""" + + def prepare_execution( + self, reservation: SelectedPreSubmitReservationFacts + ) -> AbstractAsyncContextManager[PreparedSelectedPreSubmitExecution]: + """Prepare execution authority before TASK/CHECKERS locks in the claim root.""" + + def prepare_finalization( + self, facts: SelectedPreSubmitFinalizeFacts + ) -> AbstractAsyncContextManager[PreparedSelectedPreSubmitFinalization]: + """Prepare exact finalization authority in the terminal root.""" + + +@dataclass(frozen=True, slots=True) +class SelectedPreSubmitCompletion: + """Terminal facts and immediate admission authority from finalization.""" + + terminal: SelectedPreSubmitTerminalFacts + capability: SelectedPreSubmitAdmissionAuthority | None + + +class SelectedPreSubmitCoordinationPort(Protocol): + """CHECKERS-owned durable lease operations used by the ART workflow.""" + + async def claim( + self, + *, + run_id: UUID, + facts: SelectedPreSubmitReservationFacts, + authority: PreparedSelectedPreSubmitExecution, + ) -> SelectedPreSubmitLeaseFacts: + """Claim one queued run under TASK-first custody.""" + + async def committed_execution( + self, *, run_id: UUID, lease: SelectedPreSubmitLeaseFacts + ) -> SelectedPreSubmitExecutionAuthority: + """Mint process-local execution authority for a committed lease.""" + + async def finalize( + self, + *, + run_id: UUID, + lease: SelectedPreSubmitLeaseFacts, + authority: PreparedSelectedPreSubmitFinalization, + execution: SelectedPreSubmitExecutionFacts | None, + infrastructure_failure_code: str | None, + ) -> SelectedPreSubmitCompletion: + """Persist one terminal result and return pass authority when eligible.""" + + @dataclass(frozen=True, slots=True) class SelectedPreSubmitTerminalFacts: """Exact terminal value finalized under a fresh TASK-first transaction.""" @@ -323,8 +491,17 @@ def __init__(self, code: str) -> None: __all__ = ( "ExternalPreSubmitIsolationFacts", "ExternalPreSubmitMemberFacts", + "PreparedSelectedPreSubmitExecution", + "PreparedSelectedPreSubmitFinalization", + "SelectedPreSubmitAdmissionAuthority", + "SelectedPreSubmitAuthorityEvidence", + "SelectedPreSubmitAuthorityPort", + "SelectedPreSubmitCompletion", + "SelectedPreSubmitCoordinationPort", + "SelectedPreSubmitExecuteFacts", "SelectedPreSubmitExecutionFacts", "SelectedPreSubmitInfrastructureUnavailable", + "SelectedPreSubmitFinalizeFacts", "SelectedPreSubmitLeaseFacts", "SelectedPreSubmitReservationFacts", "SelectedPreSubmitTerminalFacts", diff --git a/backend/app/modules/checkers/selected_pre_submit_coordination.py b/backend/app/modules/checkers/selected_pre_submit_coordination.py index ba1c553b1..15939ae83 100644 --- a/backend/app/modules/checkers/selected_pre_submit_coordination.py +++ b/backend/app/modules/checkers/selected_pre_submit_coordination.py @@ -3,7 +3,6 @@ from __future__ import annotations import threading -from dataclasses import dataclass from datetime import timedelta from typing import Protocol from uuid import UUID @@ -14,7 +13,12 @@ from app.core.identifiers import new_record_id from app.modules.checkers.api.selected_pre_submit import ( + PreparedSelectedPreSubmitExecution, + PreparedSelectedPreSubmitFinalization, + SelectedPreSubmitCompletion, + SelectedPreSubmitExecuteFacts, SelectedPreSubmitExecutionFacts, + SelectedPreSubmitFinalizeFacts, SelectedPreSubmitLeaseFacts, SelectedPreSubmitReservationFacts, SelectedPreSubmitTerminalFacts, @@ -35,14 +39,6 @@ async def lock_selected_pre_submit_scope( """Lock and validate exact current TASK scope through caller commit.""" -@dataclass(frozen=True, slots=True) -class SelectedPreSubmitCompletion: - """Terminal facts and one process-local capability for immediate admission.""" - - terminal: SelectedPreSubmitTerminalFacts - capability: SelectedPreSubmitAdmissionCapability | None - - _CAPABILITY_SEAL = object() @@ -273,11 +269,11 @@ async def claim( *, run_id: UUID, facts: SelectedPreSubmitReservationFacts, - execute_evidence_id: UUID, + authority: PreparedSelectedPreSubmitExecution, ) -> SelectedPreSubmitLeaseFacts: """Issue one database-timed lease after fresh TASK and execute authority.""" row = await self._lock(run_id=run_id, facts=facts) - if row.status != "queued" or not isinstance(execute_evidence_id, UUID): + if row.status != "queued": raise SelectedPreSubmitUnavailable("selected_pre_submit_lease_unavailable") now = await self._session.scalar(select(func.clock_timestamp())) assert now is not None @@ -287,10 +283,14 @@ async def claim( lease_generation=row.lease_generation + 1, lease_expires_at=now + timedelta(milliseconds=facts.execution_budget_ms), ) + execute_facts = SelectedPreSubmitExecuteFacts(lease) + evidence = await authority.consume(execute_facts) + if evidence.facts_digest != execute_facts.facts_digest: + raise SelectedPreSubmitUnavailable("selected_pre_submit_execute_evidence_invalid") row.lease_id = str(lease.lease_id) row.lease_generation = lease.lease_generation row.lease_expires_at = lease.lease_expires_at - row.execute_evidence_id = str(execute_evidence_id) + row.execute_evidence_id = str(evidence.evidence_id) row.started_at = now row.status = "running" await self._session.flush() @@ -329,7 +329,7 @@ async def finalize( *, run_id: UUID, lease: SelectedPreSubmitLeaseFacts, - finalize_evidence_id: UUID, + authority: PreparedSelectedPreSubmitFinalization, execution: SelectedPreSubmitExecutionFacts | None, infrastructure_failure_code: str | None, ) -> SelectedPreSubmitCompletion: @@ -341,7 +341,6 @@ async def finalize( or row.lease_id != str(lease.lease_id) or row.lease_generation != lease.lease_generation or row.lease_expires_at != lease.lease_expires_at - or not isinstance(finalize_evidence_id, UUID) ): raise SelectedPreSubmitUnavailable("selected_pre_submit_finalization_unavailable") completed_at = await self._session.scalar(select(func.clock_timestamp())) @@ -349,6 +348,14 @@ async def finalize( if execution is not None and completed_at > lease.lease_expires_at: raise SelectedPreSubmitUnavailable("selected_pre_submit_lease_expired") outcome = "completed" if execution is not None else "infrastructure_failed" + finalize_facts = SelectedPreSubmitFinalizeFacts( + lease=lease, + execution=execution, + infrastructure_failure_code=infrastructure_failure_code, + ) + evidence = await authority.consume(finalize_facts) + if evidence.facts_digest != finalize_facts.facts_digest: + raise SelectedPreSubmitUnavailable("selected_pre_submit_finalize_evidence_invalid") terminal = SelectedPreSubmitTerminalFacts( lease=lease, outcome=outcome, @@ -362,7 +369,7 @@ async def finalize( row.terminal_json = terminal.canonical_body() row.terminal_digest = terminal.terminal_digest row.eligible = execution.eligible if execution is not None else None - row.finalize_evidence_id = str(finalize_evidence_id) + row.finalize_evidence_id = str(evidence.evidence_id) row.completed_at = completed_at await self._session.flush() capability = ( diff --git a/backend/tests/checkers/external/test_selected_pre_submit_coordination.py b/backend/tests/checkers/external/test_selected_pre_submit_coordination.py index fbb89bdd1..05370dc3f 100644 --- a/backend/tests/checkers/external/test_selected_pre_submit_coordination.py +++ b/backend/tests/checkers/external/test_selected_pre_submit_coordination.py @@ -11,6 +11,8 @@ from app.core.identifiers import new_record_id from app.modules.checkers.api.default_checker import WORKSTREAM_DEFAULT_BEHAVIOR_SHA256 from app.modules.checkers.api.selected_pre_submit import ( + SelectedPreSubmitExecuteFacts, + SelectedPreSubmitFinalizeFacts, SelectedPreSubmitLeaseFacts, SelectedPreSubmitReservationFacts, ) @@ -120,3 +122,42 @@ def test_selected_pre_execution_capability_is_exact_and_single_use() -> None: ) == lease with pytest.raises(SelectedPreSubmitUnavailable): capability.consume(run_id=reservation.attempt_id, lease=lease) + + +def test_selected_pre_authority_digests_bind_lease_and_infrastructure_outcome() -> None: + from datetime import UTC, datetime, timedelta + + reservation = _reservation() + lease = SelectedPreSubmitLeaseFacts( + reservation=reservation, + lease_id=new_record_id(), + lease_generation=1, + lease_expires_at=datetime.now(UTC), + ) + execution = SelectedPreSubmitExecuteFacts(lease) + changed = SelectedPreSubmitExecuteFacts( + SelectedPreSubmitLeaseFacts( + reservation=reservation, + lease_id=lease.lease_id, + lease_generation=2, + lease_expires_at=lease.lease_expires_at + timedelta(seconds=1), + ) + ) + terminal = SelectedPreSubmitFinalizeFacts( + lease=lease, + execution=None, + infrastructure_failure_code="deadline_exceeded", + ) + + assert execution.facts_digest != changed.facts_digest + assert terminal.facts_digest != SelectedPreSubmitFinalizeFacts( + lease=lease, + execution=None, + infrastructure_failure_code="material_unavailable", + ).facts_digest + with pytest.raises(ValueError, match="outcome"): + SelectedPreSubmitFinalizeFacts( + lease=lease, + execution=None, + infrastructure_failure_code=None, + ) diff --git a/backend/tests/checkers/external/test_selected_pre_submit_service.py b/backend/tests/checkers/external/test_selected_pre_submit_service.py new file mode 100644 index 000000000..ca7ce731d --- /dev/null +++ b/backend/tests/checkers/external/test_selected_pre_submit_service.py @@ -0,0 +1,172 @@ +"""Selected PRE work stays outside short claim and finalization roots.""" + +from __future__ import annotations + +from contextlib import asynccontextmanager +from datetime import UTC, datetime, timedelta +from types import SimpleNamespace + +import pytest + +from app.core.identifiers import new_record_id +from app.modules.artifacts.selected_pre_submit_execution import ( + SelectedPreSubmitExecutionService, +) +from app.modules.checkers.api.default_checker import ( + WORKSTREAM_DEFAULT_BEHAVIOR_SHA256, +) +from app.modules.checkers.api.selected_pre_submit import ( + SelectedPreSubmitAuthorityEvidence, + SelectedPreSubmitExecuteFacts, + SelectedPreSubmitFinalizeFacts, + SelectedPreSubmitInfrastructureUnavailable, + SelectedPreSubmitLeaseFacts, + SelectedPreSubmitReservationFacts, +) + + +class _Session: + def __init__(self, order: list[str]) -> None: + self.active = False + self.order = order + + @asynccontextmanager + async def begin(self): + assert not self.active + self.active = True + self.order.append("begin") + try: + yield + finally: + self.active = False + self.order.append("commit") + + +class _Prepared: + def __init__(self, order: list[str], phase: str) -> None: + self.order = order + self.phase = phase + + async def consume(self, facts): + self.order.append("consume_" + self.phase) + return SelectedPreSubmitAuthorityEvidence( + evidence_id=new_record_id(), facts_digest=facts.facts_digest + ) + + +class _Authority: + def __init__(self, session: _Session, order: list[str]) -> None: + self.session = session + self.order = order + + @asynccontextmanager + async def prepare_execution(self, _reservation): + assert self.session.active + self.order.append("prepare_execute") + yield _Prepared(self.order, "execute") + + @asynccontextmanager + async def prepare_finalization(self, _facts): + assert self.session.active + self.order.append("prepare_finalize") + yield _Prepared(self.order, "finalize") + + +class _Coordinator: + def __init__(self, session: _Session, order: list[str], lease) -> None: + self.session = session + self.order = order + self.lease = lease + + async def claim(self, *, authority, **_values): + assert self.session.active + self.order.append("claim") + await authority.consume(SelectedPreSubmitExecuteFacts(self.lease)) + return self.lease + + async def committed_execution(self, **_values): + assert not self.session.active + self.order.append("committed_execution") + return object() + + async def finalize(self, *, authority, execution, infrastructure_failure_code, **_values): + assert self.session.active + self.order.append("finalize") + facts = SelectedPreSubmitFinalizeFacts( + lease=self.lease, + execution=execution, + infrastructure_failure_code=infrastructure_failure_code, + ) + await authority.consume(facts) + return SimpleNamespace(terminal=facts, capability=None) + + +class _Materialization: + def __init__(self, session: _Session, order: list[str]) -> None: + self.session = session + self.order = order + + async def materialize_selected_pre_submit(self, *_args, **_kwargs): + assert not self.session.active + self.order.append("materialize") + raise SelectedPreSubmitInfrastructureUnavailable("material_unavailable") + + +def _reservation() -> SelectedPreSubmitReservationFacts: + return SelectedPreSubmitReservationFacts( + actor_profile_id=new_record_id(), + identity_link_id=new_record_id(), + project_id=new_record_id(), + task_id=new_record_id(), + assignment_id=new_record_id(), + attempt_id=new_record_id(), + attempt_request_digest="sha256:" + "0" * 64, + prepared_generation_id=new_record_id(), + policy_sha256="sha256:" + "1" * 64, + default_behavior_sha256=WORKSTREAM_DEFAULT_BEHAVIOR_SHA256, + default_input_sha256="sha256:" + "2" * 64, + archive_sha256="sha256:" + "3" * 64, + archive_byte_count=100, + semantic_manifest_sha256="sha256:" + "4" * 64, + execution_budget_ms=60_000, + ) + + +@pytest.mark.asyncio +async def test_selected_pre_execution_commits_lease_before_work_and_finalizes_after() -> None: + order: list[str] = [] + session = _Session(order) + reservation = _reservation() + lease = SelectedPreSubmitLeaseFacts( + reservation=reservation, + lease_id=new_record_id(), + lease_generation=1, + lease_expires_at=datetime.now(UTC) + timedelta(minutes=1), + ) + service = SelectedPreSubmitExecutionService( + session=session, + coordinator=_Coordinator(session, order, lease), + authority=_Authority(session, order), + materialization=_Materialization(session, order), + ) + + completed = await service.execute( + reservation=reservation, + materialization=SimpleNamespace(), + ) + + assert completed.terminal.infrastructure_failure_code == "material_unavailable" + assert order == [ + "begin", + "prepare_execute", + "claim", + "consume_execute", + "commit", + "committed_execution", + "materialize", + "begin", + "prepare_finalize", + "finalize", + "consume_finalize", + "commit", + ] From c0e119b5a9410d1831ea383cb896f092fa519aa2 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 19:58:26 +0100 Subject: [PATCH 064/283] [PILOT-04] Authorize selected PRE phases --- .ci/auth-boundaries/TEST_STRUCTURE_DEBT.json | 10 +- .../pilot04-workstream-default-checker.md | 6 +- backend/app/adapters/auth/__init__.py | 9 + .../modules/actors/api/service_identities.py | 1 + backend/app/modules/audit/schemas.py | 2 +- .../modules/authorization/admin_schemas.py | 2 +- .../app/modules/authorization/catalogue.py | 23 ++- .../authorization/domain/action_groups.py | 2 + .../app/modules/authorization/domain/audit.py | 2 + .../authorization/domain/audit_targets.py | 3 +- .../authorization/domain/pre_submit.py | 121 ++++++++++++ .../authorization/domain/prepared_service.py | 17 +- .../authorization/domain/resource_digest.py | 4 + .../authorization/pre_submit_authorization.py | 105 +++++++++++ backend/app/modules/authorization/prepared.py | 14 +- backend/app/modules/authorization/runtime.py | 2 + .../checkers/api/selected_pre_submit.py | 5 + .../tests/authorization/catalogue_fixtures.py | 8 +- .../pre_submit/test_contracts.py | 173 ++++++++++++++++++ backend/tests/authorization/test_catalogue.py | 10 +- .../test_default_pre_submit_execution.py | 23 +-- 21 files changed, 503 insertions(+), 39 deletions(-) create mode 100644 backend/app/modules/authorization/domain/pre_submit.py create mode 100644 backend/app/modules/authorization/pre_submit_authorization.py create mode 100644 backend/tests/authorization/pre_submit/test_contracts.py diff --git a/.ci/auth-boundaries/TEST_STRUCTURE_DEBT.json b/.ci/auth-boundaries/TEST_STRUCTURE_DEBT.json index b59fbe8fa..5f944e184 100644 --- a/.ci/auth-boundaries/TEST_STRUCTURE_DEBT.json +++ b/.ci/auth-boundaries/TEST_STRUCTURE_DEBT.json @@ -122,11 +122,11 @@ }, { "capability": "oversized_authorization_structure", - "content_sha256": "d84433a6faaf6bafb0cb44e6d35431c375b15529fce32873a5b265a0a6e5c134", - "end_line": 1561, + "content_sha256": "5be930834a7b5694625231f2f3412f1dd0930f9ae754e7907c0063e4b13bc052", + "end_line": 1558, "hard_limit": 1200, "kind": "test_file", - "observed_lines": 1561, + "observed_lines": 1558, "path": "backend/tests/test_default_pre_submit_execution.py", "qualified_symbol": null, "removal_chunk": "WS-AUTH-003-CLOSE", @@ -399,14 +399,14 @@ { "capability": "oversized_authorization_structure", "content_sha256": "c8f454738457615f8e183744c677e8384ef01c27f5dac2b352caf84f4c77b2d1", - "end_line": 931, + "end_line": 928, "hard_limit": 120, "kind": "test_function", "observed_lines": 487, "path": "backend/tests/test_default_pre_submit_execution.py", "qualified_symbol": "test_effective_evidence_workflow_persists_once_and_replays_exactly", "removal_chunk": "WS-AUTH-003-CLOSE", - "start_line": 445 + "start_line": 442 }, { "capability": "oversized_authorization_structure", diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index aadc401c8..3a9a5bbdc 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -44,6 +44,9 @@ TASK/CHECKERS locks, commits the database-timed lease before exposing material, executes through one exact process-local ART capability with no transaction open, then uses a distinct short root to authorize and finalize the exact result or one closed recoverable infrastructure outcome. +Its closed AUTH contract now assigns those two phases to the dedicated selected +PRE service principal and binds preparation, scope, the durable request and the +exact execute/finalize fact digest without granting direct service access. The selected POST processor consumes only actual Submission and ART material through the phase-typed callback grant, runs every locked POST image in order, and returns canonical evidence and observed isolation without any acceptance @@ -201,7 +204,8 @@ intermediate-wait regression. | Selected durable result contract | `pytest -q backend/tests/checkers/external/test_selected_pre_submit.py`; Ruff and `git diff --check` on the affected files | 5 passed; canonical result/terminal digests bind the default, ordered external results, isolation, generation lease, outcome and measured queue/execution latency | PostgreSQL reservation, lease and finalize storage remain pending | | Selected durable request contract | The same five selected-PRE tests plus focused Ruff and `git diff --check` | Passed; the reservation digest covers contributor/link, TASK, assignment, ART attempt/generation, policy/default, exact default input and archive/manifest custody, and the terminal includes that request digest | PostgreSQL ownership and SQL custody remain pending | | Selected durable owner source | `pytest -q` over selected PRE, policy, coordination, PROJECT activation/proposal contracts and architecture module boundaries; focused Ruff | 51 focused/architecture tests passed; the selected run is its own durable attempt identity, TASK locks precede CHECKERS state, one-use admission facts are substitution-resistant, ordered deadlines fit ART custody, and four private module edges were removed through public ports/composition | Native migration, exact AUTH SQL closure, crash reclaim and admission composition remain pending | -| Selected lease execution boundary | `pytest -q backend/tests/checkers/external/test_selected_pre_submit_coordination.py backend/tests/checkers/external/test_selected_pre_submit_service.py backend/tests/checkers/external/test_selected_pre_submit.py backend/tests/architecture/test_module_boundaries.py`; focused Ruff | 49 passed; fixed-service preparation precedes owner locks, the lease commits before material execution, execution occurs with no root open, and exact lease/result digests are consumed in a separate finalization root | Concrete AUTH registration, native SQL custody and live admission selection remain pending | +| Selected lease execution boundary | `pytest -q backend/tests/checkers/external/test_selected_pre_submit_coordination.py backend/tests/checkers/external/test_selected_pre_submit_service.py backend/tests/checkers/external/test_selected_pre_submit.py backend/tests/architecture/test_module_boundaries.py`; focused Ruff | 49 passed; fixed-service preparation precedes owner locks, the lease commits before material execution, execution occurs with no root open, and exact lease/result digests are consumed in a separate finalization root | Native SQL custody and live admission selection remain pending | +| Selected PRE authority contract | `pytest -q backend/tests/authorization/pre_submit/test_contracts.py backend/tests/authorization/test_catalogue.py backend/tests/checkers/external/test_selected_pre_submit_service.py backend/tests/architecture/test_module_boundaries.py`; focused Ruff and `git diff --check` | 50 passed; one dedicated service identity owns only execute/finalize, prepared selectors bind project/run/request, exact phase facts bind the decision and audit digest, direct service calls remain unavailable, and composition uses the public authority port | Native actor/action/evidence constraints and live workflow injection remain pending | | Selected POST callback | `pytest -q backend/tests/checkers/external/test_selected_post_submit.py`; Ruff and `git diff --check` on the affected files | 3 passed; actual Submission/ART identity reaches every locked POST image through its short-lived grant, work pass/fail remains evidence only, and infrastructure failure stays recoverable | Durable POST reservation/finalization, worker restart and routing composition remain pending | | Owner/caller trace | PROJECT approval/activation, ART preparation/admission, TASK composition and CHECKERS dispatch | In progress | Persistence delta and migration ordinal await actual linear predecessor | | End-to-end replacement | Real PostgreSQL/MinIO/Rust public and worker journey | Not run | Implementation incomplete | diff --git a/backend/app/adapters/auth/__init__.py b/backend/app/adapters/auth/__init__.py index 4deb60ef1..462ddf5ba 100644 --- a/backend/app/adapters/auth/__init__.py +++ b/backend/app/adapters/auth/__init__.py @@ -274,6 +274,15 @@ def post_submit_execution_authority(session): return PostSubmitExecutionAuthorization(session) +def selected_pre_submit_authority(session): + """Compose fixed selected-PRE execute/finalize authority.""" + from app.modules.authorization.pre_submit_authorization import ( + SelectedPreSubmitAuthorization, + ) + + return SelectedPreSubmitAuthorization(session) + + def post_submit_materialization_authority(session): """Compose the separate fixed ART materializer principal.""" from app.modules.authorization.post_submit_authorization import PostSubmitMaterializationAuthorization diff --git a/backend/app/modules/actors/api/service_identities.py b/backend/app/modules/actors/api/service_identities.py index 915a4ec27..9b89804f2 100644 --- a/backend/app/modules/actors/api/service_identities.py +++ b/backend/app/modules/actors/api/service_identities.py @@ -16,6 +16,7 @@ class ServiceIdentity(StrEnum): ARTIFACT_CHECKER_OUTPUT = "workstream.artifact.checker_output" TASK_ASSIGNMENT_RECONCILER = "workstream.task.assignment_reconciler" TASK_POST_SUBMIT_ROUTER = "workstream.task.post_submit_router" + CHECKER_PRE_SUBMIT = "workstream.checker.pre_submit" CHECKER_POST_SUBMIT = "workstream.checker.post_submit" OUTBOX_DISPATCHER = "workstream.outbox.dispatcher" PROJECT_SETUP = "workstream.project.setup" diff --git a/backend/app/modules/audit/schemas.py b/backend/app/modules/audit/schemas.py index 71d106dc1..2602256b5 100644 --- a/backend/app/modules/audit/schemas.py +++ b/backend/app/modules/audit/schemas.py @@ -34,7 +34,7 @@ } ) _RESOURCE_TYPES = frozenset( - """task_post_submit_routing_manifest joint_lifecycle_control checker_run outbox_event actor_profile actor_identity_link admin_role_grant project qualification_snapshot project_role_grant task + """task_post_submit_routing_manifest joint_lifecycle_control checker_run selected_pre_submit_run outbox_event actor_profile actor_identity_link admin_role_grant project qualification_snapshot project_role_grant task submission submission_creation submission_binding review contribution compensation_award compensation_delivery compensation_adapter_binding contribution_policy operations audit_event project_create_operation project_submission_artifact_policy_mutation project_guide_activation pre_submit_checker_input project_guide_compilation_request diff --git a/backend/app/modules/authorization/admin_schemas.py b/backend/app/modules/authorization/admin_schemas.py index d0fc7e9f7..9df53da77 100644 --- a/backend/app/modules/authorization/admin_schemas.py +++ b/backend/app/modules/authorization/admin_schemas.py @@ -35,7 +35,7 @@ class PermissionDefinitionsResponse(BaseModel): model_config = _STRICT items: tuple[PermissionDefinitionResponse, ...] - total: Literal[78] + total: Literal[80] class AdminRoleDefinitionResponse(BaseModel): diff --git a/backend/app/modules/authorization/catalogue.py b/backend/app/modules/authorization/catalogue.py index bf9ad0026..f344eff5a 100644 --- a/backend/app/modules/authorization/catalogue.py +++ b/backend/app/modules/authorization/catalogue.py @@ -24,6 +24,8 @@ class PermissionId(StrEnum): ACTOR_IDENTITY_LINK_REACTIVATE = "actor.identity_link.reactivate" TASK_ASSIGNMENT_AUTHORITY_RECONCILE = "task.assignment.authority_reconcile" TASK_POST_SUBMIT_ROUTE = "task.post_submit.route" + CHECKER_PRE_SUBMIT_EXECUTE = "checker.pre_submit.execute" + CHECKER_PRE_SUBMIT_FINALIZE = "checker.pre_submit.finalize" CHECKER_POST_SUBMIT_EXECUTE = "checker.post_submit.execute" CHECKER_POST_SUBMIT_FINALIZE = "checker.post_submit.finalize" OUTBOX_DISPATCH = "outbox.dispatch" @@ -143,6 +145,8 @@ class ActionId(StrEnum): ACTOR_IDENTITY_LINK_REACTIVATE = "actor.identity_link.reactivate" TASK_ASSIGNMENT_AUTHORITY_RECONCILE = "task.assignment.authority_reconcile" TASK_POST_SUBMIT_ROUTE = "task.post_submit.route" + CHECKER_PRE_SUBMIT_EXECUTE = "checker.pre_submit.execute" + CHECKER_PRE_SUBMIT_FINALIZE = "checker.pre_submit.finalize" CHECKER_POST_SUBMIT_EXECUTE = "checker.post_submit.execute" CHECKER_POST_SUBMIT_FINALIZE = "checker.post_submit.finalize" OUTBOX_DISPATCH = "outbox.dispatch" @@ -675,6 +679,8 @@ def _active( PermissionId.ARTIFACT_PUT_ATTEMPT_RESOLVE, ActionOwner.AUTH_ART_02D_INTERNAL, ), + _active(ActionId.CHECKER_PRE_SUBMIT_EXECUTE, PermissionId.CHECKER_PRE_SUBMIT_EXECUTE, ActionOwner.PILOT_04), + _active(ActionId.CHECKER_PRE_SUBMIT_FINALIZE, PermissionId.CHECKER_PRE_SUBMIT_FINALIZE, ActionOwner.PILOT_04), _active(ActionId.CHECKER_POST_SUBMIT_EXECUTE, PermissionId.CHECKER_POST_SUBMIT_EXECUTE, ActionOwner.ARCH_04D2), _active(ActionId.CHECKER_POST_SUBMIT_FINALIZE, PermissionId.CHECKER_POST_SUBMIT_FINALIZE, ActionOwner.ARCH_04D2), _active( @@ -740,6 +746,8 @@ def _active( { PermissionId.CHECKER_POST_SUBMIT_EXECUTE, PermissionId.CHECKER_POST_SUBMIT_FINALIZE, + PermissionId.CHECKER_PRE_SUBMIT_EXECUTE, + PermissionId.CHECKER_PRE_SUBMIT_FINALIZE, PermissionId.TASK_ASSIGNMENT_AUTHORITY_RECONCILE, PermissionId.OUTBOX_DISPATCH, PermissionId.PROJECT_SETUP_DIAGNOSTIC_READ, @@ -774,9 +782,9 @@ def _active( def _require_catalogue_counts() -> None: """Keep the closed action inventory and permission boundary exact.""" - if len(PERMISSION_IDS) != 78 or len(ACTION_IDS) != 150: + if len(PERMISSION_IDS) != 80 or len(ACTION_IDS) != 152: raise RuntimeError("authorization catalogue count mismatch") - if len(HISTORICAL_PERMISSION_IDS) != 49 or len(NEW_PERMISSION_IDS) != 29: + if len(HISTORICAL_PERMISSION_IDS) != 49 or len(NEW_PERMISSION_IDS) != 31: raise RuntimeError("authorization permission boundary mismatch") @@ -897,8 +905,8 @@ def _index_actions(definitions: tuple[ActionDefinition, ...]) -> MappingProxyTyp ActionId.ARTIFACT_PUT_ATTEMPT_RESOLVE, ActionId.ARTIFACT_PRE_SUBMIT_CHECKER_INPUT_MATERIALIZE, ActionId.ARTIFACT_POST_SUBMIT_CHECKER_INPUT_MATERIALIZE, - ActionId.CHECKER_POST_SUBMIT_EXECUTE, - ActionId.CHECKER_POST_SUBMIT_FINALIZE, + ActionId.CHECKER_POST_SUBMIT_EXECUTE, ActionId.CHECKER_POST_SUBMIT_FINALIZE, + ActionId.CHECKER_PRE_SUBMIT_EXECUTE, ActionId.CHECKER_PRE_SUBMIT_FINALIZE, ActionId.COMPENSATION_ADAPTER_BINDING_READ, ActionId.COMPENSATION_ADAPTER_BINDING_CREATE, ActionId.COMPENSATION_ADAPTER_BINDING_SUSPEND, @@ -930,6 +938,7 @@ def _index_actions(definitions: tuple[ActionDefinition, ...]) -> MappingProxyTyp _SERVICE_ACTIONS = { ServiceIdentity.TASK_POST_SUBMIT_ROUTER: frozenset({ActionId.TASK_POST_SUBMIT_ROUTE}), + ServiceIdentity.CHECKER_PRE_SUBMIT: frozenset({ActionId.CHECKER_PRE_SUBMIT_EXECUTE, ActionId.CHECKER_PRE_SUBMIT_FINALIZE}), ServiceIdentity.CHECKER_POST_SUBMIT: frozenset({ActionId.CHECKER_POST_SUBMIT_EXECUTE, ActionId.CHECKER_POST_SUBMIT_FINALIZE}), ServiceIdentity.TASK_ASSIGNMENT_RECONCILER: frozenset({ActionId.TASK_ASSIGNMENT_AUTHORITY_RECONCILE}), ServiceIdentity.OUTBOX_DISPATCHER: frozenset({ActionId.OUTBOX_DISPATCH}), @@ -982,6 +991,8 @@ def _index_actions(definitions: tuple[ActionDefinition, ...]) -> MappingProxyTyp (identity, action) for identity, action in ( (ServiceIdentity.TASK_POST_SUBMIT_ROUTER, ActionId.TASK_POST_SUBMIT_ROUTE), + (ServiceIdentity.CHECKER_PRE_SUBMIT, ActionId.CHECKER_PRE_SUBMIT_EXECUTE), + (ServiceIdentity.CHECKER_PRE_SUBMIT, ActionId.CHECKER_PRE_SUBMIT_FINALIZE), (ServiceIdentity.CHECKER_POST_SUBMIT, ActionId.CHECKER_POST_SUBMIT_EXECUTE), (ServiceIdentity.CHECKER_POST_SUBMIT, ActionId.CHECKER_POST_SUBMIT_FINALIZE), (ServiceIdentity.TASK_ASSIGNMENT_RECONCILER, ActionId.TASK_ASSIGNMENT_AUTHORITY_RECONCILE), @@ -1026,6 +1037,8 @@ def _index_actions(definitions: tuple[ActionDefinition, ...]) -> MappingProxyTyp _ACTIVE_SERVICE_ACTIONS = { + ActionId.CHECKER_PRE_SUBMIT_EXECUTE, + ActionId.CHECKER_PRE_SUBMIT_FINALIZE, ActionId.TASK_POST_SUBMIT_ROUTE, ActionId.CHECKER_POST_SUBMIT_EXECUTE, ActionId.CHECKER_POST_SUBMIT_FINALIZE, @@ -1052,6 +1065,8 @@ def _index_service_actions( ) -> MappingProxyType[ServiceIdentity, frozenset[ActionId]]: expected_metadata = { ActionId.TASK_POST_SUBMIT_ROUTE: (PermissionId.TASK_POST_SUBMIT_ROUTE, ActionOwner.ARCH_04E2), + ActionId.CHECKER_PRE_SUBMIT_EXECUTE: (PermissionId.CHECKER_PRE_SUBMIT_EXECUTE, ActionOwner.PILOT_04), + ActionId.CHECKER_PRE_SUBMIT_FINALIZE: (PermissionId.CHECKER_PRE_SUBMIT_FINALIZE, ActionOwner.PILOT_04), ActionId.CHECKER_POST_SUBMIT_EXECUTE: (PermissionId.CHECKER_POST_SUBMIT_EXECUTE, ActionOwner.ARCH_04D2), ActionId.CHECKER_POST_SUBMIT_FINALIZE: (PermissionId.CHECKER_POST_SUBMIT_FINALIZE, ActionOwner.ARCH_04D2), ActionId.TASK_ASSIGNMENT_AUTHORITY_RECONCILE: (PermissionId.TASK_ASSIGNMENT_AUTHORITY_RECONCILE, ActionOwner.ARCH_03C1), diff --git a/backend/app/modules/authorization/domain/action_groups.py b/backend/app/modules/authorization/domain/action_groups.py index 027bf6fee..a8ad94f8f 100644 --- a/backend/app/modules/authorization/domain/action_groups.py +++ b/backend/app/modules/authorization/domain/action_groups.py @@ -43,6 +43,8 @@ ActionId.ARTIFACT_TASK_IMPORT_SOURCE_DECLARE, ActionId.ARTIFACT_TASK_IMPORT_SOURCE_UPLOAD, ActionId.ARTIFACT_TASK_IMPORT_SOURCE_READ, + ActionId.CHECKER_PRE_SUBMIT_EXECUTE, + ActionId.CHECKER_PRE_SUBMIT_FINALIZE, ActionId.TASK_QUEUE_READ, ActionId.PROJECT_TASK_QUEUE_READ, ActionId.OPERATIONS_TASK_QUEUE_READ, ActionId.PROJECT_CREATE, *GUIDE_BOUND_PROJECT_MANAGER_ACTIONS, diff --git a/backend/app/modules/authorization/domain/audit.py b/backend/app/modules/authorization/domain/audit.py index 369d46a04..1b956804d 100644 --- a/backend/app/modules/authorization/domain/audit.py +++ b/backend/app/modules/authorization/domain/audit.py @@ -17,6 +17,7 @@ "submission_binding", "outbox_event", "checker_run", + "selected_pre_submit_run", "task_post_submit_routing_manifest", "task_authority", "task_submission_history", @@ -50,6 +51,7 @@ "joint_lifecycle_control", "outbox_event", "checker_run", + "selected_pre_submit_run", "task_post_submit_routing_manifest", "task_authority", "task_submission_history", diff --git a/backend/app/modules/authorization/domain/audit_targets.py b/backend/app/modules/authorization/domain/audit_targets.py index 9fb8344b2..54cea9783 100644 --- a/backend/app/modules/authorization/domain/audit_targets.py +++ b/backend/app/modules/authorization/domain/audit_targets.py @@ -6,6 +6,7 @@ from app.modules.authorization.domain.lifecycle import ReviewLifecycleActivationContract from app.modules.authorization.domain.post_submit_routing import PostSubmitRoutingResourceContext from app.modules.authorization.domain.post_submit import PostSubmitResourceContext +from app.modules.authorization.domain.pre_submit import PreSubmitResourceContext from app.modules.authorization.domain.assignment_invalidation import AssignmentInvalidationResourceContext from app.modules.authorization.domain.outbox_dispatch import OutboxDispatchResourceContext from app.modules.authorization.domain.guide_proposals import GuideProposalResourceContext @@ -103,7 +104,7 @@ def project_authority_audit_target( AdapterBindingMutationResourceContext, ProjectGuideProjectionResourceContext, ProjectSetupFinalizationResourceContext, - GuideProposalResourceContext, PostPolicyResourceContext, OutboxDispatchResourceContext, PostSubmitResourceContext, PostSubmitRoutingResourceContext, + GuideProposalResourceContext, PostPolicyResourceContext, OutboxDispatchResourceContext, PreSubmitResourceContext, PostSubmitResourceContext, PostSubmitRoutingResourceContext, ), ): project_id = str(getattr(resource, "project_id", None) or resource.scope_project_id) diff --git a/backend/app/modules/authorization/domain/pre_submit.py b/backend/app/modules/authorization/domain/pre_submit.py new file mode 100644 index 000000000..e3489ac53 --- /dev/null +++ b/backend/app/modules/authorization/domain/pre_submit.py @@ -0,0 +1,121 @@ +"""Exact fixed-service resources for selected pre-submit execution phases.""" + +from __future__ import annotations + +import re +from typing import Literal +from uuid import UUID + +from pydantic import BaseModel, ConfigDict, model_validator + +from app.modules.authorization.catalogue import ActionId +from app.modules.checkers.api.selected_pre_submit import ( + SelectedPreSubmitExecuteFacts, + SelectedPreSubmitFinalizeFacts, + SelectedPreSubmitReservationFacts, +) + + +EXECUTE = ActionId.CHECKER_PRE_SUBMIT_EXECUTE +FINALIZE = ActionId.CHECKER_PRE_SUBMIT_FINALIZE +PRE_SUBMIT_ACTIONS = frozenset({EXECUTE, FINALIZE}) + + +class PreSubmitResourceContext(BaseModel): + """One selected run phase under its exact project and durable request.""" + + model_config = ConfigDict(extra="forbid", frozen=True, strict=True) + resource_type: Literal["selected_pre_submit_run"] = "selected_pre_submit_run" + resource_id: UUID + scope_project_id: UUID + action_id: ActionId + facts: SelectedPreSubmitExecuteFacts | SelectedPreSubmitFinalizeFacts + + @model_validator(mode="after") + def validate_identity(self): + expected = ( + SelectedPreSubmitExecuteFacts + if self.action_id is EXECUTE + else SelectedPreSubmitFinalizeFacts + if self.action_id is FINALIZE + else None + ) + if expected is None or type(self.facts) is not expected: + raise ValueError("invalid selected PRE authority phase") + reservation = self.facts.lease.reservation + if ( + self.resource_id != reservation.attempt_id + or self.scope_project_id != reservation.project_id + ): + raise ValueError("invalid selected PRE authority resource") + return self + + +def pre_submit_resource( + action: ActionId, + facts: SelectedPreSubmitExecuteFacts | SelectedPreSubmitFinalizeFacts, +) -> PreSubmitResourceContext: + """Build a typed exact-run resource without provider or workspace facts.""" + reservation = facts.lease.reservation + return PreSubmitResourceContext( + action_id=action, + resource_id=reservation.attempt_id, + scope_project_id=reservation.project_id, + facts=facts, + ) + + +def pre_submit_prepare_values( + reservation: SelectedPreSubmitReservationFacts, +) -> dict[str, str]: + """Bind fixed-service preparation to the selected request before owner locks.""" + return { + "project_id": str(reservation.project_id), + "run_id": str(reservation.attempt_id), + "request_digest": reservation.request_digest, + } + + +def parse_pre_submit_prepare(action, values, invalid_error): + """Reject extra or malformed fixed-service selectors.""" + if action not in PRE_SUBMIT_ACTIONS: + return None + try: + if set(values) != {"project_id", "run_id", "request_digest"}: + raise ValueError("invalid keys") + for key in ("project_id", "run_id"): + if type(values[key]) is not str or str(UUID(values[key])) != values[key]: + raise ValueError("invalid identity") + if ( + type(values["request_digest"]) is not str + or re.fullmatch(r"sha256:[0-9a-f]{64}", values["request_digest"]) + is None + ): + raise ValueError("invalid digest") + except (KeyError, TypeError, ValueError) as error: + raise invalid_error("invalid prepared selected PRE authority") from error + return dict(values) + + +def pre_submit_prepare_matches(action, prepared, resource) -> bool: + """Match final phase facts to the exact prepared selected request.""" + if ( + action not in PRE_SUBMIT_ACTIONS + or type(resource) is not PreSubmitResourceContext + or resource.action_id is not action + ): + return False + resource.validate_identity() + return prepared == pre_submit_prepare_values(resource.facts.lease.reservation) + + +__all__ = ( + "EXECUTE", + "FINALIZE", + "PRE_SUBMIT_ACTIONS", + "PreSubmitResourceContext", + "parse_pre_submit_prepare", + "pre_submit_prepare_matches", + "pre_submit_prepare_values", + "pre_submit_resource", +) diff --git a/backend/app/modules/authorization/domain/prepared_service.py b/backend/app/modules/authorization/domain/prepared_service.py index f5e498f65..e99a2a46b 100644 --- a/backend/app/modules/authorization/domain/prepared_service.py +++ b/backend/app/modules/authorization/domain/prepared_service.py @@ -10,6 +10,11 @@ from app.modules.authorization.domain.post_submit import ( POST_SUBMIT_ACTIONS, PostSubmitResourceContext, parse_post_submit_prepare, ) +from app.modules.authorization.domain.pre_submit import ( + PRE_SUBMIT_ACTIONS, + PreSubmitResourceContext, + parse_pre_submit_prepare, +) from app.modules.authorization.domain.assignment_invalidation import AssignmentInvalidationResourceContext, parse_assignment_invalidation_binding from app.modules.authorization.domain.outbox_dispatch import OutboxDispatchResourceContext, prepared_outbox_digest from app.modules.authorization.domain.post_policy import PostPolicyResourceContext, DERIVE @@ -107,7 +112,8 @@ def fixed_service_scope_project(action_id, scope, artifact_resource): outbox = (action_id in {ActionId.OUTBOX_DISPATCH, ActionId.TASK_ASSIGNMENT_AUTHORITY_RECONCILE} and scope.kind is PreparedAuthorityScopeKind.PROJECT and scope.project_id is not None) if is_project_setup_scope(action_id, scope) or outbox or ( - action_id in POST_SUBMIT_ACTIONS | {ROUTE} and scope.kind is PreparedAuthorityScopeKind.PROJECT + action_id in PRE_SUBMIT_ACTIONS | POST_SUBMIT_ACTIONS | {ROUTE} + and scope.kind is PreparedAuthorityScopeKind.PROJECT and scope.project_id is not None ): return scope.project_id @@ -125,6 +131,12 @@ def fixed_service_resource_matches(action_id, resource, project_id, artifact_typ if action_id in POST_SUBMIT_ACTIONS: return (type(resource) is PostSubmitResourceContext and resource.action_id is action_id and resource.scope_project_id == project_id) + if action_id in PRE_SUBMIT_ACTIONS: + return ( + type(resource) is PreSubmitResourceContext + and resource.action_id is action_id + and resource.scope_project_id == project_id + ) if action_id is ActionId.TASK_ASSIGNMENT_AUTHORITY_RECONCILE: return type(resource) is AssignmentInvalidationResourceContext and resource.scope_project_id == project_id if action_id is ActionId.OUTBOX_DISPATCH: @@ -146,6 +158,9 @@ def prepared_fixed_service_bindings(action, request, invalid_error): if action is ROUTE: return {"routing_request": parse_post_submit_routing_prepare(action, request, invalid_error)} return { + "pre_submit_prepare_context": parse_pre_submit_prepare( + action, request, invalid_error + ), "post_submit_prepare_context": parse_post_submit_prepare(action, request, invalid_error), "assignment_invalidation_context": parse_assignment_invalidation_binding(action, request, invalid_error), "outbox_dispatch_digest": prepared_outbox_digest(action, request, invalid_error), diff --git a/backend/app/modules/authorization/domain/resource_digest.py b/backend/app/modules/authorization/domain/resource_digest.py index c0b5b4f84..885ba838c 100644 --- a/backend/app/modules/authorization/domain/resource_digest.py +++ b/backend/app/modules/authorization/domain/resource_digest.py @@ -3,6 +3,7 @@ from pydantic import BaseModel from app.modules.authorization.domain.post_submit_routing import PostSubmitRoutingResourceContext, post_submit_routing_resource_digest from app.modules.authorization.domain.post_submit import PostSubmitResourceContext, post_submit_digest +from app.modules.authorization.domain.pre_submit import PreSubmitResourceContext from app.modules.authorization.domain.assignment_invalidation import AssignmentInvalidationResourceContext from app.modules.tasks.api.assignment_invalidation import assignment_invalidation_resource_digest from app.modules.authorization.domain.outbox_dispatch import OutboxDispatchResourceContext @@ -30,6 +31,9 @@ def authorization_resource_digest(resource: BaseModel) -> str: if type(resource) is PostSubmitResourceContext: resource.validate_identity() return post_submit_digest(resource.facts) + if type(resource) is PreSubmitResourceContext: + resource.validate_identity() + return resource.facts.facts_digest if type(resource) is AssignmentInvalidationResourceContext: resource.validate_identity() return assignment_invalidation_resource_digest(resource.facts) diff --git a/backend/app/modules/authorization/pre_submit_authorization.py b/backend/app/modules/authorization/pre_submit_authorization.py new file mode 100644 index 000000000..d817018f5 --- /dev/null +++ b/backend/app/modules/authorization/pre_submit_authorization.py @@ -0,0 +1,105 @@ +"""Fixed selected-PRE principal through canonical AUTH/PREP.""" + +from __future__ import annotations + +from contextlib import asynccontextmanager, contextmanager + +from app.modules.actors.api import ServiceIdentity +from app.modules.authorization.domain.pre_submit import ( + EXECUTE, + FINALIZE, + pre_submit_prepare_values, + pre_submit_resource, +) +from app.modules.authorization.prepared import fixed_service_prepared_authorization +from app.modules.authorization.runtime import ( + AuthorizationDenied, + AuthorizationEvidenceUnavailable, + PreparedAuthorizationHandleInvalid, + PreparedAuthorizationInput, + PreparedAuthorizationUnsupported, + PreparedAuthorityScope, + PreparedAuthorityScopeKind, +) +from app.modules.checkers.api.selected_pre_submit import ( + SelectedPreSubmitAuthorityEvidence, + SelectedPreSubmitAuthorityUnavailable, +) + + +@contextmanager +def _authority_errors(): + try: + yield + except ( + AuthorizationDenied, + AuthorizationEvidenceUnavailable, + PreparedAuthorizationHandleInvalid, + PreparedAuthorizationUnsupported, + ) as error: + raise SelectedPreSubmitAuthorityUnavailable( + "selected_pre_submit_authority_unavailable" + ) from error + + +class _PreparedPhase: + def __init__(self, service, handle, caller_input, action): + self._service = service + self._handle = handle + self._input = caller_input + self._action = action + + async def consume(self, facts): + with _authority_errors(): + decision = await self._service.consume( + self._handle, + self._action, + self._input, + pre_submit_resource(self._action, facts), + ) + return SelectedPreSubmitAuthorityEvidence( + evidence_id=decision.decision_id, + facts_digest=facts.facts_digest, + ) + + +@asynccontextmanager +async def _prepare(session, action, reservation): + """Acquire the fixed principal before selected owner locks.""" + values = pre_submit_prepare_values(reservation) + with _authority_errors(): + async with fixed_service_prepared_authorization( + session, + service_identity=ServiceIdentity.CHECKER_PRE_SUBMIT, + request_id=reservation.attempt_id, + correlation_id=reservation.attempt_id, + ) as authority: + caller_input = PreparedAuthorizationInput( + idempotency_key=reservation.attempt_id, + request_value=values, + ) + handle = await authority.service.prepare( + action, + caller_input, + PreparedAuthorityScope( + kind=PreparedAuthorityScopeKind.PROJECT, + project_id=reservation.project_id, + ), + ) + yield _PreparedPhase(authority.service, handle, caller_input, action) + + +class SelectedPreSubmitAuthorization: + """Expose only execute and finalize for the fixed selected-PRE principal.""" + + def __init__(self, session): + self._session = session + + def prepare_execution(self, reservation): + return _prepare(self._session, EXECUTE, reservation) + + def prepare_finalization(self, facts): + return _prepare(self._session, FINALIZE, facts.lease.reservation) + + +__all__ = ("SelectedPreSubmitAuthorization",) diff --git a/backend/app/modules/authorization/prepared.py b/backend/app/modules/authorization/prepared.py index 4b3b69096..6a8e67bd3 100644 --- a/backend/app/modules/authorization/prepared.py +++ b/backend/app/modules/authorization/prepared.py @@ -127,6 +127,11 @@ ) from app.modules.tasks.api.post_submit_routing import TaskRoutingRequestFacts from app.modules.authorization.domain.post_submit import POST_SUBMIT_ACTIONS, PostSubmitResourceContext, post_submit_prepare_matches +from app.modules.authorization.domain.pre_submit import ( + PRE_SUBMIT_ACTIONS, + PreSubmitResourceContext, + pre_submit_prepare_matches, +) from app.modules.authorization.prepared_submission_replay import validate_submission_replay from app.modules.authorization.prepared_post_submit_replay import validate_post_submit_replay from app.modules.authorization.pre_submit_materialization import ( @@ -196,6 +201,7 @@ class _PreparedAuthorizationBinding: assignment_invalidation_context: AssignmentInvalidationResourceContext | None = None outbox_dispatch_digest: str | None = None post_submit_prepare_context: dict | None = None + pre_submit_prepare_context: dict | None = None routing_request: TaskRoutingRequestFacts | None = None task_authority_context: TaskAuthorityResourceContext | None = None lifecycle_command: LifecycleTransitionCommand | None = None @@ -636,6 +642,12 @@ def _validate_consumption( expected_action_id, issuance.binding.post_submit_prepare_context, final_resource_context, ): raise PreparedAuthorizationHandleInvalid("invalid prepared post-submit authority") + if expected_action_id in PRE_SUBMIT_ACTIONS and not pre_submit_prepare_matches( + expected_action_id, + issuance.binding.pre_submit_prepare_context, + final_resource_context, + ): + raise PreparedAuthorizationHandleInvalid("invalid prepared selected PRE authority") if expected_action_id is ActionId.OUTBOX_DISPATCH and ( type(final_resource_context) is not OutboxDispatchResourceContext or issuance.binding.outbox_dispatch_digest != authorization_resource_digest(final_resource_context) @@ -943,7 +955,7 @@ def _scope_from_resource( artifact_resource_type=artifact_resource[0], artifact_resource_id=resource.resource_id, ) - if isinstance(resource, (ProjectGuideProjectionResourceContext, PostPolicyResourceContext, OutboxDispatchResourceContext, AssignmentInvalidationResourceContext, PostSubmitResourceContext, PostSubmitRoutingResourceContext)): + if isinstance(resource, (ProjectGuideProjectionResourceContext, PostPolicyResourceContext, OutboxDispatchResourceContext, AssignmentInvalidationResourceContext, PreSubmitResourceContext, PostSubmitResourceContext, PostSubmitRoutingResourceContext)): return PreparedAuthorityScope( kind=PreparedAuthorityScopeKind.PROJECT, project_id=resource.scope_project_id, diff --git a/backend/app/modules/authorization/runtime.py b/backend/app/modules/authorization/runtime.py index 7b0c89987..34a3862f7 100644 --- a/backend/app/modules/authorization/runtime.py +++ b/backend/app/modules/authorization/runtime.py @@ -33,6 +33,7 @@ from app.modules.authorization.domain.outbox_dispatch import OutboxDispatchResourceContext from app.modules.authorization.domain.post_submit_routing import PostSubmitRoutingResourceContext from app.modules.authorization.domain.post_submit import PostSubmitResourceContext +from app.modules.authorization.domain.pre_submit import PreSubmitResourceContext from app.modules.authorization.domain.guide_activation import ProjectGuideActivationResourceContext from app.modules.authorization.domain.lifecycle import ReviewLifecycleActivationContract from app.modules.authorization.service_actor_schemas import ServiceActorProvisionResourceContext @@ -1061,6 +1062,7 @@ class PreSubmitCheckerInputResourceContext(PreSubmitCheckerInputPreparationConte | PostPolicyResourceContext | AssignmentInvalidationResourceContext | OutboxDispatchResourceContext + | PreSubmitResourceContext | PostSubmitResourceContext | PostSubmitRoutingResourceContext | ProjectSetupRunMutationResourceContext diff --git a/backend/app/modules/checkers/api/selected_pre_submit.py b/backend/app/modules/checkers/api/selected_pre_submit.py index a7e610640..3aa85b2a4 100644 --- a/backend/app/modules/checkers/api/selected_pre_submit.py +++ b/backend/app/modules/checkers/api/selected_pre_submit.py @@ -488,6 +488,10 @@ def __init__(self, code: str) -> None: super().__init__(code) +class SelectedPreSubmitAuthorityUnavailable(RuntimeError): + """Conceal fixed-service PRE authorization loss without product facts.""" + + __all__ = ( "ExternalPreSubmitIsolationFacts", "ExternalPreSubmitMemberFacts", @@ -495,6 +499,7 @@ def __init__(self, code: str) -> None: "PreparedSelectedPreSubmitFinalization", "SelectedPreSubmitAdmissionAuthority", "SelectedPreSubmitAuthorityEvidence", + "SelectedPreSubmitAuthorityUnavailable", "SelectedPreSubmitAuthorityPort", "SelectedPreSubmitCompletion", "SelectedPreSubmitCoordinationPort", diff --git a/backend/tests/authorization/catalogue_fixtures.py b/backend/tests/authorization/catalogue_fixtures.py index 9b0d76c57..f1cb8b08f 100644 --- a/backend/tests/authorization/catalogue_fixtures.py +++ b/backend/tests/authorization/catalogue_fixtures.py @@ -20,6 +20,10 @@ "artifact.post_submit.checker_input.materialize", "artifact.review_packet.materialize", }, + ServiceIdentity.CHECKER_PRE_SUBMIT: { + "checker.pre_submit.execute", + "checker.pre_submit.finalize", + }, ServiceIdentity.CHECKER_POST_SUBMIT: {"checker.post_submit.execute", "checker.post_submit.finalize"}, ServiceIdentity.ARTIFACT_CHECKER_OUTPUT: {"artifact.checker_output.write"}, ServiceIdentity.PROJECT_SETUP: { @@ -253,7 +257,7 @@ new_permissions = frozenset( """ - task.post_submit.route checker.post_submit.execute checker.post_submit.finalize task.assignment.authority_reconcile outbox.dispatch project.setup_diagnostic.read project.effective_policy.read + task.post_submit.route checker.pre_submit.execute checker.pre_submit.finalize checker.post_submit.execute checker.post_submit.finalize task.assignment.authority_reconcile outbox.dispatch project.setup_diagnostic.read project.effective_policy.read operations.task.start_override operations.submission_gate.repair operations.checker.retry artifact.binding.read artifact.replica.read artifact.receipt.read artifact.verification_job.read @@ -269,6 +273,8 @@ "contribution.read_self": ("contribution.read_self", "PILOT-10"), "contribution.read_project": ("contribution.read_project", "PILOT-10"), "task.post_submit.route": ("task.post_submit.route", "WS-ARCH-001-04E2"), + "checker.pre_submit.execute": ("checker.pre_submit.execute", "PILOT-04"), + "checker.pre_submit.finalize": ("checker.pre_submit.finalize", "PILOT-04"), "checker.post_submit.execute": ("checker.post_submit.execute", "WS-ARCH-001-04D2"), "checker.post_submit.finalize": ("checker.post_submit.finalize", "WS-ARCH-001-04D2"), "checker.registry.register": ("operations.reconcile.run", "PILOT-04"), diff --git a/backend/tests/authorization/pre_submit/test_contracts.py b/backend/tests/authorization/pre_submit/test_contracts.py new file mode 100644 index 000000000..f122edcfd --- /dev/null +++ b/backend/tests/authorization/pre_submit/test_contracts.py @@ -0,0 +1,173 @@ +"""Selected PRE fixed-service resources bind exact phase and durable request facts.""" + +from __future__ import annotations + +from dataclasses import replace +from datetime import UTC, datetime, timedelta + +import pytest + +from app.core.identifiers import new_record_id +from app.modules.audit.schemas import ( + ActorReferenceKind, + AuthorityAuditEventInput, + AuthorityEventType, +) +from app.modules.authorization.catalogue import PermissionId +from app.modules.authorization.domain.audit import ( + AuthorizationDecision, + MatchedAuthorityKind, +) +from app.modules.authorization.domain.pre_submit import ( + EXECUTE, + FINALIZE, + PreSubmitResourceContext, + parse_pre_submit_prepare, + pre_submit_prepare_matches, + pre_submit_prepare_values, + pre_submit_resource, +) +from app.modules.authorization.domain.action_groups import CONTEXT_DIGEST_ACTIONS +from app.modules.authorization.domain.resource_digest import authorization_resource_digest +from app.modules.authorization.runtime import PreparedAuthorizationHandleInvalid +from app.modules.checkers.api.default_checker import ( + WORKSTREAM_DEFAULT_BEHAVIOR_SHA256, +) +from app.modules.checkers.api.selected_pre_submit import ( + SelectedPreSubmitExecuteFacts, + SelectedPreSubmitFinalizeFacts, + SelectedPreSubmitLeaseFacts, + SelectedPreSubmitReservationFacts, +) + + +def _reservation() -> SelectedPreSubmitReservationFacts: + return SelectedPreSubmitReservationFacts( + actor_profile_id=new_record_id(), + identity_link_id=new_record_id(), + project_id=new_record_id(), + task_id=new_record_id(), + assignment_id=new_record_id(), + attempt_id=new_record_id(), + attempt_request_digest="sha256:" + "0" * 64, + prepared_generation_id=new_record_id(), + policy_sha256="sha256:" + "1" * 64, + default_behavior_sha256=WORKSTREAM_DEFAULT_BEHAVIOR_SHA256, + default_input_sha256="sha256:" + "2" * 64, + archive_sha256="sha256:" + "3" * 64, + archive_byte_count=100, + semantic_manifest_sha256="sha256:" + "4" * 64, + execution_budget_ms=60_000, + ) + + +def _execute() -> SelectedPreSubmitExecuteFacts: + return SelectedPreSubmitExecuteFacts( + SelectedPreSubmitLeaseFacts( + reservation=_reservation(), + lease_id=new_record_id(), + lease_generation=1, + lease_expires_at=datetime.now(UTC) + timedelta(minutes=1), + ) + ) + + +def test_selected_pre_resource_binds_phase_project_run_and_request() -> None: + execute = _execute() + resource = pre_submit_resource(EXECUTE, execute) + prepared = pre_submit_prepare_values(execute.lease.reservation) + + assert resource.resource_id == execute.lease.reservation.attempt_id + assert resource.scope_project_id == execute.lease.reservation.project_id + assert authorization_resource_digest(resource) == execute.facts_digest + assert {EXECUTE, FINALIZE} <= CONTEXT_DIGEST_ACTIONS + assert pre_submit_prepare_matches(EXECUTE, prepared, resource) + assert not pre_submit_prepare_matches( + EXECUTE, + prepared | {"request_digest": "sha256:" + "f" * 64}, + resource, + ) + with pytest.raises(ValueError, match="phase"): + PreSubmitResourceContext( + resource_id=resource.resource_id, + scope_project_id=resource.scope_project_id, + action_id=FINALIZE, + facts=execute, + ) + + +def test_selected_pre_resource_is_admitted_by_decision_and_audit_boundaries() -> None: + execute = _execute() + resource = pre_submit_resource(EXECUTE, execute) + decision_id = new_record_id() + decision = AuthorizationDecision( + decision_id=decision_id, + action_id=EXECUTE, + permission_id=PermissionId.CHECKER_PRE_SUBMIT_EXECUTE, + allowed=True, + denial_code=None, + resource_type=resource.resource_type, + resource_id=resource.resource_id, + resource_context_digest=execute.facts_digest, + matched_authority_kind=MatchedAuthorityKind.FIXED_SERVICE, + revalidated=True, + request_id=new_record_id(), + correlation_id=new_record_id(), + ) + + event = AuthorityAuditEventInput( + event_id=decision_id, + event_type=AuthorityEventType.SENSITIVE_AUTHORIZATION_ALLOWED, + entity_type="authorization_decision", + entity_id=str(decision_id), + actor_ref_kind=ActorReferenceKind.ACTOR_PROFILE, + actor_ref=str(execute.lease.reservation.actor_profile_id), + request_id=decision.request_id, + correlation_id=decision.correlation_id, + permission_id=decision.permission_id, + action_id=decision.action_id, + project_id=str(resource.scope_project_id), + resource_type=resource.resource_type, + resource_id=str(resource.resource_id), + target_ref_kind="project", + target_ref_id=str(resource.scope_project_id), + reason="authorization_evaluation", + after_facts={ + "allowed": True, + "resource_context_digest": decision.resource_context_digest, + }, + ) + + assert event.resource_type == "selected_pre_submit_run" + + +def test_selected_pre_finalize_and_prepare_parser_are_closed() -> None: + execute = _execute() + final = SelectedPreSubmitFinalizeFacts( + lease=execute.lease, + execution=None, + infrastructure_failure_code="deadline_exceeded", + ) + resource = pre_submit_resource(FINALIZE, final) + prepared = pre_submit_prepare_values(execute.lease.reservation) + + assert pre_submit_prepare_matches(FINALIZE, prepared, resource) + assert parse_pre_submit_prepare( + FINALIZE, prepared, PreparedAuthorizationHandleInvalid + ) == prepared + with pytest.raises( + PreparedAuthorizationHandleInvalid, + match="invalid prepared selected PRE authority", + ): + parse_pre_submit_prepare( + FINALIZE, + prepared | {"extra": "value"}, + PreparedAuthorizationHandleInvalid, + ) + changed = replace( + execute.lease.reservation, + attempt_id=new_record_id(), + ) + assert not pre_submit_prepare_matches( + FINALIZE, pre_submit_prepare_values(changed), resource + ) diff --git a/backend/tests/authorization/test_catalogue.py b/backend/tests/authorization/test_catalogue.py index fd11710dc..56c131de2 100644 --- a/backend/tests/authorization/test_catalogue.py +++ b/backend/tests/authorization/test_catalogue.py @@ -26,7 +26,7 @@ def test_closed_permission_and_action_catalogue_is_exact_and_non_executable() -> assert {item.value for item in HISTORICAL_PERMISSION_IDS} == historical_permissions assert {item.value for item in NEW_PERMISSION_IDS} == new_permissions assert {item.value for item in PERMISSION_IDS} == historical_permissions | new_permissions - assert len(ACTION_IDS) == len(ACTION_DEFINITIONS) == len(ACTION_BY_ID) == 150 + assert len(ACTION_IDS) == len(ACTION_DEFINITIONS) == len(ACTION_BY_ID) == 152 assert set(ACTION_BY_ID) == ACTION_IDS assert {definition.owner for definition in ACTION_DEFINITIONS} == set(ActionOwner) assert { @@ -105,7 +105,7 @@ def test_closed_permission_and_action_catalogue_is_exact_and_non_executable() -> } assert all(not owner.value.startswith("WS-REV-") for owner in ActionOwner) assert Counter(definition.availability for definition in ACTION_DEFINITIONS) == { - ActionAvailability.ACTIVE: 114, + ActionAvailability.ACTIVE: 116, ActionAvailability.PLANNED: 36, } assert resolve_executable_action(ActionId.ACTOR_PROFILE_READ_SELF).permission_id is PermissionId.ACTOR_PROFILE_READ_SELF @@ -132,7 +132,7 @@ def test_proposal_actions_have_exact_executable_authority(action): def test_permission_definition_response_is_exact() -> None: permission_response = AdminRoleGrantService.permission_definitions() - assert permission_response.total == 78 + assert permission_response.total == 80 assert [item.permission_id.value for item in permission_response.items] == sorted( permission.value for permission in PermissionId ) @@ -147,7 +147,7 @@ def test_fixed_service_action_matrix_and_activation_are_exact_and_immutable() -> identity: {action.value for action in actions} for identity, actions in SERVICE_ACTIONS_BY_IDENTITY.items() } == expected - assert sum(map(len, SERVICE_ACTIONS_BY_IDENTITY.values())) == 28 + assert sum(map(len, SERVICE_ACTIONS_BY_IDENTITY.values())) == 30 assert FUTURE_INTENT_REQUIRED_ACTIONS == { ActionId.REVIEW_FINDING_EVIDENCE_INGEST, ActionId.REVIEW_FINDING_RESPONSE_EVIDENCE_INGEST, @@ -204,6 +204,8 @@ def test_fixed_service_action_matrix_and_activation_are_exact_and_immutable() -> def test_active_fixed_service_actions_are_exact(): """Only the explicitly active fixed-service actions are executable.""" active_internal = { + ActionId.CHECKER_PRE_SUBMIT_EXECUTE, + ActionId.CHECKER_PRE_SUBMIT_FINALIZE, ActionId.CHECKER_POST_SUBMIT_EXECUTE, ActionId.CHECKER_POST_SUBMIT_FINALIZE, ActionId.ARTIFACT_POST_SUBMIT_CHECKER_INPUT_MATERIALIZE, diff --git a/backend/tests/test_default_pre_submit_execution.py b/backend/tests/test_default_pre_submit_execution.py index 0750feabb..02fac5d0b 100644 --- a/backend/tests/test_default_pre_submit_execution.py +++ b/backend/tests/test_default_pre_submit_execution.py @@ -112,11 +112,8 @@ async def _bytes(value: bytes): class _AllowOperatorAuthority: async def authorize(self, *, facts, **_values) -> ArtifactOperatorAuthorizationEvidence: - return ArtifactOperatorAuthorizationEvidence( - action_id=facts.action_id, - permission_id=ACTION_BY_ID[facts.action_id].permission_id.value, - decision_id=new_record_id(), - ) + return ArtifactOperatorAuthorizationEvidence(action_id=facts.action_id, + permission_id=ACTION_BY_ID[facts.action_id].permission_id.value, decision_id=new_record_id()) @pytest.mark.asyncio @@ -137,16 +134,9 @@ async def test_evidence_workflow_requires_transaction_free_session() -> None: ) -def _archive( - path: str = "task.toml", - *, - primary_bytes: bytes = b"[task]\nname='proof'\n", - extra_path: str | None = None, - evidence_path="evidence/results", -) -> bytes: +def _archive(path: str = "task.toml", *, primary_bytes: bytes = b"[task]\nname='proof'\n", extra_path: str | None = None, evidence_path="evidence/results") -> bytes: output = BytesIO() with zipfile.ZipFile(output, "w") as archive: - def write(name: str, value: bytes) -> None: entry = zipfile.ZipInfo(name, date_time=(1980, 1, 1, 0, 0, 0)) archive.writestr(entry, value) @@ -271,12 +261,7 @@ async def _request( ): selected_catalogue = catalogue or build_pre_submission_checker_catalogue() plan = _plan(selected_catalogue) if plan is None else plan - data = _archive( - path, - primary_bytes=primary_bytes, - extra_path=extra_path, - evidence_path=evidence_path, - ) + data = _archive(path, primary_bytes=primary_bytes, extra_path=extra_path, evidence_path=evidence_path) inspector = SubmissionArchiveInspector(SubmissionArchiveLimits()) manager = ArtifactScratchManager(root=tmp_path / "scratch", limits=_limits()) preparation = ArtifactPreparationService(manager) From 82bbdc834881fedea5bb055866769963d75442ac Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 20:02:15 +0100 Subject: [PATCH 065/283] [PILOT-04] Bind selected admission lineage --- .../checkers/api/selected_pre_submit.py | 115 ++++++++++++++++++ .../test_selected_pre_submit_coordination.py | 41 +++++++ 2 files changed, 156 insertions(+) diff --git a/backend/app/modules/checkers/api/selected_pre_submit.py b/backend/app/modules/checkers/api/selected_pre_submit.py index 3aa85b2a4..b94902abc 100644 --- a/backend/app/modules/checkers/api/selected_pre_submit.py +++ b/backend/app/modules/checkers/api/selected_pre_submit.py @@ -14,6 +14,99 @@ from app.modules.checkers.api.external import ExternalCheckerExecutionResult +@dataclass(frozen=True, slots=True) +class SelectedPreSubmitAdmissionLineage: + """Immutable TASK, PROJECT, packet and manifest facts needed after verification.""" + + predecessor_submission_id: UUID | None + predecessor_submission_version: int | None + guide_id: UUID + guide_version: str + source_snapshot_id: UUID + source_snapshot_sha256: str + locked_guide_sha256: str + effective_policy_id: UUID + effective_policy_sha256: str + pre_submit_policy_id: UUID + pre_submit_policy_sha256: str + effective_plan_sha256: str + locked_policy_context_hash: str + semantic_manifest_id: UUID + semantic_manifest_body: dict[str, object] + packet_sha256: str + storage_scheme: str + + def __post_init__(self) -> None: + identifiers = ( + self.guide_id, + self.source_snapshot_id, + self.effective_policy_id, + self.pre_submit_policy_id, + self.semantic_manifest_id, + ) + digests = ( + self.source_snapshot_sha256, + self.locked_guide_sha256, + self.effective_policy_sha256, + self.pre_submit_policy_sha256, + self.effective_plan_sha256, + self.locked_policy_context_hash, + self.packet_sha256, + ) + if ( + any(type(value) is not UUID for value in identifiers) + or (self.predecessor_submission_id is None) + != (self.predecessor_submission_version is None) + or ( + self.predecessor_submission_id is not None + and type(self.predecessor_submission_id) is not UUID + ) + or ( + self.predecessor_submission_version is not None + and ( + type(self.predecessor_submission_version) is not int + or self.predecessor_submission_version < 1 + ) + ) + or not self.guide_version.strip() + or any( + type(value) is not str + or len(value) != 71 + or not value.startswith("sha256:") + for value in digests + ) + or type(self.semantic_manifest_body) is not dict + or self.storage_scheme not in {"local", "s3"} + ): + raise ValueError("selected PRE admission lineage is invalid") + + def canonical_body(self) -> dict[str, object]: + """Return every fact later copied into verified admission custody.""" + return { + "predecessor_submission_id": ( + str(self.predecessor_submission_id) + if self.predecessor_submission_id is not None + else None + ), + "predecessor_submission_version": self.predecessor_submission_version, + "guide_id": str(self.guide_id), + "guide_version": self.guide_version, + "source_snapshot_id": str(self.source_snapshot_id), + "source_snapshot_sha256": self.source_snapshot_sha256, + "locked_guide_sha256": self.locked_guide_sha256, + "effective_policy_id": str(self.effective_policy_id), + "effective_policy_sha256": self.effective_policy_sha256, + "pre_submit_policy_id": str(self.pre_submit_policy_id), + "pre_submit_policy_sha256": self.pre_submit_policy_sha256, + "effective_plan_sha256": self.effective_plan_sha256, + "locked_policy_context_hash": self.locked_policy_context_hash, + "semantic_manifest_id": str(self.semantic_manifest_id), + "semantic_manifest_body": self.semantic_manifest_body, + "packet_sha256": self.packet_sha256, + "storage_scheme": self.storage_scheme, + } + + @dataclass(frozen=True, slots=True) class ExternalPreSubmitIsolationFacts: """Observed sandbox identity detached from the trusted service response.""" @@ -138,6 +231,7 @@ class SelectedPreSubmitReservationFacts: archive_byte_count: int semantic_manifest_sha256: str execution_budget_ms: int + admission_lineage: SelectedPreSubmitAdmissionLineage | None = None def __post_init__(self) -> None: """Reject partial authority, material, policy or default-input custody.""" @@ -171,6 +265,22 @@ def __post_init__(self) -> None: or self.archive_byte_count < 0 or type(self.execution_budget_ms) is not int or not 100 <= self.execution_budget_ms <= 14_400_000 + or ( + self.admission_lineage is not None + and type(self.admission_lineage) + is not SelectedPreSubmitAdmissionLineage + ) + or ( + self.admission_lineage is not None + and ( + canonical_json_hash( + self.admission_lineage.semantic_manifest_body + ) + != self.semantic_manifest_sha256 + or self.admission_lineage.effective_plan_sha256 + != self.policy_sha256 + ) + ) ): raise ValueError("selected PRE reservation facts are invalid") @@ -193,6 +303,11 @@ def canonical_body(self) -> dict[str, object]: "archive_byte_count": self.archive_byte_count, "semantic_manifest_sha256": self.semantic_manifest_sha256, "execution_budget_ms": self.execution_budget_ms, + "admission_lineage": ( + self.admission_lineage.canonical_body() + if self.admission_lineage is not None + else None + ), } @property diff --git a/backend/tests/checkers/external/test_selected_pre_submit_coordination.py b/backend/tests/checkers/external/test_selected_pre_submit_coordination.py index 05370dc3f..5715e5503 100644 --- a/backend/tests/checkers/external/test_selected_pre_submit_coordination.py +++ b/backend/tests/checkers/external/test_selected_pre_submit_coordination.py @@ -2,6 +2,7 @@ from __future__ import annotations +from dataclasses import replace from types import SimpleNamespace import pytest @@ -9,9 +10,11 @@ from sqlalchemy.schema import CreateTable from app.core.identifiers import new_record_id +from app.core.hashing import canonical_json_hash from app.modules.checkers.api.default_checker import WORKSTREAM_DEFAULT_BEHAVIOR_SHA256 from app.modules.checkers.api.selected_pre_submit import ( SelectedPreSubmitExecuteFacts, + SelectedPreSubmitAdmissionLineage, SelectedPreSubmitFinalizeFacts, SelectedPreSubmitLeaseFacts, SelectedPreSubmitReservationFacts, @@ -161,3 +164,41 @@ def test_selected_pre_authority_digests_bind_lease_and_infrastructure_outcome() execution=None, infrastructure_failure_code=None, ) + + +def test_selected_pre_request_binds_complete_later_admission_lineage() -> None: + manifest = {"schema_version": "submission_manifest.v1", "entries": []} + digest = canonical_json_hash(manifest) + lineage = SelectedPreSubmitAdmissionLineage( + predecessor_submission_id=None, + predecessor_submission_version=None, + guide_id=new_record_id(), + guide_version="locked-v1", + source_snapshot_id=new_record_id(), + source_snapshot_sha256=SHA, + locked_guide_sha256=SHA, + effective_policy_id=new_record_id(), + effective_policy_sha256=SHA, + pre_submit_policy_id=new_record_id(), + pre_submit_policy_sha256=SHA, + effective_plan_sha256="sha256:" + "1" * 64, + locked_policy_context_hash=SHA, + semantic_manifest_id=new_record_id(), + semantic_manifest_body=manifest, + packet_sha256=SHA, + storage_scheme="s3", + ) + reservation = replace( + _reservation(), + policy_sha256=lineage.effective_plan_sha256, + semantic_manifest_sha256=digest, + admission_lineage=lineage, + ) + + assert reservation.canonical_body()["admission_lineage"] == lineage.canonical_body() + assert reservation.request_digest != replace( + reservation, + admission_lineage=replace(lineage, packet_sha256="sha256:" + "9" * 64), + ).request_digest + with pytest.raises(ValueError, match="reservation"): + replace(reservation, semantic_manifest_sha256=SHA) From 11ad0dd7f759e68f62b4e0c8cde8db69a12d5e01 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 20:03:13 +0100 Subject: [PATCH 066/283] [PILOT-04] Build selected PRE admission request --- .../selected_pre_submit_admission.py | 110 +++++++++++++++++- .../external/test_selected_pre_submit.py | 58 ++++++++- 2 files changed, 161 insertions(+), 7 deletions(-) diff --git a/backend/app/modules/artifacts/selected_pre_submit_admission.py b/backend/app/modules/artifacts/selected_pre_submit_admission.py index b56c6d8db..074987ace 100644 --- a/backend/app/modules/artifacts/selected_pre_submit_admission.py +++ b/backend/app/modules/artifacts/selected_pre_submit_admission.py @@ -3,9 +3,11 @@ from __future__ import annotations from dataclasses import dataclass +from uuid import UUID from app.core.hashing import canonical_json_hash from app.modules.artifacts.sources import ArtifactCommitment +from app.modules.artifacts.pre_submit_evidence import semantic_manifest_identity from app.modules.artifacts.submission_manifest import ( SubmissionCanonicalPredecessor, SubmissionChangeGateResult, @@ -13,8 +15,10 @@ bind_submission_change, ) from app.modules.checkers.api.default_checker import ( + WORKSTREAM_DEFAULT_BEHAVIOR_SHA256, WorkstreamDefaultCheckerInput, WorkstreamDefaultPredecessor, + workstream_default_input_body, ) from app.modules.checkers.api.external_policy import ( LockedExternalCheckerPolicies, @@ -22,6 +26,10 @@ ) from app.modules.checkers.api.materialization import SubmissionMaterialEntry from app.modules.checkers.api.pre_submit import SubmissionPacketView +from app.modules.checkers.api.selected_pre_submit import ( + SelectedPreSubmitAdmissionLineage, + SelectedPreSubmitReservationFacts, +) from app.modules.projects.api import ProjectLockedPolicyContextFacts from app.modules.tasks.api import TaskSubmissionContextFacts @@ -36,6 +44,102 @@ class SelectedPreSubmitAdmissionContext: rules_sha256: str +def build_selected_pre_submit_reservation( + *, + actor_profile_id: UUID, + identity_link_id: UUID, + task: TaskSubmissionContextFacts, + project: ProjectLockedPolicyContextFacts, + prepared_generation_id: UUID, + attempt_id: UUID, + attempt_request_digest: str, + commitment: ArtifactCommitment, + manifest: SubmissionManifest, + packet: SubmissionPacketView, + selected: SelectedPreSubmitAdmissionContext, + storage_scheme: str, + execution_budget_ms: int, +) -> SelectedPreSubmitReservationFacts: + """Bind all later ART-admission facts into the selected durable request.""" + if ( + task.contributor_id != actor_profile_id + or task.locked_project_context.project_id != project.project_id + or selected.policy.policy_sha256 + != canonical_json_hash( + selected.policy.model_dump(mode="json", exclude={"policy_sha256"}) + ) + ): + raise ValueError("selected PRE reservation context differs") + predecessor = task.predecessor + locked_guide_sha256 = canonical_json_hash( + { + "domain": "workstream.locked_task_guide.v1", + "project_id": str(project.project_id), + "guide_id": str(project.guide_id), + "guide_version": project.guide_version, + "source_snapshot_id": str(project.source_snapshot_id), + "source_snapshot_sha256": project.source_snapshot_hash, + } + ) + locked_policy_context_hash = canonical_json_hash( + { + "guide_id": str(project.guide_id), + "guide_version": project.guide_version, + "source_snapshot_id": str(project.source_snapshot_id), + "source_snapshot_sha256": project.source_snapshot_hash, + "locked_guide_sha256": locked_guide_sha256, + "effective_policy_id": str(project.effective_policy_id), + "locked_artifact_policy_sha256": project.effective_policy_hash, + "pre_submit_policy_id": str(project.pre_submit_policy_id), + "locked_checker_policy_sha256": project.pre_submit_policy_bundle_hash, + "effective_plan_sha256": selected.policy.policy_sha256, + } + ) + lineage = SelectedPreSubmitAdmissionLineage( + predecessor_submission_id=( + predecessor.submission_id if predecessor is not None else None + ), + predecessor_submission_version=( + predecessor.version if predecessor is not None else None + ), + guide_id=project.guide_id, + guide_version=project.guide_version, + source_snapshot_id=project.source_snapshot_id, + source_snapshot_sha256=project.source_snapshot_hash, + locked_guide_sha256=locked_guide_sha256, + effective_policy_id=project.effective_policy_id, + effective_policy_sha256=project.effective_policy_hash, + pre_submit_policy_id=project.pre_submit_policy_id, + pre_submit_policy_sha256=project.pre_submit_policy_bundle_hash, + effective_plan_sha256=selected.policy.policy_sha256, + locked_policy_context_hash=locked_policy_context_hash, + semantic_manifest_id=semantic_manifest_identity(manifest.sha256), + semantic_manifest_body=manifest.as_dict(), + packet_sha256=packet.sha256, + storage_scheme=storage_scheme, + ) + return SelectedPreSubmitReservationFacts( + actor_profile_id=actor_profile_id, + identity_link_id=identity_link_id, + project_id=project.project_id, + task_id=task.task_id, + assignment_id=task.assignment_id, + attempt_id=attempt_id, + attempt_request_digest=attempt_request_digest, + prepared_generation_id=prepared_generation_id, + policy_sha256=selected.policy.policy_sha256, + default_behavior_sha256=WORKSTREAM_DEFAULT_BEHAVIOR_SHA256, + default_input_sha256=canonical_json_hash( + workstream_default_input_body(selected.default_input) + ), + archive_sha256=commitment.sha256, + archive_byte_count=commitment.byte_count, + semantic_manifest_sha256=manifest.sha256, + execution_budget_ms=execution_budget_ms, + admission_lineage=lineage, + ) + + def bind_selected_pre_submit_admission( *, task: TaskSubmissionContextFacts, @@ -109,4 +213,8 @@ def bind_selected_pre_submit_admission( ) -__all__ = ("SelectedPreSubmitAdmissionContext", "bind_selected_pre_submit_admission") +__all__ = ( + "SelectedPreSubmitAdmissionContext", + "bind_selected_pre_submit_admission", + "build_selected_pre_submit_reservation", +) diff --git a/backend/tests/checkers/external/test_selected_pre_submit.py b/backend/tests/checkers/external/test_selected_pre_submit.py index 76f5b6965..dfc1d6b5d 100644 --- a/backend/tests/checkers/external/test_selected_pre_submit.py +++ b/backend/tests/checkers/external/test_selected_pre_submit.py @@ -49,6 +49,7 @@ from app.modules.artifacts.pre_submit_attempts import PreSubmitAttemptClaim from app.modules.artifacts.selected_pre_submit_admission import ( bind_selected_pre_submit_admission, + build_selected_pre_submit_reservation, ) from app.modules.artifacts.submission_manifest import SubmissionCanonicalPredecessor from app.modules.artifacts.submission_materialization import ( @@ -400,7 +401,27 @@ async def test_selected_admission_binds_unchanged_work_to_current_task_rules( request, _inspector, manager, _preparation, _catalogue = await _request(tmp_path) policies = _policies() project_id = request.effective_plan.lineage.project_id + actor_profile_id = new_record_id() + identity_link_id = new_record_id() + assignment_id = new_record_id() + guide_id = new_record_id() + source_snapshot_id = new_record_id() + effective_policy_id = new_record_id() + pre_submit_policy_id = new_record_id() + predecessor = SubmissionCanonicalPredecessor( + submission_id=new_record_id(), + submission_version=1, + archive_sha256=request.prepared_artifact.commitment.sha256, + semantic_manifest_sha256=request.manifest.sha256, + ) task = SimpleNamespace( + contributor_id=actor_profile_id, + task_id=request.task_id, + assignment_id=assignment_id, + predecessor=SimpleNamespace( + submission_id=predecessor.submission_id, + version=predecessor.submission_version, + ), locked_project_context=SimpleNamespace(project_id=project_id), locked_policy=SimpleNamespace( model_dump=lambda **_kwargs: { @@ -411,6 +432,14 @@ async def test_selected_admission_binds_unchanged_work_to_current_task_rules( ) project = SimpleNamespace( project_id=project_id, + guide_id=guide_id, + guide_version="v1", + source_snapshot_id=source_snapshot_id, + source_snapshot_hash=SHA, + effective_policy_id=effective_policy_id, + effective_policy_hash=SHA, + pre_submit_policy_id=pre_submit_policy_id, + pre_submit_policy_bundle_hash=SHA, external_checker_policies=SimpleNamespace( value=json.dumps( policies.model_dump(mode="json"), @@ -419,12 +448,6 @@ async def test_selected_admission_binds_unchanged_work_to_current_task_rules( ) ), ) - predecessor = SubmissionCanonicalPredecessor( - submission_id=new_record_id(), - submission_version=1, - archive_sha256=request.prepared_artifact.commitment.sha256, - semantic_manifest_sha256=request.manifest.sha256, - ) try: bound = bind_selected_pre_submit_admission( task=task, @@ -441,6 +464,29 @@ async def test_selected_admission_binds_unchanged_work_to_current_task_rules( assert bound.default_input.predecessor_rules_sha256 == "sha256:" + "d" * 64 assert bound.default_input.current_rules_sha256 == bound.rules_sha256 assert bound.policy.policy_sha256 == policies.pre_submit.policy_sha256 + reservation = build_selected_pre_submit_reservation( + actor_profile_id=actor_profile_id, + identity_link_id=identity_link_id, + task=task, + project=project, + prepared_generation_id=request.prepared_artifact.generation_id, + attempt_id=new_record_id(), + attempt_request_digest=SHA, + commitment=request.prepared_artifact.commitment, + manifest=request.manifest, + packet=request.packet, + selected=bound, + storage_scheme="s3", + execution_budget_ms=120_000, + ) + assert reservation.admission_lineage is not None + assert reservation.admission_lineage.semantic_manifest_body == ( + request.manifest.as_dict() + ) + assert reservation.admission_lineage.packet_sha256 == request.packet.sha256 + assert reservation.admission_lineage.predecessor_submission_id == ( + predecessor.submission_id + ) finally: await request.prepared_artifact.close() manager.close() From a3993e0e041452f0893d07e5194f82fae5950bbd Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 20:04:04 +0100 Subject: [PATCH 067/283] [PILOT-04] Seal selected PRE admission custody --- backend/app/modules/artifacts/schemas.py | 20 +++++- .../modules/artifacts/submission_custody.py | 65 ++++++++++++++++++- .../test_selected_pre_submit_coordination.py | 23 +++++++ 3 files changed, 106 insertions(+), 2 deletions(-) diff --git a/backend/app/modules/artifacts/schemas.py b/backend/app/modules/artifacts/schemas.py index 9b7f66c74..15944e31b 100644 --- a/backend/app/modules/artifacts/schemas.py +++ b/backend/app/modules/artifacts/schemas.py @@ -99,9 +99,27 @@ async def consume(self, request: CheckerOutputArtifactAdmissionRequest) -> None: class SubmissionBundleArtifactAdmissionRequest: """One passing prepared bundle selected for durable provider intent.""" - pre_submit_evidence_set_id: UUID + pre_submit_evidence_set_id: UUID | None custody: object replay_durable_intent_id: UUID | None + selected_pre_submit_run_id: UUID | None = None + selected_terminal_digest: str | None = None + + def __post_init__(self) -> None: + if ( + (self.pre_submit_evidence_set_id is None) + == (self.selected_pre_submit_run_id is None) + or (self.selected_pre_submit_run_id is None) + != (self.selected_terminal_digest is None) + or ( + self.selected_terminal_digest is not None + and ( + len(self.selected_terminal_digest) != 71 + or not self.selected_terminal_digest.startswith("sha256:") + ) + ) + ): + raise ValueError("submission bundle admission lineage is invalid") @property def source(self) -> CommittedArtifactSource: diff --git a/backend/app/modules/artifacts/submission_custody.py b/backend/app/modules/artifacts/submission_custody.py index 11c585105..47ed2ee12 100644 --- a/backend/app/modules/artifacts/submission_custody.py +++ b/backend/app/modules/artifacts/submission_custody.py @@ -7,13 +7,17 @@ from app.modules.artifacts.pre_submit_evidence import PreSubmitPassCapability from app.modules.artifacts.sources import CommittedArtifactSource, PreparedArtifact +from app.modules.checkers.api.selected_pre_submit import ( + SelectedPreSubmitCompletion, + SelectedPreSubmitReservationFacts, +) @final class SubmissionBundlePreparedCustody: """Unforgeable join of live prepared bytes and their fresh pass capability.""" - __slots__ = ("_capability", "_prepared") + __slots__ = ("_capability", "_prepared", "_selected") def __init__(self, *_: object, **__: object) -> None: raise TypeError("submission bundle custody requires live prepared work") @@ -37,6 +41,49 @@ def _from_live_preparation( custody = object.__new__(cls) custody._prepared = prepared custody._capability = capability + custody._selected = None + return custody + + @classmethod + def _from_selected_pre_submit( + cls, + *, + prepared: PreparedArtifact, + completion: SelectedPreSubmitCompletion, + ) -> SubmissionBundlePreparedCustody: + """Seal a completed selected run to the still-live verified bytes once.""" + if ( + type(prepared) is not PreparedArtifact + or type(completion) is not SelectedPreSubmitCompletion + or completion.capability is None + or completion.terminal.outcome != "completed" + or completion.terminal.execution is None + or not completion.terminal.execution.eligible + ): + raise TypeError("submission bundle selected custody requires a passing run") + reservation = completion.terminal.lease.reservation + if ( + type(reservation) is not SelectedPreSubmitReservationFacts + or reservation.admission_lineage is None + or reservation.prepared_generation_id != prepared.generation_id + or reservation.archive_sha256 != prepared.commitment.sha256 + or reservation.archive_byte_count != prepared.commitment.byte_count + ): + raise TypeError("submission bundle selected custody differs from prepared bytes") + run_id = completion.capability.consume( + run_id=reservation.attempt_id, + terminal_digest=completion.terminal.terminal_digest, + attempt_id=reservation.attempt_id, + prepared_generation_id=reservation.prepared_generation_id, + archive_sha256=reservation.archive_sha256, + semantic_manifest_sha256=reservation.semantic_manifest_sha256, + ) + if run_id != reservation.attempt_id: + raise TypeError("submission bundle selected custody is unavailable") + custody = object.__new__(cls) + custody._prepared = prepared + custody._capability = None + custody._selected = completion.terminal return custody @property @@ -45,8 +92,24 @@ def prepared_generation_id(self) -> UUID: @property def pass_capability(self) -> PreSubmitPassCapability: + if type(self._capability) is not PreSubmitPassCapability: + raise TypeError("legacy submission pass capability is unavailable") return self._capability + @property + def selected_reservation(self) -> SelectedPreSubmitReservationFacts: + """Return the exact selected request only for selected-run custody.""" + if self._selected is None: + raise TypeError("selected submission custody is unavailable") + return self._selected.lease.reservation + + @property + def selected_terminal_digest(self) -> str: + """Return the terminal digest paired with the selected reservation.""" + if self._selected is None: + raise TypeError("selected submission custody is unavailable") + return self._selected.terminal_digest + @property def source(self) -> CommittedArtifactSource: return self._prepared.committed_source diff --git a/backend/tests/checkers/external/test_selected_pre_submit_coordination.py b/backend/tests/checkers/external/test_selected_pre_submit_coordination.py index 5715e5503..dd6c4221f 100644 --- a/backend/tests/checkers/external/test_selected_pre_submit_coordination.py +++ b/backend/tests/checkers/external/test_selected_pre_submit_coordination.py @@ -11,6 +11,7 @@ from app.core.identifiers import new_record_id from app.core.hashing import canonical_json_hash +from app.modules.artifacts.schemas import SubmissionBundleArtifactAdmissionRequest from app.modules.checkers.api.default_checker import WORKSTREAM_DEFAULT_BEHAVIOR_SHA256 from app.modules.checkers.api.selected_pre_submit import ( SelectedPreSubmitExecuteFacts, @@ -202,3 +203,25 @@ def test_selected_pre_request_binds_complete_later_admission_lineage() -> None: ).request_digest with pytest.raises(ValueError, match="reservation"): replace(reservation, semantic_manifest_sha256=SHA) + + +def test_submission_artifact_request_selects_exactly_one_pre_lineage() -> None: + selected_id = new_record_id() + request = SubmissionBundleArtifactAdmissionRequest( + pre_submit_evidence_set_id=None, + custody=object(), + replay_durable_intent_id=None, + selected_pre_submit_run_id=selected_id, + selected_terminal_digest=SHA, + ) + assert request.selected_pre_submit_run_id == selected_id + with pytest.raises(ValueError, match="lineage"): + SubmissionBundleArtifactAdmissionRequest( + pre_submit_evidence_set_id=new_record_id(), + custody=object(), + replay_durable_intent_id=None, + selected_pre_submit_run_id=selected_id, + selected_terminal_digest=SHA, + ) + with pytest.raises(ValueError, match="lineage"): + replace(request, selected_terminal_digest=None) From 5a4ca83f1f1a59e18e04dc8fdf1b4483761feb9b Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 20:04:56 +0100 Subject: [PATCH 068/283] [PILOT-04] Model selected submission admission --- backend/app/modules/artifacts/models.py | 60 +++++++++++++++++-- backend/app/modules/artifacts/service.py | 1 + .../modules/artifacts/submission_admission.py | 12 ++++ .../test_selected_pre_submit_coordination.py | 25 ++++++++ 4 files changed, 93 insertions(+), 5 deletions(-) diff --git a/backend/app/modules/artifacts/models.py b/backend/app/modules/artifacts/models.py index 80a34459f..a04da7660 100644 --- a/backend/app/modules/artifacts/models.py +++ b/backend/app/modules/artifacts/models.py @@ -1213,7 +1213,7 @@ class ArtifactPutAttempt(Base): class SubmissionBundleDurableIntent(Base): - """Immutable join fencing one passing evidence set to one provider intent.""" + """Immutable join fencing one legacy or selected PRE result to provider intent.""" __tablename__ = "submission_bundle_durable_intents" __table_args__ = ( @@ -1222,16 +1222,30 @@ class SubmissionBundleDurableIntent(Base): "pre_submit_evidence_set_id", name="uq_submission_bundle_intent_evidence", ), + UniqueConstraint( + "selected_pre_submit_run_id", + name="uq_submission_bundle_intent_selected_run", + ), UniqueConstraint( "put_attempt_id", name="uq_submission_bundle_intent_put_attempt", ), + CheckConstraint( + "((pre_submit_evidence_set_id is not null)::int + " + "(selected_pre_submit_run_id is not null)::int) = 1", + name="pre_submit_lineage", + ), ) id: Mapped[str] = mapped_column(Uuid(as_uuid=False), primary_key=True) - pre_submit_evidence_set_id: Mapped[str] = mapped_column( + pre_submit_evidence_set_id: Mapped[str | None] = mapped_column( ForeignKey("pre_submit_evidence_sets.id", ondelete="RESTRICT"), - nullable=False, + nullable=True, + index=True, + ) + selected_pre_submit_run_id: Mapped[str | None] = mapped_column( + ForeignKey("selected_pre_submit_runs.id", ondelete="RESTRICT"), + nullable=True, index=True, ) put_attempt_id: Mapped[str] = mapped_column( @@ -1254,6 +1268,9 @@ class SubmissionBundleAdmission(Base): UniqueConstraint( "pre_submit_evidence_set_id", name="uq_submission_bundle_admission_evidence" ), + UniqueConstraint( + "selected_pre_submit_run_id", name="uq_submission_bundle_admission_selected_run" + ), UniqueConstraint( "verification_receipt_id", name="uq_submission_bundle_admission_verification" ), @@ -1264,6 +1281,11 @@ class SubmissionBundleAdmission(Base): postgresql_where=text("consumed_by_submission_id is not null"), ), CheckConstraint("status in ('ready','consumed','stale')", name="status"), + CheckConstraint( + "((pre_submit_evidence_set_id is not null)::int + " + "(selected_pre_submit_run_id is not null)::int) = 1", + name="pre_submit_lineage", + ), CheckConstraint( SHA256_CHECK.format(column="locked_policy_context_hash"), name="policy_context_hash", @@ -1271,6 +1293,20 @@ class SubmissionBundleAdmission(Base): CheckConstraint( SHA256_CHECK.format(column="semantic_manifest_sha256"), name="manifest_sha256" ), + CheckConstraint( + "jsonb_typeof(semantic_manifest_body)='object'", + name="manifest_body", + ), + CheckConstraint(SHA256_CHECK.format(column="packet_sha256"), name="packet_sha256"), + CheckConstraint( + SHA256_CHECK.format(column="effective_plan_sha256"), name="effective_plan_sha256" + ), + CheckConstraint( + SHA256_CHECK.format(column="source_snapshot_sha256") + " and " + + SHA256_CHECK.format(column="effective_policy_sha256") + " and " + + SHA256_CHECK.format(column="pre_submit_policy_sha256"), + name="locked_policy_digests", + ), CheckConstraint(SHA256_CHECK.format(column="archive_sha256"), name="archive_sha256"), CheckConstraint("archive_byte_count >= 0", name="archive_size"), CheckConstraint( @@ -1300,8 +1336,11 @@ class SubmissionBundleAdmission(Base): durable_intent_id: Mapped[str] = mapped_column( ForeignKey("submission_bundle_durable_intents.id", ondelete="RESTRICT"), nullable=False ) - pre_submit_evidence_set_id: Mapped[str] = mapped_column( - ForeignKey("pre_submit_evidence_sets.id", ondelete="RESTRICT"), nullable=False, index=True + pre_submit_evidence_set_id: Mapped[str | None] = mapped_column( + ForeignKey("pre_submit_evidence_sets.id", ondelete="RESTRICT"), nullable=True, index=True + ) + selected_pre_submit_run_id: Mapped[str | None] = mapped_column( + ForeignKey("selected_pre_submit_runs.id", ondelete="RESTRICT"), nullable=True, index=True ) put_attempt_id: Mapped[str] = mapped_column( ForeignKey("artifact_put_attempts.id", ondelete="RESTRICT"), nullable=False @@ -1341,8 +1380,19 @@ class SubmissionBundleAdmission(Base): ) predecessor_submission_version: Mapped[int | None] = mapped_column(Integer) locked_policy_context_hash: Mapped[str] = mapped_column(String(71), nullable=False) + guide_id: Mapped[str] = mapped_column(Uuid(as_uuid=False), nullable=False) + guide_version: Mapped[str] = mapped_column(String(50), nullable=False) + source_snapshot_id: Mapped[str] = mapped_column(Uuid(as_uuid=False), nullable=False) + source_snapshot_sha256: Mapped[str] = mapped_column(String(71), nullable=False) + effective_policy_id: Mapped[str] = mapped_column(Uuid(as_uuid=False), nullable=False) + effective_policy_sha256: Mapped[str] = mapped_column(String(71), nullable=False) + pre_submit_policy_id: Mapped[str] = mapped_column(Uuid(as_uuid=False), nullable=False) + pre_submit_policy_sha256: Mapped[str] = mapped_column(String(71), nullable=False) + effective_plan_sha256: Mapped[str] = mapped_column(String(71), nullable=False) + packet_sha256: Mapped[str] = mapped_column(String(71), nullable=False) semantic_manifest_id: Mapped[str] = mapped_column(Uuid(as_uuid=False), nullable=False) semantic_manifest_sha256: Mapped[str] = mapped_column(String(71), nullable=False) + semantic_manifest_body: Mapped[dict] = mapped_column(JSONB, nullable=False) archive_sha256: Mapped[str] = mapped_column(String(71), nullable=False) archive_byte_count: Mapped[int] = mapped_column(BigInteger, nullable=False) status: Mapped[str] = mapped_column(String(16), nullable=False, default="ready", index=True) diff --git a/backend/app/modules/artifacts/service.py b/backend/app/modules/artifacts/service.py index f51742541..0f81aca54 100644 --- a/backend/app/modules/artifacts/service.py +++ b/backend/app/modules/artifacts/service.py @@ -2185,6 +2185,7 @@ async def admit( SubmissionBundleDurableIntent( id=str(new_record_id()), pre_submit_evidence_set_id=facts.pre_submit_evidence_set_id, + selected_pre_submit_run_id=None, put_attempt_id=attempt.id, ) ) diff --git a/backend/app/modules/artifacts/submission_admission.py b/backend/app/modules/artifacts/submission_admission.py index 9227b7661..5ab1e2cd5 100644 --- a/backend/app/modules/artifacts/submission_admission.py +++ b/backend/app/modules/artifacts/submission_admission.py @@ -334,6 +334,7 @@ async def publish_verified( id=str(new_record_id()), durable_intent_id=intent.id, pre_submit_evidence_set_id=evidence.id, + selected_pre_submit_run_id=None, put_attempt_id=attempt.id, artifact_content_id=content.id, verified_replica_id=replica.id, @@ -348,8 +349,19 @@ async def publish_verified( predecessor_submission_id=evidence.predecessor_submission_id, predecessor_submission_version=evidence.predecessor_submission_version, locked_policy_context_hash=evidence.locked_policy_context_hash, + guide_id=evidence.guide_id, + guide_version=evidence.guide_version, + source_snapshot_id=evidence.source_snapshot_id, + source_snapshot_sha256=evidence.source_snapshot_sha256, + effective_policy_id=evidence.effective_policy_id, + effective_policy_sha256=evidence.locked_artifact_policy_sha256, + pre_submit_policy_id=evidence.pre_submit_policy_id, + pre_submit_policy_sha256=evidence.locked_checker_policy_sha256, + effective_plan_sha256=evidence.effective_plan_sha256, + packet_sha256=evidence.packet_sha256, semantic_manifest_id=evidence.semantic_manifest_id, semantic_manifest_sha256=evidence.semantic_manifest_sha256, + semantic_manifest_body=evidence.semantic_manifest_body, archive_sha256=evidence.archive_sha256, archive_byte_count=evidence.archive_byte_count, status="ready", diff --git a/backend/tests/checkers/external/test_selected_pre_submit_coordination.py b/backend/tests/checkers/external/test_selected_pre_submit_coordination.py index dd6c4221f..46264167b 100644 --- a/backend/tests/checkers/external/test_selected_pre_submit_coordination.py +++ b/backend/tests/checkers/external/test_selected_pre_submit_coordination.py @@ -12,6 +12,10 @@ from app.core.identifiers import new_record_id from app.core.hashing import canonical_json_hash from app.modules.artifacts.schemas import SubmissionBundleArtifactAdmissionRequest +from app.modules.artifacts.models import ( + SubmissionBundleAdmission, + SubmissionBundleDurableIntent, +) from app.modules.checkers.api.default_checker import WORKSTREAM_DEFAULT_BEHAVIOR_SHA256 from app.modules.checkers.api.selected_pre_submit import ( SelectedPreSubmitExecuteFacts, @@ -65,6 +69,27 @@ def test_selected_pre_model_compiles_complete_owner_and_authority_custody() -> N assert value in sql assert "pre_submit_execution_attempts" not in sql + intent_sql = str( + CreateTable(SubmissionBundleDurableIntent.__table__).compile( + dialect=postgresql.dialect() + ) + ) + admission_sql = str( + CreateTable(SubmissionBundleAdmission.__table__).compile( + dialect=postgresql.dialect() + ) + ) + for compiled in (intent_sql, admission_sql): + assert "selected_pre_submit_run_id" in compiled + assert "pre_submit_lineage" in compiled + for value in ( + "semantic_manifest_body", + "packet_sha256", + "effective_plan_sha256", + "pre_submit_policy_sha256", + ): + assert value in admission_sql + def test_selected_pre_admission_capability_is_exact_and_single_use() -> None: reservation = _reservation() From 6221468b1d810e2cb42e8ae9f4549636d20eac0c Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 20:11:50 +0100 Subject: [PATCH 069/283] [PILOT-04] Retain selected admission custody --- backend/app/modules/artifacts/models.py | 15 + backend/app/modules/artifacts/repository.py | 11 + backend/app/modules/artifacts/schemas.py | 15 +- backend/app/modules/artifacts/service.py | 253 +++++++++++++- .../modules/artifacts/submission_admission.py | 318 +++++++++++++++--- .../modules/artifacts/submission_bindings.py | 113 ++++--- .../modules/artifacts/submission_custody.py | 12 + .../authorization/submission_consumption.py | 7 +- .../authorization/submission_preparation.py | 19 +- .../checkers/api/selected_pre_submit.py | 97 ++++++ .../test_fixed_service_action_context.py | 3 +- .../test_selected_pre_submit_coordination.py | 54 +++ .../tests/test_submission_bundle_admission.py | 142 +++++++- .../test_submission_preparation_adapter.py | 2 + 14 files changed, 941 insertions(+), 120 deletions(-) diff --git a/backend/app/modules/artifacts/models.py b/backend/app/modules/artifacts/models.py index a04da7660..18e78dc7f 100644 --- a/backend/app/modules/artifacts/models.py +++ b/backend/app/modules/artifacts/models.py @@ -1235,6 +1235,17 @@ class SubmissionBundleDurableIntent(Base): "(selected_pre_submit_run_id is not null)::int) = 1", name="pre_submit_lineage", ), + CheckConstraint( + "(pre_submit_evidence_set_id is not null and selected_request_json is null " + "and selected_request_digest is null and selected_terminal_json is null " + "and selected_terminal_digest is null) or " + "(selected_pre_submit_run_id is not null " + "and jsonb_typeof(selected_request_json)='object' " + "and selected_request_digest ~ '^sha256:[0-9a-f]{64}$' " + "and jsonb_typeof(selected_terminal_json)='object' " + "and selected_terminal_digest ~ '^sha256:[0-9a-f]{64}$')", + name="selected_snapshot", + ), ) id: Mapped[str] = mapped_column(Uuid(as_uuid=False), primary_key=True) @@ -1248,6 +1259,10 @@ class SubmissionBundleDurableIntent(Base): nullable=True, index=True, ) + selected_request_json: Mapped[dict | None] = mapped_column(JSONB) + selected_request_digest: Mapped[str | None] = mapped_column(String(71)) + selected_terminal_json: Mapped[dict | None] = mapped_column(JSONB) + selected_terminal_digest: Mapped[str | None] = mapped_column(String(71)) put_attempt_id: Mapped[str] = mapped_column( ForeignKey("artifact_put_attempts.id", ondelete="RESTRICT"), nullable=False, diff --git a/backend/app/modules/artifacts/repository.py b/backend/app/modules/artifacts/repository.py index aaafc0b16..1088210d2 100644 --- a/backend/app/modules/artifacts/repository.py +++ b/backend/app/modules/artifacts/repository.py @@ -316,6 +316,17 @@ async def get_submission_bundle_intent_by_evidence( ) ) + async def get_submission_bundle_intent_by_selected_run( + self, run_id: str + ) -> SubmissionBundleDurableIntent | None: + """Load the durable ART intent copied from one selected PRE terminal.""" + return await self._session.scalar( + select(SubmissionBundleDurableIntent).where( + SubmissionBundleDurableIntent.selected_pre_submit_run_id == run_id + ) + ) + + async def lock_submission_bundle_intent( self, intent_id: str ) -> SubmissionBundleDurableIntent | None: diff --git a/backend/app/modules/artifacts/schemas.py b/backend/app/modules/artifacts/schemas.py index 15944e31b..41583fae2 100644 --- a/backend/app/modules/artifacts/schemas.py +++ b/backend/app/modules/artifacts/schemas.py @@ -208,7 +208,7 @@ class SubmissionBundleDurableIntentAuthorityFacts: assignment_id: UUID predecessor_submission_id: UUID | None predecessor_submission_version: int | None - pre_submit_evidence_set_id: UUID + pre_submit_evidence_set_id: UUID | None prepared_generation_id: UUID guide_id: UUID guide_version: str @@ -221,12 +221,25 @@ class SubmissionBundleDurableIntentAuthorityFacts: effective_plan_sha256: str semantic_manifest_id: UUID semantic_manifest_sha256: str + semantic_manifest_body: dict[str, object] + packet_sha256: str archive_sha256: str archive_byte_count: int media_type: str storage_scheme: str operation_identity: str replay_durable_intent_id: UUID | None + selected_pre_submit_run_id: UUID | None = None + selected_terminal_digest: str | None = None + + def __post_init__(self) -> None: + if ( + (self.pre_submit_evidence_set_id is None) + == (self.selected_pre_submit_run_id is None) + or (self.selected_pre_submit_run_id is None) + != (self.selected_terminal_digest is None) + ): + raise ValueError("submission bundle authority lineage is invalid") class ArtifactInternalResourceType(StrEnum): diff --git a/backend/app/modules/artifacts/service.py b/backend/app/modules/artifacts/service.py index 0f81aca54..9eb7bcdf6 100644 --- a/backend/app/modules/artifacts/service.py +++ b/backend/app/modules/artifacts/service.py @@ -198,6 +198,7 @@ class _AdmissionFacts: pre_submit_evidence_set_id: str | None operation_identity: str task_import_source_id: str | None = None + selected_pre_submit_run_id: str | None = None def artifact_storage_namespace_spec( @@ -2039,18 +2040,19 @@ async def admit( authority_facts, operation_identity=replay_attempt.operation_identity, ) - consumed_evidence_id = request.custody.pass_capability.consume( - prepared_generation_id=authority_facts.prepared_generation_id, - predecessor_submission_id=authority_facts.predecessor_submission_id, - effective_plan_sha256=authority_facts.effective_plan_sha256, - archive_sha256=authority_facts.archive_sha256, - semantic_manifest_sha256=authority_facts.semantic_manifest_sha256, - storage_scheme=authority_facts.storage_scheme, - ) - if consumed_evidence_id != authority_facts.pre_submit_evidence_set_id: - raise ArtifactAdmissionRelationshipError( - "submission bundle pass capability evidence changed" + if not request.custody.is_selected: + consumed_evidence_id = request.custody.pass_capability.consume( + prepared_generation_id=authority_facts.prepared_generation_id, + predecessor_submission_id=authority_facts.predecessor_submission_id, + effective_plan_sha256=authority_facts.effective_plan_sha256, + archive_sha256=authority_facts.archive_sha256, + semantic_manifest_sha256=authority_facts.semantic_manifest_sha256, + storage_scheme=authority_facts.storage_scheme, ) + if consumed_evidence_id != authority_facts.pre_submit_evidence_set_id: + raise ArtifactAdmissionRelationshipError( + "submission bundle pass capability evidence changed" + ) prepared_authorization = await submission_prepared_authorization.prepare_final( facts=authority_facts ) @@ -2090,6 +2092,7 @@ async def admit( else {} ), "pre_submit_evidence_set_id": facts.pre_submit_evidence_set_id, + "selected_pre_submit_run_id": facts.selected_pre_submit_run_id, "sha256": commitment.sha256, "byte_count": commitment.byte_count, "media_type": commitment.media_type, @@ -2126,9 +2129,18 @@ async def admit( counter.scope_type, counter.counted_bytes, counter.limit_bytes ) if replay is not None: - if facts.pre_submit_evidence_set_id is not None: - intent = await self._repo.get_submission_bundle_intent_by_evidence( - facts.pre_submit_evidence_set_id + if ( + facts.pre_submit_evidence_set_id is not None + or facts.selected_pre_submit_run_id is not None + ): + intent = ( + await self._repo.get_submission_bundle_intent_by_evidence( + facts.pre_submit_evidence_set_id + ) + if facts.pre_submit_evidence_set_id is not None + else await self._repo.get_submission_bundle_intent_by_selected_run( + facts.selected_pre_submit_run_id or "" + ) ) if intent is None or intent.put_attempt_id != replay.id: raise ArtifactAdmissionConfigurationError( @@ -2180,12 +2192,45 @@ async def admit( terminal_at=None, ) await self._repo.add_put_attempt(attempt, charges) - if facts.pre_submit_evidence_set_id is not None: + if ( + facts.pre_submit_evidence_set_id is not None + or facts.selected_pre_submit_run_id is not None + ): + selected_request = ( + request.custody.selected_reservation + if type(request) is SubmissionBundleArtifactAdmissionRequest + and request.custody.is_selected + else None + ) await self._repo.add_submission_bundle_intent( SubmissionBundleDurableIntent( id=str(new_record_id()), pre_submit_evidence_set_id=facts.pre_submit_evidence_set_id, - selected_pre_submit_run_id=None, + selected_pre_submit_run_id=facts.selected_pre_submit_run_id, + selected_request_json=( + selected_request.canonical_body() + if selected_request is not None + else None + ), + selected_request_digest=( + selected_request.request_digest + if selected_request is not None + else None + ), + selected_terminal_json=( + request.custody.selected_terminal_body + if selected_request is not None + and type(request) + is SubmissionBundleArtifactAdmissionRequest + else None + ), + selected_terminal_digest=( + request.custody.selected_terminal_digest + if selected_request is not None + and type(request) + is SubmissionBundleArtifactAdmissionRequest + else None + ), put_attempt_id=attempt.id, ) ) @@ -2350,6 +2395,39 @@ async def _submission_bundle_replay_attempt( raise ArtifactAdmissionRelationshipError( "submission bundle replay intent is unavailable" ) + if request.custody.is_selected: + reservation = request.custody.selected_reservation + attempt = await self._repo.lock_put_attempt(intent.put_attempt_id) + if ( + attempt is None + or intent.selected_pre_submit_run_id != str(reservation.attempt_id) + or intent.pre_submit_evidence_set_id is not None + or intent.selected_request_json != reservation.canonical_body() + or intent.selected_request_digest != reservation.request_digest + or intent.selected_terminal_json + != request.custody.selected_terminal_body + or intent.selected_terminal_digest + != request.custody.selected_terminal_digest + or attempt.producer_request_type != "submission_bundle" + or attempt.status + not in { + "prepared", + "acknowledgement_unknown", + "absent_replay_required", + "object_confirmed", + } + or attempt.sha256 != current.archive_sha256 + or attempt.byte_count != current.archive_byte_count + or attempt.media_type != current.media_type + ): + raise ArtifactAdmissionRelationshipError( + "selected submission bundle replay intent does not match custody" + ) + return attempt + if intent.pre_submit_evidence_set_id is None: + raise ArtifactAdmissionRelationshipError( + "submission bundle replay intent is unavailable" + ) prior = await self._repo.lock_pre_submit_evidence_set(intent.pre_submit_evidence_set_id) fresh = await self._repo.lock_pre_submit_evidence_set( str(current.pre_submit_evidence_set_id) @@ -2465,6 +2543,12 @@ async def _submission_bundle_facts( if type(request.custody) is not SubmissionBundlePreparedCustody: raise ArtifactAuthorityDeniedError("submission bundle prepared custody is unavailable") + if request.custody.is_selected: + return await self._selected_submission_bundle_facts( + request, + task_contexts=task_contexts, + project_contexts=project_contexts, + ) pass_capability = request.custody.pass_capability if type(pass_capability) is not PreSubmitPassCapability: raise ArtifactAuthorityDeniedError("submission bundle pass capability is unavailable") @@ -2572,6 +2656,8 @@ async def _submission_bundle_facts( effective_plan_sha256=evidence.effective_plan_sha256, semantic_manifest_id=UUID(evidence.semantic_manifest_id), semantic_manifest_sha256=evidence.semantic_manifest_sha256, + semantic_manifest_body=evidence.semantic_manifest_body, + packet_sha256=evidence.packet_sha256, archive_sha256=evidence.archive_sha256, archive_byte_count=evidence.archive_byte_count, media_type=commitment.media_type, @@ -2598,6 +2684,141 @@ async def _submission_bundle_facts( operation_identity=operation_identity, ) + async def _selected_submission_bundle_facts( + self, + request: SubmissionBundleArtifactAdmissionRequest, + *, + task_contexts: TaskSubmissionContextPort, + project_contexts: ProjectLockedPolicyContextPort, + ) -> tuple[SubmissionBundleDurableIntentAuthorityFacts, _AdmissionFacts]: + """Revalidate selected terminal custody against current TASK and PROJECT locks.""" + reservation = request.custody.selected_reservation + lineage = reservation.admission_lineage + commitment = request.source.commitment + if ( + lineage is None + or request.pre_submit_evidence_set_id is not None + or request.selected_pre_submit_run_id != reservation.attempt_id + or request.selected_terminal_digest + != request.custody.selected_terminal_digest + or reservation.prepared_generation_id + != request.custody.prepared_generation_id + or reservation.archive_sha256 != commitment.sha256 + or reservation.archive_byte_count != commitment.byte_count + or commitment.media_type != "application/zip" + or canonical_json_hash(lineage.semantic_manifest_body) + != reservation.semantic_manifest_sha256 + ): + raise ArtifactAdmissionRelationshipError( + "selected submission bundle passing evidence is unavailable" + ) + try: + task = await task_contexts.lock_submission_context( + TaskSubmissionContextRequest( + task_id=reservation.task_id, + assignment_id=reservation.assignment_id, + contributor_id=reservation.actor_profile_id, + predecessor_submission_id=lineage.predecessor_submission_id, + ) + ) + locked = await project_contexts.lock_locked_policy_context( + ProjectLockedPolicyContextRequest( + project_id=reservation.project_id, + guide_version=lineage.guide_version, + source_snapshot_id=lineage.source_snapshot_id, + source_snapshot_hash=lineage.source_snapshot_sha256, + effective_policy_id=lineage.effective_policy_id, + effective_policy_hash=lineage.effective_policy_sha256, + pre_submit_policy_id=lineage.pre_submit_policy_id, + pre_submit_policy_bundle_hash=lineage.pre_submit_policy_sha256, + ) + ) + except (TaskSubmissionContextUnavailable, ProjectLockedPolicyContextUnavailable) as exc: + raise ArtifactAdmissionRelationshipError( + "selected_pre_submit_locked_context_changed" + ) from exc + predecessor = task.predecessor + if ( + task.contributor_id != reservation.actor_profile_id + or task.task_id != reservation.task_id + or task.assignment_id != reservation.assignment_id + or (predecessor.submission_id if predecessor is not None else None) + != lineage.predecessor_submission_id + or (predecessor.version if predecessor is not None else None) + != lineage.predecessor_submission_version + or locked.project_id != reservation.project_id + or locked.guide_id != lineage.guide_id + or locked.guide_version != lineage.guide_version + or locked.source_snapshot_id != lineage.source_snapshot_id + or locked.source_snapshot_hash != lineage.source_snapshot_sha256 + or locked.effective_policy_id != lineage.effective_policy_id + or locked.effective_policy_hash != lineage.effective_policy_sha256 + or locked.pre_submit_policy_id != lineage.pre_submit_policy_id + or locked.pre_submit_policy_bundle_hash + != lineage.pre_submit_policy_sha256 + or reservation.policy_sha256 != lineage.effective_plan_sha256 + ): + raise ArtifactAdmissionRelationshipError( + "selected submission bundle locked context changed" + ) + operation_identity = canonical_json_hash( + { + "request_type": "submission_bundle", + "selected_pre_submit_run_id": str(reservation.attempt_id), + } + ) + authority_facts = SubmissionBundleDurableIntentAuthorityFacts( + actor_profile_id=reservation.actor_profile_id, + identity_link_id=reservation.identity_link_id, + project_id=reservation.project_id, + task_id=reservation.task_id, + assignment_id=reservation.assignment_id, + predecessor_submission_id=lineage.predecessor_submission_id, + predecessor_submission_version=lineage.predecessor_submission_version, + pre_submit_evidence_set_id=None, + prepared_generation_id=reservation.prepared_generation_id, + guide_id=lineage.guide_id, + guide_version=lineage.guide_version, + source_snapshot_id=lineage.source_snapshot_id, + source_snapshot_sha256=lineage.source_snapshot_sha256, + effective_policy_id=lineage.effective_policy_id, + effective_policy_sha256=lineage.effective_policy_sha256, + pre_submit_policy_id=lineage.pre_submit_policy_id, + pre_submit_policy_sha256=lineage.pre_submit_policy_sha256, + effective_plan_sha256=lineage.effective_plan_sha256, + semantic_manifest_id=lineage.semantic_manifest_id, + semantic_manifest_sha256=reservation.semantic_manifest_sha256, + semantic_manifest_body=lineage.semantic_manifest_body, + packet_sha256=lineage.packet_sha256, + archive_sha256=reservation.archive_sha256, + archive_byte_count=reservation.archive_byte_count, + media_type=commitment.media_type, + storage_scheme=lineage.storage_scheme, + operation_identity=operation_identity, + replay_durable_intent_id=request.replay_durable_intent_id, + selected_pre_submit_run_id=reservation.attempt_id, + selected_terminal_digest=request.custody.selected_terminal_digest, + ) + return authority_facts, _AdmissionFacts( + request_type="submission_bundle", + producer_type="actor_profile", + producer_ref=str(reservation.actor_profile_id), + project_id=str(reservation.project_id), + guide_id=str(lineage.guide_id), + task_id=str(reservation.task_id), + guide_source_item_id=None, + guide_source_snapshot_id=str(lineage.source_snapshot_id), + checker_run_id=None, + logical_role=None, + submission_id=None, + submission_version=None, + checker_request_digest=None, + checker_request_digest_facts=None, + pre_submit_evidence_set_id=None, + operation_identity=operation_identity, + selected_pre_submit_run_id=str(reservation.attempt_id), + ) + async def _require_active_human_actor(self, context: AuthorizationContext) -> None: """Revalidate and lock exact human identity state inside admission.""" actor = await self._actors.lock_admission_proof( diff --git a/backend/app/modules/artifacts/submission_admission.py b/backend/app/modules/artifacts/submission_admission.py index 5ab1e2cd5..284324b07 100644 --- a/backend/app/modules/artifacts/submission_admission.py +++ b/backend/app/modules/artifacts/submission_admission.py @@ -7,6 +7,7 @@ from dataclasses import dataclass, replace import json from uuid import UUID +from app.core.hashing import canonical_json_hash from app.core.identifiers import new_record_id from sqlalchemy import func, select @@ -69,6 +70,10 @@ PreSubmissionEvaluationPort, ) from app.modules.checkers.api.post_submit import PostSubmissionEvaluationContent +from app.modules.checkers.api.selected_pre_submit import ( + SelectedPreSubmitCompletion, + SelectedPreSubmitReservationFacts, +) from app.modules.checkers.api import ( EffectivePreSubmissionExecutionPlan, EffectivePreSubmissionPlanLineage, @@ -106,8 +111,13 @@ class SubmissionBundleDurablePutRequest: prepared_authorization: object prepared_artifact: PreparedArtifact - pass_capability: PreSubmitPassCapability + pass_capability: PreSubmitPassCapability | None replay_durable_intent_id: UUID | None = None + selected_completion: SelectedPreSubmitCompletion | None = None + + def __post_init__(self) -> None: + if (self.pass_capability is None) == (self.selected_completion is None): + raise ValueError("submission bundle durable PRE custody is invalid") @dataclass(frozen=True, slots=True) @@ -115,11 +125,12 @@ class SubmissionBundleDurablePutResult: """Bounded durable operation result without provider coordinates.""" put_attempt_id: UUID - pre_submit_evidence_set_id: UUID + pre_submit_evidence_set_id: UUID | None operation_identity: str status: str replayed: bool admission_id: UUID | None + selected_pre_submit_run_id: UUID | None = None class SubmissionBundleDurablePutService: @@ -160,22 +171,45 @@ async def admit_in_transaction( or not transaction.is_active or self._session.in_nested_transaction() or type(prepared) is not PreparedArtifact - or type(request.pass_capability) is not PreSubmitPassCapability + or ( + request.pass_capability is not None + and type(request.pass_capability) is not PreSubmitPassCapability + ) + or ( + request.selected_completion is not None + and type(request.selected_completion) is not SelectedPreSubmitCompletion + ) ): if type(prepared) is PreparedArtifact: await prepared.close() raise RuntimeError("submission bundle durable transaction is unavailable") try: - evidence_set_id = request.pass_capability.evidence_set_id - custody = SubmissionBundlePreparedCustody._from_live_preparation( - prepared=prepared, - capability=request.pass_capability, - ) + if request.selected_completion is not None: + custody = SubmissionBundlePreparedCustody._from_selected_pre_submit( + prepared=prepared, + completion=request.selected_completion, + ) + evidence_set_id = None + selected_run_id = custody.selected_reservation.attempt_id + else: + assert request.pass_capability is not None + evidence_set_id = request.pass_capability.evidence_set_id + selected_run_id = None + custody = SubmissionBundlePreparedCustody._from_live_preparation( + prepared=prepared, + capability=request.pass_capability, + ) admission = await self._admission.admit( SubmissionBundleArtifactAdmissionRequest( pre_submit_evidence_set_id=evidence_set_id, custody=custody, replay_durable_intent_id=request.replay_durable_intent_id, + selected_pre_submit_run_id=selected_run_id, + selected_terminal_digest=( + custody.selected_terminal_digest + if selected_run_id is not None + else None + ), ), submission_prepared_authorization=self._authorization, submission_task_contexts=self._task_contexts, @@ -183,7 +217,7 @@ async def admit_in_transaction( prepared_authorization=request.prepared_authorization, existing_transaction=True, ) - return prepared, evidence_set_id, admission + return prepared, evidence_set_id or selected_run_id, admission except BaseException: await prepared.close() raise @@ -191,10 +225,21 @@ async def admit_in_transaction( async def publish_after_commit( self, prepared: PreparedArtifact, - evidence_set_id: UUID, + lineage_id: UUID, admission: ArtifactAdmissionResult, + *, + selected_pre_submit_run_id: UUID | None = None, ) -> SubmissionBundleDurablePutResult: """Hand the exact ZIP to storage only after the durable transaction ended.""" + if ( + selected_pre_submit_run_id is not None + and selected_pre_submit_run_id != lineage_id + ): + await prepared.close() + raise RuntimeError("submission bundle selected lineage changed") + evidence_set_id = ( + None if selected_pre_submit_run_id is not None else lineage_id + ) if self._session.in_transaction(): await prepared.close() raise RuntimeError("submission bundle durable transaction is still active") @@ -214,6 +259,7 @@ async def publish_after_commit( status="ready", replayed=True, admission_id=admission_id, + selected_pre_submit_run_id=selected_pre_submit_run_id, ) if admission.replayed and admission.status == "object_confirmed": return SubmissionBundleDurablePutResult( @@ -223,6 +269,7 @@ async def publish_after_commit( status="object_confirmed", replayed=True, admission_id=None, + selected_pre_submit_run_id=selected_pre_submit_run_id, ) if admission.replayed: status = await self._storage.resume_committed_put( @@ -246,6 +293,7 @@ async def publish_after_commit( status=status, replayed=admission.replayed, admission_id=admission_id, + selected_pre_submit_run_id=selected_pre_submit_run_id, ) finally: await prepared.close() @@ -298,11 +346,40 @@ async def publish_verified( ) if existing is not None: return existing - evidence = await self._session.scalar( - select(PreSubmitEvidenceSet) - .where(PreSubmitEvidenceSet.id == intent.pre_submit_evidence_set_id) - .with_for_update(key_share=True) + evidence = ( + await self._session.scalar( + select(PreSubmitEvidenceSet) + .where(PreSubmitEvidenceSet.id == intent.pre_submit_evidence_set_id) + .with_for_update(key_share=True) + ) + if intent.pre_submit_evidence_set_id is not None + else None ) + selected = None + if intent.selected_pre_submit_run_id is not None: + try: + selected = SelectedPreSubmitReservationFacts.from_canonical_body( + intent.selected_request_json + ) + except (TypeError, ValueError) as exc: + raise SubmissionBundleAdmissionPublicationError( + "selected PRE request snapshot is invalid" + ) from exc + terminal = intent.selected_terminal_json + if ( + selected.admission_lineage is None + or selected.attempt_id != UUID(intent.selected_pre_submit_run_id) + or selected.request_digest != intent.selected_request_digest + or type(terminal) is not dict + or canonical_json_hash(terminal) != intent.selected_terminal_digest + or terminal.get("request_digest") != selected.request_digest + or terminal.get("outcome") != "completed" + or type(terminal.get("execution")) is not dict + or terminal["execution"].get("eligible") is not True + ): + raise SubmissionBundleAdmissionPublicationError( + "selected PRE terminal snapshot is invalid" + ) replica = await self._session.scalar( select(ArtifactReplica) .where(ArtifactReplica.id == job.replica_id) @@ -322,48 +399,157 @@ async def publish_verified( if replica is not None else None ) - if not self._matches_verified_lineage(evidence, attempt, job, replica, content, receipt): + lineage = selected.admission_lineage if selected is not None else evidence + if ( + lineage is None + or ( + evidence is not None + and (evidence.terminal_status != "passed" or not evidence.eligible) + ) + or not self._matches_verified_bytes( + attempt, + job, + replica, + content, + receipt, + project_id=str( + selected.project_id if selected is not None else evidence.project_id + ), + task_id=str( + selected.task_id if selected is not None else evidence.task_id + ), + actor_profile_id=str( + selected.actor_profile_id + if selected is not None + else evidence.actor_profile_id + ), + archive_sha256=( + selected.archive_sha256 + if selected is not None + else evidence.archive_sha256 + ), + archive_byte_count=( + selected.archive_byte_count + if selected is not None + else evidence.archive_byte_count + ), + ) + ): raise SubmissionBundleAdmissionPublicationError( "verified submission bundle lineage does not match" ) operation_receipt_id, observation_receipt_id = await self._write_receipt_ids(attempt) - assert evidence is not None and replica is not None and content is not None + assert replica is not None and content is not None assert receipt is not None + selected_lineage = selected.admission_lineage if selected is not None else None now = await self._session.scalar(select(func.now())) admission = SubmissionBundleAdmission( id=str(new_record_id()), durable_intent_id=intent.id, - pre_submit_evidence_set_id=evidence.id, - selected_pre_submit_run_id=None, + pre_submit_evidence_set_id=(evidence.id if evidence is not None else None), + selected_pre_submit_run_id=( + str(selected.attempt_id) if selected is not None else None + ), put_attempt_id=attempt.id, artifact_content_id=content.id, verified_replica_id=replica.id, verification_receipt_id=receipt.id, put_operation_receipt_id=operation_receipt_id, put_observation_receipt_id=observation_receipt_id, - actor_profile_id=evidence.actor_profile_id, - identity_link_id=evidence.identity_link_id, - project_id=evidence.project_id, - task_id=evidence.task_id, - assignment_id=evidence.assignment_id, - predecessor_submission_id=evidence.predecessor_submission_id, - predecessor_submission_version=evidence.predecessor_submission_version, - locked_policy_context_hash=evidence.locked_policy_context_hash, - guide_id=evidence.guide_id, - guide_version=evidence.guide_version, - source_snapshot_id=evidence.source_snapshot_id, - source_snapshot_sha256=evidence.source_snapshot_sha256, - effective_policy_id=evidence.effective_policy_id, - effective_policy_sha256=evidence.locked_artifact_policy_sha256, - pre_submit_policy_id=evidence.pre_submit_policy_id, - pre_submit_policy_sha256=evidence.locked_checker_policy_sha256, - effective_plan_sha256=evidence.effective_plan_sha256, - packet_sha256=evidence.packet_sha256, - semantic_manifest_id=evidence.semantic_manifest_id, - semantic_manifest_sha256=evidence.semantic_manifest_sha256, - semantic_manifest_body=evidence.semantic_manifest_body, - archive_sha256=evidence.archive_sha256, - archive_byte_count=evidence.archive_byte_count, + actor_profile_id=str( + selected.actor_profile_id if selected is not None else evidence.actor_profile_id + ), + identity_link_id=str( + selected.identity_link_id if selected is not None else evidence.identity_link_id + ), + project_id=str(selected.project_id if selected is not None else evidence.project_id), + task_id=str(selected.task_id if selected is not None else evidence.task_id), + assignment_id=str( + selected.assignment_id if selected is not None else evidence.assignment_id + ), + predecessor_submission_id=( + str(selected_lineage.predecessor_submission_id) + if selected_lineage is not None + and selected_lineage.predecessor_submission_id is not None + else evidence.predecessor_submission_id if evidence is not None else None + ), + predecessor_submission_version=( + selected_lineage.predecessor_submission_version + if selected_lineage is not None + else evidence.predecessor_submission_version + ), + locked_policy_context_hash=( + selected_lineage.locked_policy_context_hash + if selected_lineage is not None + else evidence.locked_policy_context_hash + ), + guide_id=str( + selected_lineage.guide_id if selected_lineage is not None else evidence.guide_id + ), + guide_version=( + selected_lineage.guide_version if selected_lineage is not None else evidence.guide_version + ), + source_snapshot_id=str( + selected_lineage.source_snapshot_id + if selected_lineage is not None + else evidence.source_snapshot_id + ), + source_snapshot_sha256=( + selected_lineage.source_snapshot_sha256 + if selected_lineage is not None + else evidence.source_snapshot_sha256 + ), + effective_policy_id=str( + selected_lineage.effective_policy_id + if selected_lineage is not None + else evidence.effective_policy_id + ), + effective_policy_sha256=( + selected_lineage.effective_policy_sha256 + if selected_lineage is not None + else evidence.locked_artifact_policy_sha256 + ), + pre_submit_policy_id=str( + selected_lineage.pre_submit_policy_id + if selected_lineage is not None + else evidence.pre_submit_policy_id + ), + pre_submit_policy_sha256=( + selected_lineage.pre_submit_policy_sha256 + if selected_lineage is not None + else evidence.locked_checker_policy_sha256 + ), + effective_plan_sha256=( + selected_lineage.effective_plan_sha256 + if selected_lineage is not None + else evidence.effective_plan_sha256 + ), + packet_sha256=( + selected_lineage.packet_sha256 + if selected_lineage is not None + else evidence.packet_sha256 + ), + semantic_manifest_id=str( + selected_lineage.semantic_manifest_id + if selected_lineage is not None + else evidence.semantic_manifest_id + ), + semantic_manifest_sha256=( + selected.semantic_manifest_sha256 + if selected is not None + else evidence.semantic_manifest_sha256 + ), + semantic_manifest_body=( + selected_lineage.semantic_manifest_body + if selected_lineage is not None + else evidence.semantic_manifest_body + ), + archive_sha256=( + selected.archive_sha256 if selected is not None else evidence.archive_sha256 + ), + archive_byte_count=( + selected.archive_byte_count if selected is not None else evidence.archive_byte_count + ), status="ready", ready_at=now, consumed_at=None, @@ -376,12 +562,21 @@ async def publish_verified( return admission @staticmethod - def _matches_verified_lineage(evidence, attempt, job, replica, content, receipt) -> bool: + def _matches_verified_bytes( + attempt, + job, + replica, + content, + receipt, + *, + project_id: str, + task_id: str, + actor_profile_id: str, + archive_sha256: str, + archive_byte_count: int, + ) -> bool: return bool( - evidence is not None - and evidence.terminal_status == "passed" - and evidence.eligible - and replica is not None + replica is not None and content is not None and receipt is not None and receipt.verification_job_id == job.id @@ -390,11 +585,11 @@ def _matches_verified_lineage(evidence, attempt, job, replica, content, receipt) and receipt.observed_sha256 == attempt.sha256 == content.sha256 - == evidence.archive_sha256 + == archive_sha256 and receipt.observed_byte_count == attempt.byte_count == content.byte_count - == evidence.archive_byte_count + == archive_byte_count and job.originating_put_attempt_id == attempt.id and job.replica_id == replica.id and attempt.replica_id == replica.id @@ -402,12 +597,33 @@ def _matches_verified_lineage(evidence, attempt, job, replica, content, receipt) and replica.verification_state == "verified" and replica.availability_state == "available" and replica.integrity_state == "valid" - and attempt.project_id == evidence.project_id - and attempt.task_id == evidence.task_id - and attempt.producer_ref == evidence.actor_profile_id + and attempt.project_id == project_id + and attempt.task_id == task_id + and attempt.producer_ref == actor_profile_id and attempt.media_type == "application/zip" ) + @staticmethod + def _matches_verified_lineage(evidence, attempt, job, replica, content, receipt) -> bool: + """Retain the historical evidence decoder over the shared byte verifier.""" + return bool( + evidence is not None + and evidence.terminal_status == "passed" + and evidence.eligible + and SubmissionBundleAdmissionPublisher._matches_verified_bytes( + attempt, + job, + replica, + content, + receipt, + project_id=evidence.project_id, + task_id=evidence.task_id, + actor_profile_id=evidence.actor_profile_id, + archive_sha256=evidence.archive_sha256, + archive_byte_count=evidence.archive_byte_count, + ) + ) + async def _write_receipt_ids( self, attempt: ArtifactPutAttempt ) -> tuple[str | None, str | None]: diff --git a/backend/app/modules/artifacts/submission_bindings.py b/backend/app/modules/artifacts/submission_bindings.py index 11c0c106f..ae099db48 100644 --- a/backend/app/modules/artifacts/submission_bindings.py +++ b/backend/app/modules/artifacts/submission_bindings.py @@ -35,7 +35,8 @@ class SubmissionBindingAuthorityFacts: """Exact ART-owned facts consumed before binding and terminal mutation.""" admission_id: UUID - evidence_set_id: UUID + evidence_set_id: UUID | None + selected_pre_submit_run_id: UUID | None actor_profile_id: UUID identity_link_id: UUID project_id: UUID @@ -121,17 +122,13 @@ async def consume( raise SubmissionAdmissionConsumptionError( "submission_bundle_admission_already_consumed" ) - evidence = await self._session.scalar( - select(PreSubmitEvidenceSet) - .where(PreSubmitEvidenceSet.id == admission.pre_submit_evidence_set_id) - .with_for_update() - ) + evidence = await self._legacy_evidence(admission) content = await self._session.scalar( select(ArtifactContent) .where(ArtifactContent.id == admission.artifact_content_id) .with_for_update() ) - if evidence is None or content is None: + if content is None: raise SubmissionAdmissionConsumptionError( "submission_bundle_admission_unavailable" ) @@ -141,21 +138,22 @@ async def consume( ) try: SubmissionManifest.from_dict( - evidence.semantic_manifest_body, sha256=evidence.semantic_manifest_sha256, + admission.semantic_manifest_body, + sha256=admission.semantic_manifest_sha256, ) except (TypeError, ValueError) as exc: raise SubmissionAdmissionConsumptionError("submission_bundle_admission_unavailable") from exc - if evidence.packet_sha256 != request.packet_sha256: + if admission.packet_sha256 != request.packet_sha256: raise SubmissionAdmissionConsumptionError("submission_bundle_admission_unavailable") if admission.status == "consumed": raise SubmissionAdmissionConsumptionError("submission_bundle_admission_already_consumed") - if not self._task_lineage_matches(admission, evidence, request): + if not self._task_lineage_matches(admission, request): now = await self._session.scalar(select(func.now())) admission.status = "stale" admission.stale_at = now admission.stale_reason = "locked_submission_context_changed" await self._session.flush() - return self._result(admission, request, evidence, binding=None, replayed=False) + return self._result(admission, request, binding=None, replayed=False) await self._lock_binding_scope(admission, request) existing = await self._session.scalar( @@ -178,13 +176,12 @@ async def consume( return self._result( admission, request, - evidence, binding=None, replayed=False, ) binding_decision_id = await self._authorization.consume( - self._authority_facts(admission, evidence, request) + self._authority_facts(admission, request) ) binding = ArtifactBinding( @@ -210,7 +207,7 @@ async def consume( admission_id=str(request.admission_id), binding_id=binding.id, decision_id=str(binding_decision_id), )) await self._session.flush() - return self._result(admission, request, evidence, binding=binding, replayed=False, + return self._result(admission, request, binding=binding, replayed=False, binding_decision_id=binding_decision_id) async def _lock_binding_scope( @@ -256,9 +253,7 @@ async def read_consumed( populate_existing=True) if receipt is None: raise SubmissionAdmissionConsumptionError("submission_bundle_admission_unavailable") - evidence = await self._session.scalar(select(PreSubmitEvidenceSet).where( - PreSubmitEvidenceSet.id == admission.pre_submit_evidence_set_id, - ).with_for_update().execution_options(populate_existing=True)) + evidence = await self._legacy_evidence(admission) content = await self._session.scalar(select(ArtifactContent).where( ArtifactContent.id == admission.artifact_content_id, ).with_for_update().execution_options(populate_existing=True)) @@ -270,27 +265,41 @@ async def read_consumed( ArtifactBinding.scope_version == 1, ).execution_options(populate_existing=True)) if ( - evidence is None or content is None or binding is None + content is None or binding is None or binding.content_id != admission.artifact_content_id or binding.id != receipt.binding_id or not self._art_lineage_is_intact(admission, evidence, content) - or evidence.packet_sha256 != request.packet_sha256 + or admission.packet_sha256 != request.packet_sha256 ): raise SubmissionAdmissionConsumptionError("submission_bundle_admission_context_changed") await self._authorization.validate_replay( - self._authority_facts(admission, evidence, request), UUID(receipt.decision_id), + self._authority_facts(admission, request), UUID(receipt.decision_id), ) - return self._result(admission, request, evidence, binding=binding, replayed=True, + return self._result(admission, request, binding=binding, replayed=True, binding_decision_id=UUID(receipt.decision_id)) + async def _legacy_evidence( + self, admission: SubmissionBundleAdmission + ) -> PreSubmitEvidenceSet | None: + """Load retained legacy evidence only for historical lineage validation.""" + if admission.pre_submit_evidence_set_id is None: + return None + return await self._session.scalar( + select(PreSubmitEvidenceSet) + .where(PreSubmitEvidenceSet.id == admission.pre_submit_evidence_set_id) + .with_for_update() + .execution_options(populate_existing=True) + ) + @staticmethod def _art_lineage_is_intact( admission: SubmissionBundleAdmission, - evidence: PreSubmitEvidenceSet, + evidence: PreSubmitEvidenceSet | None, content: ArtifactContent, ) -> bool: - return bool( + legacy_intact = evidence is None or bool( evidence.id == admission.pre_submit_evidence_set_id + and admission.selected_pre_submit_run_id is None and evidence.actor_profile_id == admission.actor_profile_id and evidence.identity_link_id == admission.identity_link_id and evidence.project_id == admission.project_id @@ -309,6 +318,11 @@ def _art_lineage_is_intact( and evidence.archive_byte_count == admission.archive_byte_count and evidence.terminal_status == "passed" and evidence.eligible is True + ) + return bool( + legacy_intact + and (admission.pre_submit_evidence_set_id is None) + != (admission.selected_pre_submit_run_id is None) and content.id == admission.artifact_content_id and content.sha256 == admission.archive_sha256 and content.byte_count == admission.archive_byte_count @@ -317,7 +331,6 @@ def _art_lineage_is_intact( @staticmethod def _task_lineage_matches( admission: SubmissionBundleAdmission, - evidence: PreSubmitEvidenceSet, request: SubmissionAdmissionConsumptionRequest, ) -> bool: context = request.task_context @@ -332,25 +345,33 @@ def _task_lineage_matches( == (str(predecessor.submission_id) if predecessor is not None else None) and admission.predecessor_submission_version == (predecessor.version if predecessor is not None else None) - and evidence.guide_version == references.guide_version - and evidence.source_snapshot_id == str(references.source_snapshot_id) - and evidence.source_snapshot_sha256 == references.source_snapshot_hash - and evidence.effective_policy_id == str(references.effective_policy_id) - and evidence.locked_artifact_policy_sha256 == references.effective_policy_hash - and evidence.pre_submit_policy_id == str(references.pre_submit_policy_id) - and evidence.locked_checker_policy_sha256 + and admission.guide_version == references.guide_version + and admission.source_snapshot_id == str(references.source_snapshot_id) + and admission.source_snapshot_sha256 == references.source_snapshot_hash + and admission.effective_policy_id == str(references.effective_policy_id) + and admission.effective_policy_sha256 == references.effective_policy_hash + and admission.pre_submit_policy_id == str(references.pre_submit_policy_id) + and admission.pre_submit_policy_sha256 == references.pre_submit_policy_bundle_hash ) @staticmethod def _authority_facts( admission: SubmissionBundleAdmission, - evidence: PreSubmitEvidenceSet, request: SubmissionAdmissionConsumptionRequest | ConsumedSubmissionAdmissionRequest, ) -> SubmissionBindingAuthorityFacts: return SubmissionBindingAuthorityFacts( admission_id=request.admission_id, - evidence_set_id=UUID(evidence.id), + evidence_set_id=( + UUID(admission.pre_submit_evidence_set_id) + if admission.pre_submit_evidence_set_id is not None + else None + ), + selected_pre_submit_run_id=( + UUID(admission.selected_pre_submit_run_id) + if admission.selected_pre_submit_run_id is not None + else None + ), actor_profile_id=UUID(admission.actor_profile_id), identity_link_id=UUID(admission.identity_link_id), project_id=UUID(admission.project_id), @@ -364,17 +385,17 @@ def _authority_facts( predecessor_submission_version=admission.predecessor_submission_version, submission_id=request.submission_id, submission_version=request.submission_version, - guide_id=UUID(evidence.guide_id), - guide_version=evidence.guide_version, - source_snapshot_id=UUID(evidence.source_snapshot_id), - source_snapshot_sha256=evidence.source_snapshot_sha256, - effective_policy_id=UUID(evidence.effective_policy_id), - effective_policy_sha256=evidence.locked_artifact_policy_sha256, - pre_submit_policy_id=UUID(evidence.pre_submit_policy_id), - pre_submit_policy_sha256=evidence.locked_checker_policy_sha256, - locked_policy_context_hash=evidence.locked_policy_context_hash, - semantic_manifest_id=UUID(evidence.semantic_manifest_id), - semantic_manifest_sha256=evidence.semantic_manifest_sha256, + guide_id=UUID(admission.guide_id), + guide_version=admission.guide_version, + source_snapshot_id=UUID(admission.source_snapshot_id), + source_snapshot_sha256=admission.source_snapshot_sha256, + effective_policy_id=UUID(admission.effective_policy_id), + effective_policy_sha256=admission.effective_policy_sha256, + pre_submit_policy_id=UUID(admission.pre_submit_policy_id), + pre_submit_policy_sha256=admission.pre_submit_policy_sha256, + locked_policy_context_hash=admission.locked_policy_context_hash, + semantic_manifest_id=UUID(admission.semantic_manifest_id), + semantic_manifest_sha256=admission.semantic_manifest_sha256, content_id=UUID(admission.artifact_content_id), sha256=admission.archive_sha256, byte_count=admission.archive_byte_count, @@ -385,7 +406,6 @@ def _authority_facts( def _result( admission: SubmissionBundleAdmission, request: SubmissionAdmissionConsumptionRequest | ConsumedSubmissionAdmissionRequest, - evidence: PreSubmitEvidenceSet, *, binding: ArtifactBinding | None, replayed: bool, @@ -394,7 +414,8 @@ def _result( material = None if admission.status == "consumed": manifest = SubmissionManifest.from_dict( - evidence.semantic_manifest_body, sha256=evidence.semantic_manifest_sha256, + admission.semantic_manifest_body, + sha256=admission.semantic_manifest_sha256, ) material = SubmissionAdmissionMaterial( archive_sha256=admission.archive_sha256, diff --git a/backend/app/modules/artifacts/submission_custody.py b/backend/app/modules/artifacts/submission_custody.py index 47ed2ee12..ba652261a 100644 --- a/backend/app/modules/artifacts/submission_custody.py +++ b/backend/app/modules/artifacts/submission_custody.py @@ -110,6 +110,18 @@ def selected_terminal_digest(self) -> str: raise TypeError("selected submission custody is unavailable") return self._selected.terminal_digest + @property + def selected_terminal_body(self) -> dict[str, object]: + """Return a fresh canonical terminal body for the durable ART snapshot.""" + if self._selected is None: + raise TypeError("selected submission custody is unavailable") + return self._selected.canonical_body() + @property def source(self) -> CommittedArtifactSource: return self._prepared.committed_source + + @property + def is_selected(self) -> bool: + """Distinguish new selected custody from the retained legacy decoder.""" + return self._selected is not None diff --git a/backend/app/modules/authorization/submission_consumption.py b/backend/app/modules/authorization/submission_consumption.py index d775172a3..bdf990c1b 100644 --- a/backend/app/modules/authorization/submission_consumption.py +++ b/backend/app/modules/authorization/submission_consumption.py @@ -57,7 +57,8 @@ class SubmissionBindingResourceContext(BaseModel): resource_type: Literal["submission_binding"] resource_id: UUID admission_id: UUID - evidence_set_id: UUID + evidence_set_id: UUID | None + selected_pre_submit_run_id: UUID | None actor_profile_id: UUID identity_link_id: UUID project_id: UUID @@ -92,6 +93,10 @@ def bind_admission(self): self.predecessor_submission_version is None ): raise ValueError("submission binding predecessor is incomplete") + if (self.evidence_set_id is None) == ( + self.selected_pre_submit_run_id is None + ): + raise ValueError("submission binding PRE lineage is incomplete") return self diff --git a/backend/app/modules/authorization/submission_preparation.py b/backend/app/modules/authorization/submission_preparation.py index f4313bca5..f53fa00b9 100644 --- a/backend/app/modules/authorization/submission_preparation.py +++ b/backend/app/modules/authorization/submission_preparation.py @@ -36,7 +36,11 @@ class SubmissionBundlePreparationResourceContext(SubmissionBundlePreparationRequ resource_type: Literal["submission_bundle_preparation"] resource_id: UUID predecessor_submission_version: int | None = Field(default=None, ge=1) - pre_submit_evidence_set_id: UUID + pre_submit_evidence_set_id: UUID | None + selected_pre_submit_run_id: UUID | None = None + selected_terminal_digest: str | None = Field( + default=None, pattern=r"^sha256:[0-9a-f]{64}$" + ) prepared_generation_id: UUID guide_id: UUID guide_version: str @@ -49,6 +53,8 @@ class SubmissionBundlePreparationResourceContext(SubmissionBundlePreparationRequ effective_plan_sha256: str = Field(pattern=r"^sha256:[0-9a-f]{64}$") semantic_manifest_id: UUID semantic_manifest_sha256: str = Field(pattern=r"^sha256:[0-9a-f]{64}$") + semantic_manifest_body: dict[str, object] + packet_sha256: str = Field(pattern=r"^sha256:[0-9a-f]{64}$") archive_sha256: str = Field(pattern=r"^sha256:[0-9a-f]{64}$") archive_byte_count: int = Field(ge=0) media_type: Literal["application/zip"] @@ -65,6 +71,13 @@ def require_exact_identity_and_predecessor(self): self.predecessor_submission_version is None ): raise ValueError("submission predecessor identity is incomplete") + if ( + (self.pre_submit_evidence_set_id is None) + == (self.selected_pre_submit_run_id is None) + or (self.selected_pre_submit_run_id is None) + != (self.selected_terminal_digest is None) + ): + raise ValueError("submission preparation lineage is incomplete") return self @@ -91,7 +104,6 @@ def parse_submission_preparation( if "prepared_generation_id" not in value: return request_context, request_digest, None, None for field in ( - "pre_submit_evidence_set_id", "prepared_generation_id", "guide_id", "source_snapshot_id", @@ -100,6 +112,9 @@ def parse_submission_preparation( "semantic_manifest_id", ): value[field] = UUID(str(value[field])) + for field in ("pre_submit_evidence_set_id", "selected_pre_submit_run_id"): + if value.get(field) is not None: + value[field] = UUID(str(value[field])) if value.get("replay_durable_intent_id") is not None: value["replay_durable_intent_id"] = UUID(str(value["replay_durable_intent_id"])) final = SubmissionBundlePreparationResourceContext( diff --git a/backend/app/modules/checkers/api/selected_pre_submit.py b/backend/app/modules/checkers/api/selected_pre_submit.py index b94902abc..4ffb1da79 100644 --- a/backend/app/modules/checkers/api/selected_pre_submit.py +++ b/backend/app/modules/checkers/api/selected_pre_submit.py @@ -106,6 +106,54 @@ def canonical_body(self) -> dict[str, object]: "storage_scheme": self.storage_scheme, } + @classmethod + def from_canonical_body( + cls, body: object + ) -> SelectedPreSubmitAdmissionLineage: + """Parse the exact closed body copied into ART's durable intent.""" + if type(body) is not dict or set(body) != { + "predecessor_submission_id", + "predecessor_submission_version", + "guide_id", + "guide_version", + "source_snapshot_id", + "source_snapshot_sha256", + "locked_guide_sha256", + "effective_policy_id", + "effective_policy_sha256", + "pre_submit_policy_id", + "pre_submit_policy_sha256", + "effective_plan_sha256", + "locked_policy_context_hash", + "semantic_manifest_id", + "semantic_manifest_body", + "packet_sha256", + "storage_scheme", + }: + raise ValueError("selected PRE admission lineage is invalid") + predecessor = body["predecessor_submission_id"] + return cls( + predecessor_submission_id=( + UUID(str(predecessor)) if predecessor is not None else None + ), + predecessor_submission_version=body["predecessor_submission_version"], + guide_id=UUID(str(body["guide_id"])), + guide_version=body["guide_version"], + source_snapshot_id=UUID(str(body["source_snapshot_id"])), + source_snapshot_sha256=body["source_snapshot_sha256"], + locked_guide_sha256=body["locked_guide_sha256"], + effective_policy_id=UUID(str(body["effective_policy_id"])), + effective_policy_sha256=body["effective_policy_sha256"], + pre_submit_policy_id=UUID(str(body["pre_submit_policy_id"])), + pre_submit_policy_sha256=body["pre_submit_policy_sha256"], + effective_plan_sha256=body["effective_plan_sha256"], + locked_policy_context_hash=body["locked_policy_context_hash"], + semantic_manifest_id=UUID(str(body["semantic_manifest_id"])), + semantic_manifest_body=body["semantic_manifest_body"], + packet_sha256=body["packet_sha256"], + storage_scheme=body["storage_scheme"], + ) + @dataclass(frozen=True, slots=True) class ExternalPreSubmitIsolationFacts: @@ -310,6 +358,55 @@ def canonical_body(self) -> dict[str, object]: ), } + @classmethod + def from_canonical_body( + cls, body: object + ) -> SelectedPreSubmitReservationFacts: + """Recover and validate the durable request snapshot at ART publication.""" + if type(body) is not dict or set(body) != { + "schema_version", + "actor_profile_id", + "identity_link_id", + "project_id", + "task_id", + "assignment_id", + "attempt_id", + "attempt_request_digest", + "prepared_generation_id", + "policy_sha256", + "default_behavior_sha256", + "default_input_sha256", + "archive_sha256", + "archive_byte_count", + "semantic_manifest_sha256", + "execution_budget_ms", + "admission_lineage", + } or body["schema_version"] != "workstream.selected_pre_submit_reservation.v1": + raise ValueError("selected PRE reservation facts are invalid") + lineage_body = body["admission_lineage"] + return cls( + actor_profile_id=UUID(str(body["actor_profile_id"])), + identity_link_id=UUID(str(body["identity_link_id"])), + project_id=UUID(str(body["project_id"])), + task_id=UUID(str(body["task_id"])), + assignment_id=UUID(str(body["assignment_id"])), + attempt_id=UUID(str(body["attempt_id"])), + attempt_request_digest=body["attempt_request_digest"], + prepared_generation_id=UUID(str(body["prepared_generation_id"])), + policy_sha256=body["policy_sha256"], + default_behavior_sha256=body["default_behavior_sha256"], + default_input_sha256=body["default_input_sha256"], + archive_sha256=body["archive_sha256"], + archive_byte_count=body["archive_byte_count"], + semantic_manifest_sha256=body["semantic_manifest_sha256"], + execution_budget_ms=body["execution_budget_ms"], + admission_lineage=( + SelectedPreSubmitAdmissionLineage.from_canonical_body(lineage_body) + if lineage_body is not None + else None + ), + ) + @property def request_digest(self) -> str: """Return the immutable request identity used by reserve and replay.""" diff --git a/backend/tests/authorization/test_fixed_service_action_context.py b/backend/tests/authorization/test_fixed_service_action_context.py index 5115c7184..7690dec25 100644 --- a/backend/tests/authorization/test_fixed_service_action_context.py +++ b/backend/tests/authorization/test_fixed_service_action_context.py @@ -93,7 +93,8 @@ async def test_submission_binding_validation_is_concealed() -> None: """Malformed exact binding facts never expose Pydantic validation details.""" ids = [uuid4() for _ in range(12)] facts = SubmissionBindingAuthorityFacts( - admission_id=ids[0], evidence_set_id=ids[1], actor_profile_id=ids[2], + admission_id=ids[0], evidence_set_id=ids[1], selected_pre_submit_run_id=None, + actor_profile_id=ids[2], identity_link_id=ids[3], project_id=ids[4], task_id=ids[5], assignment_id=ids[6], predecessor_submission_id=None, predecessor_submission_version=None, submission_id=ids[7], diff --git a/backend/tests/checkers/external/test_selected_pre_submit_coordination.py b/backend/tests/checkers/external/test_selected_pre_submit_coordination.py index 46264167b..11fac16a0 100644 --- a/backend/tests/checkers/external/test_selected_pre_submit_coordination.py +++ b/backend/tests/checkers/external/test_selected_pre_submit_coordination.py @@ -4,6 +4,7 @@ from dataclasses import replace from types import SimpleNamespace +from uuid import UUID import pytest from sqlalchemy.dialects import postgresql @@ -12,6 +13,7 @@ from app.core.identifiers import new_record_id from app.core.hashing import canonical_json_hash from app.modules.artifacts.schemas import SubmissionBundleArtifactAdmissionRequest +from app.modules.artifacts.submission_bindings import SubmissionAdmissionConsumptionService from app.modules.artifacts.models import ( SubmissionBundleAdmission, SubmissionBundleDurableIntent, @@ -222,6 +224,9 @@ def test_selected_pre_request_binds_complete_later_admission_lineage() -> None: ) assert reservation.canonical_body()["admission_lineage"] == lineage.canonical_body() + assert SelectedPreSubmitReservationFacts.from_canonical_body( + reservation.canonical_body() + ) == reservation assert reservation.request_digest != replace( reservation, admission_lineage=replace(lineage, packet_sha256="sha256:" + "9" * 64), @@ -250,3 +255,52 @@ def test_submission_artifact_request_selects_exactly_one_pre_lineage() -> None: ) with pytest.raises(ValueError, match="lineage"): replace(request, selected_terminal_digest=None) + + +def test_selected_ready_admission_no_longer_requires_legacy_evidence() -> None: + run_id = new_record_id() + admission = SimpleNamespace( + id=str(new_record_id()), + pre_submit_evidence_set_id=None, + selected_pre_submit_run_id=str(run_id), + artifact_content_id=str(new_record_id()), + actor_profile_id=str(new_record_id()), + identity_link_id=str(new_record_id()), + project_id=str(new_record_id()), + task_id=str(new_record_id()), + assignment_id=str(new_record_id()), + predecessor_submission_id=None, + predecessor_submission_version=None, + guide_id=str(new_record_id()), + guide_version="v1", + source_snapshot_id=str(new_record_id()), + source_snapshot_sha256=SHA, + effective_policy_id=str(new_record_id()), + effective_policy_sha256=SHA, + pre_submit_policy_id=str(new_record_id()), + pre_submit_policy_sha256=SHA, + locked_policy_context_hash=SHA, + semantic_manifest_id=str(new_record_id()), + semantic_manifest_sha256=SHA, + archive_sha256=SHA, + archive_byte_count=42, + ) + content = SimpleNamespace( + id=admission.artifact_content_id, + sha256=admission.archive_sha256, + byte_count=admission.archive_byte_count, + ) + request = SimpleNamespace( + admission_id=UUID(admission.id), + submission_id=new_record_id(), + submission_version=1, + ) + + assert SubmissionAdmissionConsumptionService._art_lineage_is_intact( + admission, None, content + ) + facts = SubmissionAdmissionConsumptionService._authority_facts( + admission, request + ) + assert facts.evidence_set_id is None + assert facts.selected_pre_submit_run_id == run_id diff --git a/backend/tests/test_submission_bundle_admission.py b/backend/tests/test_submission_bundle_admission.py index 2e05f4ce9..9ce8a1e53 100644 --- a/backend/tests/test_submission_bundle_admission.py +++ b/backend/tests/test_submission_bundle_admission.py @@ -7,6 +7,7 @@ from datetime import UTC, datetime from types import SimpleNamespace from unittest.mock import AsyncMock, Mock +from app.core.hashing import canonical_json_hash from app.core.identifiers import new_record_id import pytest @@ -63,6 +64,11 @@ from app.main import create_app from app.api.routes.artifact_submissions import router as submission_router from app.modules.artifacts.submission_admission import validate_submission_packet_headers +from app.modules.checkers.api.default_checker import WORKSTREAM_DEFAULT_BEHAVIOR_SHA256 +from app.modules.checkers.api.selected_pre_submit import ( + SelectedPreSubmitAdmissionLineage, + SelectedPreSubmitReservationFacts, +) def _actor() -> ActorIdentityFacts: @@ -551,6 +557,8 @@ async def test_verified_submission_lineage_publishes_one_ready_admission( locked_checker_policy_sha256=_sha("6"), effective_plan_sha256=_sha("7"), locked_policy_context_hash=_sha("8"), + packet_sha256=_sha("9"), + semantic_manifest_body={"schema_version": "submission_manifest.v1", "entries": []}, ) attempt = SimpleNamespace( id=attempt_id, @@ -570,7 +578,11 @@ async def test_verified_submission_lineage_publishes_one_ready_admission( replica_id=replica_id, execution_generation=2, ) - intent = SimpleNamespace(id=str(new_record_id()), pre_submit_evidence_set_id=evidence_id) + intent = SimpleNamespace( + id=str(new_record_id()), + pre_submit_evidence_set_id=evidence_id, + selected_pre_submit_run_id=None, + ) replica = SimpleNamespace( id=replica_id, content_id=content_id, @@ -626,6 +638,128 @@ async def test_verified_submission_lineage_publishes_one_ready_admission( session.add.assert_called_once_with(admission) +@pytest.mark.asyncio +async def test_selected_pre_terminal_publishes_self_contained_ready_admission() -> None: + manifest = {"schema_version": "submission_manifest.v1", "entries": []} + lineage = SelectedPreSubmitAdmissionLineage( + predecessor_submission_id=None, + predecessor_submission_version=None, + guide_id=new_record_id(), + guide_version="v2", + source_snapshot_id=new_record_id(), + source_snapshot_sha256=_sha("1"), + locked_guide_sha256=_sha("2"), + effective_policy_id=new_record_id(), + effective_policy_sha256=_sha("3"), + pre_submit_policy_id=new_record_id(), + pre_submit_policy_sha256=_sha("4"), + effective_plan_sha256=_sha("5"), + locked_policy_context_hash=_sha("6"), + semantic_manifest_id=new_record_id(), + semantic_manifest_body=manifest, + packet_sha256=_sha("7"), + storage_scheme="s3", + ) + selected = SelectedPreSubmitReservationFacts( + actor_profile_id=new_record_id(), + identity_link_id=new_record_id(), + project_id=new_record_id(), + task_id=new_record_id(), + assignment_id=new_record_id(), + attempt_id=new_record_id(), + attempt_request_digest=_sha("8"), + prepared_generation_id=new_record_id(), + policy_sha256=lineage.effective_plan_sha256, + default_behavior_sha256=WORKSTREAM_DEFAULT_BEHAVIOR_SHA256, + default_input_sha256=_sha("9"), + archive_sha256=_sha("a"), + archive_byte_count=25, + semantic_manifest_sha256=canonical_json_hash(manifest), + execution_budget_ms=120_000, + admission_lineage=lineage, + ) + terminal = { + "request_digest": selected.request_digest, + "outcome": "completed", + "execution": {"eligible": True}, + } + attempt = SimpleNamespace( + id=str(new_record_id()), + producer_request_type="submission_bundle", + producer_ref=str(selected.actor_profile_id), + project_id=str(selected.project_id), + task_id=str(selected.task_id), + sha256=selected.archive_sha256, + byte_count=selected.archive_byte_count, + media_type="application/zip", + replica_id=str(new_record_id()), + receipt_id=str(new_record_id()), + ) + job = SimpleNamespace( + id=str(new_record_id()), + originating_put_attempt_id=attempt.id, + replica_id=attempt.replica_id, + execution_generation=2, + ) + intent = SimpleNamespace( + id=str(new_record_id()), + pre_submit_evidence_set_id=None, + selected_pre_submit_run_id=str(selected.attempt_id), + selected_request_json=selected.canonical_body(), + selected_request_digest=selected.request_digest, + selected_terminal_json=terminal, + selected_terminal_digest=canonical_json_hash(terminal), + ) + replica = SimpleNamespace( + id=attempt.replica_id, + content_id=str(new_record_id()), + verification_state="verified", + availability_state="available", + integrity_state="valid", + ) + content = SimpleNamespace( + id=replica.content_id, + sha256=attempt.sha256, + byte_count=attempt.byte_count, + ) + verification = SimpleNamespace( + id=str(new_record_id()), + verification_job_id=job.id, + execution_generation=job.execution_generation, + outcome="verified", + observed_sha256=attempt.sha256, + observed_byte_count=attempt.byte_count, + ) + receipt = SimpleNamespace(id=attempt.receipt_id) + session = SimpleNamespace( + scalar=AsyncMock( + side_effect=[ + job, + attempt, + intent, + None, + replica, + verification, + content, + receipt, + datetime.now(UTC), + ] + ), + add=Mock(), + flush=AsyncMock(), + ) + + admission = await SubmissionBundleAdmissionPublisher(session).publish_verified( + verification_job_id=job.id, + verification_receipt_id=verification.id, + ) + + assert admission.pre_submit_evidence_set_id is None + assert admission.selected_pre_submit_run_id == str(selected.attempt_id) + assert admission.packet_sha256 == lineage.packet_sha256 + assert admission.semantic_manifest_body == manifest + + @pytest.mark.asyncio async def test_observed_confirmed_write_receipt_is_supported() -> None: attempt = SimpleNamespace( @@ -711,7 +845,11 @@ async def test_unverified_or_mismatched_lineage_is_not_publishable() -> None: assert not SubmissionBundleAdmissionPublisher._matches_verified_lineage( evidence, attempt, job, replica, content, receipt ) - intent = SimpleNamespace(id=str(new_record_id()), pre_submit_evidence_set_id=evidence.id) + intent = SimpleNamespace( + id=str(new_record_id()), + pre_submit_evidence_set_id=evidence.id, + selected_pre_submit_run_id=None, + ) session = SimpleNamespace( scalar=AsyncMock( side_effect=[job, attempt, intent, None, evidence, replica, receipt, content] diff --git a/backend/tests/test_submission_preparation_adapter.py b/backend/tests/test_submission_preparation_adapter.py index d79202285..58c2b6c79 100644 --- a/backend/tests/test_submission_preparation_adapter.py +++ b/backend/tests/test_submission_preparation_adapter.py @@ -63,6 +63,8 @@ async def test_final_preparation_rejects_cross_request_facts() -> None: effective_plan_sha256=_sha("4"), semantic_manifest_id=new_record_id(), semantic_manifest_sha256=_sha("5"), + semantic_manifest_body={"schema_version": "submission_manifest.v1", "entries": []}, + packet_sha256=_sha("8"), archive_sha256=_sha("6"), archive_byte_count=42, media_type="application/zip", From a571c263f5ccb7629ab7d8ccca8d0f3673e396f1 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 20:14:17 +0100 Subject: [PATCH 070/283] [PILOT-04] Lock selected PRE through TASK custody --- backend/app/adapters/tasks/__init__.py | 51 +++++++++++++++ .../test_selected_pre_submit_coordination.py | 63 +++++++++++++++++++ 2 files changed, 114 insertions(+) diff --git a/backend/app/adapters/tasks/__init__.py b/backend/app/adapters/tasks/__init__.py index 49fedb9be..fe91db261 100644 --- a/backend/app/adapters/tasks/__init__.py +++ b/backend/app/adapters/tasks/__init__.py @@ -15,6 +15,7 @@ SubmissionCreationRequest, SubmissionCreationResult, TaskSubmissionContextPort, + TaskSubmissionContextRequest, ) from app.modules.tasks.repository import TaskRepository from app.modules.tasks.api import TaskSubmissionContextFacts @@ -32,6 +33,7 @@ from app.modules.tasks.api.assignment_invalidation import AssignmentInvalidationUnavailable from app.modules.outbox.api import HandlerOutcome from app.modules.checkers.api.execution import EvaluationTaskGuard +from app.modules.checkers.api.selected_pre_submit import SelectedPreSubmitReservationFacts def evaluation_task_guard(session: AsyncSession) -> EvaluationTaskGuard: @@ -40,6 +42,54 @@ def evaluation_task_guard(session: AsyncSession) -> EvaluationTaskGuard: return TaskEvaluationGuard(session) +class _SelectedPreSubmitTaskGuard: + """Project selected PRE custody through TASK's canonical submission lock.""" + + def __init__(self, session: AsyncSession) -> None: + self._contexts = TaskRepository(session) + + async def lock_selected_pre_submit_scope( + self, reservation: SelectedPreSubmitReservationFacts + ) -> None: + lineage = reservation.admission_lineage + if lineage is None: + raise RuntimeError("selected PRE admission lineage is unavailable") + context = await self._contexts.lock_submission_context( + TaskSubmissionContextRequest( + task_id=reservation.task_id, + assignment_id=reservation.assignment_id, + contributor_id=reservation.actor_profile_id, + predecessor_submission_id=lineage.predecessor_submission_id, + ) + ) + predecessor = context.predecessor + references = context.locked_project_context + if ( + context.task_id != reservation.task_id + or context.assignment_id != reservation.assignment_id + or context.contributor_id != reservation.actor_profile_id + or (predecessor.submission_id if predecessor is not None else None) + != lineage.predecessor_submission_id + or (predecessor.version if predecessor is not None else None) + != lineage.predecessor_submission_version + or references.project_id != reservation.project_id + or references.guide_version != lineage.guide_version + or references.source_snapshot_id != lineage.source_snapshot_id + or references.source_snapshot_hash != lineage.source_snapshot_sha256 + or references.effective_policy_id != lineage.effective_policy_id + or references.effective_policy_hash != lineage.effective_policy_sha256 + or references.pre_submit_policy_id != lineage.pre_submit_policy_id + or references.pre_submit_policy_bundle_hash + != lineage.pre_submit_policy_sha256 + ): + raise RuntimeError("selected PRE TASK custody changed") + + +def selected_pre_submit_task_guard(session: AsyncSession) -> _SelectedPreSubmitTaskGuard: + """Expose TASK-first selected PRE locking to CHECKERS composition.""" + return _SelectedPreSubmitTaskGuard(session) + + class TransactionalAssignmentInvalidationHandler: """Exact registered handler; commits before acknowledgement, with explicit authority.""" @@ -66,6 +116,7 @@ async def __call__(self, envelope): __all__ = ( + "selected_pre_submit_task_guard", "TransactionalAssignmentInvalidationHandler", "task_commands", "task_service", diff --git a/backend/tests/checkers/external/test_selected_pre_submit_coordination.py b/backend/tests/checkers/external/test_selected_pre_submit_coordination.py index 11fac16a0..cdc772170 100644 --- a/backend/tests/checkers/external/test_selected_pre_submit_coordination.py +++ b/backend/tests/checkers/external/test_selected_pre_submit_coordination.py @@ -26,6 +26,8 @@ SelectedPreSubmitLeaseFacts, SelectedPreSubmitReservationFacts, ) +from app.adapters.tasks import selected_pre_submit_task_guard +from app.modules.tasks.repository import TaskRepository from app.modules.checkers.models import SelectedPreSubmitRun from app.modules.checkers.selected_pre_submit_coordination import ( SelectedPreSubmitAdmissionCapability, @@ -55,6 +57,67 @@ def _reservation() -> SelectedPreSubmitReservationFacts: ) +@pytest.mark.asyncio +async def test_selected_pre_task_guard_rechecks_exact_locked_lineage(monkeypatch) -> None: + lineage = SelectedPreSubmitAdmissionLineage( + predecessor_submission_id=new_record_id(), + predecessor_submission_version=2, + guide_id=new_record_id(), + guide_version="guide-v2", + source_snapshot_id=new_record_id(), + source_snapshot_sha256="sha256:" + "5" * 64, + locked_guide_sha256="sha256:" + "6" * 64, + effective_policy_id=new_record_id(), + effective_policy_sha256="sha256:" + "7" * 64, + pre_submit_policy_id=new_record_id(), + pre_submit_policy_sha256="sha256:" + "8" * 64, + effective_plan_sha256="sha256:" + "9" * 64, + locked_policy_context_hash="sha256:" + "a" * 64, + semantic_manifest_id=new_record_id(), + semantic_manifest_body={"schema_version": "test"}, + packet_sha256="sha256:" + "b" * 64, + storage_scheme="s3", + ) + reservation = replace( + _reservation(), + policy_sha256=lineage.effective_plan_sha256, + semantic_manifest_sha256=canonical_json_hash(lineage.semantic_manifest_body), + admission_lineage=lineage, + ) + locked = SimpleNamespace( + project_id=reservation.project_id, + guide_version=lineage.guide_version, + source_snapshot_id=lineage.source_snapshot_id, + source_snapshot_hash=lineage.source_snapshot_sha256, + effective_policy_id=lineage.effective_policy_id, + effective_policy_hash=lineage.effective_policy_sha256, + pre_submit_policy_id=lineage.pre_submit_policy_id, + pre_submit_policy_bundle_hash=lineage.pre_submit_policy_sha256, + ) + context = SimpleNamespace( + task_id=reservation.task_id, + assignment_id=reservation.assignment_id, + contributor_id=reservation.actor_profile_id, + predecessor=SimpleNamespace( + submission_id=lineage.predecessor_submission_id, + version=lineage.predecessor_submission_version, + ), + locked_project_context=locked, + ) + + async def lock(_repository, request): + assert request.task_id == reservation.task_id + return context + + monkeypatch.setattr(TaskRepository, "lock_submission_context", lock) + guard = selected_pre_submit_task_guard(SimpleNamespace()) + await guard.lock_selected_pre_submit_scope(reservation) + + locked.pre_submit_policy_bundle_hash = "sha256:" + "c" * 64 + with pytest.raises(RuntimeError, match="selected PRE TASK custody changed"): + await guard.lock_selected_pre_submit_scope(reservation) + + def test_selected_pre_model_compiles_complete_owner_and_authority_custody() -> None: sql = str( CreateTable(SelectedPreSubmitRun.__table__).compile( From 84737a6f8fc59c7f227433aa5e404ccaa4f9bf24 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 20:21:26 +0100 Subject: [PATCH 071/283] [PILOT-04] Select PRE before durable admission --- backend/app/adapters/artifacts/__init__.py | 49 +++-- backend/app/adapters/checkers/__init__.py | 7 +- .../app/api/routes/artifact_submissions.py | 3 +- .../artifacts/api/submission_preparation.py | 53 ++++- backend/app/modules/artifacts/models.py | 8 + .../selected_pre_submit_admission.py | 35 +++ .../modules/artifacts/submission_admission.py | 203 +++++++++++++----- .../artifacts/submission_materialization.py | 127 ++++++++++- .../checkers/api/selected_pre_submit.py | 5 + .../test_selected_pre_submit_coordination.py | 2 + .../test_selected_preparation_command.py | 179 +++++++++++++++ .../tests/test_submission_bundle_admission.py | 1 + 12 files changed, 587 insertions(+), 85 deletions(-) create mode 100644 backend/tests/checkers/external/test_selected_preparation_command.py diff --git a/backend/app/adapters/artifacts/__init__.py b/backend/app/adapters/artifacts/__init__.py index f12ed22b6..09d0f0344 100644 --- a/backend/app/adapters/artifacts/__init__.py +++ b/backend/app/adapters/artifacts/__init__.py @@ -12,10 +12,10 @@ from app.core.config import Settings from app.core.api_controls import request_ids from app.api.deps.authorization import get_authorization_actor_identity -from app.adapters.checkers import PreSubmitCheckerExecutionAdapter, post_submission_executor, checker_output_reservations +from app.adapters.checkers import checker_output_reservations from app.adapters.projects import project_locked_policy_context_port from app.adapters.tasks import task_submission_context_port -from app.db.session import get_db_session, get_session_factory +from app.db.session import get_db_session from app.interfaces.artifact_operations import GuideArtifactIngestCommand from app.modules.projects.api.guide_documents import GuideDocumentUploadTargetPort from app.modules.artifacts.api import SubmissionBundlePreparationCommand @@ -383,7 +383,6 @@ def get_submission_bundle_preparation_command( from app.modules.artifacts.submission_archive import SubmissionArchiveInspector from app.modules.artifacts.submission_materialization import ( PreparedBundleMaterializationService, - PreparedBundlePreSubmitEvidenceService, ) from app.modules.artifacts.submission_admission import ( PreparedSubmissionBundlePreparationCommand, @@ -422,10 +421,19 @@ async def runtime(): ) ) preparation = ArtifactPreparationService(manager) - catalogue = request.app.state.pre_submission_checker_catalogue inspector = SubmissionArchiveInspector(submission_archive_limits(settings)) - checker_execution = PreSubmitCheckerExecutionAdapter( - catalogue=catalogue, + from app.adapters.auth import selected_pre_submit_authority + from app.adapters.checkers import selected_pre_submit_checker_execution + from app.adapters.tasks import selected_pre_submit_task_guard + from app.modules.artifacts.selected_pre_submit_execution import ( + SelectedPreSubmitExecutionService, + ) + from app.modules.checkers.selected_pre_submit_coordination import ( + SelectedPreSubmitCoordinator, + ) + + checker_execution = selected_pre_submit_checker_execution( + settings=settings, archive_inspector=inspector, ) storage_schemes = {"local": "local", "s3_compatible": "s3"} @@ -448,28 +456,25 @@ async def runtime(): settings, internal_authority, ) - evidence = PreparedBundlePreSubmitEvidenceService( - session=session, - materialization=materialization, - preparation_authorization=authority, - task_contexts=task_contexts, - project_contexts=project_contexts, + selected_coordinator = SelectedPreSubmitCoordinator( + session, + tasks=selected_pre_submit_task_guard(session), ) - from app.adapters.checkers import submission_evaluation_content yield SubmissionBundlePreparationRuntime( - evaluation_content=submission_evaluation_content, preparation=preparation, inspector=inspector, - catalogue=catalogue, materialization=materialization, - evidence=evidence, - checker_service=CheckerPhaseService( - pre_submission=evidence, - post_submission=post_submission_executor( - sessions=get_session_factory(), materialization=post_submission_materialization( - sessions=get_session_factory(), store=store, namespace=namespace, - preparation=preparation, inspector=inspector)), + selected_coordinator=selected_coordinator, + selected_execution=SelectedPreSubmitExecutionService( + session=session, + coordinator=selected_coordinator, + authority=selected_pre_submit_authority(session), + materialization=materialization, + ), + storage_scheme=storage_scheme, + artifact_deadline_ms=int( + settings.artifact_preparation_total_deadline_seconds * 1000 ), durable_put=SubmissionBundleDurablePutService( session=session, diff --git a/backend/app/adapters/checkers/__init__.py b/backend/app/adapters/checkers/__init__.py index 7320f4fbc..bcf47e560 100644 --- a/backend/app/adapters/checkers/__init__.py +++ b/backend/app/adapters/checkers/__init__.py @@ -99,6 +99,7 @@ def external_checker_registry_reader(session): class _ExecutionRequest(Protocol): plan: Any + project_id: Any task_id: Any assignment_id: Any commitment: Any @@ -139,6 +140,10 @@ def catalogue_manifest_sha256(self) -> str: return self._catalogue.manifest_sha256 def build(self, request: _ExecutionRequest) -> _PublicFactsCheckerProcessor: + if request.plan is None: + raise PreSubmissionInfrastructureUnavailableError( + "pre_submission_plan_identity_invalid" + ) return _PublicFactsCheckerProcessor( EffectivePreSubmissionProcessor( archive_inspector=self._archive_inspector, @@ -182,7 +187,7 @@ def build(self, request: _ExecutionRequest) -> SelectedPreSubmitProcessor: "external_pre_submit_context_unavailable" ) identity = PreSubmitExternalCheckerIdentity( - project_id=request.plan.lineage.project_id, + project_id=request.project_id, task_id=request.task_id, assignment_id=request.assignment_id, prepared_generation_id=request.prepared_generation_id, diff --git a/backend/app/api/routes/artifact_submissions.py b/backend/app/api/routes/artifact_submissions.py index 62c4fd62c..ae8c35662 100644 --- a/backend/app/api/routes/artifact_submissions.py +++ b/backend/app/api/routes/artifact_submissions.py @@ -1,6 +1,5 @@ """Hidden delivery surface for ART-owned contributor bundle preparation.""" -from dataclasses import asdict from typing import Annotated from uuid import UUID @@ -101,7 +100,7 @@ async def prepare_submission_bundle( details={ "status": "failed", "eligible_to_submit": exc.facts.eligible, - "results": [asdict(entry) for entry in exc.facts.entries], + "results": exc.public_results(), }, ) except SubmissionBundlePreparationInfrastructureUnavailable as exc: diff --git a/backend/app/modules/artifacts/api/submission_preparation.py b/backend/app/modules/artifacts/api/submission_preparation.py index 1d1cbc0d1..55a79e081 100644 --- a/backend/app/modules/artifacts/api/submission_preparation.py +++ b/backend/app/modules/artifacts/api/submission_preparation.py @@ -3,13 +3,14 @@ from __future__ import annotations from collections.abc import AsyncIterable -from dataclasses import dataclass +from dataclasses import asdict, dataclass from enum import StrEnum from typing import Protocol from uuid import UUID from app.modules.authorization.api import ActorIdentityFacts from app.modules.checkers.api import PreSubmissionExecutionFacts +from app.modules.checkers.api.selected_pre_submit import SelectedPreSubmitExecutionFacts class SubmissionBundlePreparationRejected(RuntimeError): @@ -19,14 +20,60 @@ class SubmissionBundlePreparationRejected(RuntimeError): class SubmissionBundlePreparationCheckFailed(SubmissionBundlePreparationRejected): """Carry the exact bounded CHECKERS facts for one blocked preparation.""" - def __init__(self, facts: PreSubmissionExecutionFacts) -> None: - if type(facts) is not PreSubmissionExecutionFacts: + def __init__( + self, + facts: PreSubmissionExecutionFacts | SelectedPreSubmitExecutionFacts, + ) -> None: + if type(facts) not in { + PreSubmissionExecutionFacts, + SelectedPreSubmitExecutionFacts, + }: raise TypeError("pre-submission feedback facts are invalid") if facts.eligible is not False: raise ValueError("blocked pre-submission facts require eligible false") super().__init__("pre_submission_checker_failed") self.facts = facts + def public_results(self) -> list[dict[str, object]]: + """Return sanitized ordered work findings without execution authority.""" + if type(self.facts) is PreSubmissionExecutionFacts: + return [asdict(entry) for entry in self.facts.entries] + assert type(self.facts) is SelectedPreSubmitExecutionFacts + default = self.facts.workstream_default + results: list[dict[str, object]] = [ + { + "source": "workstream_default", + "check_id": item.check_id, + "status": item.status, + "failure_code": item.failure_code, + "finding_count": item.finding_count, + } + for item in default.checks + ] + results.extend( + { + "source": "workstream_default", + "status": "warning", + "warning_code": item.code, + } + for item in default.warnings + ) + results.extend( + { + "source": "project_external_checker", + "requirement_id": member.requirement_id, + "registry_entry_id": str(member.registry_entry_id), + "registry_entry_digest": member.registry_entry_digest, + "status": member.result.verdict, + "findings": [ + finding.model_dump(mode="json") + for finding in member.result.findings + ], + } + for member in self.facts.external_members + ) + return results + class SubmissionBundlePreparationUnavailable(RuntimeError): """Conceal unavailable or denied preparation authority.""" diff --git a/backend/app/modules/artifacts/models.py b/backend/app/modules/artifacts/models.py index 18e78dc7f..d7021eae8 100644 --- a/backend/app/modules/artifacts/models.py +++ b/backend/app/modules/artifacts/models.py @@ -1316,6 +1316,13 @@ class SubmissionBundleAdmission(Base): CheckConstraint( SHA256_CHECK.format(column="effective_plan_sha256"), name="effective_plan_sha256" ), + CheckConstraint( + "(selected_pre_submit_run_id is null and selected_rules_sha256 is null) or " + "(selected_pre_submit_run_id is not null and " + + SHA256_CHECK.format(column="selected_rules_sha256") + + ")", + name="selected_rules_sha256", + ), CheckConstraint( SHA256_CHECK.format(column="source_snapshot_sha256") + " and " + SHA256_CHECK.format(column="effective_policy_sha256") + " and " @@ -1404,6 +1411,7 @@ class SubmissionBundleAdmission(Base): pre_submit_policy_id: Mapped[str] = mapped_column(Uuid(as_uuid=False), nullable=False) pre_submit_policy_sha256: Mapped[str] = mapped_column(String(71), nullable=False) effective_plan_sha256: Mapped[str] = mapped_column(String(71), nullable=False) + selected_rules_sha256: Mapped[str | None] = mapped_column(String(71)) packet_sha256: Mapped[str] = mapped_column(String(71), nullable=False) semantic_manifest_id: Mapped[str] = mapped_column(Uuid(as_uuid=False), nullable=False) semantic_manifest_sha256: Mapped[str] = mapped_column(String(71), nullable=False) diff --git a/backend/app/modules/artifacts/selected_pre_submit_admission.py b/backend/app/modules/artifacts/selected_pre_submit_admission.py index 074987ace..0a4e5deb6 100644 --- a/backend/app/modules/artifacts/selected_pre_submit_admission.py +++ b/backend/app/modules/artifacts/selected_pre_submit_admission.py @@ -34,6 +34,39 @@ from app.modules.tasks.api import TaskSubmissionContextFacts +def selected_pre_submit_attempt_request_digest( + *, + actor_profile_id: UUID, + identity_link_id: UUID, + task_id: UUID, + assignment_id: UUID, + predecessor_submission_id: UUID | None, + idempotency_key: UUID, + archive_sha256: str, + archive_byte_count: int, + packet_sha256: str, +) -> str: + """Bind the public command namespace to server-observed bytes and packet.""" + return canonical_json_hash( + { + "domain": "workstream.selected_pre_submit_attempt_request.v1", + "actor_profile_id": str(actor_profile_id), + "identity_link_id": str(identity_link_id), + "task_id": str(task_id), + "assignment_id": str(assignment_id), + "predecessor_submission_id": ( + str(predecessor_submission_id) + if predecessor_submission_id is not None + else None + ), + "idempotency_key": str(idempotency_key), + "archive_sha256": archive_sha256, + "archive_byte_count": archive_byte_count, + "packet_sha256": packet_sha256, + } + ) + + @dataclass(frozen=True, slots=True) class SelectedPreSubmitAdmissionContext: """Exact selected policy, default input and non-deciding change binding.""" @@ -112,6 +145,7 @@ def build_selected_pre_submit_reservation( pre_submit_policy_id=project.pre_submit_policy_id, pre_submit_policy_sha256=project.pre_submit_policy_bundle_hash, effective_plan_sha256=selected.policy.policy_sha256, + rules_sha256=selected.rules_sha256, locked_policy_context_hash=locked_policy_context_hash, semantic_manifest_id=semantic_manifest_identity(manifest.sha256), semantic_manifest_body=manifest.as_dict(), @@ -217,4 +251,5 @@ def bind_selected_pre_submit_admission( "SelectedPreSubmitAdmissionContext", "bind_selected_pre_submit_admission", "build_selected_pre_submit_reservation", + "selected_pre_submit_attempt_request_digest", ) diff --git a/backend/app/modules/artifacts/submission_admission.py b/backend/app/modules/artifacts/submission_admission.py index 284324b07..515746a12 100644 --- a/backend/app/modules/artifacts/submission_admission.py +++ b/backend/app/modules/artifacts/submission_admission.py @@ -61,7 +61,6 @@ from app.modules.artifacts.submission_manifest import ( SubmissionCanonicalPredecessor, build_submission_manifest, - evaluate_submission_change, ) from app.modules.artifacts.submission_materialization import ( PreparedBundleMaterializationRequest, @@ -69,11 +68,24 @@ PreparedBundlePreSubmitEvidenceService, PreSubmissionEvaluationPort, ) +from app.modules.artifacts.selected_pre_submit_admission import ( + bind_selected_pre_submit_admission, + build_selected_pre_submit_reservation, + selected_pre_submit_attempt_request_digest, +) +from app.modules.artifacts.selected_pre_submit_execution import ( + SelectedPreSubmitExecutionService, +) from app.modules.checkers.api.post_submit import PostSubmissionEvaluationContent from app.modules.checkers.api.selected_pre_submit import ( SelectedPreSubmitCompletion, + SelectedPreSubmitCoordinationPort, SelectedPreSubmitReservationFacts, ) +from app.modules.checkers.api.external_policy import ( + LockedExternalCheckerPolicies, + selected_pre_submit_execution_budget_ms, +) from app.modules.checkers.api import ( EffectivePreSubmissionExecutionPlan, EffectivePreSubmissionPlanLineage, @@ -524,6 +536,11 @@ async def publish_verified( if selected_lineage is not None else evidence.effective_plan_sha256 ), + selected_rules_sha256=( + selected_lineage.rules_sha256 + if selected_lineage is not None + else None + ), packet_sha256=( selected_lineage.packet_sha256 if selected_lineage is not None @@ -679,15 +696,19 @@ async def current_submission_bundle_admission_id( class SubmissionBundlePreparationRuntime: preparation: ArtifactPreparationService inspector: SubmissionArchiveInspector - catalogue: EffectivePreSubmissionPlanningPort materialization: PreparedBundleMaterializationService - evidence: PreparedBundlePreSubmitEvidenceService - checker_service: PreSubmissionEvaluationPort durable_put: SubmissionBundleDurablePutService + selected_coordinator: SelectedPreSubmitCoordinationPort | None = None + selected_execution: SelectedPreSubmitExecutionService | None = None + storage_scheme: str | None = None + artifact_deadline_ms: int = 0 + catalogue: EffectivePreSubmissionPlanningPort | None = None + evidence: PreparedBundlePreSubmitEvidenceService | None = None + checker_service: PreSubmissionEvaluationPort | None = None evaluation_content: Callable[ [TaskSubmissionContextFacts, ProjectLockedPolicyContextFacts, SubmissionPacketView, tuple[SubmissionBundleFile, ...], str], PostSubmissionEvaluationContent, - ] + ] | None = None class PreparedSubmissionBundlePreparationCommand: @@ -724,14 +745,18 @@ async def prepare( if request.media_type.partition(";")[0].strip().lower() != "application/zip": raise SubmissionBundlePreparationRejected("submission_bundle_media_type_invalid") async with self._runtime_factory() as runtime, AsyncExitStack() as scratch_cleanup: + if ( + runtime.selected_coordinator is None + or runtime.selected_execution is None + or runtime.storage_scheme is None + ): + raise RuntimeError("selected PRE runtime is unavailable") async with self._session.begin(): task_context, project_context = await self._lock_authorized_context(request) - plan = self._compile_plan( - task_context, - project_context, - runtime.catalogue, - ) predecessor = await self._load_predecessor(task_context) + predecessor_rules_sha256 = await self._load_predecessor_rules( + task_context + ) prepared = await runtime.preparation.prepare( request.byte_source, media_type="application/zip", @@ -739,34 +764,68 @@ async def prepare( scratch_cleanup.push_async_callback(prepared.close) async with self._session.begin(): task_context, project_context = await self._lock_authorized_context(request) - materialization_handle = await runtime.materialization.prepare_authorization( - task_id=request.task_id, - assignment_id=request.assignment_id, - submission_artifact_policy_id=project_context.effective_policy_id, - checker_policy_id=project_context.pre_submit_policy_id, - prepared_artifact=prepared, - effective_plan=plan, - idempotency_key=request.idempotency_key, + policies = LockedExternalCheckerPolicies.model_validate_json( + project_context.external_checker_policies.value + ) + materialization_handle = ( + await runtime.materialization.prepare_selected_authorization( + task=task_context, + project=project_context, + prepared_artifact=prepared, + external_policy=policies.pre_submit, + idempotency_key=request.idempotency_key, + ) ) inspection = await prepared.inspect(runtime.inspector) manifest = build_submission_manifest(inspection) packet = SubmissionPacketView( - summary=request.summary, contributor_attestation=request.contributor_attestation, + summary=request.summary, + contributor_attestation=request.contributor_attestation, ) - try: - runtime.evaluation_content( - task_context, project_context, packet, manifest.file_facts(), prepared.commitment.sha256, - ) - except (ValueError, TypeError, KeyError) as exc: - raise SubmissionBundlePreparationRejected( - "submission_evaluation_content_invalid" - ) from exc - change_gate = evaluate_submission_change( + selected = bind_selected_pre_submit_admission( + task=task_context, + project=project_context, commitment=prepared.commitment, manifest=manifest, predecessor=predecessor, - predecessor_exists=request.predecessor_submission_id is not None, - current_predecessor=predecessor, + predecessor_rules_sha256=predecessor_rules_sha256, + predecessor_exists=( + request.predecessor_submission_id is not None + ), + packet=packet, + ) + attempt_id = new_record_id() + reservation = build_selected_pre_submit_reservation( + actor_profile_id=request.actor.actor_profile_id, + identity_link_id=request.actor.identity_link_id, + task=task_context, + project=project_context, + prepared_generation_id=prepared.generation_id, + attempt_id=attempt_id, + attempt_request_digest=( + selected_pre_submit_attempt_request_digest( + actor_profile_id=request.actor.actor_profile_id, + identity_link_id=request.actor.identity_link_id, + task_id=request.task_id, + assignment_id=request.assignment_id, + predecessor_submission_id=( + request.predecessor_submission_id + ), + idempotency_key=request.idempotency_key, + archive_sha256=prepared.commitment.sha256, + archive_byte_count=prepared.commitment.byte_count, + packet_sha256=packet.sha256, + ) + ), + commitment=prepared.commitment, + manifest=manifest, + packet=packet, + selected=selected, + storage_scheme=runtime.storage_scheme, + execution_budget_ms=selected_pre_submit_execution_budget_ms( + selected.policy, + artifact_deadline_ms=runtime.artifact_deadline_ms, + ), ) materialization_request = PreparedBundleMaterializationRequest( prepared_authorization=materialization_handle, @@ -780,47 +839,63 @@ async def prepare( else None ), prepared_artifact=prepared, - effective_plan=plan, + effective_plan=None, inspection=inspection, manifest=manifest, - change_gate=change_gate, + change_gate=selected.change_gate, packet=packet, + external_policy=selected.policy, + default_checker_input=selected.default_input, + selected_reservation=reservation, + ) + await runtime.materialization.authorize_inspected( + materialization_request ) - reserved = await runtime.evidence.reserve( - materialization_request, preparation_request=request, + reserved_id = await runtime.selected_coordinator.reserve( + reservation ) - evidence = await runtime.checker_service.evaluate_pre_submission( - replace(materialization_request, prepared_authorization=None), - reserved, preparation_request=request, + if reserved_id != reservation.attempt_id: + raise RuntimeError("selected PRE reservation identity changed") + completion = await runtime.selected_execution.execute( + reservation=reservation, + materialization=replace( + materialization_request, + prepared_authorization=None, + ), ) - if not evidence.execution.eligible: + terminal = completion.terminal + if terminal.outcome == "infrastructure_failed": + raise SubmissionBundlePreparationInfrastructureUnavailable( + terminal.infrastructure_failure_code + or "pre_submission_checked_custody_unavailable" + ) + if terminal.execution is None: + raise SubmissionBundlePreparationInfrastructureUnavailable( + "pre_submission_checked_custody_unavailable" + ) + if not terminal.execution.eligible: raise SubmissionBundlePreparationCheckFailed( - evidence.execution.checker_facts + terminal.execution + ) + if completion.capability is None: + raise SubmissionBundlePreparationInfrastructureUnavailable( + "pre_submission_checked_custody_unavailable" ) - if evidence.pass_capability is None: - replay = await self._existing_durable_result(evidence.evidence.evidence_set_id) - if replay is None: - raise SubmissionBundlePreparationInfrastructureUnavailable( - "pre_submission_checked_custody_unavailable" - ) - return replay - replay_intent_id = await self._matching_replay_intent( - evidence.evidence.evidence_set_id - ) async with self._authority.transaction(): await self._lock_authorized_context(request) retained, _, durable = await runtime.durable_put.admit_in_transaction( SubmissionBundleDurablePutRequest( prepared_authorization=None, prepared_artifact=prepared, - pass_capability=evidence.pass_capability, - replay_durable_intent_id=replay_intent_id, + pass_capability=None, + selected_completion=completion, ) ) result = await runtime.durable_put.publish_after_commit( retained, - evidence.evidence.evidence_set_id, + reservation.attempt_id, durable, + selected_pre_submit_run_id=reservation.attempt_id, ) return self._result(result) except PreSubmitEvidenceConflict as exc: @@ -1070,6 +1145,30 @@ async def _load_predecessor( semantic_manifest_sha256=admission.semantic_manifest_sha256, ) + async def _load_predecessor_rules( + self, + task_context: TaskSubmissionContextFacts, + ) -> str | None: + """Return exact selected rules, treating retained legacy context as changed.""" + predecessor = task_context.predecessor + if predecessor is None: + return None + admission = await self._session.scalar( + select(SubmissionBundleAdmission).where( + SubmissionBundleAdmission.consumed_by_submission_id + == str(predecessor.submission_id), + SubmissionBundleAdmission.status == "consumed", + ) + ) + if admission is None: + raise SubmissionBundlePreparationRejected( + "submission_canonical_predecessor_unavailable" + ) + return ( + admission.selected_rules_sha256 + or admission.locked_policy_context_hash + ) + @staticmethod def _result(result: SubmissionBundleDurablePutResult) -> SubmissionBundlePreparationResult: return SubmissionBundlePreparationResult( diff --git a/backend/app/modules/artifacts/submission_materialization.py b/backend/app/modules/artifacts/submission_materialization.py index 5baa74504..3820f600a 100644 --- a/backend/app/modules/artifacts/submission_materialization.py +++ b/backend/app/modules/artifacts/submission_materialization.py @@ -68,9 +68,11 @@ SelectedPreSubmitExecutionAuthority, SelectedPreSubmitExecutionFacts, SelectedPreSubmitLeaseFacts, + SelectedPreSubmitReservationFacts, ) from app.modules.projects.api import ProjectLockedPolicyContextPort -from app.modules.tasks.api import TaskSubmissionContextPort +from app.modules.projects.api import ProjectLockedPolicyContextFacts +from app.modules.tasks.api import TaskSubmissionContextFacts, TaskSubmissionContextPort @dataclass(frozen=True, slots=True) class PreparedBundleMaterializationRequest: @@ -83,20 +85,22 @@ class PreparedBundleMaterializationRequest: checker_policy_id: UUID predecessor_submission_version: int | None prepared_artifact: PreparedArtifact - effective_plan: EffectivePreSubmissionExecutionPlan + effective_plan: EffectivePreSubmissionExecutionPlan | None inspection: SubmissionArchiveInspectionResult manifest: SubmissionManifest change_gate: SubmissionChangeGateResult packet: SubmissionPacketView external_policy: LockedExternalPreSubmitPolicy | None = None default_checker_input: WorkstreamDefaultCheckerInput | None = None + selected_reservation: SelectedPreSubmitReservationFacts | None = None @dataclass(frozen=True, slots=True) class PreSubmitCheckerExecutionRequest: """Exact process-local input supplied to the composition CHECKER adapter.""" - plan: EffectivePreSubmissionExecutionPlan + plan: EffectivePreSubmissionExecutionPlan | None + project_id: UUID task_id: UUID assignment_id: UUID commitment: object @@ -394,10 +398,13 @@ async def materialize_prepared_bundle( """Execute only after the authority root commits; no external work holds DB locks.""" if type(claim) is not PreSubmitAttemptClaim: raise PreSubmitEvidenceConflict("pre_submit_attempt_claim_invalid") + if request.effective_plan is None: + raise PreSubmitEvidenceConflict("pre_submit_effective_plan_invalid") claim.require_execution(self._session, request) processor = self._checker_execution.build( PreSubmitCheckerExecutionRequest( plan=request.effective_plan, + project_id=request.effective_plan.lineage.project_id, task_id=request.task_id, assignment_id=request.assignment_id, commitment=request.prepared_artifact.commitment, @@ -459,6 +466,7 @@ async def materialize_selected_pre_submit( run_id != reservation.attempt_id or request.task_id != reservation.task_id or request.assignment_id != reservation.assignment_id + or request.selected_reservation != reservation or request.prepared_artifact.generation_id != reservation.prepared_generation_id or request.external_policy is None @@ -476,6 +484,7 @@ async def materialize_selected_pre_submit( processor = self._checker_execution.build( PreSubmitCheckerExecutionRequest( plan=request.effective_plan, + project_id=reservation.project_id, task_id=request.task_id, assignment_id=request.assignment_id, commitment=commitment, @@ -533,9 +542,10 @@ async def prepare_authorization( submission_artifact_policy_id: UUID, checker_policy_id: UUID, prepared_artifact: PreparedArtifact, - effective_plan: EffectivePreSubmissionExecutionPlan, + effective_plan: EffectivePreSubmissionExecutionPlan | None, idempotency_key: UUID, external_policy: LockedExternalPreSubmitPolicy | None = None, + selected_reservation: SelectedPreSubmitReservationFacts | None = None, ) -> object: """Deny unavailable service authority before inspecting the ZIP.""" facts = self._preparation_facts( @@ -546,6 +556,65 @@ async def prepare_authorization( prepared_artifact=prepared_artifact, effective_plan=effective_plan, external_policy=external_policy, + selected_reservation=selected_reservation, + ) + return await self._authorization.prepare( + facts=facts, + idempotency_key=idempotency_key, + ) + + async def prepare_selected_authorization( + self, + *, + task: TaskSubmissionContextFacts, + project: ProjectLockedPolicyContextFacts, + prepared_artifact: PreparedArtifact, + external_policy: LockedExternalPreSubmitPolicy, + idempotency_key: UUID, + ) -> object: + """Prepare selected material authority before inspecting contributor bytes.""" + references = task.locked_project_context + commitment = prepared_artifact.commitment + if ( + task.task_id is None + or task.assignment_id is None + or references.project_id != project.project_id + or references.guide_version != project.guide_version + or references.source_snapshot_id != project.source_snapshot_id + or references.source_snapshot_hash != project.source_snapshot_hash + or references.effective_policy_id != project.effective_policy_id + or references.effective_policy_hash != project.effective_policy_hash + or references.pre_submit_policy_id != project.pre_submit_policy_id + or references.pre_submit_policy_bundle_hash + != project.pre_submit_policy_bundle_hash + or external_policy.policy_sha256 + != canonical_json_hash( + external_policy.model_dump(mode="json", exclude={"policy_sha256"}) + ) + or external_policy.workstream_default.behavior_sha256 + != WORKSTREAM_DEFAULT_BEHAVIOR_SHA256 + ): + raise PreSubmissionInfrastructureUnavailableError( + "selected_pre_submission_materialization_context_invalid" + ) + facts = PreSubmitMaterializationPreparationFacts( + task_id=task.task_id, + assignment_id=task.assignment_id, + project_id=project.project_id, + guide_id=project.guide_id, + guide_version=project.guide_version, + source_snapshot_id=project.source_snapshot_id, + source_snapshot_hash=project.source_snapshot_hash, + submission_artifact_policy_id=project.effective_policy_id, + submission_artifact_policy_hash=project.effective_policy_hash, + checker_policy_id=project.pre_submit_policy_id, + checker_policy_hash=project.pre_submit_policy_bundle_hash, + prepared_generation_id=prepared_artifact.generation_id, + plan_sha256=external_policy.policy_sha256, + catalogue_manifest_sha256=WORKSTREAM_DEFAULT_BEHAVIOR_SHA256, + archive_sha256=commitment.sha256, + archive_byte_count=commitment.byte_count, + storage_scheme=self._storage_scheme, ) return await self._authorization.prepare( facts=facts, @@ -566,6 +635,7 @@ def _authority_facts( prepared_artifact=request.prepared_artifact, effective_plan=plan, external_policy=request.external_policy, + selected_reservation=request.selected_reservation, ) if ( request.manifest != request.change_gate.manifest @@ -590,11 +660,58 @@ def _preparation_facts( submission_artifact_policy_id: UUID, checker_policy_id: UUID, prepared_artifact: PreparedArtifact, - effective_plan: EffectivePreSubmissionExecutionPlan, + effective_plan: EffectivePreSubmissionExecutionPlan | None, external_policy: LockedExternalPreSubmitPolicy | None = None, + selected_reservation: SelectedPreSubmitReservationFacts | None = None, ) -> PreSubmitMaterializationPreparationFacts: """Build pre-inspection facts from locked lineage and byte commitment.""" plan = effective_plan + if selected_reservation is not None: + lineage = selected_reservation.admission_lineage + commitment = prepared_artifact.commitment + if ( + plan is not None + or lineage is None + or external_policy is None + or task_id != selected_reservation.task_id + or assignment_id != selected_reservation.assignment_id + or prepared_artifact.generation_id + != selected_reservation.prepared_generation_id + or submission_artifact_policy_id != lineage.effective_policy_id + or checker_policy_id != lineage.pre_submit_policy_id + or external_policy.policy_sha256 + != selected_reservation.policy_sha256 + or commitment.sha256 != selected_reservation.archive_sha256 + or commitment.byte_count != selected_reservation.archive_byte_count + ): + raise PreSubmissionInfrastructureUnavailableError( + "selected_pre_submission_materialization_context_invalid" + ) + return PreSubmitMaterializationPreparationFacts( + task_id=task_id, + assignment_id=assignment_id, + project_id=selected_reservation.project_id, + guide_id=lineage.guide_id, + guide_version=lineage.guide_version, + source_snapshot_id=lineage.source_snapshot_id, + source_snapshot_hash=lineage.source_snapshot_sha256, + submission_artifact_policy_id=submission_artifact_policy_id, + submission_artifact_policy_hash=lineage.effective_policy_sha256, + checker_policy_id=checker_policy_id, + checker_policy_hash=lineage.pre_submit_policy_sha256, + prepared_generation_id=prepared_artifact.generation_id, + plan_sha256=selected_reservation.policy_sha256, + catalogue_manifest_sha256=( + selected_reservation.default_behavior_sha256 + ), + archive_sha256=commitment.sha256, + archive_byte_count=commitment.byte_count, + storage_scheme=self._storage_scheme, + ) + if plan is None: + raise PreSubmissionInfrastructureUnavailableError( + "pre_submission_materialization_context_invalid" + ) if plan.plan_sha256 != canonical_json_hash(plan.as_dict()): raise PreSubmissionInfrastructureUnavailableError( "pre_submission_plan_identity_invalid" diff --git a/backend/app/modules/checkers/api/selected_pre_submit.py b/backend/app/modules/checkers/api/selected_pre_submit.py index 4ffb1da79..767dd04c6 100644 --- a/backend/app/modules/checkers/api/selected_pre_submit.py +++ b/backend/app/modules/checkers/api/selected_pre_submit.py @@ -30,6 +30,7 @@ class SelectedPreSubmitAdmissionLineage: pre_submit_policy_id: UUID pre_submit_policy_sha256: str effective_plan_sha256: str + rules_sha256: str locked_policy_context_hash: str semantic_manifest_id: UUID semantic_manifest_body: dict[str, object] @@ -50,6 +51,7 @@ def __post_init__(self) -> None: self.effective_policy_sha256, self.pre_submit_policy_sha256, self.effective_plan_sha256, + self.rules_sha256, self.locked_policy_context_hash, self.packet_sha256, ) @@ -99,6 +101,7 @@ def canonical_body(self) -> dict[str, object]: "pre_submit_policy_id": str(self.pre_submit_policy_id), "pre_submit_policy_sha256": self.pre_submit_policy_sha256, "effective_plan_sha256": self.effective_plan_sha256, + "rules_sha256": self.rules_sha256, "locked_policy_context_hash": self.locked_policy_context_hash, "semantic_manifest_id": str(self.semantic_manifest_id), "semantic_manifest_body": self.semantic_manifest_body, @@ -124,6 +127,7 @@ def from_canonical_body( "pre_submit_policy_id", "pre_submit_policy_sha256", "effective_plan_sha256", + "rules_sha256", "locked_policy_context_hash", "semantic_manifest_id", "semantic_manifest_body", @@ -147,6 +151,7 @@ def from_canonical_body( pre_submit_policy_id=UUID(str(body["pre_submit_policy_id"])), pre_submit_policy_sha256=body["pre_submit_policy_sha256"], effective_plan_sha256=body["effective_plan_sha256"], + rules_sha256=body["rules_sha256"], locked_policy_context_hash=body["locked_policy_context_hash"], semantic_manifest_id=UUID(str(body["semantic_manifest_id"])), semantic_manifest_body=body["semantic_manifest_body"], diff --git a/backend/tests/checkers/external/test_selected_pre_submit_coordination.py b/backend/tests/checkers/external/test_selected_pre_submit_coordination.py index cdc772170..ba53c2756 100644 --- a/backend/tests/checkers/external/test_selected_pre_submit_coordination.py +++ b/backend/tests/checkers/external/test_selected_pre_submit_coordination.py @@ -72,6 +72,7 @@ async def test_selected_pre_task_guard_rechecks_exact_locked_lineage(monkeypatch pre_submit_policy_id=new_record_id(), pre_submit_policy_sha256="sha256:" + "8" * 64, effective_plan_sha256="sha256:" + "9" * 64, + rules_sha256="sha256:" + "d" * 64, locked_policy_context_hash="sha256:" + "a" * 64, semantic_manifest_id=new_record_id(), semantic_manifest_body={"schema_version": "test"}, @@ -273,6 +274,7 @@ def test_selected_pre_request_binds_complete_later_admission_lineage() -> None: pre_submit_policy_id=new_record_id(), pre_submit_policy_sha256=SHA, effective_plan_sha256="sha256:" + "1" * 64, + rules_sha256="sha256:" + "2" * 64, locked_policy_context_hash=SHA, semantic_manifest_id=new_record_id(), semantic_manifest_body=manifest, diff --git a/backend/tests/checkers/external/test_selected_preparation_command.py b/backend/tests/checkers/external/test_selected_preparation_command.py new file mode 100644 index 000000000..4c7fecbcc --- /dev/null +++ b/backend/tests/checkers/external/test_selected_preparation_command.py @@ -0,0 +1,179 @@ +"""The hidden contributor command selects the durable PRE owner exclusively.""" + +from contextlib import asynccontextmanager +from types import SimpleNamespace +from unittest.mock import AsyncMock, Mock + +import pytest + +import app.modules.artifacts.submission_admission as owner +from app.core.identifiers import new_record_id +from app.modules.artifacts.api import ( + SubmissionBundlePreparationRequest, + SubmissionBundlePreparationStatus, +) +from app.modules.artifacts.submission_admission import ( + PreparedSubmissionBundlePreparationCommand, + SubmissionBundleDurablePutResult, + SubmissionBundlePreparationRuntime, +) +from app.modules.authorization.api import ActorIdentityFacts, ActorKind +from app.modules.checkers.api.selected_pre_submit import SelectedPreSubmitCompletion + + +@asynccontextmanager +async def _root(): + yield + + +@pytest.mark.asyncio +async def test_hidden_preparation_uses_selected_pre_before_durable_admission( + monkeypatch, +) -> None: + actor = ActorIdentityFacts( + actor_profile_id=new_record_id(), + identity_link_id=new_record_id(), + actor_kind=ActorKind.HUMAN, + ) + task_id, assignment_id, attempt_id = (new_record_id() for _ in range(3)) + request = SubmissionBundlePreparationRequest( + actor=actor, + request_id=new_record_id(), + correlation_id=new_record_id(), + task_id=task_id, + assignment_id=assignment_id, + predecessor_submission_id=None, + idempotency_key=new_record_id(), + summary="", + contributor_attestation="", + media_type="application/zip", + byte_source=SimpleNamespace(), + ) + commitment = SimpleNamespace( + sha256="sha256:" + "1" * 64, + byte_count=100, + ) + prepared = SimpleNamespace( + generation_id=new_record_id(), + commitment=commitment, + inspect=AsyncMock(return_value=object()), + close=AsyncMock(), + ) + policy = object() + selected = SimpleNamespace( + policy=policy, + default_input=object(), + change_gate=object(), + ) + reservation = SimpleNamespace(attempt_id=attempt_id) + execution = SimpleNamespace(eligible=True) + completion = SelectedPreSubmitCompletion( + terminal=SimpleNamespace( + outcome="completed", + execution=execution, + infrastructure_failure_code=None, + ), + capability=object(), + ) + materialization = SimpleNamespace( + prepare_selected_authorization=AsyncMock(return_value=object()), + authorize_inspected=AsyncMock(), + ) + coordinator = SimpleNamespace(reserve=AsyncMock(return_value=attempt_id)) + selected_execution = SimpleNamespace(execute=AsyncMock(return_value=completion)) + durable = SimpleNamespace( + admit_in_transaction=AsyncMock( + return_value=(prepared, attempt_id, SimpleNamespace()) + ), + publish_after_commit=AsyncMock( + return_value=SubmissionBundleDurablePutResult( + put_attempt_id=new_record_id(), + pre_submit_evidence_set_id=None, + operation_identity="sha256:" + "2" * 64, + status="prepared", + replayed=False, + admission_id=None, + selected_pre_submit_run_id=attempt_id, + ) + ), + ) + runtime = SubmissionBundlePreparationRuntime( + preparation=SimpleNamespace(prepare=AsyncMock(return_value=prepared)), + inspector=object(), + materialization=materialization, + durable_put=durable, + selected_coordinator=coordinator, + selected_execution=selected_execution, + storage_scheme="s3", + artifact_deadline_ms=120_000, + ) + + @asynccontextmanager + async def runtime_factory(): + yield runtime + + authority = SimpleNamespace( + preflight=AsyncMock(), + transaction=_root, + close=Mock(), + ) + command = PreparedSubmissionBundlePreparationCommand( + session=SimpleNamespace(begin=_root), + authority=authority, + task_contexts=SimpleNamespace(), + project_contexts=SimpleNamespace(), + runtime_factory=runtime_factory, + ) + task = SimpleNamespace(predecessor=None) + project = SimpleNamespace( + effective_policy_id=new_record_id(), + pre_submit_policy_id=new_record_id(), + external_checker_policies=SimpleNamespace(value="{}"), + ) + command._lock_authorized_context = AsyncMock(return_value=(task, project)) + command._load_predecessor = AsyncMock(return_value=None) + command._load_predecessor_rules = AsyncMock(return_value=None) + monkeypatch.setattr( + owner, + "LockedExternalCheckerPolicies", + SimpleNamespace( + model_validate_json=Mock( + return_value=SimpleNamespace(pre_submit=policy) + ) + ), + ) + monkeypatch.setattr(owner, "build_submission_manifest", Mock(return_value=object())) + monkeypatch.setattr( + owner, "bind_selected_pre_submit_admission", Mock(return_value=selected) + ) + monkeypatch.setattr( + owner, "build_selected_pre_submit_reservation", Mock(return_value=reservation) + ) + monkeypatch.setattr( + owner, + "selected_pre_submit_attempt_request_digest", + Mock(return_value="sha256:" + "3" * 64), + ) + monkeypatch.setattr( + owner, "selected_pre_submit_execution_budget_ms", Mock(return_value=60_000) + ) + + result = await command.prepare(request) + + assert result.submission_bundle_preparation_status is ( + SubmissionBundlePreparationStatus.PREPARED + ) + materialization.prepare_selected_authorization.assert_awaited_once() + materialization.authorize_inspected.assert_awaited_once() + coordinator.reserve.assert_awaited_once_with(reservation) + selected_execution.execute.assert_awaited_once() + admitted = durable.admit_in_transaction.await_args.args[0] + assert admitted.pass_capability is None + assert admitted.selected_completion is completion + durable.publish_after_commit.assert_awaited_once_with( + prepared, + attempt_id, + durable.admit_in_transaction.return_value[2], + selected_pre_submit_run_id=attempt_id, + ) + diff --git a/backend/tests/test_submission_bundle_admission.py b/backend/tests/test_submission_bundle_admission.py index 9ce8a1e53..91a90b37b 100644 --- a/backend/tests/test_submission_bundle_admission.py +++ b/backend/tests/test_submission_bundle_admission.py @@ -654,6 +654,7 @@ async def test_selected_pre_terminal_publishes_self_contained_ready_admission() pre_submit_policy_id=new_record_id(), pre_submit_policy_sha256=_sha("4"), effective_plan_sha256=_sha("5"), + rules_sha256=_sha("8"), locked_policy_context_hash=_sha("6"), semantic_manifest_id=new_record_id(), semantic_manifest_body=manifest, From a8183e6301ee34a73a055cffb17dab188ce88982 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 20:28:39 +0100 Subject: [PATCH 072/283] [PILOT-04] Make selected PRE replay idempotent --- .../pilot04-workstream-default-checker.md | 1 + .../selected_pre_submit_admission.py | 2 + .../modules/artifacts/submission_admission.py | 79 ++++++++++ .../checkers/api/selected_pre_submit.py | 149 ++++++++++++++++++ backend/app/modules/checkers/models.py | 6 + .../selected_pre_submit_coordination.py | 84 +++++++++- .../pre_submit/test_contracts.py | 1 + .../external/test_selected_pre_submit.py | 8 + .../test_selected_pre_submit_coordination.py | 65 ++++++++ .../test_selected_pre_submit_service.py | 1 + .../test_selected_preparation_command.py | 7 +- .../tests/test_submission_bundle_admission.py | 1 + 12 files changed, 400 insertions(+), 4 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 3a9a5bbdc..e90e53cd8 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -203,6 +203,7 @@ intermediate-wait regression. | Selected admission binding | `pytest -q backend/tests/test_submission_change_gate.py backend/tests/checkers/external/test_selected_pre_submit.py`; Ruff and `git diff --check` on the affected files | 11 passed; existing callers retain their exact archive/manifest rejection while the selected binder carries unchanged work plus exact predecessor/current rules into the default checker | The binder is not yet selected by the durable admission caller | | Selected durable result contract | `pytest -q backend/tests/checkers/external/test_selected_pre_submit.py`; Ruff and `git diff --check` on the affected files | 5 passed; canonical result/terminal digests bind the default, ordered external results, isolation, generation lease, outcome and measured queue/execution latency | PostgreSQL reservation, lease and finalize storage remain pending | | Selected durable request contract | The same five selected-PRE tests plus focused Ruff and `git diff --check` | Passed; the reservation digest covers contributor/link, TASK, assignment, ART attempt/generation, policy/default, exact default input and archive/manifest custody, and the terminal includes that request digest | PostgreSQL ownership and SQL custody remain pending | +| Selected idempotent replay contract | `pytest -q backend/tests/checkers/external/test_selected_pre_submit.py backend/tests/checkers/external/test_selected_pre_submit_coordination.py backend/tests/checkers/external/test_selected_pre_submit_service.py backend/tests/checkers/external/test_selected_preparation_command.py backend/tests/authorization/pre_submit/test_contracts.py backend/tests/test_submission_bundle_admission.py`; focused Ruff and `git diff --check` | 70 passed; one actor/key namespace permits a fresh prepared generation only when every stable byte, packet, policy, TASK and assignment fact matches, validates stored terminal timing/results, replays bounded work findings or an existing durable upload, and rejects changed stable facts | Native uniqueness/immutability and concurrent PostgreSQL replay proof remain pending | | Selected durable owner source | `pytest -q` over selected PRE, policy, coordination, PROJECT activation/proposal contracts and architecture module boundaries; focused Ruff | 51 focused/architecture tests passed; the selected run is its own durable attempt identity, TASK locks precede CHECKERS state, one-use admission facts are substitution-resistant, ordered deadlines fit ART custody, and four private module edges were removed through public ports/composition | Native migration, exact AUTH SQL closure, crash reclaim and admission composition remain pending | | Selected lease execution boundary | `pytest -q backend/tests/checkers/external/test_selected_pre_submit_coordination.py backend/tests/checkers/external/test_selected_pre_submit_service.py backend/tests/checkers/external/test_selected_pre_submit.py backend/tests/architecture/test_module_boundaries.py`; focused Ruff | 49 passed; fixed-service preparation precedes owner locks, the lease commits before material execution, execution occurs with no root open, and exact lease/result digests are consumed in a separate finalization root | Native SQL custody and live admission selection remain pending | | Selected PRE authority contract | `pytest -q backend/tests/authorization/pre_submit/test_contracts.py backend/tests/authorization/test_catalogue.py backend/tests/checkers/external/test_selected_pre_submit_service.py backend/tests/architecture/test_module_boundaries.py`; focused Ruff and `git diff --check` | 50 passed; one dedicated service identity owns only execute/finalize, prepared selectors bind project/run/request, exact phase facts bind the decision and audit digest, direct service calls remain unavailable, and composition uses the public authority port | Native actor/action/evidence constraints and live workflow injection remain pending | diff --git a/backend/app/modules/artifacts/selected_pre_submit_admission.py b/backend/app/modules/artifacts/selected_pre_submit_admission.py index 0a4e5deb6..1ab84bba1 100644 --- a/backend/app/modules/artifacts/selected_pre_submit_admission.py +++ b/backend/app/modules/artifacts/selected_pre_submit_admission.py @@ -85,6 +85,7 @@ def build_selected_pre_submit_reservation( project: ProjectLockedPolicyContextFacts, prepared_generation_id: UUID, attempt_id: UUID, + idempotency_key: UUID, attempt_request_digest: str, commitment: ArtifactCommitment, manifest: SubmissionManifest, @@ -159,6 +160,7 @@ def build_selected_pre_submit_reservation( task_id=task.task_id, assignment_id=task.assignment_id, attempt_id=attempt_id, + idempotency_key=idempotency_key, attempt_request_digest=attempt_request_digest, prepared_generation_id=prepared_generation_id, policy_sha256=selected.policy.policy_sha256, diff --git a/backend/app/modules/artifacts/submission_admission.py b/backend/app/modules/artifacts/submission_admission.py index 515746a12..aeda0f500 100644 --- a/backend/app/modules/artifacts/submission_admission.py +++ b/backend/app/modules/artifacts/submission_admission.py @@ -80,7 +80,9 @@ from app.modules.checkers.api.selected_pre_submit import ( SelectedPreSubmitCompletion, SelectedPreSubmitCoordinationPort, + SelectedPreSubmitCurrentFacts, SelectedPreSubmitReservationFacts, + SelectedPreSubmitRequestConflict, ) from app.modules.checkers.api.external_policy import ( LockedExternalCheckerPolicies, @@ -802,6 +804,7 @@ async def prepare( project=project_context, prepared_generation_id=prepared.generation_id, attempt_id=attempt_id, + idempotency_key=request.idempotency_key, attempt_request_digest=( selected_pre_submit_attempt_request_digest( actor_profile_id=request.actor.actor_profile_id, @@ -848,6 +851,11 @@ async def prepare( default_checker_input=selected.default_input, selected_reservation=reservation, ) + current = await runtime.selected_coordinator.read_current( + reservation + ) + if current is not None: + return await self._selected_replay_result(current) await runtime.materialization.authorize_inspected( materialization_request ) @@ -898,6 +906,10 @@ async def prepare( selected_pre_submit_run_id=reservation.attempt_id, ) return self._result(result) + except SelectedPreSubmitRequestConflict as exc: + raise SubmissionBundlePreparationRejected( + "submission_bundle_preparation_request_conflict" + ) from exc except PreSubmitEvidenceConflict as exc: raise self._evidence_failure(exc) from exc except ArtifactAuthorityDeniedError as exc: @@ -907,6 +919,73 @@ async def prepare( finally: self._authority.close() + async def _selected_replay_result( + self, current: SelectedPreSubmitCurrentFacts + ) -> SubmissionBundlePreparationResult: + """Replay exact work facts or an already durable pass without execution.""" + terminal = current.terminal + if current.status in {"queued", "running"} or terminal is None: + raise SubmissionBundlePreparationInfrastructureUnavailable( + "pre_submission_attempt_outcome_unresolved" + ) + if terminal.outcome == "infrastructure_failed": + raise SubmissionBundlePreparationInfrastructureUnavailable( + terminal.infrastructure_failure_code + or "pre_submission_checked_custody_unavailable" + ) + execution = terminal.execution + if execution is None: + raise SubmissionBundlePreparationInfrastructureUnavailable( + "pre_submission_checked_custody_unavailable" + ) + if not execution.eligible: + raise SubmissionBundlePreparationCheckFailed(execution) + row = ( + await self._session.execute( + select( + SubmissionBundleDurableIntent, + ArtifactPutAttempt, + SubmissionBundleAdmission, + ) + .join( + ArtifactPutAttempt, + ArtifactPutAttempt.id + == SubmissionBundleDurableIntent.put_attempt_id, + ) + .outerjoin( + SubmissionBundleAdmission, + SubmissionBundleAdmission.durable_intent_id + == SubmissionBundleDurableIntent.id, + ) + .where( + SubmissionBundleDurableIntent.selected_pre_submit_run_id + == str(current.run_id) + ) + ) + ).one_or_none() + if row is None: + raise SubmissionBundlePreparationInfrastructureUnavailable( + "pre_submission_checked_custody_unavailable" + ) + _, attempt, admission = row + status = attempt.status + admission_id = None + if admission is not None: + if admission.status == "ready": + status, admission_id = "ready", UUID(admission.id) + elif admission.status == "stale": + status = "stale" + else: + status = "conflict" + return SubmissionBundlePreparationResult( + put_attempt_id=UUID(attempt.id), + admission_id=admission_id, + submission_bundle_preparation_status=SubmissionBundlePreparationStatus( + status + ), + replayed=True, + ) + async def _matching_replay_intent(self, evidence_id: UUID) -> UUID | None: """Find an older exact lineage without trusting client replay selectors.""" async with self._session.begin(): diff --git a/backend/app/modules/checkers/api/selected_pre_submit.py b/backend/app/modules/checkers/api/selected_pre_submit.py index 767dd04c6..5940a93f8 100644 --- a/backend/app/modules/checkers/api/selected_pre_submit.py +++ b/backend/app/modules/checkers/api/selected_pre_submit.py @@ -259,6 +259,51 @@ def canonical_body(self) -> dict[str, object]: "eligible": self.eligible, } + @classmethod + def from_canonical_body( + cls, body: object + ) -> SelectedPreSubmitExecutionFacts: + """Parse the exact bounded result retained for idempotent work replay.""" + if type(body) is not dict or set(body) != { + "schema_version", + "policy_sha256", + "workstream_default", + "required_external_count", + "external_members", + "eligible", + } or body["schema_version"] != "workstream.selected_pre_submit_execution.v1": + raise ValueError("selected PRE execution facts are invalid") + members = body["external_members"] + if type(members) is not list: + raise ValueError("selected PRE execution facts are invalid") + return cls( + policy_sha256=body["policy_sha256"], + workstream_default=WorkstreamDefaultCheckerResult.model_validate( + body["workstream_default"] + ), + required_external_count=body["required_external_count"], + external_members=tuple( + ExternalPreSubmitMemberFacts( + order=item["order"], + requirement_id=item["requirement_id"], + registry_entry_id=UUID(str(item["registry_entry_id"])), + registry_entry_digest=item["registry_entry_digest"], + request_digest=item["request_digest"], + result=ExternalCheckerExecutionResult.model_validate( + item["result"] + | { + "registry_entry_id": UUID( + str(item["result"]["registry_entry_id"]) + ) + } + ), + isolation=ExternalPreSubmitIsolationFacts(**item["isolation"]), + ) + for item in members + ), + eligible=body["eligible"], + ) + @property def result_digest(self) -> str: """Bind every default, project-image and observed-isolation result fact.""" @@ -275,6 +320,7 @@ class SelectedPreSubmitReservationFacts: task_id: UUID assignment_id: UUID attempt_id: UUID + idempotency_key: UUID attempt_request_digest: str prepared_generation_id: UUID policy_sha256: str @@ -295,6 +341,7 @@ def __post_init__(self) -> None: self.task_id, self.assignment_id, self.attempt_id, + self.idempotency_key, self.prepared_generation_id, ) digests = ( @@ -347,6 +394,7 @@ def canonical_body(self) -> dict[str, object]: "task_id": str(self.task_id), "assignment_id": str(self.assignment_id), "attempt_id": str(self.attempt_id), + "idempotency_key": str(self.idempotency_key), "attempt_request_digest": self.attempt_request_digest, "prepared_generation_id": str(self.prepared_generation_id), "policy_sha256": self.policy_sha256, @@ -376,6 +424,7 @@ def from_canonical_body( "task_id", "assignment_id", "attempt_id", + "idempotency_key", "attempt_request_digest", "prepared_generation_id", "policy_sha256", @@ -396,6 +445,7 @@ def from_canonical_body( task_id=UUID(str(body["task_id"])), assignment_id=UUID(str(body["assignment_id"])), attempt_id=UUID(str(body["attempt_id"])), + idempotency_key=UUID(str(body["idempotency_key"])), attempt_request_digest=body["attempt_request_digest"], prepared_generation_id=UUID(str(body["prepared_generation_id"])), policy_sha256=body["policy_sha256"], @@ -592,6 +642,14 @@ class SelectedPreSubmitCompletion: class SelectedPreSubmitCoordinationPort(Protocol): """CHECKERS-owned durable lease operations used by the ART workflow.""" + async def read_current( + self, facts: SelectedPreSubmitReservationFacts + ) -> SelectedPreSubmitCurrentFacts | None: + """Read one exact actor/key result after TASK custody is locked.""" + + async def reserve(self, facts: SelectedPreSubmitReservationFacts) -> UUID: + """Reserve one exact actor/key request after TASK custody is locked.""" + async def claim( self, *, @@ -683,12 +741,97 @@ def canonical_body(self) -> dict[str, object]: ), } + @classmethod + def from_canonical_body( + cls, body: object + ) -> SelectedPreSubmitTerminalFacts: + """Parse and revalidate every persisted lease, result and timing fact.""" + if type(body) is not dict or set(body) != { + "schema_version", + "reservation", + "request_digest", + "lease_id", + "lease_generation", + "lease_expires_at", + "outcome", + "execution", + "infrastructure_failure_code", + "queued_at", + "started_at", + "completed_at", + "queue_latency_ms", + "execution_latency_ms", + } or body["schema_version"] != "workstream.selected_pre_submit_terminal.v1": + raise ValueError("selected PRE terminal facts are invalid") + reservation = SelectedPreSubmitReservationFacts.from_canonical_body( + body["reservation"] + ) + if body["request_digest"] != reservation.request_digest: + raise ValueError("selected PRE terminal request is invalid") + execution_body = body["execution"] + value = cls( + lease=SelectedPreSubmitLeaseFacts( + reservation=reservation, + lease_id=UUID(str(body["lease_id"])), + lease_generation=body["lease_generation"], + lease_expires_at=datetime.fromisoformat(body["lease_expires_at"]), + ), + outcome=body["outcome"], + execution=( + SelectedPreSubmitExecutionFacts.from_canonical_body(execution_body) + if execution_body is not None + else None + ), + infrastructure_failure_code=body["infrastructure_failure_code"], + queued_at=datetime.fromisoformat(body["queued_at"]), + started_at=datetime.fromisoformat(body["started_at"]), + completed_at=datetime.fromisoformat(body["completed_at"]), + ) + if value.canonical_body() != body: + raise ValueError("selected PRE terminal facts are invalid") + return value + @property def terminal_digest(self) -> str: """Bind the exact terminal body used by replay and admission.""" return canonical_json_hash(self.canonical_body()) +@dataclass(frozen=True, slots=True) +class SelectedPreSubmitCurrentFacts: + """One exact actor/key namespace result safe for bounded ART replay.""" + + run_id: UUID + reservation: SelectedPreSubmitReservationFacts + status: Literal["queued", "running", "completed", "infrastructure_failed"] + terminal: SelectedPreSubmitTerminalFacts | None + + def __post_init__(self) -> None: + terminal_status = ( + self.terminal.outcome if self.terminal is not None else None + ) + if ( + type(self.run_id) is not UUID + or type(self.reservation) is not SelectedPreSubmitReservationFacts + or self.run_id != self.reservation.attempt_id + or self.status not in { + "queued", + "running", + "completed", + "infrastructure_failed", + } + or (self.status in {"queued", "running"}) != (self.terminal is None) + or ( + self.terminal is not None + and ( + self.terminal.lease.reservation != self.reservation + or terminal_status != self.status + ) + ) + ): + raise ValueError("selected PRE current facts are invalid") + + class SelectedPreSubmitInfrastructureUnavailable(RuntimeError): """Retain a recoverable PRE infrastructure category, never a work failure.""" @@ -705,6 +848,10 @@ def __init__(self, code: str) -> None: super().__init__(code) +class SelectedPreSubmitRequestConflict(RuntimeError): + """Refuse one actor/key namespace reused with changed stable facts.""" + + class SelectedPreSubmitAuthorityUnavailable(RuntimeError): """Conceal fixed-service PRE authorization loss without product facts.""" @@ -720,11 +867,13 @@ class SelectedPreSubmitAuthorityUnavailable(RuntimeError): "SelectedPreSubmitAuthorityPort", "SelectedPreSubmitCompletion", "SelectedPreSubmitCoordinationPort", + "SelectedPreSubmitCurrentFacts", "SelectedPreSubmitExecuteFacts", "SelectedPreSubmitExecutionFacts", "SelectedPreSubmitInfrastructureUnavailable", "SelectedPreSubmitFinalizeFacts", "SelectedPreSubmitLeaseFacts", "SelectedPreSubmitReservationFacts", + "SelectedPreSubmitRequestConflict", "SelectedPreSubmitTerminalFacts", ) diff --git a/backend/app/modules/checkers/models.py b/backend/app/modules/checkers/models.py index def68e8c3..2d3f8ecd0 100644 --- a/backend/app/modules/checkers/models.py +++ b/backend/app/modules/checkers/models.py @@ -428,6 +428,11 @@ class SelectedPreSubmitRun(Base): name="json_objects", ), UniqueConstraint("request_digest", name="request_digest"), + UniqueConstraint( + "actor_profile_id", + "idempotency_key", + name="uq_selected_pre_run_actor_key", + ), Index("ix_selected_pre_runs_task", "task_id"), Index("ix_selected_pre_runs_status", "status"), ) @@ -438,6 +443,7 @@ class SelectedPreSubmitRun(Base): project_id: Mapped[str] = mapped_column(Uuid(as_uuid=False), nullable=False) task_id: Mapped[str] = mapped_column(Uuid(as_uuid=False), nullable=False) assignment_id: Mapped[str] = mapped_column(Uuid(as_uuid=False), nullable=False) + idempotency_key: Mapped[str] = mapped_column(Uuid(as_uuid=False), nullable=False) prepared_generation_id: Mapped[str] = mapped_column(Uuid(as_uuid=False), nullable=False) request_json: Mapped[dict] = mapped_column(JSONB(), nullable=False) request_digest: Mapped[str] = mapped_column(String(71), nullable=False) diff --git a/backend/app/modules/checkers/selected_pre_submit_coordination.py b/backend/app/modules/checkers/selected_pre_submit_coordination.py index 15939ae83..2f153dd11 100644 --- a/backend/app/modules/checkers/selected_pre_submit_coordination.py +++ b/backend/app/modules/checkers/selected_pre_submit_coordination.py @@ -3,6 +3,7 @@ from __future__ import annotations import threading +from dataclasses import replace from datetime import timedelta from typing import Protocol from uuid import UUID @@ -16,11 +17,13 @@ PreparedSelectedPreSubmitExecution, PreparedSelectedPreSubmitFinalization, SelectedPreSubmitCompletion, + SelectedPreSubmitCurrentFacts, SelectedPreSubmitExecuteFacts, SelectedPreSubmitExecutionFacts, SelectedPreSubmitFinalizeFacts, SelectedPreSubmitLeaseFacts, SelectedPreSubmitReservationFacts, + SelectedPreSubmitRequestConflict, SelectedPreSubmitTerminalFacts, ) from app.modules.checkers.models import SelectedPreSubmitRun @@ -192,6 +195,7 @@ def _matches(row: SelectedPreSubmitRun, facts: SelectedPreSubmitReservationFacts and row.project_id == str(facts.project_id) and row.task_id == str(facts.task_id) and row.assignment_id == str(facts.assignment_id) + and row.idempotency_key == str(facts.idempotency_key) and row.prepared_generation_id == str(facts.prepared_generation_id) and row.policy_sha256 == facts.policy_sha256 and row.default_behavior_sha256 == facts.default_behavior_sha256 @@ -217,6 +221,69 @@ def __init__( self._capability: SelectedPreSubmitAdmissionCapability | None = None self._execution_capability: SelectedPreSubmitExecutionCapability | None = None + async def read_current( + self, facts: SelectedPreSubmitReservationFacts + ) -> SelectedPreSubmitCurrentFacts | None: + """Lock TASK before reading and validating one actor/key CHECKERS row.""" + _require_root(self._session) + if type(facts) is not SelectedPreSubmitReservationFacts: + raise TypeError("selected PRE reservation facts are invalid") + await self._tasks.lock_selected_pre_submit_scope(facts) + row = await self._session.scalar( + select(SelectedPreSubmitRun) + .where( + SelectedPreSubmitRun.actor_profile_id + == str(facts.actor_profile_id), + SelectedPreSubmitRun.idempotency_key + == str(facts.idempotency_key), + ) + .with_for_update() + .execution_options(populate_existing=True) + ) + if row is None: + return None + try: + stored = SelectedPreSubmitReservationFacts.from_canonical_body( + row.request_json + ) + normalized = replace( + facts, + attempt_id=stored.attempt_id, + prepared_generation_id=stored.prepared_generation_id, + ) + terminal = ( + SelectedPreSubmitTerminalFacts.from_canonical_body(row.terminal_json) + if row.terminal_json is not None + else None + ) + except (TypeError, ValueError): + raise SelectedPreSubmitUnavailable( + "selected_pre_submit_stored_facts_invalid" + ) from None + if ( + normalized != stored + or not _matches(row, stored) + or row.request_digest != stored.request_digest + or ( + terminal is not None + and ( + terminal.terminal_digest != row.terminal_digest + or terminal.lease.reservation != stored + or terminal.execution is not None + and terminal.execution.eligible != row.eligible + ) + ) + ): + raise SelectedPreSubmitRequestConflict( + "selected_pre_submit_request_conflict" + ) + return SelectedPreSubmitCurrentFacts( + run_id=UUID(row.id), + reservation=stored, + status=row.status, + terminal=terminal, + ) + async def reserve(self, facts: SelectedPreSubmitReservationFacts) -> UUID: """Acquire TASK custody before the CHECKERS key and exact request row.""" _require_root(self._session) @@ -225,11 +292,23 @@ async def reserve(self, facts: SelectedPreSubmitReservationFacts) -> UUID: await self._tasks.lock_selected_pre_submit_scope(facts) await self._session.execute( text("select pg_advisory_xact_lock(hashtextextended(:key,0))"), - {"key": "checkers:selected-pre:" + str(facts.attempt_id)}, + { + "key": ( + "checkers:selected-pre:" + + str(facts.actor_profile_id) + + ":" + + str(facts.idempotency_key) + ) + }, ) row = await self._session.scalar( select(SelectedPreSubmitRun) - .where(SelectedPreSubmitRun.id == str(facts.attempt_id)) + .where( + SelectedPreSubmitRun.actor_profile_id + == str(facts.actor_profile_id), + SelectedPreSubmitRun.idempotency_key + == str(facts.idempotency_key), + ) .with_for_update() .execution_options(populate_existing=True) ) @@ -244,6 +323,7 @@ async def reserve(self, facts: SelectedPreSubmitReservationFacts) -> UUID: project_id=str(facts.project_id), task_id=str(facts.task_id), assignment_id=str(facts.assignment_id), + idempotency_key=str(facts.idempotency_key), prepared_generation_id=str(facts.prepared_generation_id), request_json=facts.canonical_body(), request_digest=facts.request_digest, diff --git a/backend/tests/authorization/pre_submit/test_contracts.py b/backend/tests/authorization/pre_submit/test_contracts.py index f122edcfd..80217b081 100644 --- a/backend/tests/authorization/pre_submit/test_contracts.py +++ b/backend/tests/authorization/pre_submit/test_contracts.py @@ -49,6 +49,7 @@ def _reservation() -> SelectedPreSubmitReservationFacts: task_id=new_record_id(), assignment_id=new_record_id(), attempt_id=new_record_id(), + idempotency_key=new_record_id(), attempt_request_digest="sha256:" + "0" * 64, prepared_generation_id=new_record_id(), policy_sha256="sha256:" + "1" * 64, diff --git a/backend/tests/checkers/external/test_selected_pre_submit.py b/backend/tests/checkers/external/test_selected_pre_submit.py index dfc1d6b5d..bfae5d516 100644 --- a/backend/tests/checkers/external/test_selected_pre_submit.py +++ b/backend/tests/checkers/external/test_selected_pre_submit.py @@ -279,6 +279,7 @@ async def test_selected_pre_runs_default_then_locked_external_image( task_id=identity.task_id, assignment_id=identity.assignment_id, attempt_id=identity.attempt_id, + idempotency_key=new_record_id(), attempt_request_digest=identity.attempt_request_digest, prepared_generation_id=identity.prepared_generation_id, policy_sha256=policy.policy_sha256, @@ -308,6 +309,12 @@ async def test_selected_pre_runs_default_then_locked_external_image( assert terminal.canonical_body()["execution_latency_ms"] == 50 assert terminal.canonical_body()["request_digest"] == reservation.request_digest assert terminal.terminal_digest == canonical_json_hash(terminal.canonical_body()) + assert SelectedPreSubmitTerminalFacts.from_canonical_body( + terminal.canonical_body() + ) == terminal + changed_terminal = terminal.canonical_body() | {"queue_latency_ms": 26} + with pytest.raises(ValueError, match="terminal facts"): + SelectedPreSubmitTerminalFacts.from_canonical_body(changed_terminal) finally: await request.prepared_artifact.close() manager.close() @@ -471,6 +478,7 @@ async def test_selected_admission_binds_unchanged_work_to_current_task_rules( project=project, prepared_generation_id=request.prepared_artifact.generation_id, attempt_id=new_record_id(), + idempotency_key=new_record_id(), attempt_request_digest=SHA, commitment=request.prepared_artifact.commitment, manifest=request.manifest, diff --git a/backend/tests/checkers/external/test_selected_pre_submit_coordination.py b/backend/tests/checkers/external/test_selected_pre_submit_coordination.py index ba53c2756..249c7791b 100644 --- a/backend/tests/checkers/external/test_selected_pre_submit_coordination.py +++ b/backend/tests/checkers/external/test_selected_pre_submit_coordination.py @@ -4,6 +4,7 @@ from dataclasses import replace from types import SimpleNamespace +from unittest.mock import AsyncMock from uuid import UUID import pytest @@ -25,6 +26,7 @@ SelectedPreSubmitFinalizeFacts, SelectedPreSubmitLeaseFacts, SelectedPreSubmitReservationFacts, + SelectedPreSubmitRequestConflict, ) from app.adapters.tasks import selected_pre_submit_task_guard from app.modules.tasks.repository import TaskRepository @@ -32,6 +34,7 @@ from app.modules.checkers.selected_pre_submit_coordination import ( SelectedPreSubmitAdmissionCapability, SelectedPreSubmitExecutionCapability, + SelectedPreSubmitCoordinator, SelectedPreSubmitUnavailable, ) from tests.checkers.external.support import SHA @@ -45,6 +48,7 @@ def _reservation() -> SelectedPreSubmitReservationFacts: task_id=new_record_id(), assignment_id=new_record_id(), attempt_id=new_record_id(), + idempotency_key=new_record_id(), attempt_request_digest=SHA, prepared_generation_id=new_record_id(), policy_sha256="sha256:" + "1" * 64, @@ -57,6 +61,67 @@ def _reservation() -> SelectedPreSubmitReservationFacts: ) +def _queued_row(reservation: SelectedPreSubmitReservationFacts) -> SimpleNamespace: + return SimpleNamespace( + id=str(reservation.attempt_id), + actor_profile_id=str(reservation.actor_profile_id), + identity_link_id=str(reservation.identity_link_id), + project_id=str(reservation.project_id), + task_id=str(reservation.task_id), + assignment_id=str(reservation.assignment_id), + idempotency_key=str(reservation.idempotency_key), + prepared_generation_id=str(reservation.prepared_generation_id), + request_json=reservation.canonical_body(), + request_digest=reservation.request_digest, + policy_sha256=reservation.policy_sha256, + default_behavior_sha256=reservation.default_behavior_sha256, + default_input_sha256=reservation.default_input_sha256, + archive_sha256=reservation.archive_sha256, + archive_byte_count=reservation.archive_byte_count, + semantic_manifest_sha256=reservation.semantic_manifest_sha256, + execution_budget_ms=reservation.execution_budget_ms, + status="queued", + terminal_json=None, + terminal_digest=None, + eligible=None, + ) + + +@pytest.mark.asyncio +async def test_selected_pre_current_replays_only_stable_actor_key_facts() -> None: + stored = _reservation() + row = _queued_row(stored) + transaction = SimpleNamespace(is_active=True) + session = SimpleNamespace( + sync_session=SimpleNamespace(get_transaction=lambda: transaction), + in_nested_transaction=lambda: False, + scalar=AsyncMock(return_value=row), + ) + tasks = SimpleNamespace(lock_selected_pre_submit_scope=AsyncMock()) + coordinator = SelectedPreSubmitCoordinator(session, tasks=tasks) + fresh = replace( + stored, + attempt_id=new_record_id(), + prepared_generation_id=new_record_id(), + ) + + current = await coordinator.read_current(fresh) + + assert current is not None + assert current.run_id == stored.attempt_id + assert current.reservation == stored + assert current.status == "queued" + tasks.lock_selected_pre_submit_scope.assert_awaited_once_with(fresh) + + with pytest.raises( + SelectedPreSubmitRequestConflict, + match="selected_pre_submit_request_conflict", + ): + await coordinator.read_current( + replace(fresh, archive_sha256="sha256:" + "f" * 64) + ) + + @pytest.mark.asyncio async def test_selected_pre_task_guard_rechecks_exact_locked_lineage(monkeypatch) -> None: lineage = SelectedPreSubmitAdmissionLineage( diff --git a/backend/tests/checkers/external/test_selected_pre_submit_service.py b/backend/tests/checkers/external/test_selected_pre_submit_service.py index ca7ce731d..87d02f8cb 100644 --- a/backend/tests/checkers/external/test_selected_pre_submit_service.py +++ b/backend/tests/checkers/external/test_selected_pre_submit_service.py @@ -120,6 +120,7 @@ def _reservation() -> SelectedPreSubmitReservationFacts: task_id=new_record_id(), assignment_id=new_record_id(), attempt_id=new_record_id(), + idempotency_key=new_record_id(), attempt_request_digest="sha256:" + "0" * 64, prepared_generation_id=new_record_id(), policy_sha256="sha256:" + "1" * 64, diff --git a/backend/tests/checkers/external/test_selected_preparation_command.py b/backend/tests/checkers/external/test_selected_preparation_command.py index 4c7fecbcc..26a5f7bcd 100644 --- a/backend/tests/checkers/external/test_selected_preparation_command.py +++ b/backend/tests/checkers/external/test_selected_preparation_command.py @@ -79,7 +79,10 @@ async def test_hidden_preparation_uses_selected_pre_before_durable_admission( prepare_selected_authorization=AsyncMock(return_value=object()), authorize_inspected=AsyncMock(), ) - coordinator = SimpleNamespace(reserve=AsyncMock(return_value=attempt_id)) + coordinator = SimpleNamespace( + read_current=AsyncMock(return_value=None), + reserve=AsyncMock(return_value=attempt_id), + ) selected_execution = SimpleNamespace(execute=AsyncMock(return_value=completion)) durable = SimpleNamespace( admit_in_transaction=AsyncMock( @@ -165,6 +168,7 @@ async def runtime_factory(): ) materialization.prepare_selected_authorization.assert_awaited_once() materialization.authorize_inspected.assert_awaited_once() + coordinator.read_current.assert_awaited_once_with(reservation) coordinator.reserve.assert_awaited_once_with(reservation) selected_execution.execute.assert_awaited_once() admitted = durable.admit_in_transaction.await_args.args[0] @@ -176,4 +180,3 @@ async def runtime_factory(): durable.admit_in_transaction.return_value[2], selected_pre_submit_run_id=attempt_id, ) - diff --git a/backend/tests/test_submission_bundle_admission.py b/backend/tests/test_submission_bundle_admission.py index 91a90b37b..25f97d8da 100644 --- a/backend/tests/test_submission_bundle_admission.py +++ b/backend/tests/test_submission_bundle_admission.py @@ -668,6 +668,7 @@ async def test_selected_pre_terminal_publishes_self_contained_ready_admission() task_id=new_record_id(), assignment_id=new_record_id(), attempt_id=new_record_id(), + idempotency_key=new_record_id(), attempt_request_digest=_sha("8"), prepared_generation_id=new_record_id(), policy_sha256=lineage.effective_plan_sha256, From 7700f723db7b9219d35ea4338f83c1f946721589 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 20:33:56 +0100 Subject: [PATCH 073/283] [PILOT-04] Carry selected POST policy through ART --- .../pilot04-workstream-default-checker.md | 1 + backend/app/adapters/tasks/__init__.py | 11 +++++++ .../artifacts/api/submission_admission.py | 21 ++++++++++++++ backend/app/modules/artifacts/models.py | 13 +++++++++ .../selected_pre_submit_admission.py | 8 +++++ .../modules/artifacts/submission_admission.py | 10 +++++++ .../modules/artifacts/submission_bindings.py | 20 +++++++++++++ .../checkers/api/selected_pre_submit.py | 29 +++++++++++++++++++ .../modules/tasks/submission_participants.py | 2 ++ .../test_selected_pre_submit_coordination.py | 18 ++++++++++++ .../tests/test_submission_bundle_admission.py | 14 +++++++++ 11 files changed, 147 insertions(+) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index e90e53cd8..b4429e8be 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -204,6 +204,7 @@ intermediate-wait regression. | Selected durable result contract | `pytest -q backend/tests/checkers/external/test_selected_pre_submit.py`; Ruff and `git diff --check` on the affected files | 5 passed; canonical result/terminal digests bind the default, ordered external results, isolation, generation lease, outcome and measured queue/execution latency | PostgreSQL reservation, lease and finalize storage remain pending | | Selected durable request contract | The same five selected-PRE tests plus focused Ruff and `git diff --check` | Passed; the reservation digest covers contributor/link, TASK, assignment, ART attempt/generation, policy/default, exact default input and archive/manifest custody, and the terminal includes that request digest | PostgreSQL ownership and SQL custody remain pending | | Selected idempotent replay contract | `pytest -q backend/tests/checkers/external/test_selected_pre_submit.py backend/tests/checkers/external/test_selected_pre_submit_coordination.py backend/tests/checkers/external/test_selected_pre_submit_service.py backend/tests/checkers/external/test_selected_preparation_command.py backend/tests/authorization/pre_submit/test_contracts.py backend/tests/test_submission_bundle_admission.py`; focused Ruff and `git diff --check` | 70 passed; one actor/key namespace permits a fresh prepared generation only when every stable byte, packet, policy, TASK and assignment fact matches, validates stored terminal timing/results, replays bounded work findings or an existing durable upload, and rejects changed stable facts | Native uniqueness/immutability and concurrent PostgreSQL replay proof remain pending | +| Selected POST policy handoff | Focused selected PRE/admission/composition tests plus Ruff and `git diff --check` | 76 database-free tests passed; the complete approved POST image policy and digest now travel inside the selected PRE request, verified admission and ART consumption result, and malformed or substituted retained policy fails closed | Submission request selection and durable external POST result storage remain pending; seven separately selected routing tests required a PostgreSQL URL and were not claimed | | Selected durable owner source | `pytest -q` over selected PRE, policy, coordination, PROJECT activation/proposal contracts and architecture module boundaries; focused Ruff | 51 focused/architecture tests passed; the selected run is its own durable attempt identity, TASK locks precede CHECKERS state, one-use admission facts are substitution-resistant, ordered deadlines fit ART custody, and four private module edges were removed through public ports/composition | Native migration, exact AUTH SQL closure, crash reclaim and admission composition remain pending | | Selected lease execution boundary | `pytest -q backend/tests/checkers/external/test_selected_pre_submit_coordination.py backend/tests/checkers/external/test_selected_pre_submit_service.py backend/tests/checkers/external/test_selected_pre_submit.py backend/tests/architecture/test_module_boundaries.py`; focused Ruff | 49 passed; fixed-service preparation precedes owner locks, the lease commits before material execution, execution occurs with no root open, and exact lease/result digests are consumed in a separate finalization root | Native SQL custody and live admission selection remain pending | | Selected PRE authority contract | `pytest -q backend/tests/authorization/pre_submit/test_contracts.py backend/tests/authorization/test_catalogue.py backend/tests/checkers/external/test_selected_pre_submit_service.py backend/tests/architecture/test_module_boundaries.py`; focused Ruff and `git diff --check` | 50 passed; one dedicated service identity owns only execute/finalize, prepared selectors bind project/run/request, exact phase facts bind the decision and audit digest, direct service calls remain unavailable, and composition uses the public authority port | Native actor/action/evidence constraints and live workflow injection remain pending | diff --git a/backend/app/adapters/tasks/__init__.py b/backend/app/adapters/tasks/__init__.py index fe91db261..479014717 100644 --- a/backend/app/adapters/tasks/__init__.py +++ b/backend/app/adapters/tasks/__init__.py @@ -185,6 +185,16 @@ async def consume( or result.material is None or result.binding_decision_id is None): raise RuntimeError("admission did not produce a binding") from app.adapters.checkers import submission_evaluation_content + from app.modules.checkers.api.external_policy import ( + LockedExternalPostSubmitPolicy, + ) + selected_post_policy = ( + LockedExternalPostSubmitPolicy.model_validate( + result.selected_post_submit_policy_body + ) + if result.selected_post_submit_policy_body is not None + else None + ) return SubmissionArtifactAdmissionResult( binding_id=result.binding_id, content_id=result.content_id, binding_decision_id=result.binding_decision_id, @@ -194,6 +204,7 @@ async def consume( request.task_context, request.project_context, request.packet, result.material.files, result.material.archive_sha256, ), + selected_post_submit_policy=selected_post_policy, ) async def read_consumed(self, request: SubmissionArtifactReplayRequest) -> SubmissionArtifactBindingFacts: diff --git a/backend/app/modules/artifacts/api/submission_admission.py b/backend/app/modules/artifacts/api/submission_admission.py index 8b1a346d0..226d34d84 100644 --- a/backend/app/modules/artifacts/api/submission_admission.py +++ b/backend/app/modules/artifacts/api/submission_admission.py @@ -7,6 +7,8 @@ from uuid import UUID import re +from app.core.hashing import canonical_json_hash + from app.modules.tasks.api import TaskSubmissionContextFacts SubmissionAdmissionConsumptionStatus = Literal["consumed", "stale"] @@ -123,6 +125,8 @@ class SubmissionAdmissionConsumptionResult: replayed: bool material: SubmissionAdmissionMaterial | None binding_decision_id: UUID | None + selected_post_submit_policy_sha256: str | None = None + selected_post_submit_policy_body: dict[str, object] | None = None def __post_init__(self) -> None: if self.status == "consumed": @@ -130,6 +134,23 @@ def __post_init__(self) -> None: raise ValueError("consumed admission requires verified material") elif self.status != "stale" or self.material is not None or self.binding_id is not None: raise ValueError("stale admission has no material") + if (self.selected_post_submit_policy_sha256 is None) != ( + self.selected_post_submit_policy_body is None + ): + raise ValueError("selected POST policy custody is incomplete") + if self.selected_post_submit_policy_body is not None and ( + self.selected_post_submit_policy_body.get("policy_sha256") + != self.selected_post_submit_policy_sha256 + or canonical_json_hash( + { + key: value + for key, value in self.selected_post_submit_policy_body.items() + if key != "policy_sha256" + } + ) + != self.selected_post_submit_policy_sha256 + ): + raise ValueError("selected POST policy custody is invalid") class SubmissionAdmissionConsumptionPort(Protocol): diff --git a/backend/app/modules/artifacts/models.py b/backend/app/modules/artifacts/models.py index d7021eae8..f848f39c5 100644 --- a/backend/app/modules/artifacts/models.py +++ b/backend/app/modules/artifacts/models.py @@ -1323,6 +1323,15 @@ class SubmissionBundleAdmission(Base): + ")", name="selected_rules_sha256", ), + CheckConstraint( + "(selected_pre_submit_run_id is null and " + "selected_post_submit_policy_sha256 is null and " + "selected_post_submit_policy_body is null) or " + "(selected_pre_submit_run_id is not null and " + + SHA256_CHECK.format(column="selected_post_submit_policy_sha256") + + " and jsonb_typeof(selected_post_submit_policy_body)='object')", + name="selected_post_submit_policy", + ), CheckConstraint( SHA256_CHECK.format(column="source_snapshot_sha256") + " and " + SHA256_CHECK.format(column="effective_policy_sha256") + " and " @@ -1412,6 +1421,10 @@ class SubmissionBundleAdmission(Base): pre_submit_policy_sha256: Mapped[str] = mapped_column(String(71), nullable=False) effective_plan_sha256: Mapped[str] = mapped_column(String(71), nullable=False) selected_rules_sha256: Mapped[str | None] = mapped_column(String(71)) + selected_post_submit_policy_sha256: Mapped[str | None] = mapped_column( + String(71) + ) + selected_post_submit_policy_body: Mapped[dict | None] = mapped_column(JSONB) packet_sha256: Mapped[str] = mapped_column(String(71), nullable=False) semantic_manifest_id: Mapped[str] = mapped_column(Uuid(as_uuid=False), nullable=False) semantic_manifest_sha256: Mapped[str] = mapped_column(String(71), nullable=False) diff --git a/backend/app/modules/artifacts/selected_pre_submit_admission.py b/backend/app/modules/artifacts/selected_pre_submit_admission.py index 1ab84bba1..7521a4a3e 100644 --- a/backend/app/modules/artifacts/selected_pre_submit_admission.py +++ b/backend/app/modules/artifacts/selected_pre_submit_admission.py @@ -22,6 +22,7 @@ ) from app.modules.checkers.api.external_policy import ( LockedExternalCheckerPolicies, + LockedExternalPostSubmitPolicy, LockedExternalPreSubmitPolicy, ) from app.modules.checkers.api.materialization import SubmissionMaterialEntry @@ -72,6 +73,8 @@ class SelectedPreSubmitAdmissionContext: """Exact selected policy, default input and non-deciding change binding.""" policy: LockedExternalPreSubmitPolicy + post_policy: LockedExternalPostSubmitPolicy + policies_sha256: str default_input: WorkstreamDefaultCheckerInput change_gate: SubmissionChangeGateResult rules_sha256: str @@ -147,6 +150,9 @@ def build_selected_pre_submit_reservation( pre_submit_policy_sha256=project.pre_submit_policy_bundle_hash, effective_plan_sha256=selected.policy.policy_sha256, rules_sha256=selected.rules_sha256, + external_checker_policies_sha256=selected.policies_sha256, + post_submit_policy_sha256=selected.post_policy.policy_sha256, + post_submit_policy_body=selected.post_policy.model_dump(mode="json"), locked_policy_context_hash=locked_policy_context_hash, semantic_manifest_id=semantic_manifest_identity(manifest.sha256), semantic_manifest_body=manifest.as_dict(), @@ -231,6 +237,8 @@ def bind_selected_pre_submit_admission( ) return SelectedPreSubmitAdmissionContext( policy=policies.pre_submit, + post_policy=policies.post_submit, + policies_sha256=policies.policies_sha256, default_input=WorkstreamDefaultCheckerInput( archive_sha256=commitment.sha256, archive_byte_count=commitment.byte_count, diff --git a/backend/app/modules/artifacts/submission_admission.py b/backend/app/modules/artifacts/submission_admission.py index aeda0f500..f88bd8bdc 100644 --- a/backend/app/modules/artifacts/submission_admission.py +++ b/backend/app/modules/artifacts/submission_admission.py @@ -543,6 +543,16 @@ async def publish_verified( if selected_lineage is not None else None ), + selected_post_submit_policy_sha256=( + selected_lineage.post_submit_policy_sha256 + if selected_lineage is not None + else None + ), + selected_post_submit_policy_body=( + selected_lineage.post_submit_policy_body + if selected_lineage is not None + else None + ), packet_sha256=( selected_lineage.packet_sha256 if selected_lineage is not None diff --git a/backend/app/modules/artifacts/submission_bindings.py b/backend/app/modules/artifacts/submission_bindings.py index ae099db48..c426e5d5e 100644 --- a/backend/app/modules/artifacts/submission_bindings.py +++ b/backend/app/modules/artifacts/submission_bindings.py @@ -19,6 +19,7 @@ ) from app.modules.artifacts.api.submission_admission import ConsumedSubmissionAdmissionRequest from app.modules.artifacts.submission_manifest import SubmissionManifest +from app.modules.checkers.api.external_policy import LockedExternalPostSubmitPolicy from app.modules.artifacts.models import ( ArtifactBinding, ArtifactContent, @@ -319,8 +320,21 @@ def _art_lineage_is_intact( and evidence.terminal_status == "passed" and evidence.eligible is True ) + selected_policy_intact = admission.selected_pre_submit_run_id is None + if admission.selected_pre_submit_run_id is not None: + try: + selected_policy = LockedExternalPostSubmitPolicy.model_validate( + admission.selected_post_submit_policy_body + ) + selected_policy_intact = ( + selected_policy.policy_sha256 + == admission.selected_post_submit_policy_sha256 + ) + except (TypeError, ValueError): + selected_policy_intact = False return bool( legacy_intact + and selected_policy_intact and (admission.pre_submit_evidence_set_id is None) != (admission.selected_pre_submit_run_id is None) and content.id == admission.artifact_content_id @@ -433,4 +447,10 @@ def _result( replayed=replayed, material=material, binding_decision_id=binding_decision_id, + selected_post_submit_policy_sha256=( + getattr(admission, "selected_post_submit_policy_sha256", None) + ), + selected_post_submit_policy_body=( + getattr(admission, "selected_post_submit_policy_body", None) + ), ) diff --git a/backend/app/modules/checkers/api/selected_pre_submit.py b/backend/app/modules/checkers/api/selected_pre_submit.py index 5940a93f8..a76de1c4b 100644 --- a/backend/app/modules/checkers/api/selected_pre_submit.py +++ b/backend/app/modules/checkers/api/selected_pre_submit.py @@ -31,6 +31,9 @@ class SelectedPreSubmitAdmissionLineage: pre_submit_policy_sha256: str effective_plan_sha256: str rules_sha256: str + external_checker_policies_sha256: str + post_submit_policy_sha256: str + post_submit_policy_body: dict[str, object] locked_policy_context_hash: str semantic_manifest_id: UUID semantic_manifest_body: dict[str, object] @@ -52,6 +55,8 @@ def __post_init__(self) -> None: self.pre_submit_policy_sha256, self.effective_plan_sha256, self.rules_sha256, + self.external_checker_policies_sha256, + self.post_submit_policy_sha256, self.locked_policy_context_hash, self.packet_sha256, ) @@ -78,6 +83,17 @@ def __post_init__(self) -> None: for value in digests ) or type(self.semantic_manifest_body) is not dict + or type(self.post_submit_policy_body) is not dict + or canonical_json_hash( + { + key: value + for key, value in self.post_submit_policy_body.items() + if key != "policy_sha256" + } + ) + != self.post_submit_policy_sha256 + or self.post_submit_policy_body.get("policy_sha256") + != self.post_submit_policy_sha256 or self.storage_scheme not in {"local", "s3"} ): raise ValueError("selected PRE admission lineage is invalid") @@ -102,6 +118,11 @@ def canonical_body(self) -> dict[str, object]: "pre_submit_policy_sha256": self.pre_submit_policy_sha256, "effective_plan_sha256": self.effective_plan_sha256, "rules_sha256": self.rules_sha256, + "external_checker_policies_sha256": ( + self.external_checker_policies_sha256 + ), + "post_submit_policy_sha256": self.post_submit_policy_sha256, + "post_submit_policy_body": self.post_submit_policy_body, "locked_policy_context_hash": self.locked_policy_context_hash, "semantic_manifest_id": str(self.semantic_manifest_id), "semantic_manifest_body": self.semantic_manifest_body, @@ -128,6 +149,9 @@ def from_canonical_body( "pre_submit_policy_sha256", "effective_plan_sha256", "rules_sha256", + "external_checker_policies_sha256", + "post_submit_policy_sha256", + "post_submit_policy_body", "locked_policy_context_hash", "semantic_manifest_id", "semantic_manifest_body", @@ -152,6 +176,11 @@ def from_canonical_body( pre_submit_policy_sha256=body["pre_submit_policy_sha256"], effective_plan_sha256=body["effective_plan_sha256"], rules_sha256=body["rules_sha256"], + external_checker_policies_sha256=body[ + "external_checker_policies_sha256" + ], + post_submit_policy_sha256=body["post_submit_policy_sha256"], + post_submit_policy_body=body["post_submit_policy_body"], locked_policy_context_hash=body["locked_policy_context_hash"], semantic_manifest_id=UUID(str(body["semantic_manifest_id"])), semantic_manifest_body=body["semantic_manifest_body"], diff --git a/backend/app/modules/tasks/submission_participants.py b/backend/app/modules/tasks/submission_participants.py index 794908b32..d7f7c3666 100644 --- a/backend/app/modules/tasks/submission_participants.py +++ b/backend/app/modules/tasks/submission_participants.py @@ -6,6 +6,7 @@ from app.modules.checkers.api import SubmissionPacketView from app.modules.checkers.api.post_submit import PostSubmissionEvaluationContent +from app.modules.checkers.api.external_policy import LockedExternalPostSubmitPolicy from app.modules.projects.api import ProjectLockedPolicyContextFacts from app.modules.tasks.api import TaskSubmissionContextFacts @@ -32,6 +33,7 @@ class SubmissionArtifactBindingFacts: @dataclass(frozen=True, slots=True) class SubmissionArtifactAdmissionResult(SubmissionArtifactBindingFacts): evaluation_content: PostSubmissionEvaluationContent + selected_post_submit_policy: LockedExternalPostSubmitPolicy | None = None @dataclass(frozen=True, slots=True) diff --git a/backend/tests/checkers/external/test_selected_pre_submit_coordination.py b/backend/tests/checkers/external/test_selected_pre_submit_coordination.py index 249c7791b..368f82edc 100644 --- a/backend/tests/checkers/external/test_selected_pre_submit_coordination.py +++ b/backend/tests/checkers/external/test_selected_pre_submit_coordination.py @@ -40,6 +40,16 @@ from tests.checkers.external.support import SHA +_POST_POLICY_WITHOUT_DIGEST = { + "schema_version": "external_post_submit_policy.v1", + "entries": [], +} +_POST_POLICY_SHA256 = canonical_json_hash(_POST_POLICY_WITHOUT_DIGEST) +_POST_POLICY = _POST_POLICY_WITHOUT_DIGEST | { + "policy_sha256": _POST_POLICY_SHA256 +} + + def _reservation() -> SelectedPreSubmitReservationFacts: return SelectedPreSubmitReservationFacts( actor_profile_id=new_record_id(), @@ -138,6 +148,9 @@ async def test_selected_pre_task_guard_rechecks_exact_locked_lineage(monkeypatch pre_submit_policy_sha256="sha256:" + "8" * 64, effective_plan_sha256="sha256:" + "9" * 64, rules_sha256="sha256:" + "d" * 64, + external_checker_policies_sha256=SHA, + post_submit_policy_sha256=_POST_POLICY_SHA256, + post_submit_policy_body=_POST_POLICY, locked_policy_context_hash="sha256:" + "a" * 64, semantic_manifest_id=new_record_id(), semantic_manifest_body={"schema_version": "test"}, @@ -340,6 +353,9 @@ def test_selected_pre_request_binds_complete_later_admission_lineage() -> None: pre_submit_policy_sha256=SHA, effective_plan_sha256="sha256:" + "1" * 64, rules_sha256="sha256:" + "2" * 64, + external_checker_policies_sha256=SHA, + post_submit_policy_sha256=_POST_POLICY_SHA256, + post_submit_policy_body=_POST_POLICY, locked_policy_context_hash=SHA, semantic_manifest_id=new_record_id(), semantic_manifest_body=manifest, @@ -409,6 +425,8 @@ def test_selected_ready_admission_no_longer_requires_legacy_evidence() -> None: effective_policy_sha256=SHA, pre_submit_policy_id=str(new_record_id()), pre_submit_policy_sha256=SHA, + selected_post_submit_policy_sha256=_POST_POLICY_SHA256, + selected_post_submit_policy_body=_POST_POLICY, locked_policy_context_hash=SHA, semantic_manifest_id=str(new_record_id()), semantic_manifest_sha256=SHA, diff --git a/backend/tests/test_submission_bundle_admission.py b/backend/tests/test_submission_bundle_admission.py index 25f97d8da..70dbdbc21 100644 --- a/backend/tests/test_submission_bundle_admission.py +++ b/backend/tests/test_submission_bundle_admission.py @@ -641,6 +641,12 @@ async def test_verified_submission_lineage_publishes_one_ready_admission( @pytest.mark.asyncio async def test_selected_pre_terminal_publishes_self_contained_ready_admission() -> None: manifest = {"schema_version": "submission_manifest.v1", "entries": []} + post_policy = { + "schema_version": "external_post_submit_policy.v1", + "entries": [], + } + post_policy_sha256 = canonical_json_hash(post_policy) + post_policy["policy_sha256"] = post_policy_sha256 lineage = SelectedPreSubmitAdmissionLineage( predecessor_submission_id=None, predecessor_submission_version=None, @@ -655,6 +661,9 @@ async def test_selected_pre_terminal_publishes_self_contained_ready_admission() pre_submit_policy_sha256=_sha("4"), effective_plan_sha256=_sha("5"), rules_sha256=_sha("8"), + external_checker_policies_sha256=_sha("9"), + post_submit_policy_sha256=post_policy_sha256, + post_submit_policy_body=post_policy, locked_policy_context_hash=_sha("6"), semantic_manifest_id=new_record_id(), semantic_manifest_body=manifest, @@ -760,6 +769,11 @@ async def test_selected_pre_terminal_publishes_self_contained_ready_admission() assert admission.selected_pre_submit_run_id == str(selected.attempt_id) assert admission.packet_sha256 == lineage.packet_sha256 assert admission.semantic_manifest_body == manifest + assert ( + admission.selected_post_submit_policy_sha256 + == lineage.post_submit_policy_sha256 + ) + assert admission.selected_post_submit_policy_body == post_policy @pytest.mark.asyncio From 889f181538a879b71656d0aa633b70c976cb629f Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 20:36:46 +0100 Subject: [PATCH 074/283] [PILOT-04] Bind selected POST requests and results --- .../pilot04-workstream-default-checker.md | 1 + .../checkers/api/selected_post_submit.py | 153 ++++++++++++++++++ .../external/test_selected_post_submit.py | 83 ++++++++++ 3 files changed, 237 insertions(+) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index b4429e8be..14ed6019a 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -209,6 +209,7 @@ intermediate-wait regression. | Selected lease execution boundary | `pytest -q backend/tests/checkers/external/test_selected_pre_submit_coordination.py backend/tests/checkers/external/test_selected_pre_submit_service.py backend/tests/checkers/external/test_selected_pre_submit.py backend/tests/architecture/test_module_boundaries.py`; focused Ruff | 49 passed; fixed-service preparation precedes owner locks, the lease commits before material execution, execution occurs with no root open, and exact lease/result digests are consumed in a separate finalization root | Native SQL custody and live admission selection remain pending | | Selected PRE authority contract | `pytest -q backend/tests/authorization/pre_submit/test_contracts.py backend/tests/authorization/test_catalogue.py backend/tests/checkers/external/test_selected_pre_submit_service.py backend/tests/architecture/test_module_boundaries.py`; focused Ruff and `git diff --check` | 50 passed; one dedicated service identity owns only execute/finalize, prepared selectors bind project/run/request, exact phase facts bind the decision and audit digest, direct service calls remain unavailable, and composition uses the public authority port | Native actor/action/evidence constraints and live workflow injection remain pending | | Selected POST callback | `pytest -q backend/tests/checkers/external/test_selected_post_submit.py`; Ruff and `git diff --check` on the affected files | 3 passed; actual Submission/ART identity reaches every locked POST image through its short-lived grant, work pass/fail remains evidence only, and infrastructure failure stays recoverable | Durable POST reservation/finalization, worker restart and routing composition remain pending | +| Selected durable POST contract | `pytest -q backend/tests/checkers/external/test_selected_post_submit.py`; Ruff and `git diff --check` on the affected files | 4 passed; the request digest binds the exact approved POST policy, locked TASK context and native Submission/ART identity, while the result digest binds request/generation, ordered execution evidence or a closed recoverable infrastructure category without acceptance authority | The existing scheduler/materializer still needs to select this contract and persist it through restart/replay | | Owner/caller trace | PROJECT approval/activation, ART preparation/admission, TASK composition and CHECKERS dispatch | In progress | Persistence delta and migration ordinal await actual linear predecessor | | End-to-end replacement | Real PostgreSQL/MinIO/Rust public and worker journey | Not run | Implementation incomplete | diff --git a/backend/app/modules/checkers/api/selected_post_submit.py b/backend/app/modules/checkers/api/selected_post_submit.py index c8a8c3e12..e4b361c36 100644 --- a/backend/app/modules/checkers/api/selected_post_submit.py +++ b/backend/app/modules/checkers/api/selected_post_submit.py @@ -3,10 +3,82 @@ from __future__ import annotations from dataclasses import asdict, dataclass +from typing import Literal, Self from uuid import UUID +from pydantic import model_validator + from app.core.hashing import canonical_json_hash from app.modules.checkers.api.external import ExternalCheckerExecutionResult +from app.modules.checkers.api.external_policy import LockedExternalPostSubmitPolicy +from app.modules.checkers.api.post_submit import ExpectedPostSubmitContext +from app.modules.checkers.api.post_submit_catalogue import ( + ByteCount, + PostSubmitValue, + ResourceId, + Sha256, + VersionNumber, +) + + +class SelectedPostSubmissionContent(PostSubmitValue): + """Approved POST image policy plus the exact locked TASK context.""" + + project_id: ResourceId + expected_context: ExpectedPostSubmitContext + policy: LockedExternalPostSubmitPolicy + + @model_validator(mode="after") + def validate_content(self) -> Self: + """Require the exact approved policy digest stamped on the Submission.""" + if self.expected_context.post_policy_hash != self.policy.policy_sha256: + raise ValueError("selected POST locked policy mismatch") + return self + + +class SelectedPostSubmissionEvaluationRequest(SelectedPostSubmissionContent): + """Hash-bound selected POST request reserved with one immutable Submission.""" + + schema_version: Literal["workstream.selected_post_submit_request.v1"] = ( + "workstream.selected_post_submit_request.v1" + ) + evaluation_request_id: ResourceId + evaluation_generation: VersionNumber + task_id: ResourceId + assignment_id: ResourceId + submission_id: ResourceId + submission_version: VersionNumber + content_id: ResourceId + binding_id: ResourceId + content_sha256: Sha256 + byte_count: ByteCount + request_sha256: Sha256 + + @model_validator(mode="after") + def validate_request(self) -> Self: + """Bind the entire selected policy and native Submission identity.""" + expected = canonical_json_hash( + self.model_dump(mode="json", exclude={"request_sha256"}) + ) + if self.request_sha256 != expected: + raise ValueError("selected POST request digest mismatch") + return self + + +def make_selected_post_submit_request( + **fields: object, +) -> SelectedPostSubmissionEvaluationRequest: + """Derive the selected request identity before strict validation.""" + if "request_sha256" in fields: + raise ValueError("selected POST request identity is derived") + candidate = SelectedPostSubmissionEvaluationRequest.model_construct( + **fields, + request_sha256="sha256:" + "0" * 64, + ) + fields["request_sha256"] = canonical_json_hash( + candidate.model_dump(mode="json", exclude={"request_sha256"}) + ) + return SelectedPostSubmissionEvaluationRequest.model_validate(fields) @dataclass(frozen=True, slots=True) @@ -100,6 +172,82 @@ def result_digest(self) -> str: return canonical_json_hash(self.canonical_body()) +class SelectedPostSubmissionEvaluationResult(PostSubmitValue): + """Durable selected POST evidence envelope with no acceptance authority.""" + + schema_version: Literal["workstream.selected_post_submit_result.v1"] = ( + "workstream.selected_post_submit_result.v1" + ) + request_id: ResourceId + request_digest: Sha256 + attempt_id: ResourceId + evaluation_generation: VersionNumber + result_id: ResourceId + result_digest: Sha256 + outcome: Literal["completed", "infrastructure_failed"] + execution: SelectedPostSubmitExecutionFacts | None + infrastructure_failure_code: ( + Literal[ + "capacity_exceeded", + "deadline_exceeded", + "material_unavailable", + "implementation_unavailable", + "invalid_output", + ] + | None + ) = None + + @model_validator(mode="after") + def validate_result(self) -> Self: + """Separate complete external evidence from recoverable infrastructure.""" + if self.outcome == "completed": + if self.execution is None or self.infrastructure_failure_code is not None: + raise ValueError("selected POST completed result is invalid") + elif self.execution is not None or self.infrastructure_failure_code is None: + raise ValueError("selected POST infrastructure result is invalid") + if self.result_digest != canonical_json_hash( + self.model_dump(mode="json", exclude={"result_digest"}) + ): + raise ValueError("selected POST result digest mismatch") + return self + + def validate_request( + self, request: SelectedPostSubmissionEvaluationRequest + ) -> None: + """Bind result identity and selected policy without claiming currentness.""" + result = SelectedPostSubmissionEvaluationResult.model_validate(self) + request = SelectedPostSubmissionEvaluationRequest.model_validate(request) + if ( + result.request_id, + result.request_digest, + result.evaluation_generation, + ) != ( + request.evaluation_request_id, + request.request_sha256, + request.evaluation_generation, + ) or ( + result.execution is not None + and result.execution.policy_sha256 != request.policy.policy_sha256 + ): + raise ValueError("selected POST result request mismatch") + + +def make_selected_post_submit_result( + **fields: object, +) -> SelectedPostSubmissionEvaluationResult: + """Derive the selected result identity before strict validation.""" + if "result_digest" in fields: + raise ValueError("selected POST result identity is derived") + candidate = SelectedPostSubmissionEvaluationResult.model_construct( + **fields, + result_digest="sha256:" + "0" * 64, + ) + fields["result_digest"] = canonical_json_hash( + candidate.model_dump(mode="json", exclude={"result_digest"}) + ) + return SelectedPostSubmissionEvaluationResult.model_validate(fields) + + class SelectedPostSubmitInfrastructureUnavailable(RuntimeError): """Retain a recoverable POST infrastructure category, never a work verdict.""" @@ -121,4 +269,9 @@ def __init__(self, code: str) -> None: "ExternalPostSubmitMemberFacts", "SelectedPostSubmitExecutionFacts", "SelectedPostSubmitInfrastructureUnavailable", + "SelectedPostSubmissionContent", + "SelectedPostSubmissionEvaluationRequest", + "SelectedPostSubmissionEvaluationResult", + "make_selected_post_submit_request", + "make_selected_post_submit_result", ) diff --git a/backend/tests/checkers/external/test_selected_post_submit.py b/backend/tests/checkers/external/test_selected_post_submit.py index c2d144415..670555011 100644 --- a/backend/tests/checkers/external/test_selected_post_submit.py +++ b/backend/tests/checkers/external/test_selected_post_submit.py @@ -27,6 +27,12 @@ from app.modules.checkers.selected_post_submit_execution import ( SelectedPostSubmitProcessor, ) +from app.modules.checkers.api.post_submit import ExpectedPostSubmitContext +from app.modules.checkers.api.selected_post_submit import ( + make_selected_post_submit_request, + make_selected_post_submit_result, +) +from app.core.identifiers import new_record_id from tests.checkers.external.support import ( SHA, execution_identity, @@ -164,3 +170,80 @@ async def test_selected_post_separates_infrastructure_from_work_findings() -> No identity=identity, execution=_Execution(outcome="infrastructure_failed"), ).evaluate(object(), _MaterialView(execution_material(identity))) + + +@pytest.mark.asyncio +async def test_selected_post_request_and_result_bind_exact_locked_policy() -> None: + identity = execution_identity("post_submit") + policy = _policy() + context = ExpectedPostSubmitContext( + guide_version="guide-v1", + source_id=new_record_id(), + source_hash=SHA, + effective_policy_id=new_record_id(), + effective_policy_hash=SHA, + pre_policy_id=new_record_id(), + pre_policy_hash=SHA, + post_policy_id=new_record_id(), + post_policy_version="guide-v1", + post_policy_hash=policy.policy_sha256, + review_policy_id=new_record_id(), + review_generation=1, + review_hash=SHA, + revision_policy_id=new_record_id(), + revision_generation=1, + revision_hash=SHA, + ) + request = make_selected_post_submit_request( + project_id=identity.project_id, + expected_context=context, + policy=policy, + evaluation_request_id=identity.evaluation_request_id, + evaluation_generation=identity.evaluation_generation, + task_id=identity.task_id, + assignment_id=identity.assignment_id, + submission_id=identity.submission_id, + submission_version=identity.submission_version, + content_id=new_record_id(), + binding_id=new_record_id(), + content_sha256=SHA, + byte_count=42, + ) + execution = await SelectedPostSubmitProcessor( + policy=policy, + identity=identity, + execution=_Execution(), + ).evaluate(request, _MaterialView(execution_material(identity))) + result = make_selected_post_submit_result( + request_id=request.evaluation_request_id, + request_digest=request.request_sha256, + attempt_id=identity.attempt_id, + evaluation_generation=request.evaluation_generation, + result_id=identity.result_id, + outcome="completed", + execution=execution, + infrastructure_failure_code=None, + ) + + result.validate_request(request) + empty_policy = LockedExternalPostSubmitPolicy( + entries=(), + policy_sha256=canonical_json_hash( + { + "schema_version": "external_post_submit_policy.v1", + "entries": [], + } + ), + ) + with pytest.raises(ValueError, match="request mismatch"): + result.validate_request( + make_selected_post_submit_request( + **request.model_dump( + exclude={"request_sha256", "policy", "expected_context"}, + ), + policy=empty_policy, + expected_context=context.model_copy( + update={"post_policy_hash": empty_policy.policy_sha256} + ), + ) + ) From 82b2e5aa5cfa9e5fbb80c36a4ba2067e42f73b50 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 20:41:29 +0100 Subject: [PATCH 075/283] [PILOT-04] Separate selected POST policy identity --- .../pilot04-workstream-default-checker.md | 2 +- backend/app/adapters/checkers/__init__.py | 38 +++++++++++++++ backend/app/adapters/tasks/__init__.py | 12 ++++- .../checkers/api/selected_post_submit.py | 30 ++++++++++-- .../modules/tasks/submission_participants.py | 15 ++++++ .../external/test_selected_post_submit.py | 46 ++++++++++++++++--- 6 files changed, 131 insertions(+), 12 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 14ed6019a..578ea9d20 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -209,7 +209,7 @@ intermediate-wait regression. | Selected lease execution boundary | `pytest -q backend/tests/checkers/external/test_selected_pre_submit_coordination.py backend/tests/checkers/external/test_selected_pre_submit_service.py backend/tests/checkers/external/test_selected_pre_submit.py backend/tests/architecture/test_module_boundaries.py`; focused Ruff | 49 passed; fixed-service preparation precedes owner locks, the lease commits before material execution, execution occurs with no root open, and exact lease/result digests are consumed in a separate finalization root | Native SQL custody and live admission selection remain pending | | Selected PRE authority contract | `pytest -q backend/tests/authorization/pre_submit/test_contracts.py backend/tests/authorization/test_catalogue.py backend/tests/checkers/external/test_selected_pre_submit_service.py backend/tests/architecture/test_module_boundaries.py`; focused Ruff and `git diff --check` | 50 passed; one dedicated service identity owns only execute/finalize, prepared selectors bind project/run/request, exact phase facts bind the decision and audit digest, direct service calls remain unavailable, and composition uses the public authority port | Native actor/action/evidence constraints and live workflow injection remain pending | | Selected POST callback | `pytest -q backend/tests/checkers/external/test_selected_post_submit.py`; Ruff and `git diff --check` on the affected files | 3 passed; actual Submission/ART identity reaches every locked POST image through its short-lived grant, work pass/fail remains evidence only, and infrastructure failure stays recoverable | Durable POST reservation/finalization, worker restart and routing composition remain pending | -| Selected durable POST contract | `pytest -q backend/tests/checkers/external/test_selected_post_submit.py`; Ruff and `git diff --check` on the affected files | 4 passed; the request digest binds the exact approved POST policy, locked TASK context and native Submission/ART identity, while the result digest binds request/generation, ordered execution evidence or a closed recoverable infrastructure category without acceptance authority | The existing scheduler/materializer still needs to select this contract and persist it through restart/replay | +| Selected durable POST contract | `pytest -q backend/tests/checkers/external/test_selected_post_submit.py backend/tests/test_submission_bundle_admission.py`; Ruff and `git diff --check` on the affected files | 56 passed; the request digest binds the exact approved selected policy, separately named locked TASK context and native Submission/ART identity, while the result digest binds request/generation, ordered execution evidence or a closed recoverable infrastructure category without acceptance authority; a legacy catalogue hash cannot stand in for the selected image-policy digest | The existing scheduler/materializer still needs to select this contract and persist it through restart/replay | | Owner/caller trace | PROJECT approval/activation, ART preparation/admission, TASK composition and CHECKERS dispatch | In progress | Persistence delta and migration ordinal await actual linear predecessor | | End-to-end replacement | Real PostgreSQL/MinIO/Rust public and worker journey | Not run | Implementation incomplete | diff --git a/backend/app/adapters/checkers/__init__.py b/backend/app/adapters/checkers/__init__.py index bcf47e560..2adee56ef 100644 --- a/backend/app/adapters/checkers/__init__.py +++ b/backend/app/adapters/checkers/__init__.py @@ -18,6 +18,11 @@ PostSubmissionEvaluationContent, ExpectedPostSubmitContext, ObservedPostSubmitContext, PostSubmitPolicyInputs, PostSubmissionStructuralInput, PostSubmitManifestEntry, PostSubmitEvidenceEntry, ) +from app.modules.checkers.api.external_policy import LockedExternalPostSubmitPolicy +from app.modules.checkers.api.selected_post_submit import ( + SelectedPostSubmissionContent, + SelectedPostSubmitLockedContext, +) from app.modules.checkers.api.history import CheckerHistoryReadPort from app.modules.checkers.api.execution import EvaluationCoordinationPort from typing import Any, BinaryIO, Protocol @@ -347,6 +352,39 @@ def submission_evaluation_content( ) +def selected_submission_evaluation_content( + task_context: TaskSubmissionContextFacts, + policy: LockedExternalPostSubmitPolicy, +) -> SelectedPostSubmissionContent: + """Bind selected POST policy to exact TASK lineage without a catalogue hash.""" + locked = task_context.locked_policy + references = task_context.locked_project_context + return SelectedPostSubmissionContent( + project_id=references.project_id, + expected_context=SelectedPostSubmitLockedContext( + guide_version=locked.locked_guide_version, + source_id=locked.locked_guide_source_snapshot_id, + source_hash=locked.locked_guide_source_snapshot_hash, + effective_policy_id=( + locked.locked_effective_project_submission_artifact_policy_id + ), + effective_policy_hash=( + locked.locked_effective_project_submission_artifact_policy_hash + ), + pre_policy_id=locked.locked_pre_submit_checker_policy_id, + pre_policy_hash=locked.locked_pre_submit_checker_bundle_hash, + selected_post_policy_hash=policy.policy_sha256, + review_policy_id=locked.locked_review_policy_id, + review_generation=locked.locked_review_policy_generation, + review_hash=locked.locked_review_policy_hash, + revision_policy_id=locked.locked_revision_policy_id, + revision_generation=locked.locked_revision_policy_generation, + revision_hash=locked.locked_revision_policy_hash, + ), + policy=policy, + ) + + def delivery_bound_post_submission_executor(*, sessions, materialization, envelope, request): """Add invocation custody to the existing executor without registering delivery.""" from app.adapters.auth import post_submit_execution_authority diff --git a/backend/app/adapters/tasks/__init__.py b/backend/app/adapters/tasks/__init__.py index 479014717..a9d9502b4 100644 --- a/backend/app/adapters/tasks/__init__.py +++ b/backend/app/adapters/tasks/__init__.py @@ -184,7 +184,10 @@ async def consume( if (result.binding_id is None or result.status != "consumed" or result.material is None or result.binding_decision_id is None): raise RuntimeError("admission did not produce a binding") - from app.adapters.checkers import submission_evaluation_content + from app.adapters.checkers import ( + selected_submission_evaluation_content, + submission_evaluation_content, + ) from app.modules.checkers.api.external_policy import ( LockedExternalPostSubmitPolicy, ) @@ -205,6 +208,13 @@ async def consume( result.material.files, result.material.archive_sha256, ), selected_post_submit_policy=selected_post_policy, + selected_evaluation_content=( + selected_submission_evaluation_content( + request.task_context, selected_post_policy + ) + if selected_post_policy is not None + else None + ), ) async def read_consumed(self, request: SubmissionArtifactReplayRequest) -> SubmissionArtifactBindingFacts: diff --git a/backend/app/modules/checkers/api/selected_post_submit.py b/backend/app/modules/checkers/api/selected_post_submit.py index e4b361c36..26e5dabea 100644 --- a/backend/app/modules/checkers/api/selected_post_submit.py +++ b/backend/app/modules/checkers/api/selected_post_submit.py @@ -6,12 +6,11 @@ from typing import Literal, Self from uuid import UUID -from pydantic import model_validator +from pydantic import Field, model_validator from app.core.hashing import canonical_json_hash from app.modules.checkers.api.external import ExternalCheckerExecutionResult from app.modules.checkers.api.external_policy import LockedExternalPostSubmitPolicy -from app.modules.checkers.api.post_submit import ExpectedPostSubmitContext from app.modules.checkers.api.post_submit_catalogue import ( ByteCount, PostSubmitValue, @@ -21,17 +20,39 @@ ) +class SelectedPostSubmitLockedContext(PostSubmitValue): + """Exact TASK and selected-policy lineage carried by a new Submission.""" + + guide_version: str = Field(min_length=1, max_length=50) + source_id: ResourceId + source_hash: Sha256 + effective_policy_id: ResourceId + effective_policy_hash: Sha256 + pre_policy_id: ResourceId + pre_policy_hash: Sha256 + selected_post_policy_hash: Sha256 + review_policy_id: ResourceId + review_generation: VersionNumber + review_hash: Sha256 + revision_policy_id: ResourceId + revision_generation: VersionNumber + revision_hash: Sha256 + + class SelectedPostSubmissionContent(PostSubmitValue): """Approved POST image policy plus the exact locked TASK context.""" project_id: ResourceId - expected_context: ExpectedPostSubmitContext + expected_context: SelectedPostSubmitLockedContext policy: LockedExternalPostSubmitPolicy @model_validator(mode="after") def validate_content(self) -> Self: """Require the exact approved policy digest stamped on the Submission.""" - if self.expected_context.post_policy_hash != self.policy.policy_sha256: + if ( + self.expected_context.selected_post_policy_hash + != self.policy.policy_sha256 + ): raise ValueError("selected POST locked policy mismatch") return self @@ -269,6 +290,7 @@ def __init__(self, code: str) -> None: "ExternalPostSubmitMemberFacts", "SelectedPostSubmitExecutionFacts", "SelectedPostSubmitInfrastructureUnavailable", + "SelectedPostSubmitLockedContext", "SelectedPostSubmissionContent", "SelectedPostSubmissionEvaluationRequest", "SelectedPostSubmissionEvaluationResult", diff --git a/backend/app/modules/tasks/submission_participants.py b/backend/app/modules/tasks/submission_participants.py index d7f7c3666..96079cc0c 100644 --- a/backend/app/modules/tasks/submission_participants.py +++ b/backend/app/modules/tasks/submission_participants.py @@ -7,6 +7,7 @@ from app.modules.checkers.api import SubmissionPacketView from app.modules.checkers.api.post_submit import PostSubmissionEvaluationContent from app.modules.checkers.api.external_policy import LockedExternalPostSubmitPolicy +from app.modules.checkers.api.selected_post_submit import SelectedPostSubmissionContent from app.modules.projects.api import ProjectLockedPolicyContextFacts from app.modules.tasks.api import TaskSubmissionContextFacts @@ -34,6 +35,20 @@ class SubmissionArtifactBindingFacts: class SubmissionArtifactAdmissionResult(SubmissionArtifactBindingFacts): evaluation_content: PostSubmissionEvaluationContent selected_post_submit_policy: LockedExternalPostSubmitPolicy | None = None + selected_evaluation_content: SelectedPostSubmissionContent | None = None + + def __post_init__(self) -> None: + """Require selected policy and its locked request content together.""" + if (self.selected_post_submit_policy is None) != ( + self.selected_evaluation_content is None + ): + raise ValueError("selected POST admission content is incomplete") + if ( + self.selected_evaluation_content is not None + and self.selected_evaluation_content.policy + != self.selected_post_submit_policy + ): + raise ValueError("selected POST admission policy differs") @dataclass(frozen=True, slots=True) diff --git a/backend/tests/checkers/external/test_selected_post_submit.py b/backend/tests/checkers/external/test_selected_post_submit.py index 670555011..fbe1bc8ee 100644 --- a/backend/tests/checkers/external/test_selected_post_submit.py +++ b/backend/tests/checkers/external/test_selected_post_submit.py @@ -3,9 +3,11 @@ from __future__ import annotations from contextlib import contextmanager +from types import SimpleNamespace import pytest +from app.adapters.checkers import selected_submission_evaluation_content from app.core.hashing import canonical_json_hash from app.interfaces.external_checker_execution import ( ExternalCheckerExecutionResponse, @@ -27,8 +29,8 @@ from app.modules.checkers.selected_post_submit_execution import ( SelectedPostSubmitProcessor, ) -from app.modules.checkers.api.post_submit import ExpectedPostSubmitContext from app.modules.checkers.api.selected_post_submit import ( + SelectedPostSubmitLockedContext, make_selected_post_submit_request, make_selected_post_submit_result, ) @@ -176,7 +178,7 @@ async def test_selected_post_separates_infrastructure_from_work_findings() -> No async def test_selected_post_request_and_result_bind_exact_locked_policy() -> None: identity = execution_identity("post_submit") policy = _policy() - context = ExpectedPostSubmitContext( + context = SelectedPostSubmitLockedContext( guide_version="guide-v1", source_id=new_record_id(), source_hash=SHA, @@ -184,9 +186,7 @@ async def test_selected_post_request_and_result_bind_exact_locked_policy() -> No effective_policy_hash=SHA, pre_policy_id=new_record_id(), pre_policy_hash=SHA, - post_policy_id=new_record_id(), - post_policy_version="guide-v1", - post_policy_hash=policy.policy_sha256, + selected_post_policy_hash=policy.policy_sha256, review_policy_id=new_record_id(), review_generation=1, review_hash=SHA, @@ -243,7 +243,41 @@ async def test_selected_post_request_and_result_bind_exact_locked_policy() -> No ), policy=empty_policy, expected_context=context.model_copy( - update={"post_policy_hash": empty_policy.policy_sha256} + update={ + "selected_post_policy_hash": empty_policy.policy_sha256 + } ), ) ) + + +def test_selected_post_content_uses_selected_digest_not_catalogue_hash() -> None: + policy = _policy() + locked = SimpleNamespace( + locked_guide_version="guide-v1", + locked_guide_source_snapshot_id=new_record_id(), + locked_guide_source_snapshot_hash=SHA, + locked_effective_project_submission_artifact_policy_id=new_record_id(), + locked_effective_project_submission_artifact_policy_hash=SHA, + locked_pre_submit_checker_policy_id=new_record_id(), + locked_pre_submit_checker_bundle_hash=SHA, + locked_post_submit_checker_policy_hash="sha256:" + "1" * 64, + locked_review_policy_id=new_record_id(), + locked_review_policy_generation=1, + locked_review_policy_hash=SHA, + locked_revision_policy_id=new_record_id(), + locked_revision_policy_generation=1, + locked_revision_policy_hash=SHA, + ) + task = SimpleNamespace( + locked_policy=locked, + locked_project_context=SimpleNamespace(project_id=new_record_id()), + ) + + content = selected_submission_evaluation_content(task, policy) + + assert content.expected_context.selected_post_policy_hash == policy.policy_sha256 + assert ( + content.expected_context.selected_post_policy_hash + != locked.locked_post_submit_checker_policy_hash + ) From d42661d3b9308f6736a984bf4984bf1499193436 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 20:51:40 +0100 Subject: [PATCH 076/283] [PILOT-04] Select external post-submit scheduler contracts --- .../pilot04-workstream-default-checker.md | 8 +- backend/app/adapters/checkers/__init__.py | 9 ++ backend/app/interfaces/project_agents.py | 5 +- .../artifacts/post_submit_materialization.py | 31 +++- .../post_submit_authorization.py | 6 +- backend/app/modules/checkers/api/__init__.py | 13 ++ .../modules/checkers/api/default_checker.py | 2 +- .../checkers/api/evaluation_contract.py | 47 ++++++ backend/app/modules/checkers/api/execution.py | 32 ++--- .../modules/checkers/api/external_policy.py | 21 +++ backend/app/modules/checkers/api/material.py | 18 +++ .../modules/checkers/api/materialization.py | 25 ++-- .../modules/checkers/api/output_custody.py | 6 +- .../app/modules/checkers/api/post_submit.py | 8 +- .../checkers/api/selected_post_submit.py | 3 + backend/app/modules/checkers/execution.py | 135 ++++++++++++++++-- .../checkers/execution_coordination.py | 51 +++++-- .../modules/checkers/execution_repository.py | 60 ++++++-- .../app/modules/checkers/execution_results.py | 26 +++- backend/app/modules/checkers/models.py | 2 + .../app/modules/tasks/api/submitted_bundle.py | 2 + backend/app/modules/tasks/models.py | 2 + .../post_submit_routing/evaluation_guard.py | 36 ++++- .../modules/tasks/submission_composition.py | 38 ++++- backend/app/modules/tasks/submitted_bundle.py | 8 ++ .../external/test_selected_post_submit.py | 5 + 26 files changed, 500 insertions(+), 99 deletions(-) create mode 100644 backend/app/modules/checkers/api/evaluation_contract.py create mode 100644 backend/app/modules/checkers/api/material.py diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 578ea9d20..2829a1142 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -50,7 +50,12 @@ exact execute/finalize fact digest without granting direct service access. The selected POST processor consumes only actual Submission and ART material through the phase-typed callback grant, runs every locked POST image in order, and returns canonical evidence and observed isolation without any acceptance -or routing authority. Its durable worker and result store are not selected yet. +or routing authority. The existing CHECKERS scheduler now recognizes that +selected envelope alongside retained legacy evidence, derives its lease and +execution deadlines from the exact locked images, recomputes the ART-owned +manifest before execution, and retains the complete selected result for +restart/replay. Production outbox registration and the native SQL custody +extension remain unfinished. Production still uses the older pre/post catalogues. ## Bounded change @@ -210,6 +215,7 @@ intermediate-wait regression. | Selected PRE authority contract | `pytest -q backend/tests/authorization/pre_submit/test_contracts.py backend/tests/authorization/test_catalogue.py backend/tests/checkers/external/test_selected_pre_submit_service.py backend/tests/architecture/test_module_boundaries.py`; focused Ruff and `git diff --check` | 50 passed; one dedicated service identity owns only execute/finalize, prepared selectors bind project/run/request, exact phase facts bind the decision and audit digest, direct service calls remain unavailable, and composition uses the public authority port | Native actor/action/evidence constraints and live workflow injection remain pending | | Selected POST callback | `pytest -q backend/tests/checkers/external/test_selected_post_submit.py`; Ruff and `git diff --check` on the affected files | 3 passed; actual Submission/ART identity reaches every locked POST image through its short-lived grant, work pass/fail remains evidence only, and infrastructure failure stays recoverable | Durable POST reservation/finalization, worker restart and routing composition remain pending | | Selected durable POST contract | `pytest -q backend/tests/checkers/external/test_selected_post_submit.py backend/tests/test_submission_bundle_admission.py`; Ruff and `git diff --check` on the affected files | 56 passed; the request digest binds the exact approved selected policy, separately named locked TASK context and native Submission/ART identity, while the result digest binds request/generation, ordered execution evidence or a closed recoverable infrastructure category without acceptance authority; a legacy catalogue hash cannot stand in for the selected image-policy digest | The existing scheduler/materializer still needs to select this contract and persist it through restart/replay | +| Selected POST scheduler compatibility | `pytest -q backend/tests/checkers/external/test_selected_post_submit.py backend/tests/checkers/execution/test_results.py backend/tests/checkers/execution/test_completion_contract.py backend/tests/checkers/post_submit/test_request.py backend/tests/test_submission_bundle_admission.py`; focused Ruff | 82 passed; one discriminated owner accepts retained legacy and selected request/result envelopes, selected leases cover the ordered image budget and finalization margin, ART recomputes the selected manifest, and the exact result envelope remains the replay authority | Production outbox registration, native selected columns/constraints and live Rust worker proof remain pending | | Owner/caller trace | PROJECT approval/activation, ART preparation/admission, TASK composition and CHECKERS dispatch | In progress | Persistence delta and migration ordinal await actual linear predecessor | | End-to-end replacement | Real PostgreSQL/MinIO/Rust public and worker journey | Not run | Implementation incomplete | diff --git a/backend/app/adapters/checkers/__init__.py b/backend/app/adapters/checkers/__init__.py index 2adee56ef..16b702c43 100644 --- a/backend/app/adapters/checkers/__init__.py +++ b/backend/app/adapters/checkers/__init__.py @@ -373,6 +373,15 @@ def selected_submission_evaluation_content( ), pre_policy_id=locked.locked_pre_submit_checker_policy_id, pre_policy_hash=locked.locked_pre_submit_checker_bundle_hash, + retained_catalogue_policy_id=( + locked.locked_post_submit_checker_policy_id + ), + retained_catalogue_policy_version=( + locked.locked_post_submit_checker_policy_version + ), + retained_catalogue_policy_hash=( + locked.locked_post_submit_checker_policy_hash + ), selected_post_policy_hash=policy.policy_sha256, review_policy_id=locked.locked_review_policy_id, review_generation=locked.locked_review_policy_generation, diff --git a/backend/app/interfaces/project_agents.py b/backend/app/interfaces/project_agents.py index 7b2884ed8..4847c6532 100644 --- a/backend/app/interfaces/project_agents.py +++ b/backend/app/interfaces/project_agents.py @@ -26,7 +26,10 @@ ) from app.modules.projects.api.task_examples import ProjectGuideTaskExamples -from app.modules.checkers.api import PostSubmitCatalogue, PostSubmitDefinition +from app.modules.checkers.api.post_submit_catalogue import ( + PostSubmitCatalogue, + PostSubmitDefinition, +) from app.modules.checkers.api.pre_submit_catalogue import ( PreSubmissionCapabilityDefinition, PreSubmissionCapabilityProjection, diff --git a/backend/app/modules/artifacts/post_submit_materialization.py b/backend/app/modules/artifacts/post_submit_materialization.py index 2239b360a..5d65317a9 100644 --- a/backend/app/modules/artifacts/post_submit_materialization.py +++ b/backend/app/modules/artifacts/post_submit_materialization.py @@ -29,7 +29,13 @@ SubmissionArchiveRejectedError, ) from app.modules.artifacts.submission_manifest import build_submission_manifest -from app.modules.checkers.api import PostSubmissionEvaluationResult +from app.modules.checkers.api.evaluation_contract import ( + PostSubmissionExecutionResult, + validate_execution_result, +) +from app.modules.checkers.api.selected_post_submit import ( + SelectedPostSubmissionEvaluationRequest, +) from app.modules.checkers.api.execution import ( ExecuteFacts, CurrentExecutionPort, VerifiedMaterialFacts, CheckerExecutionUnavailable, ) @@ -196,7 +202,7 @@ def __init__( self._execution, self._materialization = execution, materialization self._media_type = media_type self._aborted = False - self._consumer_task: asyncio.Task[PostSubmissionEvaluationResult] | None = None + self._consumer_task: asyncio.Task[PostSubmissionExecutionResult] | None = None self._view: _MaterialView | None = None def abort(self) -> None: @@ -207,7 +213,7 @@ def abort(self) -> None: if self._consumer_task is not None: self._consumer_task.cancel() - async def process(self, reader, workspace) -> PostSubmissionEvaluationResult: + async def process(self, reader, workspace) -> PostSubmissionExecutionResult: """Project off-loop, validate callback output, and drain projection cleanup.""" projection = self._inspector._projected_tree(reader, workspace, expected=self._inspection) # The preparation owner shields and drains this entire operation, including @@ -222,7 +228,7 @@ async def process(self, reader, workspace) -> PostSubmissionEvaluationResult: materialization=self._materialization, media_type=self._media_type, ) self._consumer_task = asyncio.create_task(self._consumer.evaluate(self._request, self._view)) - result = PostSubmissionEvaluationResult.model_validate(await self._consumer_task) + result = validate_execution_result(await self._consumer_task) result.validate_request(self._request) return result finally: @@ -318,9 +324,20 @@ async def materialize( expected_files = tuple((entry.normalized_path, entry.sha256, entry.byte_count) for entry in manifest.entries if entry.entry_type is SubmissionArchiveEntryType.FILE) - supplied_files = tuple(sorted((entry.artifact, entry.hash, entry.size_bytes) - for entry in request.structural_input.manifest)) - if manifest.sha256 != selected.semantic_manifest_sha256 or supplied_files != expected_files: + supplied_files = ( + expected_files + if isinstance(request, SelectedPostSubmissionEvaluationRequest) + else tuple( + sorted( + (entry.artifact, entry.hash, entry.size_bytes) + for entry in request.structural_input.manifest + ) + ) + ) + if ( + manifest.sha256 != selected.semantic_manifest_sha256 + or supplied_files != expected_files + ): raise PostSubmissionMaterializationFailure("post_submit_material_manifest_mismatch") materialization_facts = self._authority_facts(facts, selected) evaluation = await self._preparation._process_prepared_submission( diff --git a/backend/app/modules/authorization/post_submit_authorization.py b/backend/app/modules/authorization/post_submit_authorization.py index bca98ef86..ccd301d23 100644 --- a/backend/app/modules/authorization/post_submit_authorization.py +++ b/backend/app/modules/authorization/post_submit_authorization.py @@ -20,7 +20,7 @@ from app.modules.checkers.api.materialization import ( PreparedMaterialization, PostSubmissionMaterializationUnavailable, ) -from app.modules.checkers.api.post_submit import PostSubmissionEvaluationRequest +from app.modules.checkers.api.evaluation_contract import validate_execution_request @contextmanager @@ -75,7 +75,7 @@ async def consume(self, facts): async def _prepare(session, action, request, *, execution=None): """Acquire fixed principal custody before any CHECKERS or ART feature locks.""" try: - PostSubmissionEvaluationRequest.model_validate_json(request.model_dump_json()) + validate_execution_request(request) prepare_values = post_submit_prepare_values(action, request, execution) except (AttributeError, ValueError, TypeError) as error: exception = PostSubmissionMaterializationUnavailable if action == MATERIALIZE else CheckerExecutionUnavailable @@ -105,7 +105,7 @@ def __init__(self, session): async def preflight(self, request): """Validate value shape; preparation admits and locks the live principal before owner access.""" - PostSubmissionEvaluationRequest.model_validate_json(request.model_dump_json()) + validate_execution_request(request) def prepare_execution(self, request): return _prepare(self._session, EXECUTE, request) diff --git a/backend/app/modules/checkers/api/__init__.py b/backend/app/modules/checkers/api/__init__.py index f2d393fce..a34f325a0 100644 --- a/backend/app/modules/checkers/api/__init__.py +++ b/backend/app/modules/checkers/api/__init__.py @@ -92,6 +92,15 @@ PostSubmitMemberResult, PostSubmitPolicyInputs, ) +from app.modules.checkers.api.selected_post_submit import ( + SelectedPostSubmissionContent, + SelectedPostSubmissionEvaluationRequest, + SelectedPostSubmissionEvaluationResult, + SelectedPostSubmitExecutionFacts, + SelectedPostSubmitLockedContext, + make_selected_post_submit_request, + make_selected_post_submit_result, +) __all__ += ( "CompiledPostSubmitPolicy", "EmptyPostSubmitConfiguration", "PostSubmitCatalogue", @@ -100,6 +109,10 @@ "PostSubmissionExecutionPort", "PostSubmissionStructuralInput", "PostSubmitCurrentResultReference", "PostSubmitEvidenceEntry", "PostSubmitManifestEntry", "PostSubmitMemberResult", "PostSubmitPolicyInputs", + "SelectedPostSubmissionContent", "SelectedPostSubmissionEvaluationRequest", + "SelectedPostSubmissionEvaluationResult", "SelectedPostSubmitExecutionFacts", + "SelectedPostSubmitLockedContext", "make_selected_post_submit_request", + "make_selected_post_submit_result", ) __all__ += ( diff --git a/backend/app/modules/checkers/api/default_checker.py b/backend/app/modules/checkers/api/default_checker.py index 17bceaade..1256d97a4 100644 --- a/backend/app/modules/checkers/api/default_checker.py +++ b/backend/app/modules/checkers/api/default_checker.py @@ -9,7 +9,7 @@ from pydantic import BaseModel, ConfigDict, Field, model_validator from app.core.hashing import canonical_json_hash -from app.modules.checkers.api.materialization import SubmissionMaterialEntry +from app.modules.checkers.api.material import SubmissionMaterialEntry from app.modules.checkers.api.pre_submit import SubmissionPacketView diff --git a/backend/app/modules/checkers/api/evaluation_contract.py b/backend/app/modules/checkers/api/evaluation_contract.py new file mode 100644 index 000000000..5dcf82d6f --- /dev/null +++ b/backend/app/modules/checkers/api/evaluation_contract.py @@ -0,0 +1,47 @@ +"""Closed active and retained POST envelopes for the single execution owner.""" + +from __future__ import annotations + +from typing import Annotated, TypeAlias + +from pydantic import Field, TypeAdapter + +from app.modules.checkers.api.post_submit import ( + PostSubmissionEvaluationRequest, + PostSubmissionEvaluationResult, +) +from app.modules.checkers.api.selected_post_submit import ( + SelectedPostSubmissionEvaluationRequest, + SelectedPostSubmissionEvaluationResult, +) + + +PostSubmissionExecutionRequest: TypeAlias = Annotated[ + PostSubmissionEvaluationRequest | SelectedPostSubmissionEvaluationRequest, + Field(discriminator="schema_version"), +] +PostSubmissionExecutionResult: TypeAlias = Annotated[ + PostSubmissionEvaluationResult | SelectedPostSubmissionEvaluationResult, + Field(discriminator="schema_version"), +] + +_REQUEST = TypeAdapter(PostSubmissionExecutionRequest) +_RESULT = TypeAdapter(PostSubmissionExecutionResult) + + +def validate_execution_request(value: object) -> PostSubmissionExecutionRequest: + """Validate the selected writer or a retained legacy request by schema.""" + return _REQUEST.validate_python(value) + + +def validate_execution_result(value: object) -> PostSubmissionExecutionResult: + """Validate the selected writer or a retained legacy result by schema.""" + return _RESULT.validate_python(value) + + +__all__ = ( + "PostSubmissionExecutionRequest", + "PostSubmissionExecutionResult", + "validate_execution_request", + "validate_execution_result", +) diff --git a/backend/app/modules/checkers/api/execution.py b/backend/app/modules/checkers/api/execution.py index f42d69b68..4dc348672 100644 --- a/backend/app/modules/checkers/api/execution.py +++ b/backend/app/modules/checkers/api/execution.py @@ -9,11 +9,11 @@ from app.core.hashing import canonical_json_hash -from app.modules.checkers.api.post_submit import ( - PostSubmissionEvaluationRequest, - PostSubmissionEvaluationResult, - PostSubmitCurrentResultReference, +from app.modules.checkers.api.evaluation_contract import ( + PostSubmissionExecutionRequest, + PostSubmissionExecutionResult, ) +from app.modules.checkers.api.post_submit import PostSubmitCurrentResultReference from app.modules.checkers.api.post_submit_catalogue import ( PostSubmitValue, ResourceId, @@ -46,7 +46,7 @@ class EvaluationReservation(PostSubmitValue): class ReservedEvaluation(PostSubmitValue): """Exact retained request and identities, without a currentness assertion.""" - request: PostSubmissionEvaluationRequest + request: PostSubmissionExecutionRequest reservation: EvaluationReservation @@ -62,7 +62,7 @@ class ExecutionLease(PostSubmitValue): class ExecuteFacts(PostSubmitValue): """Exact request and lease consumed by execution authority.""" - request: PostSubmissionEvaluationRequest + request: PostSubmissionExecutionRequest lease: ExecutionLease @@ -83,7 +83,7 @@ class VerifiedMaterialFacts(PostSubmitValue): class FinalizeFacts(ExecuteFacts): """Exact terminal result and material custody consumed by finalization authority.""" - result: PostSubmissionEvaluationResult + result: PostSubmissionExecutionResult material: VerifiedMaterialFacts | None input_materialization_evidence_id: ResourceId | None output_binding_ids: tuple[ResourceId, ...] = Field(max_length=0) @@ -208,12 +208,12 @@ async def require_current_execution(self, facts: ExecuteFacts) -> None: class ExecutionAuthorityPort(Protocol): """Provide fresh authorization before acquiring an execution lease.""" - async def preflight(self, request: PostSubmissionEvaluationRequest) -> None: + async def preflight(self, request: PostSubmissionExecutionRequest) -> None: """Reject unavailable execution authority before entering preparation.""" ... def prepare_execution( - self, request: PostSubmissionEvaluationRequest + self, request: PostSubmissionExecutionRequest ) -> AbstractAsyncContextManager[PreparedExecution]: """Hold execution preparation within the caller transaction.""" ... @@ -222,12 +222,12 @@ def prepare_execution( class FinalizationAuthorityPort(Protocol): """Provide fresh authorization for atomic terminal publication.""" - async def preflight(self, request: PostSubmissionEvaluationRequest) -> None: + async def preflight(self, request: PostSubmissionExecutionRequest) -> None: """Reject unavailable finalization authority before preparation.""" ... def prepare_finalization( - self, request: PostSubmissionEvaluationRequest + self, request: PostSubmissionExecutionRequest ) -> AbstractAsyncContextManager[PreparedFinalization]: """Hold finalization preparation within the terminal transaction.""" ... @@ -238,13 +238,13 @@ class CompletedEvaluation(PostSubmitValue): reference: PostSubmitCurrentResultReference routing_recommendation: Literal["allow_review", "needs_revision", "task_setup_blocked"] - result: PostSubmissionEvaluationResult + result: PostSubmissionExecutionResult class EvaluationTaskGuard(Protocol): """TASK locks exact evaluation scope; the boolean is reservation eligibility, not authority.""" - async def lock_evaluation_scope(self, request: PostSubmissionEvaluationRequest) -> bool: + async def lock_evaluation_scope(self, request: PostSubmissionExecutionRequest) -> bool: """Hold TASK locks through commit; False forbids new reservations, not current reads.""" ... @@ -266,13 +266,13 @@ async def require_current_completion( ... async def reserve_current_evaluation( - self, request: PostSubmissionEvaluationRequest + self, request: PostSubmissionExecutionRequest ) -> EvaluationReservation: """Reserve or replay the exact request without committing the caller transaction.""" ... async def read_current_result( - self, request: PostSubmissionEvaluationRequest + self, request: PostSubmissionExecutionRequest ) -> CompletedEvaluation: """Lock and return the completed evaluation for the exact current request.""" ... @@ -298,7 +298,7 @@ class VerifiedEvaluationCompletion(PostSubmitValue): submission_version: VersionNumber material: VerifiedMaterialFacts input_materialization_evidence_id: ResourceId - result: PostSubmissionEvaluationResult + result: PostSubmissionExecutionResult @model_validator(mode="after") def bind_completed_result(self): diff --git a/backend/app/modules/checkers/api/external_policy.py b/backend/app/modules/checkers/api/external_policy.py index 09db92d63..8be1debdd 100644 --- a/backend/app/modules/checkers/api/external_policy.py +++ b/backend/app/modules/checkers/api/external_policy.py @@ -28,6 +28,9 @@ WORKSTREAM_DEFAULT_EXECUTION_BUDGET_MS = 60_000 MAXIMUM_SELECTED_PRE_EXECUTION_BUDGET_MS = 7_200_000 +SELECTED_POST_MATERIALIZATION_BUDGET_MS = 60_000 +MAXIMUM_SELECTED_POST_EXECUTION_BUDGET_MS = 3_600_000 +SELECTED_POST_FINALIZATION_MARGIN_MS = 60_000 class ExternalCheckerPolicyError(ValueError): @@ -289,3 +292,21 @@ def selected_pre_submit_execution_budget_ms( "selected PRE execution exceeds ART custody deadline" ) return required + + +def selected_post_submit_execution_budget_ms( + policy: LockedExternalPostSubmitPolicy, +) -> int: + """Bound ART materialization and every ordered POST image under one lease.""" + if type(policy) is not LockedExternalPostSubmitPolicy: + raise ExternalCheckerPolicyError("selected POST execution budget is invalid") + required = SELECTED_POST_MATERIALIZATION_BUDGET_MS + sum( + binding.registry.resources.deadline_ms + + EXTERNAL_CHECKER_EXECUTION_CLEANUP_MARGIN_MS + for binding in policy.entries + ) + if required > MAXIMUM_SELECTED_POST_EXECUTION_BUDGET_MS: + raise ExternalCheckerPolicyError( + "selected POST execution exceeds durable worker deadline" + ) + return required diff --git a/backend/app/modules/checkers/api/material.py b/backend/app/modules/checkers/api/material.py new file mode 100644 index 000000000..fea248eee --- /dev/null +++ b/backend/app/modules/checkers/api/material.py @@ -0,0 +1,18 @@ +"""Detached verified material metadata shared by PRE and POST contracts.""" + +from dataclasses import dataclass +from typing import Literal + + +@dataclass(frozen=True, slots=True) +class SubmissionMaterialEntry: + """Expose verified archive metadata without a filesystem path.""" + + normalized_path: str + entry_type: Literal["file", "directory"] + byte_count: int + sha256: str | None + executable: bool | None + + +__all__ = ("SubmissionMaterialEntry",) diff --git a/backend/app/modules/checkers/api/materialization.py b/backend/app/modules/checkers/api/materialization.py index d64f85a14..01707588b 100644 --- a/backend/app/modules/checkers/api/materialization.py +++ b/backend/app/modules/checkers/api/materialization.py @@ -3,16 +3,17 @@ from dataclasses import dataclass from abc import ABC, abstractmethod from contextlib import AbstractAsyncContextManager, AbstractContextManager -from typing import Literal, Protocol +from typing import Protocol from uuid import UUID from app.core.hashing import canonical_json_hash from app.modules.checkers.api.execution import ExecuteFacts, execution_authority_digest, VerifiedMaterialFacts +from app.modules.checkers.api.material import SubmissionMaterialEntry from app.modules.checkers.api.post_submit_catalogue import PostSubmitValue, ResourceId, Sha256, VersionNumber -from app.modules.checkers.api.post_submit import ( - PostSubmissionEvaluationRequest, - PostSubmissionEvaluationResult, +from app.modules.checkers.api.evaluation_contract import ( + PostSubmissionExecutionRequest, + PostSubmissionExecutionResult, ) from app.modules.checkers.api.external import ( ExternalCheckerExecutionRequest, @@ -88,16 +89,6 @@ def prepare_materialization(self, facts: ExecuteFacts) -> AbstractAsyncContextMa ... -@dataclass(frozen=True, slots=True) -class SubmissionMaterialEntry: - """Expose verified archive metadata without a filesystem path.""" - normalized_path: str - entry_type: Literal["file", "directory"] - byte_count: int - sha256: str | None - executable: bool | None - - class SubmissionMaterialView(Protocol): """Permit bounded reads only during the consumer callback.""" @@ -128,8 +119,8 @@ class ExternalCheckerGrantReference(Protocol): class PostSubmissionMaterialConsumer(Protocol): """Evaluate scoped input asynchronously and return detached phase facts.""" async def evaluate( - self, request: PostSubmissionEvaluationRequest, material: SubmissionMaterialView, - ) -> PostSubmissionEvaluationResult: + self, request: PostSubmissionExecutionRequest, material: SubmissionMaterialView, + ) -> PostSubmissionExecutionResult: """Return detached closed phase facts before ART revokes material access.""" @@ -146,7 +137,7 @@ class PostSubmissionMaterializationResult: content_sha256: str byte_count: int semantic_manifest_sha256: str - evaluation: PostSubmissionEvaluationResult + evaluation: PostSubmissionExecutionResult input_materialization_evidence_id: UUID diff --git a/backend/app/modules/checkers/api/output_custody.py b/backend/app/modules/checkers/api/output_custody.py index be8a9b36c..49cd75bd6 100644 --- a/backend/app/modules/checkers/api/output_custody.py +++ b/backend/app/modules/checkers/api/output_custody.py @@ -7,7 +7,7 @@ from pydantic import Field, StrictInt, model_validator -from app.modules.checkers.api.post_submit import PostSubmissionEvaluationRequest +from app.modules.checkers.api.evaluation_contract import PostSubmissionExecutionRequest from app.modules.checkers.api.post_submit_catalogue import ( Identifier, PostSubmitValue, @@ -23,7 +23,7 @@ class CheckerOutputUnavailable(RuntimeError): class CheckerOutputSelector(PostSubmitValue): """Select exact immutable evaluation and the caller's claimed execution lease.""" - evaluation: PostSubmissionEvaluationRequest + evaluation: PostSubmissionExecutionRequest checker_run_id: ResourceId worker_lease_id: ResourceId worker_lease_generation: VersionNumber @@ -41,7 +41,7 @@ class CheckerOutputSlot(PostSubmitValue): class CheckerOutputReservation(PostSubmitValue): """Detached owner facts, never a substitute for fresh action authority.""" - evaluation: PostSubmissionEvaluationRequest + evaluation: PostSubmissionExecutionRequest checker_run_id: ResourceId worker_lease_id: ResourceId worker_lease_generation: VersionNumber diff --git a/backend/app/modules/checkers/api/post_submit.py b/backend/app/modules/checkers/api/post_submit.py index afabaf787..181d87e61 100644 --- a/backend/app/modules/checkers/api/post_submit.py +++ b/backend/app/modules/checkers/api/post_submit.py @@ -323,10 +323,14 @@ class PostSubmitCurrentResultReference(PostSubmitValue): result_id: ResourceId result_digest: Sha256 - def validate_result(self, result: PostSubmissionEvaluationResult) -> None: + def validate_result(self, result: object) -> None: """Match exact completed result identity; the repository must prove currentness.""" self = PostSubmitCurrentResultReference.model_validate(self) - result = PostSubmissionEvaluationResult.model_validate(result) + from app.modules.checkers.api.evaluation_contract import ( + validate_execution_result, + ) + + result = validate_execution_result(result) names = ( "request_id", "request_digest", diff --git a/backend/app/modules/checkers/api/selected_post_submit.py b/backend/app/modules/checkers/api/selected_post_submit.py index 26e5dabea..18bce8080 100644 --- a/backend/app/modules/checkers/api/selected_post_submit.py +++ b/backend/app/modules/checkers/api/selected_post_submit.py @@ -30,6 +30,9 @@ class SelectedPostSubmitLockedContext(PostSubmitValue): effective_policy_hash: Sha256 pre_policy_id: ResourceId pre_policy_hash: Sha256 + retained_catalogue_policy_id: ResourceId + retained_catalogue_policy_version: str = Field(min_length=1, max_length=50) + retained_catalogue_policy_hash: Sha256 selected_post_policy_hash: Sha256 review_policy_id: ResourceId review_generation: VersionNumber diff --git a/backend/app/modules/checkers/execution.py b/backend/app/modules/checkers/execution.py index da9602541..348937157 100644 --- a/backend/app/modules/checkers/execution.py +++ b/backend/app/modules/checkers/execution.py @@ -2,6 +2,7 @@ import asyncio import json +import math from dataclasses import asdict from datetime import timedelta from uuid import UUID @@ -26,11 +27,26 @@ PreparedFinalization, VerifiedMaterialFacts, ) -from app.modules.checkers.api.post_submit import ( - PostSubmissionEvaluationRequest, - PostSubmissionEvaluationResult, - PostSubmitCurrentResultReference, +from app.modules.checkers.api.post_submit import PostSubmitCurrentResultReference +from app.modules.checkers.api.evaluation_contract import ( + PostSubmissionExecutionRequest, + PostSubmissionExecutionResult, + validate_execution_request, ) +from app.modules.checkers.api.external import PostSubmitExternalCheckerIdentity +from app.modules.checkers.api.external_policy import ( + SELECTED_POST_FINALIZATION_MARGIN_MS, + selected_post_submit_execution_budget_ms, +) +from app.modules.checkers.api.selected_post_submit import ( + SelectedPostSubmissionEvaluationRequest, + SelectedPostSubmitInfrastructureUnavailable, + make_selected_post_submit_result, +) +from app.modules.checkers.selected_post_submit_execution import ( + SelectedPostSubmitProcessor, +) +from app.interfaces.external_checker_execution import ExternalCheckerExecutionAdapter from app.modules.checkers.api.post_submit_catalogue import canonical_post_submit_bytes from app.modules.checkers.execution_repository import ( ExecutionRepository, @@ -129,6 +145,63 @@ async def evaluate(self, request, material): ) +class _SelectedExternalConsumer: + """Run the selected POST policy through the existing ART callback lifetime.""" + + def __init__( + self, + execution: ExternalCheckerExecutionAdapter, + lease: ExecutionLease, + ) -> None: + self._execution = execution + self._lease = lease + + async def evaluate(self, request, material): + request = SelectedPostSubmissionEvaluationRequest.model_validate(request) + reservation = self._lease.reservation + identity = PostSubmitExternalCheckerIdentity( + project_id=request.project_id, + task_id=request.task_id, + assignment_id=request.assignment_id, + submission_id=request.submission_id, + submission_version=request.submission_version, + evaluation_request_id=request.evaluation_request_id, + evaluation_request_digest=request.request_sha256, + evaluation_generation=request.evaluation_generation, + attempt_id=reservation.attempt_id, + result_id=reservation.result_id, + lease_id=self._lease.lease_id, + lease_generation=self._lease.lease_generation, + lease_expires_at=self._lease.expires_at, + ) + values = dict( + request_id=request.evaluation_request_id, + request_digest=request.request_sha256, + attempt_id=reservation.attempt_id, + evaluation_generation=request.evaluation_generation, + result_id=reservation.result_id, + ) + try: + execution = await SelectedPostSubmitProcessor( + policy=request.policy, + identity=identity, + execution=self._execution, + ).evaluate(request, material) + return make_selected_post_submit_result( + **values, + outcome="completed", + execution=execution, + infrastructure_failure_code=None, + ) + except SelectedPostSubmitInfrastructureUnavailable as exc: + return make_selected_post_submit_result( + **values, + outcome="infrastructure_failed", + execution=None, + infrastructure_failure_code=exc.code, + ) + + class PostSubmissionExecutor: """Own short execution transactions; all materialization happens outside them.""" @@ -140,12 +213,29 @@ def __init__( finalize_authority: Callable[[AsyncSession], FinalizationAuthorityPort], materialization: PostSubmissionMaterializationPort, registry: CheckerRegistry, + selected_execution: ExternalCheckerExecutionAdapter | None = None, outbox: Callable[[AsyncSession], OutboxAppendPort], ): """Receive explicit session, authority, materialization and publication ports.""" self._sessions = sessions self._execute_authority, self._finalize_authority = execute_authority, finalize_authority self._materialization, self._registry, self._outbox = materialization, registry, outbox + self._selected_execution = selected_execution + + @staticmethod + def _execution_budget_seconds(request: PostSubmissionExecutionRequest) -> int: + if isinstance(request, SelectedPostSubmissionEvaluationRequest): + return math.ceil(selected_post_submit_execution_budget_ms(request.policy) / 1000) + return EXECUTION_TIMEOUT_SECONDS + + def _consumer(self, request, lease): + if isinstance(request, SelectedPostSubmissionEvaluationRequest): + if self._selected_execution is None: + raise CheckerExecutionUnavailable( + "checker_external_execution_unavailable" + ) + return _SelectedExternalConsumer(self._selected_execution, lease) + return _StructuralConsumer(self._registry, lease) async def _claim(self, request): """Authorize replay or acquire the next database-timed lease atomically.""" @@ -179,11 +269,15 @@ async def _claim(self, request): now = await repo.now() if run.status == "running" and run.worker_lease_expires_at > now: raise CheckerExecutionUnavailable("checker_execution_lease_unavailable") + execution_seconds = self._execution_budget_seconds(request) + lease_seconds = execution_seconds + math.ceil( + SELECTED_POST_FINALIZATION_MARGIN_MS / 1000 + ) if isinstance(request, SelectedPostSubmissionEvaluationRequest) else LEASE_SECONDS lease = ExecutionLease( reservation=reservation(run), lease_id=new_record_id(), lease_generation=run.worker_lease_generation + 1, - expires_at=now + timedelta(seconds=LEASE_SECONDS), + expires_at=now + timedelta(seconds=lease_seconds), ) facts = ExecuteFacts(request=request, lease=lease) evidence_id = _evidence(await prepared.consume(facts), ExecuteEvidence, facts) @@ -197,19 +291,20 @@ async def _claim(self, request): return lease, None async def evaluate_post_submission( - self, request: PostSubmissionEvaluationRequest - ) -> PostSubmissionEvaluationResult: + self, request: PostSubmissionExecutionRequest + ) -> PostSubmissionExecutionResult: """Evaluate outside custody transactions, then separately authorize finalization.""" - request = PostSubmissionEvaluationRequest.model_validate(request) + request = validate_execution_request(request) lease, replay = await self._claim(request) if replay is not None: return await self.finalize(replay) material = None input_materialization_evidence_id = None try: - async with asyncio.timeout(EXECUTION_TIMEOUT_SECONDS): + async with asyncio.timeout(self._execution_budget_seconds(request)): materialized = await self._materialization.materialize( - ExecuteFacts(request=request, lease=lease), _StructuralConsumer(self._registry, lease) + ExecuteFacts(request=request, lease=lease), + self._consumer(request, lease), ) material = VerifiedMaterialFacts( **{ @@ -221,18 +316,30 @@ async def evaluate_post_submission( input_materialization_evidence_id = materialized.input_materialization_evidence_id result = materialized.evaluation except (TimeoutError, PostSubmissionMaterializationFailure) as error: - result = make_post_submit_result( + values = dict( request_id=request.evaluation_request_id, request_digest=request.request_sha256, attempt_id=lease.reservation.attempt_id, result_id=lease.reservation.result_id, evaluation_generation=request.evaluation_generation, outcome="infrastructure_failed", - member_results=(), infrastructure_failure_code=( - "deadline_exceeded" if isinstance(error, TimeoutError) else "material_unavailable" + "deadline_exceeded" + if isinstance(error, TimeoutError) + else "material_unavailable" ), ) + result = ( + make_selected_post_submit_result( + **values, + execution=None, + ) + if isinstance(request, SelectedPostSubmissionEvaluationRequest) + else make_post_submit_result( + **values, + member_results=(), + ) + ) return await self.finalize( FinalizeFacts( request=request, @@ -244,7 +351,7 @@ async def evaluate_post_submission( ) ) - async def finalize(self, facts: FinalizeFacts) -> PostSubmissionEvaluationResult: + async def finalize(self, facts: FinalizeFacts) -> PostSubmissionExecutionResult: """Fresh phase-specific PREP and one atomic terminal/member/outbox commit.""" facts = FinalizeFacts.model_validate(facts) request, result = facts.request, facts.result diff --git a/backend/app/modules/checkers/execution_coordination.py b/backend/app/modules/checkers/execution_coordination.py index d29bd5dfd..f22da8078 100644 --- a/backend/app/modules/checkers/execution_coordination.py +++ b/backend/app/modules/checkers/execution_coordination.py @@ -19,9 +19,13 @@ VerifiedMaterialFacts, VerifiedEvaluationCompletion, ) -from app.modules.checkers.api.post_submit import ( - PostSubmissionEvaluationRequest, - PostSubmitCurrentResultReference, +from app.modules.checkers.api.evaluation_contract import ( + PostSubmissionExecutionRequest, + validate_execution_request, +) +from app.modules.checkers.api.post_submit import PostSubmitCurrentResultReference +from app.modules.checkers.api.selected_post_submit import ( + SelectedPostSubmissionEvaluationRequest, ) from app.modules.checkers.api.output_custody import ( CheckerOutputReservation, @@ -49,10 +53,10 @@ def __init__(self, session: AsyncSession, *, tasks: EvaluationTaskGuard): self._tasks = tasks async def reserve_current_evaluation( - self, request: PostSubmissionEvaluationRequest + self, request: PostSubmissionExecutionRequest ) -> EvaluationReservation: """Serialize initial creation, exact replay and the next current generation.""" - request = PostSubmissionEvaluationRequest.model_validate(request) + request = validate_execution_request(request) with self._session.no_autoflush: can_create = await self._lock_task_scope(request) if not can_create: @@ -90,6 +94,7 @@ async def reserve_current_evaluation( if request.evaluation_generation != expected: raise CheckerRequestConflict("checker_generation_conflict") context = request.expected_context + selected = isinstance(request, SelectedPostSubmissionEvaluationRequest) run = CheckerRun( id=str(new_record_id()), project_id=str(request.project_id), @@ -109,9 +114,31 @@ async def reserve_current_evaluation( worker_lease_generation=0, supersedes_checker_run_id=prior.id if prior else None, locked_guide_version=context.guide_version, - locked_post_submit_checker_policy_id=str(context.post_policy_id), - locked_post_submit_checker_policy_version=context.post_policy_version, - locked_post_submit_checker_policy_hash=context.post_policy_hash, + locked_post_submit_checker_policy_id=str( + context.retained_catalogue_policy_id + if selected + else context.post_policy_id + ), + locked_post_submit_checker_policy_version=( + context.retained_catalogue_policy_version + if selected + else context.post_policy_version + ), + locked_post_submit_checker_policy_hash=( + context.retained_catalogue_policy_hash + if selected + else context.post_policy_hash + ), + selected_post_submit_policy_sha256=( + request.policy.policy_sha256 + if selected + else None + ), + selected_post_submit_policy_body=( + request.policy.model_dump(mode="json") + if selected + else None + ), locked_review_policy_id=str(context.review_policy_id), locked_review_policy_generation=context.review_generation, locked_review_policy_hash=context.review_hash, @@ -158,7 +185,7 @@ async def read_reserved_evaluation( raise CheckerExecutionUnavailable("checker_reservation_unavailable") return ReservedEvaluation(request=request, reservation=reservation(run)) - async def _lock_task_scope(self, request: PostSubmissionEvaluationRequest) -> bool: + async def _lock_task_scope(self, request: PostSubmissionExecutionRequest) -> bool: """Retain root-transaction TASK custody before any coordination fence lock.""" require_transaction(self._session) connection = await self._session.connection() @@ -176,7 +203,7 @@ async def _lock_task_scope(self, request: PostSubmissionEvaluationRequest) -> bo raise CheckerExecutionUnavailable("checker_reservation_scope_unavailable") return can_create - async def _replay(self, request: PostSubmissionEvaluationRequest) -> CheckerRun | None: + async def _replay(self, request: PostSubmissionExecutionRequest) -> CheckerRun | None: """Read an exact stored envelope; never repair or restore its current fence.""" replay = await self._session.scalar(select(CheckerRun).where( CheckerRun.evaluation_request_id == str(request.evaluation_request_id), @@ -190,10 +217,10 @@ async def _replay(self, request: PostSubmissionEvaluationRequest) -> CheckerRun return replay async def read_current_result( - self, request: PostSubmissionEvaluationRequest + self, request: PostSubmissionExecutionRequest ) -> CompletedEvaluation: """Return only a locked completed result matching the entire current request.""" - request = PostSubmissionEvaluationRequest.model_validate(request) + request = validate_execution_request(request) with self._session.no_autoflush: await self._lock_task_scope(request) run = await ExecutionRepository(self._session).lock_current(request) diff --git a/backend/app/modules/checkers/execution_repository.py b/backend/app/modules/checkers/execution_repository.py index b799d382f..9b705393c 100644 --- a/backend/app/modules/checkers/execution_repository.py +++ b/backend/app/modules/checkers/execution_repository.py @@ -13,9 +13,14 @@ EvaluationReservation, ExecutionLease, ) -from app.modules.checkers.api.post_submit import ( - PostSubmissionEvaluationRequest, - PostSubmissionEvaluationResult, +from app.modules.checkers.api.evaluation_contract import ( + PostSubmissionExecutionRequest, + PostSubmissionExecutionResult, + validate_execution_request, + validate_execution_result, +) +from app.modules.checkers.api.selected_post_submit import ( + SelectedPostSubmissionEvaluationResult, ) from app.modules.checkers.api.post_submit_catalogue import canonical_post_submit_bytes from app.modules.checkers.models import CheckerResult, CheckerRun, CheckerSubmissionFence @@ -27,7 +32,7 @@ def require_transaction(session: AsyncSession) -> None: raise CheckerExecutionUnavailable("checker_caller_transaction_required") -def request_text(request: PostSubmissionEvaluationRequest) -> str: +def request_text(request: PostSubmissionExecutionRequest) -> str: """Serialize canonical request facts without the separately stored digest.""" return canonical_post_submit_bytes(request, exclude={"request_sha256"}).decode("utf-8") @@ -43,20 +48,20 @@ def reservation(run: CheckerRun) -> EvaluationReservation: ) -def stored_request(run: CheckerRun) -> PostSubmissionEvaluationRequest: +def stored_request(run: CheckerRun) -> PostSubmissionExecutionRequest: """Reconstitute and validate the stored request with its digest.""" body = json.loads(run.request_json) body["request_sha256"] = run.request_digest - return PostSubmissionEvaluationRequest.model_validate_json(json.dumps(body)) + return validate_execution_request(body) -def stored_result(run: CheckerRun) -> PostSubmissionEvaluationResult: +def stored_result(run: CheckerRun) -> PostSubmissionExecutionResult: """Validate retained results against their stored request and run identities.""" if run.result_json is None or run.result_digest is None: raise CheckerExecutionUnavailable("checker_result_unavailable") body = json.loads(run.result_json) body["result_digest"] = run.result_digest - result = PostSubmissionEvaluationResult.model_validate_json(json.dumps(body)) + result = validate_execution_result(body) result.validate_request(stored_request(run)) if (str(result.attempt_id), str(result.result_id)) != (run.id, run.result_id): raise CheckerExecutionUnavailable("checker_result_unavailable") @@ -70,7 +75,7 @@ def __init__(self, session: AsyncSession): """Bind repository operations to the supplied transaction session.""" self.session = session - async def lock_current(self, request: PostSubmissionEvaluationRequest) -> CheckerRun: + async def lock_current(self, request: PostSubmissionExecutionRequest) -> CheckerRun: """Qualify stored owner facts before locking the single fence, then run.""" require_transaction(self.session) match = ( @@ -121,7 +126,7 @@ async def now(self) -> datetime: return await self.session.scalar(select(func.clock_timestamp())) async def require_lease( - self, request: PostSubmissionEvaluationRequest, lease: ExecutionLease + self, request: PostSubmissionExecutionRequest, lease: ExecutionLease ) -> CheckerRun: """Lock current custody and reject stale, expired or substituted leases.""" run = await self.lock_current(request) @@ -136,8 +141,41 @@ async def require_lease( raise CheckerExecutionUnavailable("checker_execution_lease_unavailable") return run - async def write_members(self, run: CheckerRun, result: PostSubmissionEvaluationResult) -> None: + async def write_members(self, run: CheckerRun, result: PostSubmissionExecutionResult) -> None: """Flush ordered closed results under the locked running parent.""" + if isinstance(result, SelectedPostSubmissionEvaluationResult): + for member in result.execution.external_members if result.execution else (): + self.session.add( + CheckerResult( + id=str(new_record_id()), + checker_run_id=run.id, + task_id=run.task_id, + submission_id=run.submission_id, + member_order=member.order, + checker_name=member.requirement_id, + definition_version=member.result.schema_version, + implementation_version=member.registry_entry_digest, + status=member.result.verdict or "infrastructure_failed", + code=( + "passed" + if member.result.verdict == "passed" + else member.result.findings[0].code + if member.result.findings + else "invalid_output" + ), + failure_category=( + "none" if member.result.verdict == "passed" else "submission_structure" + ), + severity=( + "info" + if member.result.verdict == "passed" + else "error" + ), + counters=[], + ) + ) + await self.session.flush() + return for order, member in enumerate(result.member_results): self.session.add( CheckerResult( diff --git a/backend/app/modules/checkers/execution_results.py b/backend/app/modules/checkers/execution_results.py index 68c7c0e35..87549cb6c 100644 --- a/backend/app/modules/checkers/execution_results.py +++ b/backend/app/modules/checkers/execution_results.py @@ -6,6 +6,14 @@ PostSubmissionEvaluationRequest, PostSubmissionEvaluationResult, ) +from app.modules.checkers.api.evaluation_contract import ( + PostSubmissionExecutionRequest, + PostSubmissionExecutionResult, +) +from app.modules.checkers.api.selected_post_submit import ( + SelectedPostSubmissionEvaluationRequest, + SelectedPostSubmissionEvaluationResult, +) @dataclass(frozen=True, slots=True) @@ -20,12 +28,28 @@ class ResultClassification: def classify_result( - request: PostSubmissionEvaluationRequest, result: PostSubmissionEvaluationResult + request: PostSubmissionExecutionRequest, result: PostSubmissionExecutionResult ) -> ResultClassification: """Validate every selected member before deriving policy-governed routing.""" result.validate_request(request) if result.outcome == "infrastructure_failed": return ResultClassification("not_evaluated", 0, 0, 0, 0) + if isinstance(request, SelectedPostSubmissionEvaluationRequest) and isinstance( + result, SelectedPostSubmissionEvaluationResult + ): + members = result.execution.external_members if result.execution else () + failed = sum(member.result.verdict == "failed" for member in members) + return ResultClassification( + "needs_revision" if failed else "allow_review", + sum(member.result.verdict == "passed" for member in members), + 0, + failed, + failed, + ) + if not isinstance(request, PostSubmissionEvaluationRequest) or not isinstance( + result, PostSubmissionEvaluationResult + ): + raise ValueError("post-submit request and result schemas differ") members = result.member_results blocking = tuple( m diff --git a/backend/app/modules/checkers/models.py b/backend/app/modules/checkers/models.py index 2d3f8ecd0..a062f1b14 100644 --- a/backend/app/modules/checkers/models.py +++ b/backend/app/modules/checkers/models.py @@ -287,6 +287,8 @@ class CheckerRun(Base): nullable=False, ) locked_post_submit_checker_policy_hash: Mapped[str] = mapped_column(String(71), nullable=False) + selected_post_submit_policy_sha256: Mapped[str | None] = mapped_column(String(71)) + selected_post_submit_policy_body: Mapped[dict | None] = mapped_column(JSON) locked_review_policy_id: Mapped[str] = mapped_column(Uuid(as_uuid=False), nullable=False) locked_review_policy_generation: Mapped[int] = mapped_column(Integer, nullable=False) locked_review_policy_hash: Mapped[str] = mapped_column(String(71), nullable=False) diff --git a/backend/app/modules/tasks/api/submitted_bundle.py b/backend/app/modules/tasks/api/submitted_bundle.py index e189c555f..dd8d149e9 100644 --- a/backend/app/modules/tasks/api/submitted_bundle.py +++ b/backend/app/modules/tasks/api/submitted_bundle.py @@ -31,6 +31,8 @@ class SubmittedPolicyContext: post_policy_id: UUID post_policy_version: str post_policy_hash: str + selected_post_policy_hash: str | None + selected_post_policy_body: dict | None review_policy_id: UUID review_generation: int review_hash: str diff --git a/backend/app/modules/tasks/models.py b/backend/app/modules/tasks/models.py index 32c550229..31fb00fca 100644 --- a/backend/app/modules/tasks/models.py +++ b/backend/app/modules/tasks/models.py @@ -592,6 +592,8 @@ class Submission(Base): ) locked_post_submit_checker_policy_hash: Mapped[str] = mapped_column(String(71), nullable=False) locked_post_submit_checker_policy_body: Mapped[dict] = mapped_column(JSON, nullable=False) + selected_post_submit_policy_sha256: Mapped[str | None] = mapped_column(String(71)) + selected_post_submit_policy_body: Mapped[dict | None] = mapped_column(JSON) locked_review_policy_id: Mapped[str] = mapped_column(Uuid(as_uuid=False), nullable=False) locked_review_policy_generation: Mapped[int] = mapped_column(Integer, nullable=False) locked_review_policy_hash: Mapped[str] = mapped_column(String(71), nullable=False) diff --git a/backend/app/modules/tasks/post_submit_routing/evaluation_guard.py b/backend/app/modules/tasks/post_submit_routing/evaluation_guard.py index 5777fb348..0f5d558fa 100644 --- a/backend/app/modules/tasks/post_submit_routing/evaluation_guard.py +++ b/backend/app/modules/tasks/post_submit_routing/evaluation_guard.py @@ -6,7 +6,10 @@ from sqlalchemy.ext.asyncio import AsyncSession from app.modules.checkers.api.execution import CheckerExecutionUnavailable -from app.modules.checkers.api.post_submit import PostSubmissionEvaluationRequest +from app.modules.checkers.api.evaluation_contract import PostSubmissionExecutionRequest +from app.modules.checkers.api.selected_post_submit import ( + SelectedPostSubmissionEvaluationRequest, +) from app.modules.tasks.api.submitted_bundle import SubmittedBundleRequest, SubmittedBundleUnavailable from app.modules.tasks.repository import TaskRepository from app.modules.tasks.submitted_bundle import SubmittedBundleReader @@ -19,7 +22,7 @@ def __init__(self, session: AsyncSession): self._repository = TaskRepository(session) self._submitted = SubmittedBundleReader(session) - async def lock_evaluation_scope(self, request: PostSubmissionEvaluationRequest) -> bool: + async def lock_evaluation_scope(self, request: PostSubmissionExecutionRequest) -> bool: """Return new-generation eligibility after exact Task/Assignment/Submission locks.""" task = await self._repository.lock_project_task(request.project_id, request.task_id) if task is None: @@ -46,13 +49,40 @@ async def lock_evaluation_scope(self, request: PostSubmissionEvaluationRequest) )) except SubmittedBundleUnavailable: raise CheckerExecutionUnavailable("checker_reservation_scope_unavailable") from None + observed = asdict(facts.context) + expected = request.expected_context.model_dump() + context_matches = expected == { + name: observed[name] for name in expected if name in observed + } + if isinstance(request, SelectedPostSubmissionEvaluationRequest): + context_matches = expected == { + "guide_version": observed["guide_version"], + "source_id": observed["source_id"], + "source_hash": observed["source_hash"], + "effective_policy_id": observed["effective_policy_id"], + "effective_policy_hash": observed["effective_policy_hash"], + "pre_policy_id": observed["pre_policy_id"], + "pre_policy_hash": observed["pre_policy_hash"], + "retained_catalogue_policy_id": observed["post_policy_id"], + "retained_catalogue_policy_version": observed["post_policy_version"], + "retained_catalogue_policy_hash": observed["post_policy_hash"], + "selected_post_policy_hash": observed["selected_post_policy_hash"], + "review_policy_id": observed["review_policy_id"], + "review_generation": observed["review_generation"], + "review_hash": observed["review_hash"], + "revision_policy_id": observed["revision_policy_id"], + "revision_generation": observed["revision_generation"], + "revision_hash": observed["revision_hash"], + } and observed["selected_post_policy_body"] == request.policy.model_dump( + mode="json" + ) if not ( facts.assignment_id == request.assignment_id and facts.submission_version == request.submission_version and facts.contributor_id == UUID(assignment.contributor_id) and facts.binding_id == request.binding_id and facts.content_id == request.content_id - and asdict(facts.context) == request.expected_context.model_dump() + and context_matches ): raise CheckerExecutionUnavailable("checker_reservation_scope_unavailable") if task.status in {"accepted", "rejected"}: diff --git a/backend/app/modules/tasks/submission_composition.py b/backend/app/modules/tasks/submission_composition.py index 179515c39..f99ebbcd1 100644 --- a/backend/app/modules/tasks/submission_composition.py +++ b/backend/app/modules/tasks/submission_composition.py @@ -33,6 +33,9 @@ from app.modules.tasks.lifecycle import ensure_allowed_transition from app.modules.checkers.api.execution import EvaluationCoordinationPort from app.modules.checkers.api.post_submit import make_post_submit_request +from app.modules.checkers.api.selected_post_submit import ( + make_selected_post_submit_request, +) from app.modules.outbox.api import OutboxAppendPort from app.modules.tasks.repository import TaskRepository from app.modules.tasks.service import TaskService @@ -197,18 +200,39 @@ async def create(self, request: SubmissionCreationRequest) -> SubmissionCreation submission.submission_bundle_admission_id = str(request.admission_id) submission.artifact_binding_id = str(consumed.binding_id) submission.artifact_content_id = str(consumed.content_id) + if consumed.selected_evaluation_content is not None: + submission.selected_post_submit_policy_sha256 = ( + consumed.selected_evaluation_content.policy.policy_sha256 + ) + submission.selected_post_submit_policy_body = ( + consumed.selected_evaluation_content.policy.model_dump(mode="json") + ) await self._session.flush() creation_decision_id = await self._authorization.consume(prepared_authorization, final) if not isinstance(creation_decision_id, UUID): raise SubmissionCreationUnavailable("submission creation is unavailable") - evaluation = make_post_submit_request( - **consumed.evaluation_content.model_dump(), - evaluation_request_id=new_record_id(), evaluation_generation=1, - task_id=request.task_id, assignment_id=request.assignment_id, - submission_id=submission_id, submission_version=version, - content_id=consumed.content_id, binding_id=consumed.binding_id, - content_sha256=consumed.archive_sha256, byte_count=consumed.byte_count, + request_fields = dict( + evaluation_request_id=new_record_id(), + evaluation_generation=1, + task_id=request.task_id, + assignment_id=request.assignment_id, + submission_id=submission_id, + submission_version=version, + content_id=consumed.content_id, + binding_id=consumed.binding_id, + content_sha256=consumed.archive_sha256, + byte_count=consumed.byte_count, ) + if consumed.selected_evaluation_content is not None: + evaluation = make_selected_post_submit_request( + **consumed.selected_evaluation_content.model_dump(), + **request_fields, + ) + else: + evaluation = make_post_submit_request( + **consumed.evaluation_content.model_dump(), + **request_fields, + ) ensure_allowed_transition(task.status, "submitted") task.status = "submitted" await self._session.flush() diff --git a/backend/app/modules/tasks/submitted_bundle.py b/backend/app/modules/tasks/submitted_bundle.py index 826da986f..7f22fde22 100644 --- a/backend/app/modules/tasks/submitted_bundle.py +++ b/backend/app/modules/tasks/submitted_bundle.py @@ -44,6 +44,8 @@ async def read(self, request: SubmittedBundleRequest) -> SubmittedBundleFacts: Submission.locked_post_submit_checker_policy_id, Submission.locked_post_submit_checker_policy_version, Submission.locked_post_submit_checker_policy_hash, + Submission.selected_post_submit_policy_sha256, + Submission.selected_post_submit_policy_body, Submission.locked_review_policy_id, Submission.locked_review_policy_generation, Submission.locked_review_policy_hash, @@ -75,6 +77,12 @@ async def read(self, request: SubmittedBundleRequest) -> SubmittedBundleFacts: post_policy_id=UUID(row["locked_post_submit_checker_policy_id"]), post_policy_version=row["locked_post_submit_checker_policy_version"], post_policy_hash=row["locked_post_submit_checker_policy_hash"], + selected_post_policy_hash=row[ + "selected_post_submit_policy_sha256" + ], + selected_post_policy_body=row[ + "selected_post_submit_policy_body" + ], review_policy_id=UUID(row["locked_review_policy_id"]), review_generation=row["locked_review_policy_generation"], review_hash=row["locked_review_policy_hash"], diff --git a/backend/tests/checkers/external/test_selected_post_submit.py b/backend/tests/checkers/external/test_selected_post_submit.py index fbe1bc8ee..6dd89b059 100644 --- a/backend/tests/checkers/external/test_selected_post_submit.py +++ b/backend/tests/checkers/external/test_selected_post_submit.py @@ -186,6 +186,9 @@ async def test_selected_post_request_and_result_bind_exact_locked_policy() -> No effective_policy_hash=SHA, pre_policy_id=new_record_id(), pre_policy_hash=SHA, + retained_catalogue_policy_id=new_record_id(), + retained_catalogue_policy_version="guide-v1", + retained_catalogue_policy_hash=SHA, selected_post_policy_hash=policy.policy_sha256, review_policy_id=new_record_id(), review_generation=1, @@ -262,6 +265,8 @@ def test_selected_post_content_uses_selected_digest_not_catalogue_hash() -> None locked_pre_submit_checker_policy_id=new_record_id(), locked_pre_submit_checker_bundle_hash=SHA, locked_post_submit_checker_policy_hash="sha256:" + "1" * 64, + locked_post_submit_checker_policy_id=new_record_id(), + locked_post_submit_checker_policy_version="guide-v1", locked_review_policy_id=new_record_id(), locked_review_policy_generation=1, locked_review_policy_hash=SHA, From 1a8337b4007127cf7e13e1a9961ec24d80fbe41b Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 20:57:21 +0100 Subject: [PATCH 077/283] [PILOT-04] Register selected post-submit delivery --- .../pilot04-workstream-default-checker.md | 8 +++- backend/app/adapters/artifacts/__init__.py | 10 +---- backend/app/adapters/checkers/__init__.py | 27 ++++++++++++- backend/app/adapters/outbox/__init__.py | 39 +++++++++++++++---- backend/app/adapters/tasks/__init__.py | 21 +++++++++- .../app/modules/tasks/evaluation_delivery.py | 8 ++-- .../tests/outbox/test_worker_postgresql.py | 8 +++- .../evaluation_delivery/test_delivery.py | 2 +- .../test_worker_materialization.py | 2 +- backend/tests/test_artifact_architecture.py | 24 ++++++++---- 10 files changed, 111 insertions(+), 38 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 2829a1142..644b5ef8a 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -54,8 +54,11 @@ or routing authority. The existing CHECKERS scheduler now recognizes that selected envelope alongside retained legacy evidence, derives its lease and execution deadlines from the exact locked images, recomputes the ART-owned manifest before execution, and retains the complete selected result for -restart/replay. Production outbox registration and the native SQL custody -extension remain unfinished. +restart/replay. The existing production outbox registry now owns the evaluation +request handler alongside assignment invalidation, leases worker-owned ART +material only during execution, and creates the configured Rust adapter only +for a selected request. Native SQL custody and the live worker journey remain +unfinished. Production still uses the older pre/post catalogues. ## Bounded change @@ -216,6 +219,7 @@ intermediate-wait regression. | Selected POST callback | `pytest -q backend/tests/checkers/external/test_selected_post_submit.py`; Ruff and `git diff --check` on the affected files | 3 passed; actual Submission/ART identity reaches every locked POST image through its short-lived grant, work pass/fail remains evidence only, and infrastructure failure stays recoverable | Durable POST reservation/finalization, worker restart and routing composition remain pending | | Selected durable POST contract | `pytest -q backend/tests/checkers/external/test_selected_post_submit.py backend/tests/test_submission_bundle_admission.py`; Ruff and `git diff --check` on the affected files | 56 passed; the request digest binds the exact approved selected policy, separately named locked TASK context and native Submission/ART identity, while the result digest binds request/generation, ordered execution evidence or a closed recoverable infrastructure category without acceptance authority; a legacy catalogue hash cannot stand in for the selected image-policy digest | The existing scheduler/materializer still needs to select this contract and persist it through restart/replay | | Selected POST scheduler compatibility | `pytest -q backend/tests/checkers/external/test_selected_post_submit.py backend/tests/checkers/execution/test_results.py backend/tests/checkers/execution/test_completion_contract.py backend/tests/checkers/post_submit/test_request.py backend/tests/test_submission_bundle_admission.py`; focused Ruff | 82 passed; one discriminated owner accepts retained legacy and selected request/result envelopes, selected leases cover the ordered image budget and finalization margin, ART recomputes the selected manifest, and the exact result envelope remains the replay authority | Production outbox registration, native selected columns/constraints and live Rust worker proof remain pending | +| Production delivery registration and owner boundaries | `pytest -q backend/tests/architecture/test_module_boundaries.py backend/tests/test_artifact_architecture.py backend/tests/outbox/test_contracts.py`; focused Ruff and a direct registry construction probe | 116 passed; the existing production outbox registry exposes assignment invalidation and evaluation request handlers, selected Rust configuration is lazy, and PRE coordination stays behind CHECKERS' public adapter root | Database-backed legacy/selected delivery and worker restart proofs remain pending | | Owner/caller trace | PROJECT approval/activation, ART preparation/admission, TASK composition and CHECKERS dispatch | In progress | Persistence delta and migration ordinal await actual linear predecessor | | End-to-end replacement | Real PostgreSQL/MinIO/Rust public and worker journey | Not run | Implementation incomplete | diff --git a/backend/app/adapters/artifacts/__init__.py b/backend/app/adapters/artifacts/__init__.py index 09d0f0344..b665ab0ff 100644 --- a/backend/app/adapters/artifacts/__init__.py +++ b/backend/app/adapters/artifacts/__init__.py @@ -424,13 +424,10 @@ async def runtime(): inspector = SubmissionArchiveInspector(submission_archive_limits(settings)) from app.adapters.auth import selected_pre_submit_authority from app.adapters.checkers import selected_pre_submit_checker_execution - from app.adapters.tasks import selected_pre_submit_task_guard from app.modules.artifacts.selected_pre_submit_execution import ( SelectedPreSubmitExecutionService, ) - from app.modules.checkers.selected_pre_submit_coordination import ( - SelectedPreSubmitCoordinator, - ) + from app.adapters.checkers import selected_pre_submit_coordinator checker_execution = selected_pre_submit_checker_execution( settings=settings, @@ -456,10 +453,7 @@ async def runtime(): settings, internal_authority, ) - selected_coordinator = SelectedPreSubmitCoordinator( - session, - tasks=selected_pre_submit_task_guard(session), - ) + selected_coordinator = selected_pre_submit_coordinator(session) yield SubmissionBundlePreparationRuntime( preparation=preparation, diff --git a/backend/app/adapters/checkers/__init__.py b/backend/app/adapters/checkers/__init__.py index 16b702c43..5e0486134 100644 --- a/backend/app/adapters/checkers/__init__.py +++ b/backend/app/adapters/checkers/__init__.py @@ -84,6 +84,13 @@ def configured_external_checker_execution_factory(settings): ) +def configured_external_checker_execution(settings): + """Create the sole configured Rust-service adapter for selected execution.""" + return configured_external_checker_execution_factory(settings).create( + EXTERNAL_CHECKER_PROVIDER_KEY + ) + + def selected_pre_submit_checker_execution(*, settings, archive_inspector): """Compose the sole selected PRE runtime from the configured Rust service.""" execution = configured_external_checker_execution_factory(settings).create( @@ -102,6 +109,19 @@ def external_checker_registry_reader(session): return ExternalCheckerRegistryReader(session) +def selected_pre_submit_coordinator(session): + """Compose selected PRE custody through CHECKERS' public adapter root.""" + from app.adapters.tasks import selected_pre_submit_task_guard + from app.modules.checkers.selected_pre_submit_coordination import ( + SelectedPreSubmitCoordinator, + ) + + return SelectedPreSubmitCoordinator( + session, + tasks=selected_pre_submit_task_guard(session), + ) + + class _ExecutionRequest(Protocol): plan: Any project_id: Any @@ -394,7 +414,9 @@ def selected_submission_evaluation_content( ) -def delivery_bound_post_submission_executor(*, sessions, materialization, envelope, request): +def delivery_bound_post_submission_executor( + *, sessions, materialization, envelope, request, selected_execution=None +): """Add invocation custody to the existing executor without registering delivery.""" from app.adapters.auth import post_submit_execution_authority from app.adapters.outbox import outbox_append, outbox_invocation_fence @@ -411,5 +433,6 @@ def authority(session): return PostSubmissionExecutor( sessions=sessions, execute_authority=authority, finalize_authority=authority, - materialization=materialization, registry=default_checker_registry(), outbox=outbox_append, + materialization=materialization, registry=default_checker_registry(), + selected_execution=selected_execution, outbox=outbox_append, ) diff --git a/backend/app/adapters/outbox/__init__.py b/backend/app/adapters/outbox/__init__.py index 36053137f..ad5fef55e 100644 --- a/backend/app/adapters/outbox/__init__.py +++ b/backend/app/adapters/outbox/__init__.py @@ -32,19 +32,42 @@ def outbox_delivery( def production_outbox_delivery(session_factory): - """Install the exact assignment handler with separate dispatcher and feature authority.""" + """Install exact assignment and selected evaluation handlers.""" + from app.adapters.artifacts import worker_post_submission_materialization from app.adapters.auth import outbox_dispatch_authorization, assignment_invalidation_authorization - from app.adapters.tasks import TransactionalAssignmentInvalidationHandler + from app.adapters.tasks import ( + TransactionalAssignmentInvalidationHandler, + evaluation_request_handler, + ) + from app.modules.checkers.api.execution import REQUEST_EVENT from app.modules.tasks.api.assignment_invalidation import ASSIGNMENT_INVALIDATION_EVENT return outbox_delivery( session_factory, authorization_factory=outbox_dispatch_authorization, - registry=HandlerRegistry([(ASSIGNMENT_INVALIDATION_EVENT, 1, - TransactionalAssignmentInvalidationHandler( - session_factory, observer=CommittedInvocationReader(session_factory), - authorization_factory=assignment_invalidation_authorization, - ), - )]), options=DeliveryOptions(), + registry=HandlerRegistry( + [ + ( + ASSIGNMENT_INVALIDATION_EVENT, + 1, + TransactionalAssignmentInvalidationHandler( + session_factory, + observer=CommittedInvocationReader(session_factory), + authorization_factory=assignment_invalidation_authorization, + ), + ), + ( + REQUEST_EVENT, + 1, + evaluation_request_handler( + sessions=session_factory, + materialization=worker_post_submission_materialization( + sessions=session_factory + ), + ), + ), + ] + ), + options=DeliveryOptions(), ) diff --git a/backend/app/adapters/tasks/__init__.py b/backend/app/adapters/tasks/__init__.py index a9d9502b4..412342c37 100644 --- a/backend/app/adapters/tasks/__init__.py +++ b/backend/app/adapters/tasks/__init__.py @@ -303,13 +303,30 @@ def validate_submission_policy_context(task_context: TaskSubmissionContextFacts, def evaluation_request_handler(*, sessions, materialization): """Compose one hidden TASK request handler; production registration is separate.""" - from app.adapters.checkers import evaluation_coordinator, delivery_bound_post_submission_executor + from app.adapters.checkers import ( + configured_external_checker_execution, + delivery_bound_post_submission_executor, + evaluation_coordinator, + ) from app.adapters.outbox import committed_invocation_reader + from app.core.config import get_settings + from app.modules.checkers.api.selected_post_submit import ( + SelectedPostSubmissionEvaluationRequest, + ) from app.modules.tasks.evaluation_delivery import EvaluationRequestHandler def executor(envelope, request): + selected_execution = ( + configured_external_checker_execution(get_settings()) + if isinstance(request, SelectedPostSubmissionEvaluationRequest) + else None + ) return delivery_bound_post_submission_executor( - sessions=sessions, materialization=materialization, envelope=envelope, request=request, + sessions=sessions, + materialization=materialization, + envelope=envelope, + request=request, + selected_execution=selected_execution, ) return EvaluationRequestHandler( diff --git a/backend/app/modules/tasks/evaluation_delivery.py b/backend/app/modules/tasks/evaluation_delivery.py index 146f1ef61..f6f7fb211 100644 --- a/backend/app/modules/tasks/evaluation_delivery.py +++ b/backend/app/modules/tasks/evaluation_delivery.py @@ -11,8 +11,8 @@ from app.modules.checkers.api.execution import ( CheckerExecutionUnavailable, EvaluationCoordinationPort, REQUEST_EVENT, ) -from app.modules.checkers.api.post_submit import ( - PostSubmissionEvaluationRequest, PostSubmissionExecutionPort, +from app.modules.checkers.api.evaluation_contract import ( + PostSubmissionExecutionRequest, ) from app.modules.outbox.api import ( CommittedInvocationPort, HandlerOutcome, OutboxEventEnvelope, @@ -31,7 +31,7 @@ class EvaluationDeliveryRequestReader: def __init__(self, session: AsyncSession, evaluations: EvaluationCoordinationPort): self._session, self._evaluations = session, evaluations - async def read(self, envelope: OutboxEventEnvelope) -> PostSubmissionEvaluationRequest: + async def read(self, envelope: OutboxEventEnvelope) -> PostSubmissionExecutionRequest: """Select all owner identifiers together, without creating or repairing rows.""" receipt = await self._session.scalar(select(SubmissionDispatch).where( SubmissionDispatch.project_id == str(envelope.claim.project_id), @@ -85,7 +85,7 @@ def __init__( self, sessions: async_sessionmaker[AsyncSession], *, observer: CommittedInvocationPort, evaluations: Callable[[AsyncSession], EvaluationCoordinationPort], - executor: Callable[[OutboxEventEnvelope, PostSubmissionEvaluationRequest], PostSubmissionExecutionPort], + executor: Callable[[OutboxEventEnvelope, PostSubmissionExecutionRequest], object], ): self._sessions, self._observer = sessions, observer self._evaluations, self._executor = evaluations, executor diff --git a/backend/tests/outbox/test_worker_postgresql.py b/backend/tests/outbox/test_worker_postgresql.py index e8a51c00c..b8963c3ed 100644 --- a/backend/tests/outbox/test_worker_postgresql.py +++ b/backend/tests/outbox/test_worker_postgresql.py @@ -187,13 +187,17 @@ def publish(*, args): assert attempts == [(str(cursor), str(selectors[0].project_id)), (str(cursor),)] -async def test_production_registry_claims_only_registered_invalidation(delivery_harness): +async def test_production_registry_claims_only_registered_features(delivery_harness): from app.adapters.outbox import production_outbox_delivery + from app.modules.checkers.api.execution import REQUEST_EVENT h = delivery_harness event = await h.append() production = production_outbox_delivery(h.factory) - assert production._registry.keys == (("TaskAssignmentAuthorityInvalidationRequested", 1),) + assert production._registry.keys == ( + ("TaskAssignmentAuthorityInvalidationRequested", 1), + (REQUEST_EVENT, 1), + ) assert (await production.candidates()).items == () assert await production.deliver(event.event_id, h.project, "worker") is None async with h.factory() as session: diff --git a/backend/tests/tasks/evaluation_delivery/test_delivery.py b/backend/tests/tasks/evaluation_delivery/test_delivery.py index 97f6fd8b9..bf1b464fe 100644 --- a/backend/tests/tasks/evaluation_delivery/test_delivery.py +++ b/backend/tests/tasks/evaluation_delivery/test_delivery.py @@ -25,7 +25,7 @@ async def test_shared_delivery_runs_exact_request_once(tmp_path, isolated_databa await provision_minio_bucket.__wrapped__() async with material_fixture(tmp_path, isolated_database_env, provider=provider) as h: d = await delivery_fixture(h) - assert (REQUEST_EVENT, 1) not in production_outbox_delivery(h.factory)._registry.keys + assert (REQUEST_EVENT, 1) in production_outbox_delivery(h.factory)._registry.keys receipt = await d.delivery.deliver(h.created.evaluation_event_id, h.request.project_id, "worker") assert outcome(receipt)["delivery_state"] == "acknowledged" saved = await state(h) diff --git a/backend/tests/tasks/evaluation_delivery/test_worker_materialization.py b/backend/tests/tasks/evaluation_delivery/test_worker_materialization.py index b46f591b2..83a7d9584 100644 --- a/backend/tests/tasks/evaluation_delivery/test_worker_materialization.py +++ b/backend/tests/tasks/evaluation_delivery/test_worker_materialization.py @@ -66,7 +66,7 @@ async def test_worker_art_lease_executes_exact_hidden_request( port = _worker_port(h, monkeypatch) try: d = await delivery_fixture(h, materialization=port) - assert (REQUEST_EVENT, 1) not in production_outbox_delivery(h.factory)._registry.keys + assert (REQUEST_EVENT, 1) in production_outbox_delivery(h.factory)._registry.keys receipt = await d.delivery.deliver( h.created.evaluation_event_id, h.request.project_id, "worker-runtime", ) diff --git a/backend/tests/test_artifact_architecture.py b/backend/tests/test_artifact_architecture.py index e6e4b35ca..2e492215e 100644 --- a/backend/tests/test_artifact_architecture.py +++ b/backend/tests/test_artifact_architecture.py @@ -27,6 +27,7 @@ CHECKER_MATERIALIZATION_API = ( APP_ROOT / "modules" / "checkers" / "api" / "materialization.py" ) +CHECKER_MATERIAL_API = APP_ROOT / "modules" / "checkers" / "api" / "material.py" RETIRED_ARTIFACT_MATERIALIZATION_API = ( APP_ROOT / "modules" / "artifacts" / "api" / "submission_materialization.py" ) @@ -616,12 +617,18 @@ def test_checker_materialization_contract_has_one_canonical_consumer_owner() -> "MaterializationFacts", "PreparedMaterialization", "MaterializationAuthorityPort", "PostSubmissionMaterializationUnavailable", "PostSubmissionMaterializationFailure", - "SubmissionMaterialEntry", + "ExternalCheckerGrantReference", "SubmissionMaterialView", "PostSubmissionMaterialConsumer", "PostSubmissionMaterializationResult", "PostSubmissionMaterializationPort", } + material_classes = { + node.name: node + for node in _tree(CHECKER_MATERIAL_API).body + if isinstance(node, ast.ClassDef) + } + assert set(material_classes) == {"SubmissionMaterialEntry"} assert { node.name for node in classes["PostSubmissionMaterializationPort"].body @@ -646,13 +653,14 @@ def test_checker_custody_ports_have_exact_owner_and_art_consumers() -> None: "app.modules.checkers.api.materialization": { "app/modules/authorization/domain/post_submit.py", "app/modules/authorization/post_submit_authorization.py", - "app/adapters/artifacts/__init__.py", - "app/modules/artifacts/post_submit_materialization.py", - "app/modules/artifacts/post_submit_selection.py", - "app/modules/checkers/api/default_checker.py", - "app/modules/checkers/default_checker.py", - "app/modules/checkers/execution.py", - }, + "app/adapters/artifacts/__init__.py", + "app/modules/artifacts/post_submit_materialization.py", + "app/modules/artifacts/post_submit_selection.py", + "app/modules/artifacts/selected_pre_submit_admission.py", + "app/modules/checkers/default_checker.py", + "app/modules/checkers/execution.py", + "app/modules/checkers/selected_pre_submit_execution.py", + }, } actual = {module: set() for module in expected} for path in _python_files(APP_ROOT): From d486a2a1ad501e6c1b79b59ff695d5dccc8f902a Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 21:00:54 +0100 Subject: [PATCH 078/283] [PILOT-04] Prove selected post-submit scheduler envelopes --- .../pilot04-workstream-default-checker.md | 2 +- .../external/test_selected_post_submit.py | 112 ++++++++++++------ 2 files changed, 78 insertions(+), 36 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 644b5ef8a..2501e99b1 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -218,7 +218,7 @@ intermediate-wait regression. | Selected PRE authority contract | `pytest -q backend/tests/authorization/pre_submit/test_contracts.py backend/tests/authorization/test_catalogue.py backend/tests/checkers/external/test_selected_pre_submit_service.py backend/tests/architecture/test_module_boundaries.py`; focused Ruff and `git diff --check` | 50 passed; one dedicated service identity owns only execute/finalize, prepared selectors bind project/run/request, exact phase facts bind the decision and audit digest, direct service calls remain unavailable, and composition uses the public authority port | Native actor/action/evidence constraints and live workflow injection remain pending | | Selected POST callback | `pytest -q backend/tests/checkers/external/test_selected_post_submit.py`; Ruff and `git diff --check` on the affected files | 3 passed; actual Submission/ART identity reaches every locked POST image through its short-lived grant, work pass/fail remains evidence only, and infrastructure failure stays recoverable | Durable POST reservation/finalization, worker restart and routing composition remain pending | | Selected durable POST contract | `pytest -q backend/tests/checkers/external/test_selected_post_submit.py backend/tests/test_submission_bundle_admission.py`; Ruff and `git diff --check` on the affected files | 56 passed; the request digest binds the exact approved selected policy, separately named locked TASK context and native Submission/ART identity, while the result digest binds request/generation, ordered execution evidence or a closed recoverable infrastructure category without acceptance authority; a legacy catalogue hash cannot stand in for the selected image-policy digest | The existing scheduler/materializer still needs to select this contract and persist it through restart/replay | -| Selected POST scheduler compatibility | `pytest -q backend/tests/checkers/external/test_selected_post_submit.py backend/tests/checkers/execution/test_results.py backend/tests/checkers/execution/test_completion_contract.py backend/tests/checkers/post_submit/test_request.py backend/tests/test_submission_bundle_admission.py`; focused Ruff | 82 passed; one discriminated owner accepts retained legacy and selected request/result envelopes, selected leases cover the ordered image budget and finalization margin, ART recomputes the selected manifest, and the exact result envelope remains the replay authority | Production outbox registration, native selected columns/constraints and live Rust worker proof remain pending | +| Selected POST scheduler compatibility | `pytest -q backend/tests/checkers/external/test_selected_post_submit.py backend/tests/checkers/execution/test_results.py backend/tests/checkers/execution/test_completion_contract.py backend/tests/checkers/post_submit/test_request.py backend/tests/test_submission_bundle_admission.py`; focused Ruff | 84 passed; one discriminated owner accepts retained legacy and selected request/result envelopes, selected leases cover the ordered image budget and finalization margin, ART recomputes the selected manifest, and focused scheduler controls prove exact completed/infrastructure envelopes and generic replay parsing | Native selected columns/constraints and live Rust worker proof remain pending | | Production delivery registration and owner boundaries | `pytest -q backend/tests/architecture/test_module_boundaries.py backend/tests/test_artifact_architecture.py backend/tests/outbox/test_contracts.py`; focused Ruff and a direct registry construction probe | 116 passed; the existing production outbox registry exposes assignment invalidation and evaluation request handlers, selected Rust configuration is lazy, and PRE coordination stays behind CHECKERS' public adapter root | Database-backed legacy/selected delivery and worker restart proofs remain pending | | Owner/caller trace | PROJECT approval/activation, ART preparation/admission, TASK composition and CHECKERS dispatch | In progress | Persistence delta and migration ordinal await actual linear predecessor | | End-to-end replacement | Real PostgreSQL/MinIO/Rust public and worker journey | Not run | Implementation incomplete | diff --git a/backend/tests/checkers/external/test_selected_post_submit.py b/backend/tests/checkers/external/test_selected_post_submit.py index 6dd89b059..7123f59d0 100644 --- a/backend/tests/checkers/external/test_selected_post_submit.py +++ b/backend/tests/checkers/external/test_selected_post_submit.py @@ -25,6 +25,11 @@ LockedExternalCheckerBinding, LockedExternalPostSubmitPolicy, ) +from app.modules.checkers.api.evaluation_contract import ( + validate_execution_request, + validate_execution_result, +) +from app.modules.checkers.api.execution import EvaluationReservation, ExecutionLease from app.modules.checkers.api.materialization import SubmissionMaterialEntry from app.modules.checkers.selected_post_submit_execution import ( SelectedPostSubmitProcessor, @@ -84,6 +89,43 @@ def _policy() -> LockedExternalPostSubmitPolicy: ) +def _request(identity, policy): + context = SelectedPostSubmitLockedContext( + guide_version="guide-v1", + source_id=new_record_id(), + source_hash=SHA, + effective_policy_id=new_record_id(), + effective_policy_hash=SHA, + pre_policy_id=new_record_id(), + pre_policy_hash=SHA, + retained_catalogue_policy_id=new_record_id(), + retained_catalogue_policy_version="guide-v1", + retained_catalogue_policy_hash=SHA, + selected_post_policy_hash=policy.policy_sha256, + review_policy_id=new_record_id(), + review_generation=1, + review_hash=SHA, + revision_policy_id=new_record_id(), + revision_generation=1, + revision_hash=SHA, + ) + return make_selected_post_submit_request( + project_id=identity.project_id, + expected_context=context, + policy=policy, + evaluation_request_id=identity.evaluation_request_id, + evaluation_generation=identity.evaluation_generation, + task_id=identity.task_id, + assignment_id=identity.assignment_id, + submission_id=identity.submission_id, + submission_version=identity.submission_version, + content_id=new_record_id(), + binding_id=new_record_id(), + content_sha256=SHA, + byte_count=42, + ) + + class _MaterialView: def __init__(self, material) -> None: self.external_checker_material = material @@ -178,40 +220,7 @@ async def test_selected_post_separates_infrastructure_from_work_findings() -> No async def test_selected_post_request_and_result_bind_exact_locked_policy() -> None: identity = execution_identity("post_submit") policy = _policy() - context = SelectedPostSubmitLockedContext( - guide_version="guide-v1", - source_id=new_record_id(), - source_hash=SHA, - effective_policy_id=new_record_id(), - effective_policy_hash=SHA, - pre_policy_id=new_record_id(), - pre_policy_hash=SHA, - retained_catalogue_policy_id=new_record_id(), - retained_catalogue_policy_version="guide-v1", - retained_catalogue_policy_hash=SHA, - selected_post_policy_hash=policy.policy_sha256, - review_policy_id=new_record_id(), - review_generation=1, - review_hash=SHA, - revision_policy_id=new_record_id(), - revision_generation=1, - revision_hash=SHA, - ) - request = make_selected_post_submit_request( - project_id=identity.project_id, - expected_context=context, - policy=policy, - evaluation_request_id=identity.evaluation_request_id, - evaluation_generation=identity.evaluation_generation, - task_id=identity.task_id, - assignment_id=identity.assignment_id, - submission_id=identity.submission_id, - submission_version=identity.submission_version, - content_id=new_record_id(), - binding_id=new_record_id(), - content_sha256=SHA, - byte_count=42, - ) + request = _request(identity, policy) execution = await SelectedPostSubmitProcessor( policy=policy, identity=identity, @@ -245,7 +254,7 @@ async def test_selected_post_request_and_result_bind_exact_locked_policy() -> No exclude={"request_sha256", "policy", "expected_context"}, ), policy=empty_policy, - expected_context=context.model_copy( + expected_context=request.expected_context.model_copy( update={ "selected_post_policy_hash": empty_policy.policy_sha256 } @@ -254,6 +263,39 @@ async def test_selected_post_request_and_result_bind_exact_locked_policy() -> No ) +@pytest.mark.asyncio +@pytest.mark.parametrize( + "outcome,expected", + [("completed", "completed"), ("infrastructure_failed", "infrastructure_failed")], +) +async def test_selected_scheduler_consumer_derives_exact_envelope(outcome, expected) -> None: + from app.modules.checkers.execution import _SelectedExternalConsumer + + identity = execution_identity("post_submit") + policy = _policy() + request = _request(identity, policy) + lease = ExecutionLease( + reservation=EvaluationReservation( + request_id=request.evaluation_request_id, + request_digest=request.request_sha256, + attempt_id=identity.attempt_id, + result_id=identity.result_id, + evaluation_generation=request.evaluation_generation, + ), + lease_id=identity.lease_id, + lease_generation=identity.lease_generation, + expires_at=identity.lease_expires_at, + ) + result = await _SelectedExternalConsumer( + _Execution(outcome=outcome), lease + ).evaluate(request, _MaterialView(execution_material(identity))) + + assert result.outcome == expected + result.validate_request(request) + assert type(validate_execution_request(request.model_dump())) is type(request) + assert type(validate_execution_result(result.model_dump())) is type(result) + + def test_selected_post_content_uses_selected_digest_not_catalogue_hash() -> None: policy = _policy() locked = SimpleNamespace( From 028e7f3eebb492428abf4975c1d26abae7a3893f Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 21:01:53 +0100 Subject: [PATCH 079/283] [PILOT-04] Require selected post-submit custody for admission --- .../pilot04-workstream-default-checker.md | 7 +++-- backend/app/adapters/tasks/__init__.py | 13 ++++++-- .../modules/tasks/submission_composition.py | 31 +++++++------------ .../modules/tasks/submission_participants.py | 8 +++-- 4 files changed, 33 insertions(+), 26 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 2501e99b1..ef8428914 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -57,8 +57,10 @@ manifest before execution, and retains the complete selected result for restart/replay. The existing production outbox registry now owns the evaluation request handler alongside assignment invalidation, leases worker-owned ART material only during execution, and creates the configured Rust adapter only -for a selected request. Native SQL custody and the live worker journey remain -unfinished. +for a selected request. New TASK submission composition now requires selected +POST custody and refuses an unresolved legacy admission instead of executing +it; retained legacy envelopes remain read-only decoding inputs. Native SQL +custody and the live worker journey remain unfinished. Production still uses the older pre/post catalogues. ## Bounded change @@ -220,6 +222,7 @@ intermediate-wait regression. | Selected durable POST contract | `pytest -q backend/tests/checkers/external/test_selected_post_submit.py backend/tests/test_submission_bundle_admission.py`; Ruff and `git diff --check` on the affected files | 56 passed; the request digest binds the exact approved selected policy, separately named locked TASK context and native Submission/ART identity, while the result digest binds request/generation, ordered execution evidence or a closed recoverable infrastructure category without acceptance authority; a legacy catalogue hash cannot stand in for the selected image-policy digest | The existing scheduler/materializer still needs to select this contract and persist it through restart/replay | | Selected POST scheduler compatibility | `pytest -q backend/tests/checkers/external/test_selected_post_submit.py backend/tests/checkers/execution/test_results.py backend/tests/checkers/execution/test_completion_contract.py backend/tests/checkers/post_submit/test_request.py backend/tests/test_submission_bundle_admission.py`; focused Ruff | 84 passed; one discriminated owner accepts retained legacy and selected request/result envelopes, selected leases cover the ordered image budget and finalization margin, ART recomputes the selected manifest, and focused scheduler controls prove exact completed/infrastructure envelopes and generic replay parsing | Native selected columns/constraints and live Rust worker proof remain pending | | Production delivery registration and owner boundaries | `pytest -q backend/tests/architecture/test_module_boundaries.py backend/tests/test_artifact_architecture.py backend/tests/outbox/test_contracts.py`; focused Ruff and a direct registry construction probe | 116 passed; the existing production outbox registry exposes assignment invalidation and evaluation request handlers, selected Rust configuration is lazy, and PRE coordination stays behind CHECKERS' public adapter root | Database-backed legacy/selected delivery and worker restart proofs remain pending | +| New Submission selected-only boundary | `pytest -q backend/tests/test_submission_bundle_admission.py backend/tests/checkers/external/test_selected_post_submit.py backend/tests/test_artifact_architecture.py::test_checker_custody_ports_have_exact_owner_and_art_consumers`; focused Ruff | 59 passed; retained legacy and selected admission projections are mutually exclusive, and the TASK writer accepts only selected POST custody for a new immutable Submission | Native rollback proof for a retained unresolved legacy admission remains pending | | Owner/caller trace | PROJECT approval/activation, ART preparation/admission, TASK composition and CHECKERS dispatch | In progress | Persistence delta and migration ordinal await actual linear predecessor | | End-to-end replacement | Real PostgreSQL/MinIO/Rust public and worker journey | Not run | Implementation incomplete | diff --git a/backend/app/adapters/tasks/__init__.py b/backend/app/adapters/tasks/__init__.py index 412342c37..56adf1124 100644 --- a/backend/app/adapters/tasks/__init__.py +++ b/backend/app/adapters/tasks/__init__.py @@ -203,9 +203,16 @@ async def consume( binding_decision_id=result.binding_decision_id, archive_sha256=result.material.archive_sha256, byte_count=result.material.archive_byte_count, - evaluation_content=submission_evaluation_content( - request.task_context, request.project_context, request.packet, - result.material.files, result.material.archive_sha256, + evaluation_content=( + submission_evaluation_content( + request.task_context, + request.project_context, + request.packet, + result.material.files, + result.material.archive_sha256, + ) + if selected_post_policy is None + else None ), selected_post_submit_policy=selected_post_policy, selected_evaluation_content=( diff --git a/backend/app/modules/tasks/submission_composition.py b/backend/app/modules/tasks/submission_composition.py index f99ebbcd1..b38c495c3 100644 --- a/backend/app/modules/tasks/submission_composition.py +++ b/backend/app/modules/tasks/submission_composition.py @@ -32,7 +32,6 @@ from app.modules.tasks.submission_replay import read_creation_replay from app.modules.tasks.lifecycle import ensure_allowed_transition from app.modules.checkers.api.execution import EvaluationCoordinationPort -from app.modules.checkers.api.post_submit import make_post_submit_request from app.modules.checkers.api.selected_post_submit import ( make_selected_post_submit_request, ) @@ -195,18 +194,18 @@ async def create(self, request: SubmissionCreationRequest) -> SubmissionCreation type(consumed) is not SubmissionArtifactAdmissionResult or not isinstance(consumed.binding_id, UUID) or not isinstance(consumed.content_id, UUID) + or consumed.selected_evaluation_content is None ): - raise RuntimeError("artifact admission did not produce exact binding facts") + raise SubmissionCreationUnavailable("submission creation is unavailable") submission.submission_bundle_admission_id = str(request.admission_id) submission.artifact_binding_id = str(consumed.binding_id) submission.artifact_content_id = str(consumed.content_id) - if consumed.selected_evaluation_content is not None: - submission.selected_post_submit_policy_sha256 = ( - consumed.selected_evaluation_content.policy.policy_sha256 - ) - submission.selected_post_submit_policy_body = ( - consumed.selected_evaluation_content.policy.model_dump(mode="json") - ) + submission.selected_post_submit_policy_sha256 = ( + consumed.selected_evaluation_content.policy.policy_sha256 + ) + submission.selected_post_submit_policy_body = ( + consumed.selected_evaluation_content.policy.model_dump(mode="json") + ) await self._session.flush() creation_decision_id = await self._authorization.consume(prepared_authorization, final) if not isinstance(creation_decision_id, UUID): @@ -223,16 +222,10 @@ async def create(self, request: SubmissionCreationRequest) -> SubmissionCreation content_sha256=consumed.archive_sha256, byte_count=consumed.byte_count, ) - if consumed.selected_evaluation_content is not None: - evaluation = make_selected_post_submit_request( - **consumed.selected_evaluation_content.model_dump(), - **request_fields, - ) - else: - evaluation = make_post_submit_request( - **consumed.evaluation_content.model_dump(), - **request_fields, - ) + evaluation = make_selected_post_submit_request( + **consumed.selected_evaluation_content.model_dump(), + **request_fields, + ) ensure_allowed_transition(task.status, "submitted") task.status = "submitted" await self._session.flush() diff --git a/backend/app/modules/tasks/submission_participants.py b/backend/app/modules/tasks/submission_participants.py index 96079cc0c..6f880a462 100644 --- a/backend/app/modules/tasks/submission_participants.py +++ b/backend/app/modules/tasks/submission_participants.py @@ -33,16 +33,20 @@ class SubmissionArtifactBindingFacts: @dataclass(frozen=True, slots=True) class SubmissionArtifactAdmissionResult(SubmissionArtifactBindingFacts): - evaluation_content: PostSubmissionEvaluationContent + evaluation_content: PostSubmissionEvaluationContent | None = None selected_post_submit_policy: LockedExternalPostSubmitPolicy | None = None selected_evaluation_content: SelectedPostSubmissionContent | None = None def __post_init__(self) -> None: - """Require selected policy and its locked request content together.""" + """Keep retained legacy and selected content mutually exclusive.""" if (self.selected_post_submit_policy is None) != ( self.selected_evaluation_content is None ): raise ValueError("selected POST admission content is incomplete") + if (self.evaluation_content is None) == ( + self.selected_evaluation_content is None + ): + raise ValueError("admission must select exactly one POST contract") if ( self.selected_evaluation_content is not None and self.selected_evaluation_content.policy From f16f7d63a281a6942567e09e76683a7f8d4a26a6 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 21:02:57 +0100 Subject: [PATCH 080/283] [PILOT-04] Preserve retained admission history --- .../pilot04-workstream-default-checker.md | 6 +- backend/app/modules/artifacts/models.py | 58 +++++++++++++------ 2 files changed, 46 insertions(+), 18 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index ef8428914..d84f0dec4 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -142,7 +142,10 @@ rewritten or deleted. Historical decoders remain narrowly scoped to immutable old evidence. An unresolved old-catalogue queue item or locked guide fails closed and requires an authorized recompile/reapproval transition; it is never silently run through a new image. This retained-data reader is not an executable -compatibility runtime. +compatibility runtime. New selected admission columns are nullable only for +those retained legacy rows; native checks require the complete guide, policy, +packet, manifest and selected-run custody whenever selected lineage is present, +so migration does not synthesize or rewrite historical facts. Pre execution uses a durable lease/generation fence. One root reserves the exact prepared-generation, policy, registry and request identities, commits, @@ -223,6 +226,7 @@ intermediate-wait regression. | Selected POST scheduler compatibility | `pytest -q backend/tests/checkers/external/test_selected_post_submit.py backend/tests/checkers/execution/test_results.py backend/tests/checkers/execution/test_completion_contract.py backend/tests/checkers/post_submit/test_request.py backend/tests/test_submission_bundle_admission.py`; focused Ruff | 84 passed; one discriminated owner accepts retained legacy and selected request/result envelopes, selected leases cover the ordered image budget and finalization margin, ART recomputes the selected manifest, and focused scheduler controls prove exact completed/infrastructure envelopes and generic replay parsing | Native selected columns/constraints and live Rust worker proof remain pending | | Production delivery registration and owner boundaries | `pytest -q backend/tests/architecture/test_module_boundaries.py backend/tests/test_artifact_architecture.py backend/tests/outbox/test_contracts.py`; focused Ruff and a direct registry construction probe | 116 passed; the existing production outbox registry exposes assignment invalidation and evaluation request handlers, selected Rust configuration is lazy, and PRE coordination stays behind CHECKERS' public adapter root | Database-backed legacy/selected delivery and worker restart proofs remain pending | | New Submission selected-only boundary | `pytest -q backend/tests/test_submission_bundle_admission.py backend/tests/checkers/external/test_selected_post_submit.py backend/tests/test_artifact_architecture.py::test_checker_custody_ports_have_exact_owner_and_art_consumers`; focused Ruff | 59 passed; retained legacy and selected admission projections are mutually exclusive, and the TASK writer accepts only selected POST custody for a new immutable Submission | Native rollback proof for a retained unresolved legacy admission remains pending | +| Retained admission migration shape | `pytest -q backend/tests/test_submission_bundle_admission.py backend/tests/checkers/external/test_selected_pre_submit_coordination.py backend/tests/checkers/external/test_selected_preparation_command.py backend/tests/test_artifact_architecture.py::test_checker_materialization_contract_has_one_canonical_consumer_owner`; focused Ruff | 62 passed; selected rows require complete new custody while every new column stays null on retained legacy rows, avoiding fabricated backfill or historical hash rewrites | Successor SQL and direct retained/selected row controls remain pending | | Owner/caller trace | PROJECT approval/activation, ART preparation/admission, TASK composition and CHECKERS dispatch | In progress | Persistence delta and migration ordinal await actual linear predecessor | | End-to-end replacement | Real PostgreSQL/MinIO/Rust public and worker journey | Not run | Implementation incomplete | diff --git a/backend/app/modules/artifacts/models.py b/backend/app/modules/artifacts/models.py index f848f39c5..9073563e9 100644 --- a/backend/app/modules/artifacts/models.py +++ b/backend/app/modules/artifacts/models.py @@ -1309,12 +1309,24 @@ class SubmissionBundleAdmission(Base): SHA256_CHECK.format(column="semantic_manifest_sha256"), name="manifest_sha256" ), CheckConstraint( - "jsonb_typeof(semantic_manifest_body)='object'", + "(selected_pre_submit_run_id is null and semantic_manifest_body is null) or " + "(selected_pre_submit_run_id is not null and " + "jsonb_typeof(semantic_manifest_body)='object')", name="manifest_body", ), - CheckConstraint(SHA256_CHECK.format(column="packet_sha256"), name="packet_sha256"), CheckConstraint( - SHA256_CHECK.format(column="effective_plan_sha256"), name="effective_plan_sha256" + "(selected_pre_submit_run_id is null and packet_sha256 is null) or " + "(selected_pre_submit_run_id is not null and " + + SHA256_CHECK.format(column="packet_sha256") + + ")", + name="packet_sha256", + ), + CheckConstraint( + "(selected_pre_submit_run_id is null and effective_plan_sha256 is null) or " + "(selected_pre_submit_run_id is not null and " + + SHA256_CHECK.format(column="effective_plan_sha256") + + ")", + name="effective_plan_sha256", ), CheckConstraint( "(selected_pre_submit_run_id is null and selected_rules_sha256 is null) or " @@ -1333,9 +1345,21 @@ class SubmissionBundleAdmission(Base): name="selected_post_submit_policy", ), CheckConstraint( - SHA256_CHECK.format(column="source_snapshot_sha256") + " and " - + SHA256_CHECK.format(column="effective_policy_sha256") + " and " - + SHA256_CHECK.format(column="pre_submit_policy_sha256"), + "(selected_pre_submit_run_id is null and guide_id is null and " + "guide_version is null and source_snapshot_id is null and " + "source_snapshot_sha256 is null and effective_policy_id is null and " + "effective_policy_sha256 is null and pre_submit_policy_id is null and " + "pre_submit_policy_sha256 is null) or " + "(selected_pre_submit_run_id is not null and guide_id is not null and " + "octet_length(guide_version) between 1 and 50 and " + "source_snapshot_id is not null and effective_policy_id is not null and " + "pre_submit_policy_id is not null and " + + SHA256_CHECK.format(column="source_snapshot_sha256") + + " and " + + SHA256_CHECK.format(column="effective_policy_sha256") + + " and " + + SHA256_CHECK.format(column="pre_submit_policy_sha256") + + ")", name="locked_policy_digests", ), CheckConstraint(SHA256_CHECK.format(column="archive_sha256"), name="archive_sha256"), @@ -1411,24 +1435,24 @@ class SubmissionBundleAdmission(Base): ) predecessor_submission_version: Mapped[int | None] = mapped_column(Integer) locked_policy_context_hash: Mapped[str] = mapped_column(String(71), nullable=False) - guide_id: Mapped[str] = mapped_column(Uuid(as_uuid=False), nullable=False) - guide_version: Mapped[str] = mapped_column(String(50), nullable=False) - source_snapshot_id: Mapped[str] = mapped_column(Uuid(as_uuid=False), nullable=False) - source_snapshot_sha256: Mapped[str] = mapped_column(String(71), nullable=False) - effective_policy_id: Mapped[str] = mapped_column(Uuid(as_uuid=False), nullable=False) - effective_policy_sha256: Mapped[str] = mapped_column(String(71), nullable=False) - pre_submit_policy_id: Mapped[str] = mapped_column(Uuid(as_uuid=False), nullable=False) - pre_submit_policy_sha256: Mapped[str] = mapped_column(String(71), nullable=False) - effective_plan_sha256: Mapped[str] = mapped_column(String(71), nullable=False) + guide_id: Mapped[str | None] = mapped_column(Uuid(as_uuid=False)) + guide_version: Mapped[str | None] = mapped_column(String(50)) + source_snapshot_id: Mapped[str | None] = mapped_column(Uuid(as_uuid=False)) + source_snapshot_sha256: Mapped[str | None] = mapped_column(String(71)) + effective_policy_id: Mapped[str | None] = mapped_column(Uuid(as_uuid=False)) + effective_policy_sha256: Mapped[str | None] = mapped_column(String(71)) + pre_submit_policy_id: Mapped[str | None] = mapped_column(Uuid(as_uuid=False)) + pre_submit_policy_sha256: Mapped[str | None] = mapped_column(String(71)) + effective_plan_sha256: Mapped[str | None] = mapped_column(String(71)) selected_rules_sha256: Mapped[str | None] = mapped_column(String(71)) selected_post_submit_policy_sha256: Mapped[str | None] = mapped_column( String(71) ) selected_post_submit_policy_body: Mapped[dict | None] = mapped_column(JSONB) - packet_sha256: Mapped[str] = mapped_column(String(71), nullable=False) + packet_sha256: Mapped[str | None] = mapped_column(String(71)) semantic_manifest_id: Mapped[str] = mapped_column(Uuid(as_uuid=False), nullable=False) semantic_manifest_sha256: Mapped[str] = mapped_column(String(71), nullable=False) - semantic_manifest_body: Mapped[dict] = mapped_column(JSONB, nullable=False) + semantic_manifest_body: Mapped[dict | None] = mapped_column(JSONB) archive_sha256: Mapped[str] = mapped_column(String(71), nullable=False) archive_byte_count: Mapped[int] = mapped_column(BigInteger, nullable=False) status: Mapped[str] = mapped_column(String(16), nullable=False, default="ready", index=True) From 9ea4959a1422cc8aeca2c6e81d07b1faa6d19d85 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 21:08:09 +0100 Subject: [PATCH 081/283] [PILOT-04] Preserve qualified predecessor closures --- .../versions/0034_task_import_batches.py | 42 ++++++++++++--- .../versions/0035_task_batch_transitions.py | 54 ++++++++++++++----- 2 files changed, 77 insertions(+), 19 deletions(-) diff --git a/backend/alembic/versions/0034_task_import_batches.py b/backend/alembic/versions/0034_task_import_batches.py index e593205c0..e810bed69 100644 --- a/backend/alembic/versions/0034_task_import_batches.py +++ b/backend/alembic/versions/0034_task_import_batches.py @@ -446,7 +446,6 @@ def _create_custody_functions() -> None: binding_digest,c.idempotency_key,c.request_digest) then raise exception 'task import command custody invalid' using errcode='23514'; end if; - perform public.validate_task_import_batch_custody(b.id); end $$ """) @@ -504,18 +503,47 @@ def _create_guards() -> None: def _create_trigger_wrappers() -> None: op.execute(r""" create function public.trigger_validate_task_import_batch() returns trigger -language plpgsql set search_path=pg_catalog,public,pg_temp as $$ begin - perform public.validate_task_import_batch_custody(new.id); return new; end $$ +language plpgsql set search_path=pg_catalog,public,pg_temp as $$ +declare final_status text; +begin + select status into final_status from public.task_import_batches where id=new.id; + if not found or final_status<>'committed' then + raise exception 'task import batch cannot remain pending' using errcode='23514'; + end if; + if new.status='committed' then + perform public.validate_task_import_batch_custody(new.id); + end if; + return new; +end $$ """) op.execute(r""" create function public.trigger_validate_task_import_command() returns trigger -language plpgsql set search_path=pg_catalog,public,pg_temp as $$ begin - perform public.validate_task_import_command_custody(new.id); return new; end $$ +language plpgsql set search_path=pg_catalog,public,pg_temp as $$ +declare final_status text; +begin + select status into final_status from public.task_import_batch_command_receipts where id=new.id; + if not found or final_status<>'committed' then + raise exception 'task import command cannot remain pending' using errcode='23514'; + end if; + if new.status='committed' then + perform public.validate_task_import_command_custody(new.id); + end if; + return new; +end $$ """) op.execute(r""" create function public.trigger_validate_task_import_member() returns trigger -language plpgsql set search_path=pg_catalog,public,pg_temp as $$ begin - perform public.validate_task_import_batch_custody(new.batch_id); return new; end $$ +language plpgsql set search_path=pg_catalog,public,pg_temp as $$ +declare parent_status text; parent_xid xid; +begin + select status,xmin into parent_status,parent_xid + from public.task_import_batches where id=new.batch_id; + if not found or parent_status<>'committed' + or parent_xid<>pg_catalog.pg_current_xact_id()::xid then + raise exception 'task import member must be committed with its batch root' using errcode='23514'; + end if; + return new; +end $$ """) diff --git a/backend/alembic/versions/0035_task_batch_transitions.py b/backend/alembic/versions/0035_task_batch_transitions.py index b03008297..00552aba0 100644 --- a/backend/alembic/versions/0035_task_batch_transitions.py +++ b/backend/alembic/versions/0035_task_batch_transitions.py @@ -325,7 +325,16 @@ def _create_custody() -> None: and e.event_payload::jsonb#>>'{manager_authority_facts,idempotency_key}'=c.idempotency_key::text and e.event_payload::jsonb#>>'{manager_authority_facts,request_digest}'=c.request_digest and e.event_payload::jsonb#>>'{manager_authority_facts,identity_link_id}'=b.identity_link_id::text - and e.event_payload::jsonb#>>'{manager_authority_facts,locked_context_hash}'=c.locked_context_hash + and e.event_payload::jsonb#>>'{manager_authority_facts,task_status}'= + case b.action_id when 'project.task.screen' then 'draft' else 'screening' end + and coalesce((e.event_payload::jsonb#>>'{manager_authority_facts,locked_context_hash}') + ~ '^sha256:[0-9a-f]{64}$',false) + and (b.action_id='project.task.screen' or + e.event_payload::jsonb#>>'{manager_authority_facts,locked_context_hash}'=c.locked_context_hash) + and public.external_checker_registry_digest(jsonb_build_object( + 'resource_context',jsonb_strip_nulls( + e.event_payload::jsonb->'manager_authority_facts'))) + =d.after_facts::jsonb->>'resource_context_digest' and e.event_payload::jsonb->>'authorization_resource_digest' =d.after_facts::jsonb->>'resource_context_digest' and e.event_payload::jsonb->>'locked_guide_version'=c.response::jsonb->>'locked_guide_version' @@ -350,25 +359,46 @@ def _create_custody() -> None: """) op.execute(r""" create function public.trigger_validate_task_batch_transition() returns trigger -language plpgsql set search_path=pg_catalog,public,pg_temp as $$ begin - if not public.validate_task_batch_transition_custody(new.id) then +language plpgsql set search_path=pg_catalog,public,pg_temp as $$ +declare final_status text; +begin + select status into final_status from public.task_batch_transition_receipts where id=new.id; + if not found or final_status<>'committed' then + raise exception 'task batch transition cannot remain pending' using errcode='23514'; + end if; + if new.status='committed' + and not public.validate_task_batch_transition_custody(new.id) then raise exception 'task batch transition custody mismatch' using errcode='23514'; end if; return new; end $$ """) op.execute(r""" create function public.trigger_validate_task_batch_transition_member() returns trigger -language plpgsql set search_path=pg_catalog,public,pg_temp as $$ begin - if not public.validate_task_batch_transition_custody(new.transition_receipt_id) then - raise exception 'task batch transition member custody mismatch' using errcode='23514'; - end if; return new; end $$ +language plpgsql set search_path=pg_catalog,public,pg_temp as $$ +declare parent_status text; parent_xid xid; +begin + select status,xmin into parent_status,parent_xid + from public.task_batch_transition_receipts where id=new.transition_receipt_id; + if not found or parent_status<>'committed' + or parent_xid<>pg_catalog.pg_current_xact_id()::xid then + raise exception 'task batch transition member must be committed with its root' using errcode='23514'; + end if; + return new; +end $$ """) op.execute(r""" create function public.trigger_validate_task_batch_command_root() returns trigger -language plpgsql set search_path=pg_catalog,public,pg_temp as $$ begin - if new.batch_transition_receipt_id is not null - and not public.validate_task_batch_transition_custody(new.batch_transition_receipt_id) then - raise exception 'task batch transition command custody mismatch' using errcode='23514'; - end if; return new; end $$ +language plpgsql set search_path=pg_catalog,public,pg_temp as $$ +declare parent_status text; parent_xid xid; +begin + if new.batch_transition_receipt_id is null then return new; end if; + select status,xmin into parent_status,parent_xid + from public.task_batch_transition_receipts where id=new.batch_transition_receipt_id; + if not found or parent_status<>'committed' + or parent_xid<>pg_catalog.pg_current_xact_id()::xid then + raise exception 'task batch transition command must be committed with its root' using errcode='23514'; + end if; + return new; +end $$ """) op.execute( "create constraint trigger task_batch_transition_custody after insert or update on public.task_batch_transition_receipts deferrable initially deferred for each row execute function public.trigger_validate_task_batch_transition()" From f40f4120d74db99513479033793e12768bd28800 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 21:16:18 +0100 Subject: [PATCH 082/283] [PILOT-04] Install selected checker flow custody --- backend/alembic/env.py | 3 +- .../versions/0037_selected_checker_flow.py | 451 ++++++++++++++++++ backend/app/modules/checkers/models.py | 9 +- backend/app/modules/tasks/models.py | 9 +- backend/tests/conftest.py | 4 +- backend/tests/test_alembic.py | 2 +- 6 files changed, 473 insertions(+), 5 deletions(-) create mode 100644 backend/alembic/versions/0037_selected_checker_flow.py diff --git a/backend/alembic/env.py b/backend/alembic/env.py index 627f1ac78..6421cdf4b 100644 --- a/backend/alembic/env.py +++ b/backend/alembic/env.py @@ -21,7 +21,7 @@ target_metadata = Base.metadata _BASELINE_REVISION = "0001_uuid7_v01" -_CURRENT_HEAD_REVISION = "0036_contribution_export_pages" +_CURRENT_HEAD_REVISION = "0037_selected_checker_flow" _RECREATE_GUIDANCE = ( "Workstream v0.1 requires a fresh database; recreate this database before " "running the 0001_uuid7_v01 migration" @@ -89,6 +89,7 @@ def do_run_migrations(connection: Connection) -> None: ("0033_contribution_reads",), ("0034_task_import_batches",), ("0035_task_batch_transitions",), + ("0036_contribution_export_pages",), (_CURRENT_HEAD_REVISION,), ): raise RuntimeError(_RECREATE_GUIDANCE) diff --git a/backend/alembic/versions/0037_selected_checker_flow.py b/backend/alembic/versions/0037_selected_checker_flow.py new file mode 100644 index 000000000..0f8483453 --- /dev/null +++ b/backend/alembic/versions/0037_selected_checker_flow.py @@ -0,0 +1,451 @@ +"""Install selected PRE custody and selected POST policy lineage.""" + +from alembic import op +import sqlalchemy as sa +from sqlalchemy.dialects import postgresql + +revision = "0037_selected_checker_flow" +down_revision = "0036_contribution_export_pages" +branch_labels = None +depends_on = None + + +def _definition(table: str, name: str) -> str: + return op.get_bind().execute(sa.text( + "select pg_catalog.pg_get_constraintdef(oid) from pg_catalog.pg_constraint " + "where conrelid=cast(:table as regclass) and conname=:name" + ), {"table": "public." + table, "name": name}).scalar_one() + + +def _replace(table: str, name: str, definition: str) -> None: + op.execute(f"alter table public.{table} drop constraint {name}") + op.execute(f"alter table public.{table} add constraint {name} {definition}") + + +def _extend(table: str, name: str, anchor: str, addition: str, count: int) -> None: + definition = _definition(table, name) + if definition.count(anchor) != count or addition in definition: + raise RuntimeError(f"selected checker constraint shape changed: {name}") + _replace(table, name, definition.replace(anchor, anchor + addition)) + + +def _extend_authority_vocabulary() -> None: + _extend( + "actor_profiles", "ck_actor_profiles_kind_service_identity", + "('workstream.checker.post_submit'::character varying)::text", + ", ('workstream.checker.pre_submit'::character varying)::text", 1, + ) + _extend( + "audit_events", "ck_audit_events_authority_registries", + "('checker.post_submit.execute'::character varying)::text", + ", ('checker.pre_submit.execute'::character varying)::text, " + "('checker.pre_submit.finalize'::character varying)::text", 1, + ) + _extend( + "audit_events", "ck_audit_events_authority_privacy_bounds", + "('checker_run'::character varying)::text", + ", ('selected_pre_submit_run'::character varying)::text", 1, + ) + name = "ck_audit_events_authorization_action_evidence" + definition = _definition("audit_events", name) + anchor = ( + "(((action_id)::text = 'project.task.create'::text) AND " + "((permission_id)::text = 'project.task.manage'::text))" + ) + additions = " OR ".join( + "(((action_id)::text = " + f"'{action}'::text) AND ((permission_id)::text = '{action}'::text))" + for action in ("checker.pre_submit.execute", "checker.pre_submit.finalize") + ) + if definition.count(anchor) != 2 or additions in definition: + raise RuntimeError("selected PRE audit action constraint shape changed") + _replace("audit_events", name, definition.replace(anchor, anchor + " OR " + additions)) + + +def _create_selected_run_table() -> None: + op.create_table( + "selected_pre_submit_runs", + sa.Column("id", sa.Uuid(as_uuid=False), nullable=False), + sa.Column("actor_profile_id", sa.Uuid(as_uuid=False), nullable=False), + sa.Column("identity_link_id", sa.Uuid(as_uuid=False), nullable=False), + sa.Column("project_id", sa.Uuid(as_uuid=False), nullable=False), + sa.Column("task_id", sa.Uuid(as_uuid=False), nullable=False), + sa.Column("assignment_id", sa.Uuid(as_uuid=False), nullable=False), + sa.Column("idempotency_key", sa.Uuid(as_uuid=False), nullable=False), + sa.Column("prepared_generation_id", sa.Uuid(as_uuid=False), nullable=False), + sa.Column("request_json", postgresql.JSONB(), nullable=False), + sa.Column("request_digest", sa.String(71), nullable=False), + sa.Column("policy_sha256", sa.String(71), nullable=False), + sa.Column("default_behavior_sha256", sa.String(71), nullable=False), + sa.Column("default_input_sha256", sa.String(71), nullable=False), + sa.Column("archive_sha256", sa.String(71), nullable=False), + sa.Column("archive_byte_count", sa.BigInteger(), nullable=False), + sa.Column("semantic_manifest_sha256", sa.String(71), nullable=False), + sa.Column("execution_budget_ms", sa.Integer(), nullable=False), + sa.Column("status", sa.String(32), nullable=False), + sa.Column("lease_id", sa.Uuid(as_uuid=False)), + sa.Column("lease_generation", sa.Integer(), nullable=False), + sa.Column("lease_expires_at", sa.DateTime(timezone=True)), + sa.Column("execute_evidence_id", sa.Uuid(as_uuid=False)), + sa.Column("finalize_evidence_id", sa.Uuid(as_uuid=False)), + sa.Column("terminal_json", postgresql.JSONB()), + sa.Column("terminal_digest", sa.String(71)), + sa.Column("eligible", sa.Boolean()), + sa.Column("queued_at", sa.DateTime(timezone=True), server_default=sa.text("clock_timestamp()"), nullable=False), + sa.Column("started_at", sa.DateTime(timezone=True)), + sa.Column("completed_at", sa.DateTime(timezone=True)), + sa.CheckConstraint("(get_byte(uuid_send(id),6)>>4)=7 and (get_byte(uuid_send(id),8)&192)=128", name="id_uuid7"), + sa.CheckConstraint("status in ('queued','running','completed','infrastructure_failed')", name="status"), + sa.CheckConstraint("request_digest ~ '^sha256:[0-9a-f]{64}$' and policy_sha256 ~ '^sha256:[0-9a-f]{64}$' and default_behavior_sha256 ~ '^sha256:[0-9a-f]{64}$' and default_input_sha256 ~ '^sha256:[0-9a-f]{64}$' and archive_sha256 ~ '^sha256:[0-9a-f]{64}$' and semantic_manifest_sha256 ~ '^sha256:[0-9a-f]{64}$' and (terminal_digest is null or terminal_digest ~ '^sha256:[0-9a-f]{64}$')", name="digests"), + sa.CheckConstraint("archive_byte_count > 0", name="archive_size"), + sa.CheckConstraint("execution_budget_ms between 100 and 14400000", name="execution_budget"), + sa.CheckConstraint("lease_generation >= 0", name="lease_generation"), + sa.CheckConstraint("jsonb_typeof(request_json)='object' and (terminal_json is null or jsonb_typeof(terminal_json)='object')", name="json_objects"), + sa.CheckConstraint( + "(status='queued' and lease_id is null and lease_expires_at is null and terminal_json is null and terminal_digest is null and eligible is null and started_at is null and completed_at is null and execute_evidence_id is null and finalize_evidence_id is null) or " + "(status='running' and lease_id is not null and lease_generation>0 and lease_expires_at is not null and terminal_json is null and terminal_digest is null and eligible is null and started_at is not null and completed_at is null and execute_evidence_id is not null and finalize_evidence_id is null) or " + "(status='completed' and lease_id is not null and lease_generation>0 and lease_expires_at is not null and terminal_json is not null and terminal_digest is not null and eligible is not null and started_at is not null and completed_at is not null and execute_evidence_id is not null and finalize_evidence_id is not null) or " + "(status='infrastructure_failed' and lease_id is not null and lease_generation>0 and lease_expires_at is not null and terminal_json is not null and terminal_digest is not null and eligible is null and started_at is not null and completed_at is not null and execute_evidence_id is not null and finalize_evidence_id is not null)", + name="lifecycle", + ), + sa.ForeignKeyConstraint(["task_id", "project_id"], ["workstream_tasks.id", "workstream_tasks.project_id"], name="fk_selected_pre_run_task_project"), + sa.ForeignKeyConstraint(["assignment_id", "task_id", "actor_profile_id"], ["task_assignments.id", "task_assignments.task_id", "task_assignments.contributor_id"], name="fk_selected_pre_run_assignment"), + sa.ForeignKeyConstraint(["identity_link_id", "actor_profile_id"], ["actor_identity_links.id", "actor_identity_links.actor_profile_id"], name="fk_selected_pre_run_actor_link"), + sa.ForeignKeyConstraint(["execute_evidence_id"], ["audit_events.id"], name="fk_selected_pre_submit_runs_execute_evidence_id_audit_events", ondelete="RESTRICT"), + sa.ForeignKeyConstraint(["finalize_evidence_id"], ["audit_events.id"], name="fk_selected_pre_submit_runs_finalize_evidence_id_audit_events", ondelete="RESTRICT"), + sa.PrimaryKeyConstraint("id", name="pk_selected_pre_submit_runs"), + sa.UniqueConstraint("request_digest", name="request_digest"), + sa.UniqueConstraint("actor_profile_id", "idempotency_key", name="uq_selected_pre_run_actor_key"), + schema="public", + ) + op.create_index("ix_selected_pre_runs_task", "selected_pre_submit_runs", ["task_id"]) + op.create_index("ix_selected_pre_runs_status", "selected_pre_submit_runs", ["status"]) + + +def _alter_selected_lineage() -> None: + for table in ("submissions", "checker_runs"): + op.add_column(table, sa.Column("selected_post_submit_policy_sha256", sa.String(71))) + op.add_column(table, sa.Column("selected_post_submit_policy_body", postgresql.JSONB())) + op.create_check_constraint( + "selected_post_submit_policy", table, + "(selected_post_submit_policy_sha256 is null and selected_post_submit_policy_body is null) or (selected_post_submit_policy_sha256 ~ '^sha256:[0-9a-f]{64}$' and jsonb_typeof(selected_post_submit_policy_body)='object')", + ) + + table = "submission_bundle_durable_intents" + op.alter_column(table, "pre_submit_evidence_set_id", existing_type=sa.Uuid(), nullable=True) + op.add_column(table, sa.Column("selected_pre_submit_run_id", sa.Uuid(as_uuid=False))) + op.add_column(table, sa.Column("selected_request_json", postgresql.JSONB())) + op.add_column(table, sa.Column("selected_request_digest", sa.String(71))) + op.add_column(table, sa.Column("selected_terminal_json", postgresql.JSONB())) + op.add_column(table, sa.Column("selected_terminal_digest", sa.String(71))) + op.create_foreign_key(op.f("fk_submission_bundle_durable_intents_selected_pre_submit_run_id_selected_pre_submit_runs"), table, "selected_pre_submit_runs", ["selected_pre_submit_run_id"], ["id"], ondelete="RESTRICT") + op.create_index(op.f("ix_submission_bundle_durable_intents_selected_pre_submit_run_id"), table, ["selected_pre_submit_run_id"]) + op.create_unique_constraint("uq_submission_bundle_intent_selected_run", table, ["selected_pre_submit_run_id"]) + op.create_check_constraint("pre_submit_lineage", table, "((pre_submit_evidence_set_id is not null)::int + (selected_pre_submit_run_id is not null)::int)=1") + op.create_check_constraint("selected_snapshot", table, "(pre_submit_evidence_set_id is not null and selected_request_json is null and selected_request_digest is null and selected_terminal_json is null and selected_terminal_digest is null) or (selected_pre_submit_run_id is not null and jsonb_typeof(selected_request_json)='object' and selected_request_digest ~ '^sha256:[0-9a-f]{64}$' and jsonb_typeof(selected_terminal_json)='object' and selected_terminal_digest ~ '^sha256:[0-9a-f]{64}$')") + + table = "submission_bundle_admissions" + op.alter_column(table, "pre_submit_evidence_set_id", existing_type=sa.Uuid(), nullable=True) + columns = ( + sa.Column("selected_pre_submit_run_id", sa.Uuid(as_uuid=False)), + sa.Column("guide_id", sa.Uuid(as_uuid=False)), sa.Column("guide_version", sa.String(50)), + sa.Column("source_snapshot_id", sa.Uuid(as_uuid=False)), sa.Column("source_snapshot_sha256", sa.String(71)), + sa.Column("effective_policy_id", sa.Uuid(as_uuid=False)), sa.Column("effective_policy_sha256", sa.String(71)), + sa.Column("pre_submit_policy_id", sa.Uuid(as_uuid=False)), sa.Column("pre_submit_policy_sha256", sa.String(71)), + sa.Column("effective_plan_sha256", sa.String(71)), sa.Column("selected_rules_sha256", sa.String(71)), + sa.Column("selected_post_submit_policy_sha256", sa.String(71)), sa.Column("selected_post_submit_policy_body", postgresql.JSONB()), + sa.Column("packet_sha256", sa.String(71)), sa.Column("semantic_manifest_body", postgresql.JSONB()), + ) + for column in columns: + op.add_column(table, column) + op.create_foreign_key(op.f("fk_submission_bundle_admissions_selected_pre_submit_run_id_selected_pre_submit_runs"), table, "selected_pre_submit_runs", ["selected_pre_submit_run_id"], ["id"], ondelete="RESTRICT") + op.create_index("ix_submission_bundle_admissions_selected_pre_submit_run_id", table, ["selected_pre_submit_run_id"]) + op.create_unique_constraint("uq_submission_bundle_admission_selected_run", table, ["selected_pre_submit_run_id"]) + op.create_check_constraint("pre_submit_lineage", table, "((pre_submit_evidence_set_id is not null)::int + (selected_pre_submit_run_id is not null)::int)=1") + op.create_check_constraint("manifest_body", table, "(selected_pre_submit_run_id is null and semantic_manifest_body is null) or (selected_pre_submit_run_id is not null and jsonb_typeof(semantic_manifest_body)='object')") + for name in ("packet_sha256", "effective_plan_sha256", "selected_rules_sha256"): + op.create_check_constraint(name, table, f"(selected_pre_submit_run_id is null and {name} is null) or (selected_pre_submit_run_id is not null and {name} ~ '^sha256:[0-9a-f]{{64}}$')") + op.create_check_constraint("selected_post_submit_policy", table, "(selected_pre_submit_run_id is null and selected_post_submit_policy_sha256 is null and selected_post_submit_policy_body is null) or (selected_pre_submit_run_id is not null and selected_post_submit_policy_sha256 ~ '^sha256:[0-9a-f]{64}$' and jsonb_typeof(selected_post_submit_policy_body)='object')") + op.create_check_constraint("locked_policy_digests", table, "(selected_pre_submit_run_id is null and guide_id is null and guide_version is null and source_snapshot_id is null and source_snapshot_sha256 is null and effective_policy_id is null and effective_policy_sha256 is null and pre_submit_policy_id is null and pre_submit_policy_sha256 is null) or (selected_pre_submit_run_id is not null and guide_id is not null and octet_length(guide_version) between 1 and 50 and source_snapshot_id is not null and effective_policy_id is not null and pre_submit_policy_id is not null and source_snapshot_sha256 ~ '^sha256:[0-9a-f]{64}$' and effective_policy_sha256 ~ '^sha256:[0-9a-f]{64}$' and pre_submit_policy_sha256 ~ '^sha256:[0-9a-f]{64}$')") + + + +def _replace_admission_guards() -> None: + op.execute(r""" +create or replace function public.guard_submission_bundle_durable_intent_put_attempt() +returns trigger language plpgsql set search_path=pg_catalog,public,pg_temp as $$ +declare request_type text; selected_matches integer; +begin + select producer_request_type into request_type from public.artifact_put_attempts + where id=new.put_attempt_id for share; + if request_type is distinct from 'submission_bundle' then + raise exception 'submission bundle durable intent requires submission_bundle put attempt' + using errcode='23514'; + end if; + if new.selected_pre_submit_run_id is not null then + select count(*) into selected_matches + from public.selected_pre_submit_runs r + join public.artifact_put_attempts a on a.id=new.put_attempt_id + where r.id=new.selected_pre_submit_run_id and r.status='completed' and r.eligible + and new.selected_request_json=r.request_json + and new.selected_request_digest=r.request_digest + and new.selected_terminal_json=r.terminal_json + and new.selected_terminal_digest=r.terminal_digest + and a.producer_type='actor_profile' and a.producer_ref=r.actor_profile_id::text + and a.project_id=r.project_id and a.task_id=r.task_id + and a.sha256=r.archive_sha256 and a.byte_count=r.archive_byte_count + and a.media_type='application/zip'; + if selected_matches<>1 then + raise exception 'selected PRE durable intent custody mismatch' using errcode='23514'; + end if; + end if; + return new; +end $$ +""") + op.execute(r""" +create or replace function public.guard_submission_bundle_admission_lineage() +returns trigger language plpgsql set search_path=pg_catalog,public,pg_temp as $$ +begin + if (to_jsonb(old)-array['status','consumed_at','consumed_by_submission_id', + 'consumed_by_submission_version','stale_at','stale_reason']::text[]) + is distinct from + (to_jsonb(new)-array['status','consumed_at','consumed_by_submission_id', + 'consumed_by_submission_version','stale_at','stale_reason']::text[]) then + raise exception 'submission bundle admission lineage is immutable' using errcode='55000'; + end if; + if old.status<>'ready' or new.status not in ('consumed','stale') then + raise exception 'invalid submission bundle admission transition' using errcode='23514'; + end if; + return new; +end $$ +""") + op.execute(r""" +create or replace function public.guard_submission_bundle_admission_verified_lineage() +returns trigger language plpgsql set search_path=pg_catalog,public,pg_temp as $$ +declare matches integer; +begin + if new.pre_submit_evidence_set_id is not null then + select count(*) into matches + from public.submission_bundle_durable_intents intent + join public.pre_submit_evidence_sets evidence on evidence.id=intent.pre_submit_evidence_set_id + join public.artifact_put_attempts attempt on attempt.id=intent.put_attempt_id + join public.artifact_replicas replica on replica.id=attempt.replica_id + join public.artifact_contents content on content.id=replica.content_id + join public.artifact_verification_jobs job + on job.originating_put_attempt_id=attempt.id and job.replica_id=replica.id + join public.artifact_verification_receipts verification on verification.verification_job_id=job.id + where intent.id=new.durable_intent_id and evidence.id=new.pre_submit_evidence_set_id + and attempt.id=new.put_attempt_id and content.id=new.artifact_content_id + and replica.id=new.verified_replica_id and verification.id=new.verification_receipt_id + and attempt.producer_request_type='submission_bundle' + and attempt.producer_type='actor_profile' and attempt.producer_ref=evidence.actor_profile_id::text + and attempt.project_id=evidence.project_id and attempt.task_id=evidence.task_id + and attempt.media_type='application/zip' and content.media_type='application/zip' + and attempt.status='object_confirmed' and evidence.terminal_status='passed' and evidence.eligible + and replica.verification_state='verified' and replica.availability_state='available' + and replica.integrity_state='valid' and verification.outcome='verified' + and verification.execution_generation=job.execution_generation + and verification.observed_sha256=attempt.sha256 + and verification.observed_sha256=content.sha256 + and verification.observed_sha256=evidence.archive_sha256 + and verification.observed_byte_count=attempt.byte_count + and verification.observed_byte_count=content.byte_count + and verification.observed_byte_count=evidence.archive_byte_count + and new.actor_profile_id=evidence.actor_profile_id + and new.identity_link_id=evidence.identity_link_id + and new.project_id=evidence.project_id and new.task_id=evidence.task_id + and new.assignment_id=evidence.assignment_id + and new.predecessor_submission_id is not distinct from evidence.predecessor_submission_id + and new.predecessor_submission_version is not distinct from evidence.predecessor_submission_version + and new.locked_policy_context_hash=evidence.locked_policy_context_hash + and new.semantic_manifest_id=evidence.semantic_manifest_id + and new.semantic_manifest_sha256=evidence.semantic_manifest_sha256 + and new.archive_sha256=evidence.archive_sha256 and new.archive_byte_count=evidence.archive_byte_count + and ((new.put_operation_receipt_id is not null and exists( + select 1 from public.artifact_operation_receipts receipt + where receipt.id=new.put_operation_receipt_id and receipt.put_attempt_id=attempt.id + and receipt.replica_id=replica.id and receipt.outcome='stored_pending_verification')) + or (new.put_observation_receipt_id is not null and exists( + select 1 from public.artifact_put_observation_receipts observation + where observation.id=new.put_observation_receipt_id and observation.put_attempt_id=attempt.id + and observation.outcome='observed_confirmed' + and observation.observed_sha256=attempt.sha256 + and observation.observed_byte_count=attempt.byte_count))); + else + select count(*) into matches + from public.submission_bundle_durable_intents intent + join public.selected_pre_submit_runs r on r.id=intent.selected_pre_submit_run_id + join public.artifact_put_attempts attempt on attempt.id=intent.put_attempt_id + join public.artifact_replicas replica on replica.id=attempt.replica_id + join public.artifact_contents content on content.id=replica.content_id + join public.artifact_verification_jobs job + on job.originating_put_attempt_id=attempt.id and job.replica_id=replica.id + join public.artifact_verification_receipts verification on verification.verification_job_id=job.id + where intent.id=new.durable_intent_id and r.id=new.selected_pre_submit_run_id + and r.status='completed' and r.eligible and intent.selected_request_json=r.request_json + and intent.selected_request_digest=r.request_digest + and intent.selected_terminal_json=r.terminal_json and intent.selected_terminal_digest=r.terminal_digest + and attempt.id=new.put_attempt_id and content.id=new.artifact_content_id + and replica.id=new.verified_replica_id and verification.id=new.verification_receipt_id + and attempt.producer_request_type='submission_bundle' + and attempt.producer_type='actor_profile' and attempt.producer_ref=r.actor_profile_id::text + and attempt.project_id=r.project_id and attempt.task_id=r.task_id + and attempt.media_type='application/zip' and content.media_type='application/zip' + and attempt.status='object_confirmed' and replica.verification_state='verified' + and replica.availability_state='available' and replica.integrity_state='valid' + and verification.outcome='verified' and verification.execution_generation=job.execution_generation + and verification.observed_sha256=attempt.sha256 and verification.observed_sha256=content.sha256 + and verification.observed_sha256=r.archive_sha256 + and verification.observed_byte_count=attempt.byte_count + and verification.observed_byte_count=content.byte_count + and verification.observed_byte_count=r.archive_byte_count + and new.actor_profile_id=r.actor_profile_id + and new.identity_link_id=r.identity_link_id and new.project_id=r.project_id + and new.task_id=r.task_id and new.assignment_id=r.assignment_id + and new.predecessor_submission_id is not distinct from + nullif(r.request_json#>>'{admission_lineage,predecessor_submission_id}','')::uuid + and new.predecessor_submission_version is not distinct from + (r.request_json#>>'{admission_lineage,predecessor_submission_version}')::integer + and new.guide_id=(r.request_json#>>'{admission_lineage,guide_id}')::uuid + and new.guide_version=r.request_json#>>'{admission_lineage,guide_version}' + and new.source_snapshot_id=(r.request_json#>>'{admission_lineage,source_snapshot_id}')::uuid + and new.source_snapshot_sha256=r.request_json#>>'{admission_lineage,source_snapshot_sha256}' + and new.effective_policy_id=(r.request_json#>>'{admission_lineage,effective_policy_id}')::uuid + and new.effective_policy_sha256=r.request_json#>>'{admission_lineage,effective_policy_sha256}' + and new.pre_submit_policy_id=(r.request_json#>>'{admission_lineage,pre_submit_policy_id}')::uuid + and new.pre_submit_policy_sha256=r.request_json#>>'{admission_lineage,pre_submit_policy_sha256}' + and new.effective_plan_sha256=r.request_json#>>'{admission_lineage,effective_plan_sha256}' + and new.selected_rules_sha256=r.request_json#>>'{admission_lineage,rules_sha256}' + and new.selected_post_submit_policy_sha256=r.request_json#>>'{admission_lineage,post_submit_policy_sha256}' + and new.selected_post_submit_policy_body=r.request_json#>'{admission_lineage,post_submit_policy_body}' + and new.locked_policy_context_hash=r.request_json#>>'{admission_lineage,locked_policy_context_hash}' + and new.packet_sha256=r.request_json#>>'{admission_lineage,packet_sha256}' + and new.semantic_manifest_id=(r.request_json#>>'{admission_lineage,semantic_manifest_id}')::uuid + and new.semantic_manifest_body=r.request_json#>'{admission_lineage,semantic_manifest_body}' + and new.semantic_manifest_sha256=r.semantic_manifest_sha256 + and new.archive_sha256=r.archive_sha256 and new.archive_byte_count=r.archive_byte_count + and ((new.put_operation_receipt_id is not null and exists( + select 1 from public.artifact_operation_receipts receipt + where receipt.id=new.put_operation_receipt_id and receipt.put_attempt_id=attempt.id + and receipt.replica_id=replica.id and receipt.outcome='stored_pending_verification')) + or (new.put_observation_receipt_id is not null and exists( + select 1 from public.artifact_put_observation_receipts observation + where observation.id=new.put_observation_receipt_id and observation.put_attempt_id=attempt.id + and observation.outcome='observed_confirmed' + and observation.observed_sha256=attempt.sha256 + and observation.observed_byte_count=attempt.byte_count))); + end if; + if matches<>1 then + raise exception 'submission bundle admission verified lineage mismatch' using errcode='23514'; + end if; + return new; +end $$ +""") + +def _selected_run_guards() -> None: + op.execute(r""" +create function public.selected_pre_submit_facts_digest(r public.selected_pre_submit_runs, phase text) +returns text language sql immutable strict set search_path=pg_catalog,public,pg_temp as $$ + select case phase + when 'execute' then 'sha256:'||encode(sha256(convert_to(public.project_guide_projection_canonical_json( + jsonb_build_object('schema_version','workstream.selected_pre_submit_execute.v1', + 'reservation',r.request_json,'lease_id',r.lease_id::text, + 'lease_generation',r.lease_generation,'lease_expires_at',public.outbox_dispatch_utc(r.lease_expires_at))), 'UTF8')),'hex') + when 'finalize' then 'sha256:'||encode(sha256(convert_to(public.project_guide_projection_canonical_json( + jsonb_build_object('schema_version','workstream.selected_pre_submit_finalize.v1', + 'execute_facts_digest',public.selected_pre_submit_facts_digest(r,'execute'), + 'execution',r.terminal_json->'execution', + 'infrastructure_failure_code',r.terminal_json->'infrastructure_failure_code')), 'UTF8')),'hex') + else null end +$$ +""") + op.execute(r""" +create function public.selected_pre_submit_receipt_valid(r public.selected_pre_submit_runs, phase text, require_active boolean) +returns boolean language sql stable set search_path=pg_catalog,public,pg_temp as $$ + select coalesce(exists( + select 1 from public.audit_events a + join public.actor_profiles p on p.id::text=a.actor_id + join public.actor_identity_links l on l.actor_profile_id=p.id + where a.id=case when phase='execute' then r.execute_evidence_id else r.finalize_evidence_id end + and phase in ('execute','finalize') + and a.event_domain='authority' and a.event_type='SensitiveAuthorizationAllowed' + and a.actor_ref_kind='actor_profile' and p.actor_kind='service' + and p.service_identity='workstream.checker.pre_submit' and l.subject_kind='service' + and (not require_active or (p.status='active' and l.status='active')) + and a.action_id='checker.pre_submit.'||phase and a.permission_id=a.action_id + and a.denial_code is null and a.matched_grant_id is null + and a.project_id=r.project_id and a.resource_type='selected_pre_submit_run' + and a.resource_id=r.id::text and a.target_ref_kind='project' + and a.target_ref_id=r.project_id::text and a.request_id=r.id and a.correlation_id=r.id + and a.after_facts::jsonb=jsonb_build_object('allowed',true, + 'resource_context_digest',public.selected_pre_submit_facts_digest(r,phase)) + and (phase='execute' or (r.execute_evidence_id is not null + and r.finalize_evidence_id is distinct from r.execute_evidence_id + and r.status in ('completed','infrastructure_failed'))) + ),false) +$$ +""") + op.execute(r""" +create function public.guard_selected_pre_submit_run() returns trigger +language plpgsql set search_path=pg_catalog,public,pg_temp as $$ +declare current_run public.selected_pre_submit_runs%rowtype; +begin + if tg_op='DELETE' then raise exception 'selected PRE runs are retained' using errcode='55000'; end if; + if tg_op='TRUNCATE' then raise exception 'selected PRE runs cannot be truncated' using errcode='55000'; end if; + if row(old.id,old.actor_profile_id,old.identity_link_id,old.project_id,old.task_id, + old.assignment_id,old.idempotency_key,old.prepared_generation_id,old.request_json, + old.request_digest,old.policy_sha256,old.default_behavior_sha256,old.default_input_sha256, + old.archive_sha256,old.archive_byte_count,old.semantic_manifest_sha256, + old.execution_budget_ms,old.queued_at) + is distinct from + row(new.id,new.actor_profile_id,new.identity_link_id,new.project_id,new.task_id, + new.assignment_id,new.idempotency_key,new.prepared_generation_id,new.request_json, + new.request_digest,new.policy_sha256,new.default_behavior_sha256,new.default_input_sha256, + new.archive_sha256,new.archive_byte_count,new.semantic_manifest_sha256, + new.execution_budget_ms,new.queued_at) + then raise exception 'selected PRE request custody is immutable' using errcode='55000'; end if; + if not ((old.status='queued' and new.status='running' and new.lease_generation=1) + or (old.status='running' and new.status in ('completed','infrastructure_failed') + and new.lease_generation=old.lease_generation)) + then raise exception 'selected PRE lifecycle transition is invalid' using errcode='23514'; end if; + return new; +end $$ +""") + op.execute("create trigger selected_pre_submit_run_update before update on public.selected_pre_submit_runs for each row execute function public.guard_selected_pre_submit_run()") + op.execute("create trigger selected_pre_submit_run_delete before delete on public.selected_pre_submit_runs for each row execute function public.guard_selected_pre_submit_run()") + op.execute("create trigger selected_pre_submit_run_truncate before truncate on public.selected_pre_submit_runs for each statement execute function public.guard_selected_pre_submit_run()") + op.execute(r""" +create function public.guard_selected_pre_submit_receipts() returns trigger +language plpgsql set search_path=pg_catalog,public,pg_temp as $$ +declare current_run public.selected_pre_submit_runs%rowtype; new_execute boolean; new_finalize boolean; +begin + select * into current_run from public.selected_pre_submit_runs where id=new.id; + if not found then raise exception 'selected PRE authority parent is missing' using errcode='23514'; end if; + if tg_op='INSERT' then + new_execute := current_run.execute_evidence_id is not null; + new_finalize := current_run.finalize_evidence_id is not null; + else + new_execute := current_run.execute_evidence_id is distinct from old.execute_evidence_id; + new_finalize := current_run.finalize_evidence_id is distinct from old.finalize_evidence_id; + end if; + if (current_run.execute_evidence_id is not null and not public.selected_pre_submit_receipt_valid(current_run,'execute',new_execute)) + or (current_run.finalize_evidence_id is not null and not public.selected_pre_submit_receipt_valid(current_run,'finalize',new_finalize)) + then raise exception 'selected PRE authority receipt custody mismatch' using errcode='23514'; end if; + return null; +end $$ +""") + op.execute("create constraint trigger selected_pre_submit_receipt_custody after insert or update on public.selected_pre_submit_runs deferrable initially deferred for each row execute function public.guard_selected_pre_submit_receipts()") + + +def upgrade() -> None: + op.execute("set local search_path=pg_catalog,public,pg_temp") + op.execute("lock table public.actor_profiles, public.actor_identity_links, public.audit_events, public.submissions, public.checker_runs, public.submission_bundle_durable_intents, public.submission_bundle_admissions in access exclusive mode") + _extend_authority_vocabulary() + _create_selected_run_table() + _alter_selected_lineage() + _replace_admission_guards() + _selected_run_guards() + + +def downgrade() -> None: + raise RuntimeError("Workstream v0.1 migrations cannot be downgraded; recreate the database") diff --git a/backend/app/modules/checkers/models.py b/backend/app/modules/checkers/models.py index a062f1b14..2f6434077 100644 --- a/backend/app/modules/checkers/models.py +++ b/backend/app/modules/checkers/models.py @@ -225,6 +225,13 @@ class CheckerRun(Base): ForeignKeyConstraint(["task_id", "project_id"], ["workstream_tasks.id", "workstream_tasks.project_id"], name="fk_checker_runs_task_project"), CheckConstraint("phase = 'post_submission'", name="phase"), + CheckConstraint( + "(selected_post_submit_policy_sha256 is null and " + "selected_post_submit_policy_body is null) or " + "(selected_post_submit_policy_sha256 ~ '^sha256:[0-9a-f]{64}$' and " + "jsonb_typeof(selected_post_submit_policy_body)='object')", + name="selected_post_submit_policy", + ), CheckConstraint("evaluation_generation > 0 and worker_lease_generation >= 0", name="generations"), CheckConstraint("status in ('queued','running','completed','infrastructure_failed')", name="state"), CheckConstraint("octet_length(request_json) <= 1048576 and request_digest = 'sha256:' || encode(sha256(convert_to(request_json, 'UTF8')), 'hex')", name="request_digest"), @@ -288,7 +295,7 @@ class CheckerRun(Base): ) locked_post_submit_checker_policy_hash: Mapped[str] = mapped_column(String(71), nullable=False) selected_post_submit_policy_sha256: Mapped[str | None] = mapped_column(String(71)) - selected_post_submit_policy_body: Mapped[dict | None] = mapped_column(JSON) + selected_post_submit_policy_body: Mapped[dict | None] = mapped_column(JSONB) locked_review_policy_id: Mapped[str] = mapped_column(Uuid(as_uuid=False), nullable=False) locked_review_policy_generation: Mapped[int] = mapped_column(Integer, nullable=False) locked_review_policy_hash: Mapped[str] = mapped_column(String(71), nullable=False) diff --git a/backend/app/modules/tasks/models.py b/backend/app/modules/tasks/models.py index 630cc3ed3..df2605dbe 100644 --- a/backend/app/modules/tasks/models.py +++ b/backend/app/modules/tasks/models.py @@ -550,6 +550,13 @@ class Submission(Base): "and artifact_binding_id is not null and artifact_content_id is not null)", name="artifact_lineage_shape", ), + CheckConstraint( + "(selected_post_submit_policy_sha256 is null and " + "selected_post_submit_policy_body is null) or " + "(selected_post_submit_policy_sha256 ~ '^sha256:[0-9a-f]{64}$' and " + "jsonb_typeof(selected_post_submit_policy_body)='object')", + name="selected_post_submit_policy", + ), Index( "ix_submissions_locked_source_snapshot", "locked_guide_source_snapshot_id", @@ -603,7 +610,7 @@ class Submission(Base): locked_post_submit_checker_policy_hash: Mapped[str] = mapped_column(String(71), nullable=False) locked_post_submit_checker_policy_body: Mapped[dict] = mapped_column(JSON, nullable=False) selected_post_submit_policy_sha256: Mapped[str | None] = mapped_column(String(71)) - selected_post_submit_policy_body: Mapped[dict | None] = mapped_column(JSON) + selected_post_submit_policy_body: Mapped[dict | None] = mapped_column(JSONB) locked_review_policy_id: Mapped[str] = mapped_column(Uuid(as_uuid=False), nullable=False) locked_review_policy_generation: Mapped[int] = mapped_column(Integer, nullable=False) locked_review_policy_hash: Mapped[str] = mapped_column(String(71), nullable=False) diff --git a/backend/tests/conftest.py b/backend/tests/conftest.py index b7d287eb3..9c2b62254 100644 --- a/backend/tests/conftest.py +++ b/backend/tests/conftest.py @@ -23,7 +23,7 @@ DDL_LOCK_DIRECTORY = Path("/tmp") # Match the PostgreSQL 16 engine used by Backend CI. Catalog identity rendering # differs across major versions; regenerate only after comparing actual objects. -EXPECTED_PUBLIC_SCHEMA_SHA256 = "6b698d4bca1e7a9351df2a5a64928c7823831cacd4b0a68c5f2c012d0a165f21" +EXPECTED_PUBLIC_SCHEMA_SHA256 = "312484b62c1e6c6459f16bb7cb3530d0cd2e7bb88f4c273365e809ad4ee4989c" PROTECTED_TEST_TABLES = ( "actor_profile_migration_state", "alembic_version", @@ -126,6 +126,7 @@ "review_queue_entries", "submission_policy_mutation_idempotency_records", "submission_artifact_policies", + "selected_pre_submit_runs", "submission_bundle_admissions", "submission_dispatches", "submission_binding_receipts", @@ -222,6 +223,7 @@ "review_queue_entries", "review_policies", "revision_policies", + "selected_pre_submit_runs", "submission_bundle_admissions", "submission_dispatches", "submission_binding_receipts", diff --git a/backend/tests/test_alembic.py b/backend/tests/test_alembic.py index 078d3377a..8126c30b2 100644 --- a/backend/tests/test_alembic.py +++ b/backend/tests/test_alembic.py @@ -79,7 +79,7 @@ def test_v01_graph_has_one_root_and_head() -> None: script = ScriptDirectory.from_config(config) revisions = list(script.walk_revisions()) - assert [revision.revision for revision in revisions] == [HEAD_REVISION, "0035_task_batch_transitions", "0034_task_import_batches", "0033_contribution_reads", "0032_checker_remediation", "0031_task_import_source", "0030_routing_outcomes", "0029_external_checker_registry", "0028_lifecycle_transitions", "0027_markdown_guide_media", "0026_task_guide_read", "0025_submission_dispatch", "0024_require_second_review_false", "0023_remove_task_payment_policy", "0022_submission_packet_custody", "0021_submission_manifest", "0020_review_admission_lock_order", "0019_submitter_awards", "0018_task_routing_request", "0017_acceptance_source_contracts", "0016_review_lifecycle_fence", "0015_contribution_awards", "0014_final_acceptance", "0013_review_source", "0012_review_packet", "0011_task_routing_source", "0010_post_submit_authority", "0009_checker_material_lineage", "0008_checker_execution", "0007_checker_output_custody", "0006_history_read_authority", "0005_task_evidence_authority", "0004_task_context_authority", "0003_task_read_authority", "0002_task_queue_authority", BASELINE_REVISION] + assert [revision.revision for revision in revisions] == [HEAD_REVISION, "0036_contribution_export_pages", "0035_task_batch_transitions", "0034_task_import_batches", "0033_contribution_reads", "0032_checker_remediation", "0031_task_import_source", "0030_routing_outcomes", "0029_external_checker_registry", "0028_lifecycle_transitions", "0027_markdown_guide_media", "0026_task_guide_read", "0025_submission_dispatch", "0024_require_second_review_false", "0023_remove_task_payment_policy", "0022_submission_packet_custody", "0021_submission_manifest", "0020_review_admission_lock_order", "0019_submitter_awards", "0018_task_routing_request", "0017_acceptance_source_contracts", "0016_review_lifecycle_fence", "0015_contribution_awards", "0014_final_acceptance", "0013_review_source", "0012_review_packet", "0011_task_routing_source", "0010_post_submit_authority", "0009_checker_material_lineage", "0008_checker_execution", "0007_checker_output_custody", "0006_history_read_authority", "0005_task_evidence_authority", "0004_task_context_authority", "0003_task_read_authority", "0002_task_queue_authority", BASELINE_REVISION] assert revisions[-1].down_revision is None assert script.get_heads() == [HEAD_REVISION] From a61348d5b084f9ae821038fbf82c89cced53b11c Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 21:17:58 +0100 Subject: [PATCH 083/283] [PILOT-04] Finalize expired checker leases --- .../selected_pre_submit_execution.py | 36 +++++++++++++ .../checkers/api/selected_pre_submit.py | 5 ++ .../selected_pre_submit_coordination.py | 23 +++++++++ .../test_selected_pre_submit_coordination.py | 31 ++++++++++++ .../test_selected_pre_submit_service.py | 50 +++++++++++++++++++ 5 files changed, 145 insertions(+) diff --git a/backend/app/modules/artifacts/selected_pre_submit_execution.py b/backend/app/modules/artifacts/selected_pre_submit_execution.py index b0d817eb9..5157f31f1 100644 --- a/backend/app/modules/artifacts/selected_pre_submit_execution.py +++ b/backend/app/modules/artifacts/selected_pre_submit_execution.py @@ -2,6 +2,8 @@ from __future__ import annotations +from uuid import UUID + from sqlalchemy.ext.asyncio import AsyncSession from app.modules.artifacts.submission_materialization import ( @@ -84,5 +86,39 @@ async def execute( infrastructure_failure_code=infrastructure_failure_code, ) + async def recover_expired( + self, + *, + run_id: UUID, + reservation: SelectedPreSubmitReservationFacts, + ) -> SelectedPreSubmitCompletion: + """Finalize a crashed lease without recreating its process-local grant.""" + if run_id != reservation.attempt_id: + raise SelectedPreSubmitInfrastructureUnavailable( + "material_unavailable" + ) + async with self._session.begin(): + lease = await self._coordinator.read_expired_lease( + run_id=reservation.attempt_id, + facts=reservation, + ) + + finalize_facts = SelectedPreSubmitFinalizeFacts( + lease=lease, + execution=None, + infrastructure_failure_code="deadline_exceeded", + ) + async with self._session.begin(): + async with self._authority.prepare_finalization( + finalize_facts + ) as prepared: + return await self._coordinator.finalize( + run_id=reservation.attempt_id, + lease=lease, + authority=prepared, + execution=None, + infrastructure_failure_code="deadline_exceeded", + ) + __all__ = ("SelectedPreSubmitExecutionService",) diff --git a/backend/app/modules/checkers/api/selected_pre_submit.py b/backend/app/modules/checkers/api/selected_pre_submit.py index a76de1c4b..8f5716522 100644 --- a/backend/app/modules/checkers/api/selected_pre_submit.py +++ b/backend/app/modules/checkers/api/selected_pre_submit.py @@ -693,6 +693,11 @@ async def committed_execution( ) -> SelectedPreSubmitExecutionAuthority: """Mint process-local execution authority for a committed lease.""" + async def read_expired_lease( + self, *, run_id: UUID, facts: SelectedPreSubmitReservationFacts + ) -> SelectedPreSubmitLeaseFacts: + """Read one expired committed lease under TASK-first custody.""" + async def finalize( self, *, diff --git a/backend/app/modules/checkers/selected_pre_submit_coordination.py b/backend/app/modules/checkers/selected_pre_submit_coordination.py index 2f153dd11..9cdf1d81c 100644 --- a/backend/app/modules/checkers/selected_pre_submit_coordination.py +++ b/backend/app/modules/checkers/selected_pre_submit_coordination.py @@ -404,6 +404,29 @@ async def committed_execution( self._execution_capability = capability return capability + async def read_expired_lease( + self, *, run_id: UUID, facts: SelectedPreSubmitReservationFacts + ) -> SelectedPreSubmitLeaseFacts: + """Discover an expired lease without reconstructing its ART capability.""" + row = await self._lock(run_id=run_id, facts=facts) + now = await self._session.scalar(select(func.clock_timestamp())) + if ( + now is None + or row.status != "running" + or row.lease_id is None + or row.lease_expires_at is None + or row.lease_expires_at >= now + ): + raise SelectedPreSubmitUnavailable( + "selected_pre_submit_expired_lease_unavailable" + ) + return SelectedPreSubmitLeaseFacts( + reservation=facts, + lease_id=UUID(row.lease_id), + lease_generation=row.lease_generation, + lease_expires_at=row.lease_expires_at, + ) + async def finalize( self, *, diff --git a/backend/tests/checkers/external/test_selected_pre_submit_coordination.py b/backend/tests/checkers/external/test_selected_pre_submit_coordination.py index 368f82edc..5c6953ee0 100644 --- a/backend/tests/checkers/external/test_selected_pre_submit_coordination.py +++ b/backend/tests/checkers/external/test_selected_pre_submit_coordination.py @@ -3,6 +3,7 @@ from __future__ import annotations from dataclasses import replace +from datetime import UTC, datetime, timedelta from types import SimpleNamespace from unittest.mock import AsyncMock from uuid import UUID @@ -132,6 +133,36 @@ async def test_selected_pre_current_replays_only_stable_actor_key_facts() -> Non ) +@pytest.mark.asyncio +async def test_selected_pre_expired_lease_read_keeps_task_first_custody() -> None: + reservation = _reservation() + row = _queued_row(reservation) + row.status = "running" + row.lease_id = str(new_record_id()) + row.lease_generation = 3 + row.lease_expires_at = datetime.now(UTC) - timedelta(seconds=1) + now = datetime.now(UTC) + transaction = SimpleNamespace(is_active=True) + session = SimpleNamespace( + sync_session=SimpleNamespace(get_transaction=lambda: transaction), + in_nested_transaction=lambda: False, + scalar=AsyncMock(side_effect=[row, now]), + ) + tasks = SimpleNamespace(lock_selected_pre_submit_scope=AsyncMock()) + coordinator = SelectedPreSubmitCoordinator(session, tasks=tasks) + + lease = await coordinator.read_expired_lease( + run_id=reservation.attempt_id, + facts=reservation, + ) + + assert lease.reservation == reservation + assert lease.lease_id == UUID(row.lease_id) + assert lease.lease_generation == 3 + assert lease.lease_expires_at == row.lease_expires_at + tasks.lock_selected_pre_submit_scope.assert_awaited_once_with(reservation) + + @pytest.mark.asyncio async def test_selected_pre_task_guard_rechecks_exact_locked_lineage(monkeypatch) -> None: lineage = SelectedPreSubmitAdmissionLineage( diff --git a/backend/tests/checkers/external/test_selected_pre_submit_service.py b/backend/tests/checkers/external/test_selected_pre_submit_service.py index 87d02f8cb..cf9f8469a 100644 --- a/backend/tests/checkers/external/test_selected_pre_submit_service.py +++ b/backend/tests/checkers/external/test_selected_pre_submit_service.py @@ -89,6 +89,11 @@ async def committed_execution(self, **_values): self.order.append("committed_execution") return object() + async def read_expired_lease(self, **_values): + assert self.session.active + self.order.append("read_expired_lease") + return self.lease + async def finalize(self, *, authority, execution, infrastructure_failure_code, **_values): assert self.session.active self.order.append("finalize") @@ -171,3 +176,48 @@ async def test_selected_pre_execution_commits_lease_before_work_and_finalizes_af "consume_finalize", "commit", ] + + +@pytest.mark.asyncio +async def test_selected_pre_recovery_finalizes_expired_lease_without_material() -> None: + order: list[str] = [] + session = _Session(order) + reservation = _reservation() + lease = SelectedPreSubmitLeaseFacts( + reservation=reservation, + lease_id=new_record_id(), + lease_generation=1, + lease_expires_at=datetime.now(UTC) - timedelta(seconds=1), + ) + service = SelectedPreSubmitExecutionService( + session=session, + coordinator=_Coordinator(session, order, lease), + authority=_Authority(session, order), + materialization=_Materialization(session, order), + ) + + completed = await service.recover_expired( + run_id=reservation.attempt_id, + reservation=reservation, + ) + + assert completed.terminal.infrastructure_failure_code == "deadline_exceeded" + assert order == [ + "begin", + "read_expired_lease", + "commit", + "begin", + "prepare_finalize", + "finalize", + "consume_finalize", + "commit", + ] + + with pytest.raises( + SelectedPreSubmitInfrastructureUnavailable, + match="material_unavailable", + ): + await service.recover_expired( + run_id=new_record_id(), + reservation=reservation, + ) From 4a460546a7448975ff0d99fdd7c7ef16cfbafa3e Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 21:20:03 +0100 Subject: [PATCH 084/283] [PILOT-04] Reconcile expired preparation attempts --- .../modules/artifacts/submission_admission.py | 37 ++++++++++++++----- .../checkers/api/selected_pre_submit.py | 5 +++ .../selected_pre_submit_coordination.py | 6 +-- 3 files changed, 33 insertions(+), 15 deletions(-) diff --git a/backend/app/modules/artifacts/submission_admission.py b/backend/app/modules/artifacts/submission_admission.py index f88bd8bdc..f754977f2 100644 --- a/backend/app/modules/artifacts/submission_admission.py +++ b/backend/app/modules/artifacts/submission_admission.py @@ -83,6 +83,7 @@ SelectedPreSubmitCurrentFacts, SelectedPreSubmitReservationFacts, SelectedPreSubmitRequestConflict, + SelectedPreSubmitUnavailable, ) from app.modules.checkers.api.external_policy import ( LockedExternalCheckerPolicies, @@ -864,16 +865,32 @@ async def prepare( current = await runtime.selected_coordinator.read_current( reservation ) - if current is not None: - return await self._selected_replay_result(current) - await runtime.materialization.authorize_inspected( - materialization_request - ) - reserved_id = await runtime.selected_coordinator.reserve( - reservation - ) - if reserved_id != reservation.attempt_id: - raise RuntimeError("selected PRE reservation identity changed") + if current is None: + await runtime.materialization.authorize_inspected( + materialization_request + ) + reserved_id = await runtime.selected_coordinator.reserve( + reservation + ) + if reserved_id != reservation.attempt_id: + raise RuntimeError("selected PRE reservation identity changed") + if current is not None: + if current.status == "running": + try: + recovered = await runtime.selected_execution.recover_expired( + run_id=current.run_id, + reservation=current.reservation, + ) + except SelectedPreSubmitUnavailable: + pass + else: + current = SelectedPreSubmitCurrentFacts( + run_id=current.run_id, + reservation=current.reservation, + status="infrastructure_failed", + terminal=recovered.terminal, + ) + return await self._selected_replay_result(current) completion = await runtime.selected_execution.execute( reservation=reservation, materialization=replace( diff --git a/backend/app/modules/checkers/api/selected_pre_submit.py b/backend/app/modules/checkers/api/selected_pre_submit.py index 8f5716522..5d18fe1a2 100644 --- a/backend/app/modules/checkers/api/selected_pre_submit.py +++ b/backend/app/modules/checkers/api/selected_pre_submit.py @@ -886,6 +886,10 @@ class SelectedPreSubmitRequestConflict(RuntimeError): """Refuse one actor/key namespace reused with changed stable facts.""" +class SelectedPreSubmitUnavailable(RuntimeError): + """Conceal absent, stale or conflicting durable selected PRE custody.""" + + class SelectedPreSubmitAuthorityUnavailable(RuntimeError): """Conceal fixed-service PRE authorization loss without product facts.""" @@ -910,4 +914,5 @@ class SelectedPreSubmitAuthorityUnavailable(RuntimeError): "SelectedPreSubmitReservationFacts", "SelectedPreSubmitRequestConflict", "SelectedPreSubmitTerminalFacts", + "SelectedPreSubmitUnavailable", ) diff --git a/backend/app/modules/checkers/selected_pre_submit_coordination.py b/backend/app/modules/checkers/selected_pre_submit_coordination.py index 9cdf1d81c..ff373bb54 100644 --- a/backend/app/modules/checkers/selected_pre_submit_coordination.py +++ b/backend/app/modules/checkers/selected_pre_submit_coordination.py @@ -25,14 +25,11 @@ SelectedPreSubmitReservationFacts, SelectedPreSubmitRequestConflict, SelectedPreSubmitTerminalFacts, + SelectedPreSubmitUnavailable, ) from app.modules.checkers.models import SelectedPreSubmitRun -class SelectedPreSubmitUnavailable(RuntimeError): - """Conceal absent, foreign, stale, conflicting or already leased PRE custody.""" - - class SelectedPreSubmitTaskGuard(Protocol): """TASK owns current contributor/assignment/policy checks before CHECKERS locks.""" @@ -514,5 +511,4 @@ async def _lock( "SelectedPreSubmitCoordinator", "SelectedPreSubmitExecutionCapability", "SelectedPreSubmitTaskGuard", - "SelectedPreSubmitUnavailable", ) From fd541700965ca198a6dd41f6bc7b834a44ebaf16 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 21:20:07 +0100 Subject: [PATCH 085/283] [PILOT-04] Use selected custody API exception --- .../checkers/external/test_selected_pre_submit_coordination.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/tests/checkers/external/test_selected_pre_submit_coordination.py b/backend/tests/checkers/external/test_selected_pre_submit_coordination.py index 5c6953ee0..05a68b104 100644 --- a/backend/tests/checkers/external/test_selected_pre_submit_coordination.py +++ b/backend/tests/checkers/external/test_selected_pre_submit_coordination.py @@ -28,6 +28,7 @@ SelectedPreSubmitLeaseFacts, SelectedPreSubmitReservationFacts, SelectedPreSubmitRequestConflict, + SelectedPreSubmitUnavailable, ) from app.adapters.tasks import selected_pre_submit_task_guard from app.modules.tasks.repository import TaskRepository @@ -36,7 +37,6 @@ SelectedPreSubmitAdmissionCapability, SelectedPreSubmitExecutionCapability, SelectedPreSubmitCoordinator, - SelectedPreSubmitUnavailable, ) from tests.checkers.external.support import SHA From c541e28e37dc20036059040b7d6efc6003fc0874 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 21:21:27 +0100 Subject: [PATCH 086/283] [PILOT-04] Detach selected activation from legacy catalogue --- backend/app/modules/projects/guide_activation/service.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/app/modules/projects/guide_activation/service.py b/backend/app/modules/projects/guide_activation/service.py index 59cefbd18..87c26251b 100644 --- a/backend/app/modules/projects/guide_activation/service.py +++ b/backend/app/modules/projects/guide_activation/service.py @@ -249,7 +249,7 @@ async def _readiness(self, command, locked, policy, post, review, revision): raise GuideProposalError("approval_blocked") else: require_catalogues(target, self.pre_catalogue, self.post_catalogue) - post.compiled.validate_catalogue(self.post_catalogue) + post.compiled.validate_catalogue(self.post_catalogue) ProjectService(self.session).validate_activation_ready( locked.view.guide, locked.view.snapshot, From 8544a2412f24b002c6e8f0489ca8954d861602a1 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 21:38:01 +0100 Subject: [PATCH 087/283] [PILOT-04] replace live checker catalogues with registry projection --- backend/app/adapters/checkers/__init__.py | 271 +++------- backend/app/adapters/projects/__init__.py | 99 ++-- backend/app/adapters/tasks/__init__.py | 174 ++++--- backend/app/api/deps/guide_activation.py | 14 +- backend/app/api/deps/guide_proposals.py | 41 +- backend/app/api/deps/post_policy.py | 20 +- backend/app/api/routes/guide_proposals.py | 96 ++-- backend/app/api/routes/post_policy.py | 88 +++- backend/app/interfaces/project_agents.py | 231 +++++---- backend/app/main.py | 17 +- .../modules/artifacts/submission_admission.py | 191 ++----- .../artifacts/submission_materialization.py | 111 +++-- backend/app/modules/checkers/api/external.py | 125 +++-- .../modules/checkers/api/external_policy.py | 68 +-- backend/app/modules/checkers/execution.py | 108 +--- .../app/modules/checkers/external_registry.py | 74 +-- .../modules/projects/api/guide_proposals.py | 35 +- .../projects/guide_activation/service.py | 76 +-- .../projects/guide_compilation/context.py | 19 +- .../projects/guide_compilation/contracts.py | 16 +- .../projects/guide_compilation/live.py | 19 +- .../guide_compilation/orchestrator.py | 53 +- .../guide_compilation/proposal_approval.py | 84 ++-- .../guide_compilation/proposal_service.py | 12 +- .../guide_compilation/request_inputs.py | 13 +- .../modules/projects/post_policy/compiler.py | 60 ++- .../modules/projects/post_policy/custody.py | 217 +++++--- .../modules/projects/post_policy/delivery.py | 50 +- .../modules/projects/post_policy/service.py | 311 ++++++++---- backend/app/modules/tasks/repository.py | 415 +++++++++++----- backend/app/modules/tasks/service.py | 169 ++++--- backend/app/workers/post_policy.py | 42 +- backend/app/workers/project_setup.py | 13 +- backend/tests/checkers/execution/support.py | 74 ++- .../checkers/execution/test_execution.py | 81 +-- backend/tests/checkers/external/support.py | 47 +- .../projects/guide_compilation/helpers.py | 191 ++++--- .../guide_compilation/test_context_builder.py | 118 +++-- ...est_project_guide_compilation_contracts.py | 469 ++++++++++-------- 39 files changed, 2447 insertions(+), 1865 deletions(-) diff --git a/backend/app/adapters/checkers/__init__.py b/backend/app/adapters/checkers/__init__.py index 5e0486134..94e8d477f 100644 --- a/backend/app/adapters/checkers/__init__.py +++ b/backend/app/adapters/checkers/__init__.py @@ -1,23 +1,12 @@ """CHECKER-owned composition adapters.""" -import asyncio -import json from app.adapters.checkers.external_service import ( EXTERNAL_CHECKER_CAPABILITY_KEY, EXTERNAL_CHECKER_PROVIDER_KEY, UnixSocketExternalCheckerAdapter, ) from app.interfaces.external_services import ExternalServiceAdapterFactory -from app.modules.artifacts.api import SubmissionBundleFile from app.modules.tasks.api import TaskSubmissionContextFacts -from app.modules.projects.api import ProjectLockedPolicyContextFacts -from app.modules.checkers.api import SubmissionPacketView -from app.modules.checkers.api.artifact_paths import required_evidence_path -from app.modules.checkers.api.post_submit_catalogue import CompiledPostSubmitPolicy -from app.modules.checkers.api.post_submit import ( - PostSubmissionEvaluationContent, ExpectedPostSubmitContext, ObservedPostSubmitContext, - PostSubmitPolicyInputs, PostSubmissionStructuralInput, PostSubmitManifestEntry, PostSubmitEvidenceEntry, -) from app.modules.checkers.api.external_policy import LockedExternalPostSubmitPolicy from app.modules.checkers.api.selected_post_submit import ( SelectedPostSubmissionContent, @@ -25,31 +14,22 @@ ) from app.modules.checkers.api.history import CheckerHistoryReadPort from app.modules.checkers.api.execution import EvaluationCoordinationPort -from typing import Any, BinaryIO, Protocol +from typing import Any, Protocol from pathlib import Path -from app.modules.checkers.api.pre_submit_catalogue import PreSubmissionCapabilityProjection -from app.modules.checkers.api.post_submit_catalogue import PostSubmitCatalogue -from app.modules.checkers.api.policy_compilation import PreSubmissionPolicyCompilationPort - from app.modules.checkers.api import ( - PreSubmissionExecutionFacts, PreSubmissionInfrastructureUnavailableError, ) -from app.modules.checkers.catalogue import ( - PreSubmissionCheckerCatalogue, - project_guide_pre_submission_capabilities, - build_pre_submission_checker_catalogue, - parse_disabled_pre_submission_checker_ids, -) -from app.modules.checkers.pre_submit_execution import ( - DefaultPreSubmissionExecutionError, - DefaultPreSubmissionExecutionInput, - EffectivePreSubmissionProcessor, -) from app.modules.checkers.api.external import ( + ExternalCheckerCapabilityDefinition, + ExternalCheckerCapabilityProjection, PreSubmitExternalCheckerIdentity, PreSubmitExternalCheckerMaterial, + external_checker_json_hash, +) +from app.modules.checkers.api.default_checker import ( + WORKSTREAM_DEFAULT_CHECKER_ID, + WORKSTREAM_DEFAULT_CHECKER_VERSION, ) from app.modules.checkers.selected_pre_submit_execution import SelectedPreSubmitProcessor @@ -109,6 +89,49 @@ def external_checker_registry_reader(session): return ExternalCheckerRegistryReader(session) +async def external_checker_capability_projection( + session, +) -> ExternalCheckerCapabilityProjection: + """Snapshot one default plus every immutable external registry identity.""" + entries = await external_checker_registry_reader(session).list_entries() + definitions = tuple( + sorted( + ( + ExternalCheckerCapabilityDefinition( + capability_id=WORKSTREAM_DEFAULT_CHECKER_ID, + capability_version=WORKSTREAM_DEFAULT_CHECKER_VERSION, + phase="pre_submit", + selectable=False, + registry_entry=None, + ), + *( + ExternalCheckerCapabilityDefinition( + capability_id=entry.capability_id, + capability_version=entry.capability_version, + phase=entry.phase, + selectable=True, + registry_entry=entry, + ) + for entry in entries + ), + ), + key=lambda item: ( + item.phase, + item.capability_id, + item.capability_version, + ), + ) + ) + body = { + "schema_version": "external_checker_capabilities.v1", + "definitions": [item.model_dump(mode="json") for item in definitions], + } + return ExternalCheckerCapabilityProjection( + definitions=definitions, + manifest_sha256=external_checker_json_hash(body), + ) + + def selected_pre_submit_coordinator(session): """Compose selected PRE custody through CHECKERS' public adapter root.""" from app.adapters.tasks import selected_pre_submit_task_guard @@ -136,57 +159,6 @@ class _ExecutionRequest(Protocol): storage_scheme: str -class _PublicFactsCheckerProcessor: - """Project the private CHECKER processor result to public facts.""" - - def __init__(self, processor: EffectivePreSubmissionProcessor) -> None: - self._processor = processor - - def abort(self) -> None: - self._processor.abort() - - async def process(self, reader: BinaryIO, workspace: Path) -> PreSubmissionExecutionFacts: - try: - result = await asyncio.to_thread(self._processor.process_blocking, reader, workspace) - return result.bounded_facts() - except DefaultPreSubmissionExecutionError as exc: - raise PreSubmissionInfrastructureUnavailableError(str(exc)) from exc - - -class PreSubmitCheckerExecutionAdapter: - """Build the private CHECKER processor behind dependency-safe facts.""" - - def __init__(self, *, catalogue: PreSubmissionCheckerCatalogue, archive_inspector: Any): - self._catalogue = catalogue - self._archive_inspector = archive_inspector - - @property - def catalogue_manifest_sha256(self) -> str: - return self._catalogue.manifest_sha256 - - def build(self, request: _ExecutionRequest) -> _PublicFactsCheckerProcessor: - if request.plan is None: - raise PreSubmissionInfrastructureUnavailableError( - "pre_submission_plan_identity_invalid" - ) - return _PublicFactsCheckerProcessor( - EffectivePreSubmissionProcessor( - archive_inspector=self._archive_inspector, - catalogue=self._catalogue, - execution_input=DefaultPreSubmissionExecutionInput( - plan=request.plan, - commitment=request.commitment, - inspection=request.inspection, - manifest=request.manifest, - change_gate=request.change_gate, - packet=request.packet, - prepared_generation_id=request.prepared_generation_id, - storage_scheme=request.storage_scheme, - ), - ) - ) - - class SelectedPreSubmitCheckerExecutionAdapter: """Build the selected default-plus-external PRE processor from exact ART facts.""" @@ -242,34 +214,10 @@ def build(self, request: _ExecutionRequest) -> SelectedPreSubmitProcessor: ) -def project_guide_pre_submission_catalogue() -> PreSubmissionCapabilityProjection: - """Compose the canonical immutable pre-submit capabilities for guide setup.""" - return project_guide_pre_submission_capabilities(build_pre_submission_checker_catalogue()) - - -def project_guide_approval_compiler(*, disabled_checker_ids: str = "") -> tuple[ - PreSubmissionPolicyCompilationPort, PreSubmissionCapabilityProjection, PostSubmitCatalogue, -]: - """Compose one canonical planner and its matching pre/post capabilities.""" - from app.modules.checkers.api.post_submit_catalogue import current_post_submit_catalogue - - planner = build_pre_submission_checker_catalogue( - disabled_entry_ids=parse_disabled_pre_submission_checker_ids(disabled_checker_ids), - ) - return planner, project_guide_pre_submission_capabilities(planner), current_post_submit_catalogue() - - -def installed_post_submit_catalogue() -> PostSubmitCatalogue: - """Resolve catalogue facts only after checking the installed handler registry.""" - from app.modules.checkers.post_submit_catalogue import build_post_submit_catalogue - from app.modules.checkers.runner import default_checker_registry - - return build_post_submit_catalogue(default_checker_registry()) - - def checker_history_repository(session) -> CheckerHistoryReadPort: """Compose retained CHECKERS reads through TASK's public ownership port.""" from app.modules.checkers.history import CheckerHistoryRepository + return CheckerHistoryRepository(session) @@ -286,90 +234,28 @@ def post_submission_executor(*, sessions, materialization): from app.adapters.outbox import outbox_append from app.modules.checkers.execution import PostSubmissionExecutor from app.adapters.auth import post_submit_execution_authority - from app.modules.checkers.runner import default_checker_registry - return PostSubmissionExecutor(sessions=sessions, materialization=materialization, + + return PostSubmissionExecutor( + sessions=sessions, + materialization=materialization, execute_authority=post_submit_execution_authority, finalize_authority=post_submit_execution_authority, - registry=default_checker_registry(), outbox=outbox_append) + outbox=outbox_append, + ) def checker_output_reservations(session): """Resolve exact active run/lease custody; current catalogue has zero slots.""" from app.modules.checkers.execution_coordination import CheckerOutputReservations + return CheckerOutputReservations(session) def current_post_submit_execution(session): """Keep ART currentness checks behind the CHECKERS owner port.""" from app.modules.checkers.execution_coordination import CurrentExecution - return CurrentExecution(session) - -def submission_evaluation_content( - task_context: TaskSubmissionContextFacts, - project_context: ProjectLockedPolicyContextFacts, - packet: SubmissionPacketView, - files: tuple[SubmissionBundleFile, ...], - archive_sha256: str, -) -> PostSubmissionEvaluationContent: - """Project inspected files and locked policies without executing a checker. - - Before admission, observed context is the locked TASK context. A dispatcher - must first verify stored Submission lineage against these same facts; this - projection never proves stored ownership or replaces the evaluation guard. - """ - from app.adapters.tasks import validate_submission_policy_context - - validate_submission_policy_context(task_context, project_context) - stamps = task_context.locked_policy - expected = ExpectedPostSubmitContext( - guide_version=stamps.locked_guide_version, - source_id=stamps.locked_guide_source_snapshot_id, - source_hash=stamps.locked_guide_source_snapshot_hash, - effective_policy_id=stamps.locked_effective_project_submission_artifact_policy_id, - effective_policy_hash=stamps.locked_effective_project_submission_artifact_policy_hash, - pre_policy_id=stamps.locked_pre_submit_checker_policy_id, - pre_policy_hash=stamps.locked_pre_submit_checker_bundle_hash, - post_policy_id=stamps.locked_post_submit_checker_policy_id, - post_policy_version=stamps.locked_post_submit_checker_policy_version, - post_policy_hash=stamps.locked_post_submit_checker_policy_hash, - review_policy_id=stamps.locked_review_policy_id, - review_generation=stamps.locked_review_policy_generation, - review_hash=stamps.locked_review_policy_hash, - revision_policy_id=stamps.locked_revision_policy_id, - revision_generation=stamps.locked_revision_policy_generation, - revision_hash=stamps.locked_revision_policy_hash, - ) - effective = json.loads(project_context.effective_policy.value) - policy_inputs = PostSubmitPolicyInputs( - required_evidence_keys=tuple(item["key"] for item in effective.get("required_evidence", []) - if item.get("required", True)), - required_artifact_paths=tuple(item["path"] for item in effective.get("required_artifacts", []) - if item.get("required", True)), - forbidden_artifact_patterns=tuple(item["pattern"] for item in effective.get("forbidden_artifacts", []) - if item.get("pattern")), - required_attestation_terms=tuple(term for term in effective.get("attestation_terms", []) if term), - ) - by_path = {item.normalized_path: item for item in files} - return PostSubmissionEvaluationContent( - project_id=project_context.project_id, - expected_context=expected, - catalogue=installed_post_submit_catalogue(), - policy=CompiledPostSubmitPolicy.model_validate_json(project_context.compiled_post_submit_policy.value), - structural_input=PostSubmissionStructuralInput( - summary=packet.summary, worker_attestation=packet.contributor_attestation, - package_hash=archive_sha256, criteria=task_context.acceptance_criteria or "", - manifest=tuple(PostSubmitManifestEntry( - artifact=item.normalized_path, hash=item.sha256, size_bytes=item.byte_count, - ) for item in files), - evidence=tuple(PostSubmitEvidenceEntry( - label=key, type="file", key=key, uri=item.normalized_path, hash=item.sha256, - ) for key in policy_inputs.required_evidence_keys - for item in (by_path.get(required_evidence_path(key)),) if item is not None), - policy_inputs=policy_inputs, - observed_context=ObservedPostSubmitContext(**expected.model_dump()), - ), - ) + return CurrentExecution(session) def selected_submission_evaluation_content( @@ -385,23 +271,13 @@ def selected_submission_evaluation_content( guide_version=locked.locked_guide_version, source_id=locked.locked_guide_source_snapshot_id, source_hash=locked.locked_guide_source_snapshot_hash, - effective_policy_id=( - locked.locked_effective_project_submission_artifact_policy_id - ), - effective_policy_hash=( - locked.locked_effective_project_submission_artifact_policy_hash - ), + effective_policy_id=(locked.locked_effective_project_submission_artifact_policy_id), + effective_policy_hash=(locked.locked_effective_project_submission_artifact_policy_hash), pre_policy_id=locked.locked_pre_submit_checker_policy_id, pre_policy_hash=locked.locked_pre_submit_checker_bundle_hash, - retained_catalogue_policy_id=( - locked.locked_post_submit_checker_policy_id - ), - retained_catalogue_policy_version=( - locked.locked_post_submit_checker_policy_version - ), - retained_catalogue_policy_hash=( - locked.locked_post_submit_checker_policy_hash - ), + retained_catalogue_policy_id=(locked.locked_post_submit_checker_policy_id), + retained_catalogue_policy_version=(locked.locked_post_submit_checker_policy_version), + retained_catalogue_policy_hash=(locked.locked_post_submit_checker_policy_hash), selected_post_policy_hash=policy.policy_sha256, review_policy_id=locked.locked_review_policy_id, review_generation=locked.locked_review_policy_generation, @@ -423,16 +299,21 @@ def delivery_bound_post_submission_executor( from app.adapters.tasks import evaluation_task_guard from app.modules.checkers.delivery_authority import DeliveryExecutionAuthority from app.modules.checkers.execution import PostSubmissionExecutor - from app.modules.checkers.runner import default_checker_registry def authority(session): return DeliveryExecutionAuthority( - authority=post_submit_execution_authority(session), tasks=evaluation_task_guard(session), - fence=outbox_invocation_fence(session), envelope=envelope, request=request, + authority=post_submit_execution_authority(session), + tasks=evaluation_task_guard(session), + fence=outbox_invocation_fence(session), + envelope=envelope, + request=request, ) return PostSubmissionExecutor( - sessions=sessions, execute_authority=authority, finalize_authority=authority, - materialization=materialization, registry=default_checker_registry(), - selected_execution=selected_execution, outbox=outbox_append, + sessions=sessions, + execute_authority=authority, + finalize_authority=authority, + materialization=materialization, + selected_execution=selected_execution, + outbox=outbox_append, ) diff --git a/backend/app/adapters/projects/__init__.py b/backend/app/adapters/projects/__init__.py index 806573e86..39e34758b 100644 --- a/backend/app/adapters/projects/__init__.py +++ b/backend/app/adapters/projects/__init__.py @@ -1,27 +1,32 @@ """PROJECT-owned composition adapters.""" from app.modules.projects.api.guide_activation import ( - GuideActivationAuthorizationPort, GuideActivationPort, GuideContributionPolicyPort, + GuideActivationAuthorizationPort, + GuideActivationPort, + GuideContributionPolicyPort, ) from app.modules.projects.api.guide_documents import ProjectGuideDocumentScopePort -from app.modules.projects.api.guide_proposals import GuideProposalOperationsPort, GuideCorrectionDispatchPort +from app.modules.projects.api.guide_proposals import ( + GuideProposalOperationsPort, + GuideCorrectionDispatchPort, +) from app.modules.authorization.api.guide_proposal_review import GuideProposalAuthorizationPort from app.modules.authorization.api import ProjectGuideCompilationAuthorizationPort from uuid import UUID from collections.abc import Callable from app.modules.authorization.api.post_policy import PostPolicyAuthorizationPort from app.modules.projects.api.post_policy import PostPolicyOperationsPort, PostPolicyDeliveryPort -from app.modules.checkers.api.post_submit_catalogue import CompiledPostSubmitPolicy from app.modules.projects.post_policy.delivery import PostPolicyServiceAuthority from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker -from app.modules.projects.api.guide_documents import GuideDocumentManifestPort, GuideDocumentAccessFactory +from app.modules.projects.api.guide_documents import ( + GuideDocumentManifestPort, + GuideDocumentAccessFactory, +) from app.interfaces.project_agents import ProjectGuideAgentRuntime from app.interfaces.project_guide_runtime import ProjectGuideRuntimeConfiguration -from app.modules.checkers.api.pre_submit_catalogue import PreSubmissionCapabilityProjection -from app.modules.checkers.api.post_submit_catalogue import PostSubmitCatalogue -from app.modules.checkers.api.policy_compilation import PreSubmissionPolicyCompilationPort +from app.modules.checkers.api.external import ExternalCheckerCapabilityProjection from app.modules.authorization.api import ( ActorIdentityFacts, GuideSufficiencyProjectionAuthorizationPort, @@ -64,8 +69,7 @@ def project_guide_compilation_delivery_port( *, material_factory: Callable[[AsyncSession], GuideDocumentManifestPort], document_access_factory: GuideDocumentAccessFactory, - pre_capabilities: PreSubmissionCapabilityProjection, - post_capabilities: PostSubmitCatalogue, + checker_capabilities: ExternalCheckerCapabilityProjection, request_authority: RequestAuthority, execution_authority: GuideCompilationAuthorizationContext, configuration_factory: Callable[[], ProjectGuideRuntimeConfiguration], @@ -84,15 +88,13 @@ def project_guide_compilation_delivery_port( return LiveGuideCompilationCoordinator( session_factory, material_factory=material_factory, - pre_capabilities=pre_capabilities, - post_capabilities=post_capabilities, + checker_capabilities=checker_capabilities, request_authority=request_authority, configuration_factory=configuration_factory, execution=project_guide_compilation_execution_port( session_factory, material_factory=material_factory, - pre_submission_capabilities=pre_capabilities, - post_submission_capabilities=post_capabilities, + checker_capabilities=checker_capabilities, authorization_context=execution_authority, runtime_factory=runtime_factory, document_access_factory=document_access_factory, @@ -110,7 +112,8 @@ def project_guide_compilation_delivery_port( async def cleanup_project_guide_runtime_resources(session_factory, *, runtime_factory): """Compose exact retained cleanup scopes without source grants or inference admission.""" from app.modules.projects.guide_compilation.runtime_resources import ( - SqlAlchemyGuideRuntimeCleanupCustody, pending_runtime_resource_cleanup, + SqlAlchemyGuideRuntimeCleanupCustody, + pending_runtime_resource_cleanup, ) async with session_factory() as session: @@ -123,7 +126,10 @@ async def cleanup_project_guide_runtime_resources(session_factory, *, runtime_fa if runtime.identity != configuration.adapter_identity: raise ValueError("cleanup runtime identity mismatch") custody = SqlAlchemyGuideRuntimeCleanupCustody( - session_factory, attempt_id, manifest_sha256, configuration.runtime_key, + session_factory, + attempt_id, + manifest_sha256, + configuration.runtime_key, ) completed += bool(await runtime.cleanup_resources(custody)) except Exception: @@ -137,60 +143,75 @@ async def cleanup_project_guide_runtime_resources(session_factory, *, runtime_fa def project_guide_document_scope_port(session: AsyncSession) -> ProjectGuideDocumentScopePort: """Bind PROJECTS current document scope independently from ART storage.""" - from app.modules.projects.guide_compilation.document_scope import SqlAlchemyProjectGuideDocumentScope + from app.modules.projects.guide_compilation.document_scope import ( + SqlAlchemyProjectGuideDocumentScope, + ) + return SqlAlchemyProjectGuideDocumentScope(session) def project_guide_proposal_service( - session: AsyncSession, authorization: GuideProposalAuthorizationPort, + session: AsyncSession, + authorization: GuideProposalAuthorizationPort, ) -> GuideProposalOperationsPort[ - ActorIdentityFacts, GuideDocumentManifestPort, PreSubmissionCapabilityProjection, - PostSubmitCatalogue, PreSubmissionPolicyCompilationPort, + ActorIdentityFacts, + GuideDocumentManifestPort, + ExternalCheckerCapabilityProjection, ]: """Compose the sole proposal owner with explicit authority.""" from app.adapters.checkers import external_checker_registry_reader from app.modules.projects.guide_compilation.proposal_service import GuideProposalService - return GuideProposalService( - session, authorization, external_checker_registry_reader(session) - ) + return GuideProposalService(session, authorization, external_checker_registry_reader(session)) def project_guide_correction_dispatch( - session: AsyncSession, authorization: ProjectGuideCompilationAuthorizationPort, *, - material: GuideDocumentManifestPort, pre: PreSubmissionCapabilityProjection, - post: PostSubmitCatalogue, configuration: ProjectGuideRuntimeConfiguration, + session: AsyncSession, + authorization: ProjectGuideCompilationAuthorizationPort, + *, + material: GuideDocumentManifestPort, + capabilities: ExternalCheckerCapabilityProjection, + configuration: ProjectGuideRuntimeConfiguration, ) -> GuideCorrectionDispatchPort[ActorIdentityFacts]: """Compose human correction admission and existing queue dispatch without inference.""" - from app.modules.projects.guide_compilation.correction_dispatch import GuideCorrectionDispatchService + from app.modules.projects.guide_compilation.correction_dispatch import ( + GuideCorrectionDispatchService, + ) from app.modules.projects.guide_compilation.request_inputs import CompilationRequestInputs return GuideCorrectionDispatchService( - session, authorization, CompilationRequestInputs(material, pre, post, configuration), + session, + authorization, + CompilationRequestInputs(material, capabilities, configuration), ) def project_post_policy_service( - session: AsyncSession, authorization: PostPolicyAuthorizationPort, catalogue: PostSubmitCatalogue, -) -> PostPolicyOperationsPort[ActorIdentityFacts, GuideProposalAuthorizationPort, CompiledPostSubmitPolicy]: + session: AsyncSession, + authorization: PostPolicyAuthorizationPort, +) -> PostPolicyOperationsPort[ActorIdentityFacts, GuideProposalAuthorizationPort, object]: """Compose the canonical post-policy owner with explicitly supplied authority.""" from app.modules.projects.post_policy.service import PostPolicyService - return PostPolicyService(session, authorization, catalogue) + return PostPolicyService(session, authorization) def project_post_policy_delivery_port( - session_factory: async_sessionmaker[AsyncSession], *, - authority: PostPolicyServiceAuthority, catalogue: PostSubmitCatalogue, + session_factory: async_sessionmaker[AsyncSession], + *, + authority: PostPolicyServiceAuthority, ) -> PostPolicyDeliveryPort: """Compose deterministic delivery without document or agent capabilities.""" from app.modules.projects.post_policy.delivery import PostPolicyDeliveryService - return PostPolicyDeliveryService(session_factory, authority=authority, catalogue=catalogue) + return PostPolicyDeliveryService(session_factory, authority=authority) async def pending_post_policy_approvals( - session_factory: async_sessionmaker[AsyncSession], *, after: UUID | None, limit: int, + session_factory: async_sessionmaker[AsyncSession], + *, + after: UUID | None, + limit: int, ) -> list[UUID]: """Read only pending immutable approval identifiers for a bounded internal scan.""" from app.modules.projects.post_policy.delivery import pending_approval_ids @@ -207,8 +228,9 @@ async def dispatch_post_policy_derivation_after_commit(approval_operation_id: UU def project_guide_activation_port( - session: AsyncSession, *, contribution: GuideContributionPolicyPort, planner: PreSubmissionPolicyCompilationPort, - pre_catalogue: PreSubmissionCapabilityProjection, post_catalogue: PostSubmitCatalogue, + session: AsyncSession, + *, + contribution: GuideContributionPolicyPort, authorization: GuideActivationAuthorizationPort | None = None, ) -> GuideActivationPort[ActorIdentityFacts]: """Compose canonical activation with explicit CON validation and authority.""" @@ -216,7 +238,8 @@ def project_guide_activation_port( from app.modules.projects.guide_activation.service import GuideActivationService return GuideActivationService( - session, contribution=contribution, planner=planner, pre_catalogue=pre_catalogue, - post_catalogue=post_catalogue, authorization=authorization, + session, + contribution=contribution, + authorization=authorization, registry=external_checker_registry_reader(session), ) diff --git a/backend/app/adapters/tasks/__init__.py b/backend/app/adapters/tasks/__init__.py index 12bfe5a59..f4308876e 100644 --- a/backend/app/adapters/tasks/__init__.py +++ b/backend/app/adapters/tasks/__init__.py @@ -24,8 +24,10 @@ from app.modules.tasks.authorized_commands import AuthorizedTaskCommands from app.modules.tasks.api import TaskAuthorizationPort, TaskTransitionAuditPort from app.modules.tasks.submission_participants import ( - SubmissionArtifactAdmissionRequest, SubmissionArtifactAdmissionResult, - SubmissionArtifactReplayRequest, SubmissionArtifactBindingFacts, + SubmissionArtifactAdmissionRequest, + SubmissionArtifactAdmissionResult, + SubmissionArtifactReplayRequest, + SubmissionArtifactBindingFacts, ) from app.modules.artifacts.api.submission_admission import ConsumedSubmissionAdmissionRequest from app.modules.tasks.submission_composition import TaskSubmissionCreationService @@ -39,6 +41,7 @@ def evaluation_task_guard(session: AsyncSession) -> EvaluationTaskGuard: """Expose TASK-owned locking through the required CHECKERS consumer port.""" from app.modules.tasks.post_submit_routing.evaluation_guard import TaskEvaluationGuard + return TaskEvaluationGuard(session) @@ -79,8 +82,7 @@ async def lock_selected_pre_submit_scope( or references.effective_policy_id != lineage.effective_policy_id or references.effective_policy_hash != lineage.effective_policy_sha256 or references.pre_submit_policy_id != lineage.pre_submit_policy_id - or references.pre_submit_policy_bundle_hash - != lineage.pre_submit_policy_sha256 + or references.pre_submit_policy_bundle_hash != lineage.pre_submit_policy_sha256 ): raise RuntimeError("selected PRE TASK custody changed") @@ -98,13 +100,18 @@ def __init__(self, session_factory, *, observer, authorization_factory): self._observer, self._authorization = observer, authorization_factory async def __call__(self, envelope): - from app.adapters.audit import assignment_invalidation_audit, committed_authority_invalidation + from app.adapters.audit import ( + assignment_invalidation_audit, + committed_authority_invalidation, + ) from app.adapters.outbox import outbox_invocation_fence try: async with self._sessions() as session, session.begin(): outcome = await AssignmentInvalidationOperation( - session, observer=self._observer, fence=outbox_invocation_fence(session), + session, + observer=self._observer, + fence=outbox_invocation_fence(session), causes=committed_authority_invalidation(self._sessions), authorization=self._authorization(session), audit=assignment_invalidation_audit(session), @@ -126,28 +133,32 @@ async def __call__(self, envelope): def task_service(session: AsyncSession, *, settings: Settings) -> TaskService: - """Compose exact PROJECTS custody and installed CHECKERS at the existing TASK root.""" + """Compose exact PROJECTS custody at the existing TASK transaction root.""" from app.adapters.projects import project_locked_policy_context_port - from app.adapters.checkers import project_guide_approval_compiler, installed_post_submit_catalogue - planner, _, _ = project_guide_approval_compiler( - disabled_checker_ids=settings.artifact_pre_submission_checker_disabled_ids, - ) return TaskService( - session, project_contexts=project_locked_policy_context_port(session), - pre_submit_planner=planner, post_submit_catalogue=installed_post_submit_catalogue, + session, + project_contexts=project_locked_policy_context_port(session), ) def task_commands( - session: AsyncSession, *, authorization: TaskAuthorizationPort, - audit: TaskTransitionAuditPort, actor_profile_id: UUID, settings: Settings, + session: AsyncSession, + *, + authorization: TaskAuthorizationPort, + audit: TaskTransitionAuditPort, + actor_profile_id: UUID, + settings: Settings, ) -> AuthorizedTaskCommands: """Compose TASK commands without exposing private product imports to delivery.""" from app.adapters.artifacts import task_guide_documents_port from app.adapters.contributions import locked_compensation_terms_port + return AuthorizedTaskCommands( - session, authorization=authorization, audit=audit, actor_profile_id=actor_profile_id, + session, + authorization=authorization, + audit=audit, + actor_profile_id=actor_profile_id, contexts=task_service(session, settings=settings), guide_documents=task_guide_documents_port(session, settings), compensation_terms=locked_compensation_terms_port(session), @@ -155,16 +166,30 @@ def task_commands( def task_import_batch_commands( - session: AsyncSession, *, authorization, audit: TaskTransitionAuditPort, - actor_profile_id: UUID, identity_link_id: UUID, settings: Settings, source, + session: AsyncSession, + *, + authorization, + audit: TaskTransitionAuditPort, + actor_profile_id: UUID, + identity_link_id: UUID, + settings: Settings, + source, ): """Compose the batch root from canonical TASK commands and one ART source owner.""" from app.modules.tasks.task_import_batches import TaskImportBatchCommands + return TaskImportBatchCommands( - session, actor_profile_id=actor_profile_id, identity_link_id=identity_link_id, + session, + actor_profile_id=actor_profile_id, + identity_link_id=identity_link_id, authorization=authorization, - tasks=task_commands(session, authorization=authorization, audit=audit, - actor_profile_id=actor_profile_id, settings=settings), + tasks=task_commands( + session, + authorization=authorization, + audit=audit, + actor_profile_id=actor_profile_id, + settings=settings, + ), source=source, ) @@ -172,17 +197,25 @@ def task_import_batch_commands( def contributor_task_repository(session: AsyncSession) -> TaskRepository: """Compose contributor reads with CON's bounded locked-terms public port.""" from app.adapters.contributions import locked_compensation_terms_port + return TaskRepository(session, compensation_terms=locked_compensation_terms_port(session)) def task_batch_transition_commands( - session: AsyncSession, *, tasks: AuthorizedTaskCommands, - actor_profile_id: UUID, identity_link_id: UUID, + session: AsyncSession, + *, + tasks: AuthorizedTaskCommands, + actor_profile_id: UUID, + identity_link_id: UUID, ): """Bind the batch root to the same canonical Task authority and participants.""" from app.modules.tasks.task_batch_transitions import TaskBatchTransitionCommands + return TaskBatchTransitionCommands( - session, tasks=tasks, actor_profile_id=actor_profile_id, identity_link_id=identity_link_id, + session, + tasks=tasks, + actor_profile_id=actor_profile_id, + identity_link_id=identity_link_id, ) @@ -207,63 +240,68 @@ async def consume( packet_sha256=request.packet.sha256, ) ) - if (result.binding_id is None or result.status != "consumed" - or result.material is None or result.binding_decision_id is None): + if ( + result.binding_id is None + or result.status != "consumed" + or result.material is None + or result.binding_decision_id is None + ): raise RuntimeError("admission did not produce a binding") - from app.adapters.checkers import ( - selected_submission_evaluation_content, - submission_evaluation_content, - ) + from app.adapters.checkers import selected_submission_evaluation_content from app.modules.checkers.api.external_policy import ( LockedExternalPostSubmitPolicy, ) + selected_post_policy = ( - LockedExternalPostSubmitPolicy.model_validate( - result.selected_post_submit_policy_body - ) + LockedExternalPostSubmitPolicy.model_validate(result.selected_post_submit_policy_body) if result.selected_post_submit_policy_body is not None else None ) + if selected_post_policy is None: + raise RuntimeError("legacy checker admission cannot create a submission") return SubmissionArtifactAdmissionResult( - binding_id=result.binding_id, content_id=result.content_id, + binding_id=result.binding_id, + content_id=result.content_id, binding_decision_id=result.binding_decision_id, archive_sha256=result.material.archive_sha256, byte_count=result.material.archive_byte_count, - evaluation_content=( - submission_evaluation_content( - request.task_context, - request.project_context, - request.packet, - result.material.files, - result.material.archive_sha256, - ) - if selected_post_policy is None - else None - ), + evaluation_content=None, selected_post_submit_policy=selected_post_policy, selected_evaluation_content=( - selected_submission_evaluation_content( - request.task_context, selected_post_policy - ) + selected_submission_evaluation_content(request.task_context, selected_post_policy) if selected_post_policy is not None else None ), ) - async def read_consumed(self, request: SubmissionArtifactReplayRequest) -> SubmissionArtifactBindingFacts: - result = await self._admissions.read_consumed(ConsumedSubmissionAdmissionRequest( - admission_id=request.admission_id, project_id=request.project_id, - task_id=request.task_id, assignment_id=request.assignment_id, - contributor_id=request.contributor_id, submission_id=request.submission_id, - submission_version=request.submission_version, packet_sha256=request.packet_sha256, - )) - if (result.binding_id is None or result.material is None - or result.binding_decision_id is None or result.status != "consumed"): + async def read_consumed( + self, request: SubmissionArtifactReplayRequest + ) -> SubmissionArtifactBindingFacts: + result = await self._admissions.read_consumed( + ConsumedSubmissionAdmissionRequest( + admission_id=request.admission_id, + project_id=request.project_id, + task_id=request.task_id, + assignment_id=request.assignment_id, + contributor_id=request.contributor_id, + submission_id=request.submission_id, + submission_version=request.submission_version, + packet_sha256=request.packet_sha256, + ) + ) + if ( + result.binding_id is None + or result.material is None + or result.binding_decision_id is None + or result.status != "consumed" + ): raise RuntimeError("retained admission custody unavailable") return SubmissionArtifactBindingFacts( - binding_id=result.binding_id, content_id=result.content_id, + binding_id=result.binding_id, + content_id=result.content_id, binding_decision_id=result.binding_decision_id, - archive_sha256=result.material.archive_sha256, byte_count=result.material.archive_byte_count, + archive_sha256=result.material.archive_sha256, + byte_count=result.material.archive_byte_count, ) @@ -308,12 +346,14 @@ def assignment_invalidation_targets(session: AsyncSession): def submission_history_repository(session) -> SubmissionHistoryReadPort: """Compose TASK-owned immutable history selectors and projections.""" from app.modules.tasks.submission_history import SubmissionHistoryRepository + return SubmissionHistoryRepository(session) def submitted_bundle_port(session: AsyncSession) -> SubmittedBundlePort: """Compose the exact immutable Submission read without private owner imports in ART.""" from app.modules.tasks.submitted_bundle import SubmittedBundleReader + return SubmittedBundleReader(session) @@ -324,12 +364,15 @@ def routing_source_preparer(session): from app.modules.tasks.post_submit_routing.source import TaskRoutingSourcePreparer return TaskRoutingSourcePreparer( - session, evaluations=evaluation_coordinator(session), + session, + evaluations=evaluation_coordinator(session), projects=project_locked_policy_context_port(session), ) -def validate_submission_policy_context(task_context: TaskSubmissionContextFacts, project_context: ProjectLockedPolicyContextFacts) -> None: +def validate_submission_policy_context( + task_context: TaskSubmissionContextFacts, project_context: ProjectLockedPolicyContextFacts +) -> None: """Use TASK's canonical stamp projection without exposing its implementation.""" TaskService.validate_submission_policy_context(task_context, project_context) @@ -363,8 +406,10 @@ def executor(envelope, request): ) return EvaluationRequestHandler( - sessions, observer=committed_invocation_reader(sessions), - evaluations=evaluation_coordinator, executor=executor, + sessions, + observer=committed_invocation_reader(sessions), + evaluations=evaluation_coordinator, + executor=executor, ) @@ -408,7 +453,8 @@ def evaluation_completion_handler(*, sessions): from app.modules.tasks.evaluation_completion_delivery import EvaluationCompletionHandler return EvaluationCompletionHandler( - sessions, observer=committed_invocation_reader(sessions), + sessions, + observer=committed_invocation_reader(sessions), outcomes=lambda session: task_post_submit_outcome(session, sessions), ) diff --git a/backend/app/api/deps/guide_activation.py b/backend/app/api/deps/guide_activation.py index dccc8aa08..4ae0db2a6 100644 --- a/backend/app/api/deps/guide_activation.py +++ b/backend/app/api/deps/guide_activation.py @@ -9,12 +9,13 @@ from sqlalchemy.ext.asyncio import AsyncSession from app.adapters.auth import guide_activation_authorization -from app.adapters.checkers import project_guide_approval_compiler from app.adapters.contributions import contribution_policy_validation_port from app.adapters.projects import project_guide_activation_port from app.adapters.projects.contribution_validation import GuideContributionPolicyValidation from app.api.deps.authorization import ( - _authorization_context, get_authorization_actor, get_authorization_actor_identity, + _authorization_context, + get_authorization_actor, + get_authorization_actor_identity, ) from app.core.api_controls import request_ids from app.db.session import get_db_session @@ -42,18 +43,19 @@ async def get_activation_request( context = _authorization_context(resolved, request_id, correlation_id) actor = await get_authorization_actor_identity(resolved) await session.rollback() - planner, pre, post = project_guide_approval_compiler() try: async with session.begin(): yield ActivationRequest( session, project_guide_activation_port( session, - contribution=GuideContributionPolicyValidation(contribution_policy_validation_port(session)), - planner=planner, pre_catalogue=pre, post_catalogue=post, + contribution=GuideContributionPolicyValidation( + contribution_policy_validation_port(session) + ), authorization=guide_activation_authorization(session, context), ), - actor, request_id, + actor, + request_id, ) finally: if session.in_transaction(): diff --git a/backend/app/api/deps/guide_proposals.py b/backend/app/api/deps/guide_proposals.py index 59ba29149..01d84448f 100644 --- a/backend/app/api/deps/guide_proposals.py +++ b/backend/app/api/deps/guide_proposals.py @@ -2,7 +2,10 @@ from dataclasses import dataclass from collections.abc import AsyncIterator -from app.modules.projects.api.guide_proposals import GuideProposalOperationsPort, GuideCorrectionDispatchPort +from app.modules.projects.api.guide_proposals import ( + GuideProposalOperationsPort, + GuideCorrectionDispatchPort, +) from typing import Annotated, Any from uuid import UUID @@ -10,15 +13,15 @@ from sqlalchemy.ext.asyncio import AsyncSession from app.api.deps.authorization import ( - _authorization_context, get_authorization_actor, get_authorization_actor_identity, + _authorization_context, + get_authorization_actor, + get_authorization_actor_identity, ) from app.core.api_controls import request_ids from app.db.session import get_db_session from app.modules.authorization.api import ActorIdentityFacts from app.modules.projects.api.guide_documents import GuideDocumentManifestPort -from app.modules.checkers.api.pre_submit_catalogue import PreSubmissionCapabilityProjection -from app.modules.checkers.api.post_submit_catalogue import PostSubmitCatalogue -from app.modules.checkers.api.policy_compilation import PreSubmissionPolicyCompilationPort +from app.modules.checkers.api.external import ExternalCheckerCapabilityProjection from app.adapters.auth import guide_proposal_authorization, human_guide_compilation_authorization from app.adapters.projects import project_guide_proposal_service, project_guide_correction_dispatch @@ -29,8 +32,9 @@ class ProposalRequest: session: AsyncSession service: GuideProposalOperationsPort[ - ActorIdentityFacts, GuideDocumentManifestPort, PreSubmissionCapabilityProjection, - PostSubmitCatalogue, PreSubmissionPolicyCompilationPort, + ActorIdentityFacts, + GuideDocumentManifestPort, + ExternalCheckerCapabilityProjection, ] actor: ActorIdentityFacts request_id: UUID @@ -58,7 +62,9 @@ async def get_proposal_request( async with session.begin(): yield ProposalRequest( session, - project_guide_proposal_service(session, guide_proposal_authorization(session, context)), + project_guide_proposal_service( + session, guide_proposal_authorization(session, context) + ), actor, request_id, ) @@ -74,19 +80,24 @@ async def get_correction_dispatch( ) -> AsyncIterator[CorrectionDispatchRequest]: """Compose the existing human compilation request port without a runtime.""" from app.adapters.artifacts import guide_document_manifest_port - from app.adapters.checkers import project_guide_approval_compiler + from app.adapters.checkers import external_checker_capability_projection from app.api.deps.authorization import prepared_authorization_service from app.core.config import get_settings from app.core.project_agents import project_guide_runtime_configuration actor = await get_authorization_actor_identity(resolved) - _, pre, post = project_guide_approval_compiler() async with prepared_authorization_service(request, resolved, session) as prepared: + capabilities = await external_checker_capability_projection(session) # Capture the immutable AUTH context before rollback expires the ORM # identity rows; dispatch still owns a fresh product transaction. await session.rollback() - yield CorrectionDispatchRequest(project_guide_correction_dispatch( - session, human_guide_compilation_authorization(prepared), - material=guide_document_manifest_port(session), pre=pre, post=post, - configuration=project_guide_runtime_configuration(get_settings()), - ), actor) + yield CorrectionDispatchRequest( + project_guide_correction_dispatch( + session, + human_guide_compilation_authorization(prepared), + material=guide_document_manifest_port(session), + capabilities=capabilities, + configuration=project_guide_runtime_configuration(get_settings()), + ), + actor, + ) diff --git a/backend/app/api/deps/post_policy.py b/backend/app/api/deps/post_policy.py index f011d5088..53be366e2 100644 --- a/backend/app/api/deps/post_policy.py +++ b/backend/app/api/deps/post_policy.py @@ -14,15 +14,15 @@ from app.adapters.projects.contribution_validation import GuideContributionPolicyDiscovery from app.modules.projects.api.guide_activation_context import GuideContributionDiscoveryPort from app.api.deps.authorization import ( - _authorization_context, get_authorization_actor, get_authorization_actor_identity, + _authorization_context, + get_authorization_actor, + get_authorization_actor_identity, ) from app.core.api_controls import request_ids from app.db.session import get_db_session from app.modules.authorization.api import ActorIdentityFacts from app.modules.authorization.api.guide_proposal_review import GuideProposalAuthorizationPort -from app.modules.checkers.api.post_submit_catalogue import ( - CompiledPostSubmitPolicy, current_post_submit_catalogue, -) +from app.modules.checkers.api.external_policy import LockedExternalPostSubmitPolicy from app.modules.projects.api.post_policy import PostPolicyOperationsPort @@ -32,7 +32,9 @@ class PostPolicyRequest: session: AsyncSession service: PostPolicyOperationsPort[ - ActorIdentityFacts, GuideProposalAuthorizationPort, CompiledPostSubmitPolicy, + ActorIdentityFacts, + GuideProposalAuthorizationPort, + LockedExternalPostSubmitPolicy, ] guide_authorization: GuideProposalAuthorizationPort actor: ActorIdentityFacts @@ -55,10 +57,12 @@ async def get_post_policy_request( yield PostPolicyRequest( session, project_post_policy_service( - session, post_policy_authorization(session, context), - current_post_submit_catalogue(), + session, + post_policy_authorization(session, context), ), - guide_proposal_authorization(session, context), actor, request_id, + guide_proposal_authorization(session, context), + actor, + request_id, GuideContributionPolicyDiscovery(published_contribution_policy_port(session)), ) finally: diff --git a/backend/app/api/routes/guide_proposals.py b/backend/app/api/routes/guide_proposals.py index 8057e63f8..6c8cdff6d 100644 --- a/backend/app/api/routes/guide_proposals.py +++ b/backend/app/api/routes/guide_proposals.py @@ -7,18 +7,32 @@ from sqlalchemy.exc import SQLAlchemyError from app.adapters.artifacts import guide_document_manifest_port -from app.adapters.checkers import project_guide_approval_compiler +from app.adapters.checkers import external_checker_capability_projection from app.api.deps.authorization import enforce_human_authorization_read -from app.api.deps.guide_proposals import ProposalRequest, CorrectionDispatchRequest, get_proposal_request, get_correction_dispatch +from app.api.deps.guide_proposals import ( + ProposalRequest, + CorrectionDispatchRequest, + get_proposal_request, + get_correction_dispatch, +) from app.core.api_controls import ApiErrorResponse from app.modules.projects.api.guide_proposal_package import GuideProposalReviewPackage from app.modules.projects.api.guide_proposals import ( - GuideProposalApproval, GuideProposalApprovalInput, GuideProposalApprovalReceipt, - GuideProposalCorrection, GuideProposalCorrectionInput, GuideProposalCorrectionReceipt, - GuideProposalError, GuideProposalSelection, GuideProposalDispatchResponse, + GuideProposalApproval, + GuideProposalApprovalInput, + GuideProposalApprovalReceipt, + GuideProposalCorrection, + GuideProposalCorrectionInput, + GuideProposalCorrectionReceipt, + GuideProposalError, + GuideProposalSelection, + GuideProposalDispatchResponse, ) from app.api.deps.guide_proposal_http import ( - IDEMPOTENCY_PARAMETER, require_proposal_key, proposal_http_error, require_matching_target, + IDEMPOTENCY_PARAMETER, + require_proposal_key, + proposal_http_error, + require_matching_target, ) from app.adapters.projects import dispatch_post_policy_derivation_after_commit @@ -31,18 +45,24 @@ @router.get( - "/proposal", response_model=GuideProposalReviewPackage, - openapi_extra={"x-workstream-action-id": 'project.guide_compilation.review_package.read'}, + "/proposal", + response_model=GuideProposalReviewPackage, + openapi_extra={"x-workstream-action-id": "project.guide_compilation.review_package.read"}, ) async def review_proposal( - project_id: UUID, guide_id: UUID, compilation_id: UUID, + project_id: UUID, + guide_id: UUID, + compilation_id: UUID, request: Annotated[ProposalRequest, Depends(get_proposal_request)], ) -> GuideProposalReviewPackage: """Read the exact finalized proposal and its approval/correction target.""" try: response = await request.service.review_package( - GuideProposalSelection(project_id=project_id, guide_id=guide_id, compilation_id=compilation_id), - actor=request.actor, request_id=request.request_id, + GuideProposalSelection( + project_id=project_id, guide_id=guide_id, compilation_id=compilation_id + ), + actor=request.actor, + request_id=request.request_id, ) await request.session.commit() return response @@ -53,26 +73,32 @@ async def review_proposal( @router.post( - "/pre-submission-approval", response_model=GuideProposalApprovalReceipt, - openapi_extra={"x-workstream-action-id": 'project.submission_artifact_policy.approve', - "parameters": [IDEMPOTENCY_PARAMETER]}, + "/pre-submission-approval", + response_model=GuideProposalApprovalReceipt, + openapi_extra={ + "x-workstream-action-id": "project.submission_artifact_policy.approve", + "parameters": [IDEMPOTENCY_PARAMETER], + }, dependencies=[Depends(require_proposal_key)], ) async def approve_proposal( - project_id: UUID, guide_id: UUID, compilation_id: UUID, + project_id: UUID, + guide_id: UUID, + compilation_id: UUID, payload: GuideProposalApprovalInput, key: Annotated[UUID, Depends(require_proposal_key)], request: Annotated[ProposalRequest, Depends(get_proposal_request)], ) -> GuideProposalApprovalReceipt: """Approve one displayed pre-submission policy without running inference.""" require_matching_target(payload.target, project_id, guide_id, compilation_id) - planner, pre, post = project_guide_approval_compiler() try: + capabilities = await external_checker_capability_projection(request.session) response = await request.service.approve( GuideProposalApproval(**payload.model_dump(), idempotency_key=key), - actor=request.actor, request_id=request.request_id, + actor=request.actor, + request_id=request.request_id, material=guide_document_manifest_port(request.session), - pre_capabilities=pre, post_capabilities=post, planner=planner, + capabilities=capabilities, ) await request.session.commit() await dispatch_post_policy_derivation_after_commit(response.operation_id) @@ -84,13 +110,19 @@ async def approve_proposal( @router.post( - "/corrections", response_model=GuideProposalCorrectionReceipt, status_code=201, - openapi_extra={"x-workstream-action-id": 'project.guide_compilation.correction.request', - "parameters": [IDEMPOTENCY_PARAMETER]}, + "/corrections", + response_model=GuideProposalCorrectionReceipt, + status_code=201, + openapi_extra={ + "x-workstream-action-id": "project.guide_compilation.correction.request", + "parameters": [IDEMPOTENCY_PARAMETER], + }, dependencies=[Depends(require_proposal_key)], ) async def correct_proposal( - project_id: UUID, guide_id: UUID, compilation_id: UUID, + project_id: UUID, + guide_id: UUID, + compilation_id: UUID, payload: GuideProposalCorrectionInput, key: Annotated[UUID, Depends(require_proposal_key)], request: Annotated[ProposalRequest, Depends(get_proposal_request)], @@ -100,7 +132,8 @@ async def correct_proposal( try: response = await request.service.request_correction( GuideProposalCorrection(**payload.model_dump(), idempotency_key=key), - actor=request.actor, request_id=request.request_id, + actor=request.actor, + request_id=request.request_id, ) await request.session.commit() return response @@ -111,19 +144,26 @@ async def correct_proposal( @router.post( - "/corrections/{correction_operation_id}/dispatch", response_model=GuideProposalDispatchResponse, + "/corrections/{correction_operation_id}/dispatch", + response_model=GuideProposalDispatchResponse, status_code=202, - openapi_extra={"x-workstream-action-id": 'project.guide_compilation.request'}, + openapi_extra={"x-workstream-action-id": "project.guide_compilation.request"}, ) async def dispatch_correction( - project_id: UUID, guide_id: UUID, compilation_id: UUID, correction_operation_id: UUID, + project_id: UUID, + guide_id: UUID, + compilation_id: UUID, + correction_operation_id: UUID, request: Annotated[CorrectionDispatchRequest, Depends(get_correction_dispatch)], ) -> GuideProposalDispatchResponse: """Manually dispatch the selected correction; its identity makes retries idempotent.""" try: return await request.service.dispatch( - GuideProposalSelection(project_id=project_id, guide_id=guide_id, compilation_id=compilation_id), - correction_operation_id, actor=request.actor, + GuideProposalSelection( + project_id=project_id, guide_id=guide_id, compilation_id=compilation_id + ), + correction_operation_id, + actor=request.actor, ) except GuideProposalError as exc: raise proposal_http_error(exc) from exc diff --git a/backend/app/api/routes/post_policy.py b/backend/app/api/routes/post_policy.py index 8b2000213..b4a3635ab 100644 --- a/backend/app/api/routes/post_policy.py +++ b/backend/app/api/routes/post_policy.py @@ -10,28 +10,41 @@ from app.api.deps.authorization import enforce_human_authorization_read from app.api.deps.guide_proposal_http import ( - IDEMPOTENCY_PARAMETER, proposal_http_error, require_matching_target, require_proposal_key, + IDEMPOTENCY_PARAMETER, + proposal_http_error, + require_matching_target, + require_proposal_key, ) from app.api.deps.post_policy import PostPolicyRequest, get_post_policy_request from app.core.api_controls import ApiErrorResponse -from app.modules.checkers.api.post_submit_catalogue import CompiledPostSubmitPolicy +from app.modules.checkers.api.external_policy import LockedExternalPostSubmitPolicy from app.modules.projects.api.guide_proposals import GuideProposalError from app.modules.projects.api.post_policy import ( - PostPolicyApproval, PostPolicyApprovalInput, PostPolicyCorrection, PostPolicyCorrectionInput, - PostPolicyReceipt, PostPolicyReviewPackage, PostPolicySelection, PostPolicyTarget, + PostPolicyApproval, + PostPolicyApprovalInput, + PostPolicyCorrection, + PostPolicyCorrectionInput, + PostPolicyReceipt, + PostPolicyReviewPackage, + PostPolicySelection, + PostPolicyTarget, ) router = APIRouter( prefix="/projects/{project_id}/guides/{guide_id}/compilations/{compilation_id}" - "/post-submission-policies/{policy_id}", - tags=["projects"], dependencies=[Depends(enforce_human_authorization_read)], + "/post-submission-policies/{policy_id}", + tags=["projects"], + dependencies=[Depends(enforce_human_authorization_read)], responses={code: {"model": ApiErrorResponse} for code in (404, 409, 422, 503)}, ) def require_policy_target( - target: PostPolicyTarget, project_id: UUID, guide_id: UUID, - compilation_id: UUID, policy_id: UUID, + target: PostPolicyTarget, + project_id: UUID, + guide_id: UUID, + compilation_id: UUID, + policy_id: UUID, ) -> None: """Bind every body identity to the selected public resource.""" require_matching_target(target.proposal, project_id, guide_id, compilation_id) @@ -40,21 +53,31 @@ def require_policy_target( @router.get( - "", response_model=PostPolicyReviewPackage[CompiledPostSubmitPolicy], + "", + response_model=PostPolicyReviewPackage[LockedExternalPostSubmitPolicy], openapi_extra={"x-workstream-action-id": "project.guide_compilation.review_package.read"}, ) async def read_post_policy( - project_id: UUID, guide_id: UUID, compilation_id: UUID, policy_id: UUID, + project_id: UUID, + guide_id: UUID, + compilation_id: UUID, + policy_id: UUID, request: Annotated[PostPolicyRequest, Depends(get_post_policy_request)], -) -> PostPolicyReviewPackage[CompiledPostSubmitPolicy]: +) -> PostPolicyReviewPackage[LockedExternalPostSubmitPolicy]: """Read the complete canonical body and discover any saved correction.""" try: response = await request.service.review_package( - PostPolicySelection(project_id=project_id, guide_id=guide_id, - compilation_id=compilation_id, policy_id=policy_id), - actor=request.actor, request_id=request.request_id, contribution=request.contribution, + PostPolicySelection( + project_id=project_id, + guide_id=guide_id, + compilation_id=compilation_id, + policy_id=policy_id, + ), + actor=request.actor, + request_id=request.request_id, + contribution=request.contribution, ) - adapter = TypeAdapter(PostPolicyReviewPackage[CompiledPostSubmitPolicy]) + adapter = TypeAdapter(PostPolicyReviewPackage[LockedExternalPostSubmitPolicy]) response = adapter.validate_json(adapter.dump_json(response, warnings="error")) await request.session.commit() return response @@ -65,13 +88,19 @@ async def read_post_policy( @router.post( - "/approval", response_model=PostPolicyReceipt, - openapi_extra={"x-workstream-action-id": "project.post_submit_checker_policy.approve", - "parameters": [IDEMPOTENCY_PARAMETER]}, + "/approval", + response_model=PostPolicyReceipt, + openapi_extra={ + "x-workstream-action-id": "project.post_submit_checker_policy.approve", + "parameters": [IDEMPOTENCY_PARAMETER], + }, dependencies=[Depends(require_proposal_key)], ) async def approve_post_policy( - project_id: UUID, guide_id: UUID, compilation_id: UUID, policy_id: UUID, + project_id: UUID, + guide_id: UUID, + compilation_id: UUID, + policy_id: UUID, payload: PostPolicyApprovalInput, key: Annotated[UUID, Depends(require_proposal_key)], request: Annotated[PostPolicyRequest, Depends(get_post_policy_request)], @@ -81,7 +110,8 @@ async def approve_post_policy( try: response = await request.service.approve( PostPolicyApproval(**payload.model_dump(), idempotency_key=key), - actor=request.actor, request_id=request.request_id, + actor=request.actor, + request_id=request.request_id, ) await request.session.commit() return response @@ -92,13 +122,20 @@ async def approve_post_policy( @router.post( - "/corrections", response_model=PostPolicyReceipt, status_code=201, - openapi_extra={"x-workstream-action-id": "project.post_submit_checker_policy.correction.request", - "parameters": [IDEMPOTENCY_PARAMETER]}, + "/corrections", + response_model=PostPolicyReceipt, + status_code=201, + openapi_extra={ + "x-workstream-action-id": "project.post_submit_checker_policy.correction.request", + "parameters": [IDEMPOTENCY_PARAMETER], + }, dependencies=[Depends(require_proposal_key)], ) async def correct_post_policy( - project_id: UUID, guide_id: UUID, compilation_id: UUID, policy_id: UUID, + project_id: UUID, + guide_id: UUID, + compilation_id: UUID, + policy_id: UUID, payload: PostPolicyCorrectionInput, key: Annotated[UUID, Depends(require_proposal_key)], request: Annotated[PostPolicyRequest, Depends(get_post_policy_request)], @@ -108,7 +145,8 @@ async def correct_post_policy( try: response = await request.service.request_correction( PostPolicyCorrection(**payload.model_dump(), idempotency_key=key), - actor=request.actor, request_id=request.request_id, + actor=request.actor, + request_id=request.request_id, guide_authorization=request.guide_authorization, ) await request.session.commit() diff --git a/backend/app/interfaces/project_agents.py b/backend/app/interfaces/project_agents.py index 4847c6532..06f14e0b0 100644 --- a/backend/app/interfaces/project_agents.py +++ b/backend/app/interfaces/project_agents.py @@ -10,7 +10,8 @@ from uuid import UUID from app.modules.checkers.api.artifact_paths import ( - is_canonical_relative_path, is_canonical_relative_pattern, + is_canonical_relative_path, + is_canonical_relative_pattern, ) from pydantic import ( @@ -26,13 +27,9 @@ ) from app.modules.projects.api.task_examples import ProjectGuideTaskExamples -from app.modules.checkers.api.post_submit_catalogue import ( - PostSubmitCatalogue, - PostSubmitDefinition, -) -from app.modules.checkers.api.pre_submit_catalogue import ( - PreSubmissionCapabilityDefinition, - PreSubmissionCapabilityProjection, +from app.modules.checkers.api.external import ( + ExternalCheckerCapabilityDefinition, + ExternalCheckerCapabilityProjection, ) from app.interfaces.external_services import ( ExternalServiceAdapter, @@ -40,7 +37,11 @@ ExternalServiceConfigurationError, ) from app.interfaces.project_guide_runtime import ProjectGuideRuntimeConfiguration -from app.modules.projects.api.guide_documents import GuideRuntimeCleanupCustody, GuideDocumentManifest, GuideRuntimeCapabilities +from app.modules.projects.api.guide_documents import ( + GuideRuntimeCleanupCustody, + GuideDocumentManifest, + GuideRuntimeCapabilities, +) MAXIMUM_PROJECT_GUIDE_COMPILATION_PROMPT_BYTES = 1_000_000 @@ -81,12 +82,17 @@ ), } ModelProse = Annotated[str, Field(json_schema_extra=_MODEL_PROSE_SCHEMA)] -PolicyIdentifier = Annotated[str, Field(json_schema_extra={ - "pattern": _SAFE_IDENTIFIER.pattern, - "minLength": 1, - "maxLength": 100, - "description": "Canonical machine identifier, not prose or a file path: start with a lowercase letter, then lowercase letters, digits, underscores, dots or hyphens. Example: results or rights_confirmed.", -})] +PolicyIdentifier = Annotated[ + str, + Field( + json_schema_extra={ + "pattern": _SAFE_IDENTIFIER.pattern, + "minLength": 1, + "maxLength": 100, + "description": "Canonical machine identifier, not prose or a file path: start with a lowercase letter, then lowercase letters, digits, underscores, dots or hyphens. Example: results or rights_confirmed.", + } + ), +] def _validated_safe_model_text(value: str) -> str: @@ -134,10 +140,14 @@ class GuideEvidenceRef(BaseModel): sha256: str = Field(pattern=r"^sha256:[0-9a-f]{64}$") start_page: StrictInt | None = Field(default=None, ge=1, le=100_000) end_page: StrictInt | None = Field(default=None, ge=1, le=100_000) - section: str | None = Field(default=None, max_length=200, description=( - "Optional plain-prose section label. Paraphrase headings; do not copy URLs, " - "paths, slash-separated phrases, credentials or executable command tokens." - )) + section: str | None = Field( + default=None, + max_length=200, + description=( + "Optional plain-prose section label. Paraphrase headings; do not copy URLs, " + "paths, slash-separated phrases, credentials or executable command tokens." + ), + ) @field_validator("section") @classmethod @@ -167,7 +177,10 @@ class CapabilityParameter(BaseModel): model_config = ConfigDict(extra="forbid", frozen=True) name: str = Field(json_schema_extra={"pattern": _SAFE_IDENTIFIER.pattern}) - value: CapabilityScalar | Annotated[tuple[CapabilityScalar, ...], Field(min_length=1, max_length=50)] + value: ( + CapabilityScalar + | Annotated[tuple[CapabilityScalar, ...], Field(min_length=1, max_length=50)] + ) @field_validator("name") @classmethod @@ -211,6 +224,7 @@ def validate_identifiers(cls, value: str) -> str: """Require canonical requirement and capability identity fields.""" return _validated_identifier(value) + class PreSubmissionBindingProposal(_CapabilityBindingIdentity): """Reference intake capability; its settings live only in the artifact policy.""" @@ -266,13 +280,15 @@ class AtomicGuideRequirement(BaseModel): requirement_id: str = Field(json_schema_extra={"pattern": _SAFE_IDENTIFIER.pattern}) statement: ModelProse - disposition: RequirementDisposition = Field(description=( - "Use human_review for work assigned to an authorized human reviewer. " - "Use a capability gap only for required unsupported automated evaluation. " - "A guide_blocker requires guide_blocked and no artifact policy. Capability " - "gaps remain explicit activation blockers while the manager reviews the " - "available exact bindings in a warning-ready proposal." - )) + disposition: RequirementDisposition = Field( + description=( + "Use human_review for work assigned to an authorized human reviewer. " + "Use a capability gap only for required unsupported automated evaluation. " + "A guide_blocker requires guide_blocked and no artifact policy. Capability " + "gaps remain explicit activation blockers while the manager reviews the " + "available exact bindings in a warning-ready proposal." + ) + ) platform_coverage: PlatformCoverageRef | None = None evidence_refs: tuple[GuideEvidenceRef, ...] = Field( default=(), max_length=MAXIMUM_EVIDENCE_REFS @@ -290,24 +306,29 @@ class SubmissionArtifactPolicyProposal(BaseModel): packaging: Literal["zip"] = "zip" maximum_file_size_bytes: StrictInt = Field(gt=0, le=10 * 1024 * 1024 * 1024) maximum_package_size_bytes: StrictInt = Field( - gt=0, le=10 * 1024 * 1024 * 1024, + gt=0, + le=10 * 1024 * 1024 * 1024, description="Maximum total expanded bytes in the submitted ZIP, verified from actual contents; not compressed upload bytes.", ) maximum_archive_size_bytes: StrictInt | None = Field( - default=None, gt=0, + default=None, + gt=0, description="Maximum verified byte count of the entire submitted compressed ZIP, including archive metadata; not expanded contents or summed compressed member sizes. Null adds no project limit; platform safety limits always apply.", ) maximum_archive_entries: StrictInt | None = Field( - default=None, gt=0, + default=None, + gt=0, description="Maximum normalized outer ZIP entries, counting files and directory entries including implied parent directories. Omitting a directory record cannot evade the limit. Nested archives count as files, not recursively expanded members. Null adds no project limit; platform safety limits always apply.", ) allowed_storage_schemes: tuple[Literal["artifact"], ...] = ("artifact",) required_artifacts: tuple[Annotated[str, Field(min_length=1, max_length=500)], ...] = Field( - default=(), max_length=100, + default=(), + max_length=100, description="Exact canonical relative POSIX paths inside the submitted ZIP. A bare path such as task.toml requires that file at the ZIP root; wrapper/task.toml does not satisfy it. Nested paths such as outputs/answer.md require that exact location. No traversal, storage references or secret files.", ) forbidden_artifacts: tuple[Annotated[str, Field(min_length=1, max_length=500)], ...] = Field( - default=(), max_length=100, + default=(), + max_length=100, description="Relative artifact prohibition patterns, such as secret* or outputs/*.tmp; these are machine fields, not prose.", ) required_evidence: tuple[PolicyIdentifier, ...] = Field(default=(), max_length=100) @@ -317,7 +338,9 @@ class SubmissionArtifactPolicyProposal(BaseModel): @classmethod def validate_required_paths(cls, values: tuple[str, ...]) -> tuple[str, ...]: """Artifact paths are machine fields, not display prose.""" - if len(values) != len(set(values)) or not all(is_canonical_relative_path(value) for value in values): + if len(values) != len(set(values)) or not all( + is_canonical_relative_path(value) for value in values + ): raise ValueError("artifact policy paths must be unique canonical relative paths") return values @@ -325,7 +348,9 @@ def validate_required_paths(cls, values: tuple[str, ...]) -> tuple[str, ...]: @classmethod def validate_forbidden_patterns(cls, values: tuple[str, ...]) -> tuple[str, ...]: """Express prohibition patterns without treating their secret names as requests.""" - if len(values) != len(set(values)) or not all(is_canonical_relative_pattern(value) for value in values): + if len(values) != len(set(values)) or not all( + is_canonical_relative_pattern(value) for value in values + ): raise ValueError("artifact policy patterns must be unique canonical relative patterns") return values @@ -386,10 +411,11 @@ class ProjectGuideCompilationContext(BaseModel): setup_generation: StrictInt = Field(ge=1) instruction_version: str = Field(max_length=100) agent_identity: str = Field(max_length=100) - agent_version: str = Field(max_length=100, json_schema_extra={"pattern": _SAFE_IDENTIFIER.pattern}) + agent_version: str = Field( + max_length=100, json_schema_extra={"pattern": _SAFE_IDENTIFIER.pattern} + ) runtime_configuration: ProjectGuideRuntimeConfiguration - pre_submission_capabilities: PreSubmissionCapabilityProjection - post_submission_capabilities: PostSubmitCatalogue + checker_capabilities: ExternalCheckerCapabilityProjection task_examples: ProjectGuideTaskExamples correction_feedback: ProjectGuideCorrectionFeedback | None = None @@ -397,11 +423,17 @@ class ProjectGuideCompilationContext(BaseModel): def validate_instruction_configuration(self) -> ProjectGuideCompilationContext: """Bind the semantic instruction version to its exact execution snapshot.""" configuration = self.runtime_configuration - if (self.material.setup_run_id != self.setup_run_id - or self.material.setup_generation != self.setup_generation - or len(self.material.documents) > configuration.maximum_documents - or any(item.byte_count > configuration.maximum_document_bytes for item in self.material.documents) - or sum(item.byte_count for item in self.material.documents) > configuration.maximum_total_document_bytes): + if ( + self.material.setup_run_id != self.setup_run_id + or self.material.setup_generation != self.setup_generation + or len(self.material.documents) > configuration.maximum_documents + or any( + item.byte_count > configuration.maximum_document_bytes + for item in self.material.documents + ) + or sum(item.byte_count for item in self.material.documents) + > configuration.maximum_total_document_bytes + ): raise ValueError("compilation document manifest exceeds its execution boundary") if self.instruction_version != self.runtime_configuration.instruction_version: raise ValueError("compilation instruction configuration mismatch") @@ -460,7 +492,9 @@ class ProjectGuideCompilationResult(BaseModel): ) setup_notes: tuple[ModelProse, ...] = Field(default=(), max_length=MAXIMUM_COMPILATION_NOTES) agent_name: Literal["ProjectGuideCompilationAgent"] = "ProjectGuideCompilationAgent" - agent_version: str = Field(max_length=100, json_schema_extra={"pattern": _SAFE_IDENTIFIER.pattern}) + agent_version: str = Field( + max_length=100, json_schema_extra={"pattern": _SAFE_IDENTIFIER.pattern} + ) schema_version: Literal["project_guide_compilation_result.v1"] = ( "project_guide_compilation_result.v1" ) @@ -490,10 +524,11 @@ def validate_project_guide_compilation_result( result: ProjectGuideCompilationResult, ) -> None: """Fail closed when an untrusted result diverges from canonical capability truth.""" - if project_guide_compilation_result_storage_bytes(result) > MAXIMUM_COMPILATION_RESULT_STORAGE_BYTES: + if ( + project_guide_compilation_result_storage_bytes(result) + > MAXIMUM_COMPILATION_RESULT_STORAGE_BYTES + ): raise ValueError("compilation result exceeds storage byte limit") - if not context.pre_submission_capabilities.available: - raise ValueError("pre-submit capability projection is unavailable") requirements = {item.requirement_id: item for item in result.requirements} if len(requirements) != len(result.requirements): raise ValueError("compilation requirements must be unique") @@ -505,18 +540,16 @@ def validate_project_guide_compilation_result( elif result.submission_artifact_policy is None: raise ValueError("draft-ready compilation requires artifact policy") + capabilities = ExternalCheckerCapabilityProjection.model_validate(context.checker_capabilities) pre_definitions = { - definition.stable_id: definition - for definition in context.pre_submission_capabilities.definitions + definition.capability_id: definition + for definition in capabilities.definitions + if definition.phase == "pre_submit" } - post_capabilities = context.post_submission_capabilities - post_capabilities = PostSubmitCatalogue.model_validate(post_capabilities) - if any( - item.platform_default and item.state != "enabled" for item in post_capabilities.definitions - ): - raise ValueError("post-submit capability projection is unavailable") post_definitions = { - definition.capability_id: definition for definition in post_capabilities.definitions + definition.capability_id: definition + for definition in capabilities.definitions + if definition.phase == "post_submit" } _validate_platform_coverage(result.requirements, pre_definitions, post_definitions) _validate_evidence_lineage(context, result) @@ -526,7 +559,7 @@ def validate_project_guide_compilation_result( pre_definitions, "pre_submit", ) - post_bound_requirements = validate_post_submission_bindings(result, post_capabilities) + post_bound_requirements = validate_post_submission_bindings(result, capabilities) expected_pre = { item.requirement_id for item in result.requirements @@ -542,23 +575,29 @@ def validate_project_guide_compilation_result( def validate_post_submission_bindings( - result: ProjectGuideCompilationResult, catalogue: PostSubmitCatalogue, + result: ProjectGuideCompilationResult, + capabilities: ExternalCheckerCapabilityProjection, ) -> set[str]: - """Validate the same post-stage requirement/configuration rules at both boundaries.""" + """Validate POST bindings against the immutable external registry projection.""" result = ProjectGuideCompilationResult.model_validate_json(result.model_dump_json()) - catalogue = PostSubmitCatalogue.model_validate(catalogue) + capabilities = ExternalCheckerCapabilityProjection.model_validate(capabilities) requirements = {item.requirement_id: item for item in result.requirements} if len(requirements) != len(result.requirements): raise ValueError("compilation requirements must be unique") _validate_status_consistency(result) - if any(item.platform_default and item.state != "enabled" for item in catalogue.definitions): - raise ValueError("post-submit capability projection is unavailable") bound = _validate_bindings( - result.post_submit_bindings, requirements, - {item.capability_id: item for item in catalogue.definitions}, "post_submit", + result.post_submit_bindings, + requirements, + { + item.capability_id: item + for item in capabilities.definitions + if item.phase == "post_submit" + }, + "post_submit", ) if bound != { - item.requirement_id for item in result.requirements + item.requirement_id + for item in result.requirements if item.disposition is RequirementDisposition.SUPPORTED_POST_SUBMIT }: raise ValueError("supported compilation requirements must have one binding") @@ -567,8 +606,11 @@ def validate_post_submission_bindings( def project_guide_compilation_result_storage_bytes(result: ProjectGuideCompilationResult) -> int: """Measure the default SQLAlchemy PostgreSQL JSON representation, not hash encoding.""" - return len(json.dumps(result.model_dump(mode="json"), ensure_ascii=True, - allow_nan=False).encode("utf-8")) + return len( + json.dumps(result.model_dump(mode="json"), ensure_ascii=True, allow_nan=False).encode( + "utf-8" + ) + ) def _validate_capability_suggestions( @@ -580,13 +622,18 @@ def _validate_capability_suggestions( RequirementDisposition.PRE_SUBMIT_CAPABILITY_GAP: CompilationStage.PRE_SUBMIT, RequirementDisposition.POST_SUBMIT_CAPABILITY_GAP: CompilationStage.POST_SUBMIT, } - gaps = {key: stages[item.disposition] for key, item in requirements.items() - if item.disposition in stages} + gaps = { + key: stages[item.disposition] + for key, item in requirements.items() + if item.disposition in stages + } seen: set[str] = set() for suggestion in suggestions: - if (suggestion.requirement_id in seen - or gaps.get(suggestion.requirement_id) != suggestion.stage - or not suggestion.evidence_refs): + if ( + suggestion.requirement_id in seen + or gaps.get(suggestion.requirement_id) != suggestion.stage + or not suggestion.evidence_refs + ): raise ValueError("compilation capability suggestion is invalid") seen.add(suggestion.requirement_id) if seen != set(gaps): @@ -599,9 +646,8 @@ def _validate_status_consistency(result: ProjectGuideCompilationResult) -> None: requirement.disposition is RequirementDisposition.GUIDE_BLOCKER for requirement in result.requirements ) - has_warning = ( - any(finding.severity == "warning" for finding in result.findings) - or bool(result.capability_suggestions) + has_warning = any(finding.severity == "warning" for finding in result.findings) or bool( + result.capability_suggestions ) if result.status == "guide_blocked" and not has_blocker: raise ValueError("blocked compilation requires blocking evidence") @@ -615,8 +661,8 @@ def _validate_status_consistency(result: ProjectGuideCompilationResult) -> None: def _validate_platform_coverage( requirements: tuple[AtomicGuideRequirement, ...], - pre_definitions: dict[str, PreSubmissionCapabilityDefinition], - post_definitions: dict[str, PostSubmitDefinition], + pre_definitions: dict[str, ExternalCheckerCapabilityDefinition], + post_definitions: dict[str, ExternalCheckerCapabilityDefinition], ) -> None: """Resolve platform coverage only against eligible phase-owner truth.""" for requirement in requirements: @@ -631,21 +677,14 @@ def _validate_platform_coverage( definition = pre_definitions.get(coverage.capability_id) valid = ( definition is not None - and definition.version == coverage.capability_version - and definition.dispatch_kind == "platform_capability" - and definition.state == "enabled" - and definition.classification != "advisory" + and definition.capability_version == coverage.capability_version + and definition.capability_id == "workstream.default" and not definition.selectable ) else: - post_definition = post_definitions.get(coverage.capability_id) - valid = ( - post_definition is not None - and post_definition.capability_version == coverage.capability_version - and post_definition.state == "enabled" - and post_definition.platform_default - and not post_definition.selectable - ) + # Workstream owns exactly one built-in default checker and it runs + # before admission. POST capabilities are project-selected images. + valid = False if not valid: raise ValueError("platform coverage does not resolve to canonical truth") @@ -681,7 +720,7 @@ def _validate_evidence_lineage( def _validate_bindings( bindings: tuple[PreSubmissionBindingProposal | PostSubmissionBindingProposal, ...], requirements: dict[str, AtomicGuideRequirement], - definitions: dict[str, PreSubmissionCapabilityDefinition | PostSubmitDefinition], + definitions: dict[str, ExternalCheckerCapabilityDefinition], expected_stage: Literal["pre_submit", "post_submit"], ) -> set[str]: """Validate exact stage, version, selectability, and parameter ownership.""" @@ -703,24 +742,20 @@ def _validate_bindings( or binding.stage.value != expected_stage ): raise ValueError("compilation capability binding is invalid") - version = ( - definition.version - if isinstance(definition, PreSubmissionCapabilityDefinition) - else definition.capability_version - ) - if binding.capability_version != version: + if binding.capability_version != definition.capability_version: raise ValueError("compilation capability version is stale") - if isinstance(definition, PostSubmitDefinition): + if expected_stage == "post_submit": if not isinstance(binding, PostSubmissionBindingProposal): raise ValueError("compilation capability binding is invalid") - definition.validate_configuration( + if definition.registry_entry is None: + raise ValueError("compilation capability binding is invalid") + definition.registry_entry.configuration_schema.validate_instance( {item.name: item.value for item in binding.parameters} ) seen_requirements.add(binding.requirement_id) return seen_requirements - class ProjectAgentRuntimeError(ExternalServiceAdapterError): """Raised when a project-agent runtime cannot complete a trusted operation.""" diff --git a/backend/app/main.py b/backend/app/main.py index 0d8c02b1f..afccb57e5 100644 --- a/backend/app/main.py +++ b/backend/app/main.py @@ -35,10 +35,6 @@ ) from app.core.observability import ObservabilityMiddleware, ObservabilityRuntime from app.interfaces.artifacts import ArtifactStoreBootstrap, ArtifactStoreNamespaceClaim -from app.modules.checkers.catalogue import ( - build_pre_submission_checker_catalogue, - parse_disabled_pre_submission_checker_ids, -) MAX_VALIDATION_ERRORS = 20 MAX_VALIDATION_LOCATION_PARTS = 8 @@ -93,11 +89,6 @@ async def _application_lifespan(app: FastAPI) -> AsyncIterator[None]: runtime: ObservabilityRuntime = app.state.observability_runtime runtime.start() try: - app.state.pre_submission_checker_catalogue = build_pre_submission_checker_catalogue( - disabled_entry_ids=parse_disabled_pre_submission_checker_ids( - settings.artifact_pre_submission_checker_disabled_ids - ) - ) if settings.pagination_cursor_hmac_secret is None: raise RuntimeError("pagination cursor HMAC secret is required") decode_pagination_cursor_hmac_secret(settings.pagination_cursor_hmac_secret) @@ -185,7 +176,9 @@ def _json_safe_validation_value(value: Any) -> Any: def _validation_summary(error: dict[str, Any]) -> dict[str, Any]: """Return bounded type/location evidence for the canonical error object.""" raw_type = error.get("type") - error_type = raw_type if isinstance(raw_type, str) and raw_type.isascii() else "validation_error" + error_type = ( + raw_type if isinstance(raw_type, str) and raw_type.isascii() else "validation_error" + ) error_type = error_type[:MAX_VALIDATION_CODE_LENGTH] location: list[int | str] = [] raw_location = error.get("loc") @@ -298,9 +291,7 @@ def create_app(settings: Settings | None = None) -> FastAPI: settings, service_name="workstream-api", route_templates=route_templates, - export_adapter=create_observability_export_adapter( - settings, service_name="workstream-api" - ), + export_adapter=create_observability_export_adapter(settings, service_name="workstream-api"), ) app.state.observability_runtime = runtime app.add_middleware(RequestContextMiddleware) diff --git a/backend/app/modules/artifacts/submission_admission.py b/backend/app/modules/artifacts/submission_admission.py index f754977f2..84bbec20e 100644 --- a/backend/app/modules/artifacts/submission_admission.py +++ b/backend/app/modules/artifacts/submission_admission.py @@ -5,7 +5,6 @@ from collections.abc import Callable from contextlib import AbstractAsyncContextManager, AsyncExitStack from dataclasses import dataclass, replace -import json from uuid import UUID from app.core.hashing import canonical_json_hash from app.core.identifiers import new_record_id @@ -15,7 +14,6 @@ from app.modules.artifacts.api import ( SubmissionBundlePreparationCheckFailed, - SubmissionBundleFile, SubmissionBundlePreparationRejected, SubmissionBundlePreparationInfrastructureUnavailable, SubmissionBundlePreparationRequest, @@ -65,8 +63,6 @@ from app.modules.artifacts.submission_materialization import ( PreparedBundleMaterializationRequest, PreparedBundleMaterializationService, - PreparedBundlePreSubmitEvidenceService, - PreSubmissionEvaluationPort, ) from app.modules.artifacts.selected_pre_submit_admission import ( bind_selected_pre_submit_admission, @@ -76,7 +72,6 @@ from app.modules.artifacts.selected_pre_submit_execution import ( SelectedPreSubmitExecutionService, ) -from app.modules.checkers.api.post_submit import PostSubmissionEvaluationContent from app.modules.checkers.api.selected_pre_submit import ( SelectedPreSubmitCompletion, SelectedPreSubmitCoordinationPort, @@ -89,12 +84,7 @@ LockedExternalCheckerPolicies, selected_pre_submit_execution_budget_ms, ) -from app.modules.checkers.api import ( - EffectivePreSubmissionExecutionPlan, - EffectivePreSubmissionPlanLineage, - EffectivePreSubmissionPlanningPort, - SubmissionPacketView, -) +from app.modules.checkers.api import SubmissionPacketView from app.modules.projects.api import ( ProjectLockedPolicyContextFacts, ProjectLockedPolicyContextPort, @@ -221,9 +211,7 @@ async def admit_in_transaction( replay_durable_intent_id=request.replay_durable_intent_id, selected_pre_submit_run_id=selected_run_id, selected_terminal_digest=( - custody.selected_terminal_digest - if selected_run_id is not None - else None + custody.selected_terminal_digest if selected_run_id is not None else None ), ), submission_prepared_authorization=self._authorization, @@ -246,15 +234,10 @@ async def publish_after_commit( selected_pre_submit_run_id: UUID | None = None, ) -> SubmissionBundleDurablePutResult: """Hand the exact ZIP to storage only after the durable transaction ended.""" - if ( - selected_pre_submit_run_id is not None - and selected_pre_submit_run_id != lineage_id - ): + if selected_pre_submit_run_id is not None and selected_pre_submit_run_id != lineage_id: await prepared.close() raise RuntimeError("submission bundle selected lineage changed") - evidence_set_id = ( - None if selected_pre_submit_run_id is not None else lineage_id - ) + evidence_set_id = None if selected_pre_submit_run_id is not None else lineage_id if self._session.in_transaction(): await prepared.close() raise RuntimeError("submission bundle durable transaction is still active") @@ -430,18 +413,12 @@ async def publish_verified( project_id=str( selected.project_id if selected is not None else evidence.project_id ), - task_id=str( - selected.task_id if selected is not None else evidence.task_id - ), + task_id=str(selected.task_id if selected is not None else evidence.task_id), actor_profile_id=str( - selected.actor_profile_id - if selected is not None - else evidence.actor_profile_id + selected.actor_profile_id if selected is not None else evidence.actor_profile_id ), archive_sha256=( - selected.archive_sha256 - if selected is not None - else evidence.archive_sha256 + selected.archive_sha256 if selected is not None else evidence.archive_sha256 ), archive_byte_count=( selected.archive_byte_count @@ -462,9 +439,7 @@ async def publish_verified( id=str(new_record_id()), durable_intent_id=intent.id, pre_submit_evidence_set_id=(evidence.id if evidence is not None else None), - selected_pre_submit_run_id=( - str(selected.attempt_id) if selected is not None else None - ), + selected_pre_submit_run_id=(str(selected.attempt_id) if selected is not None else None), put_attempt_id=attempt.id, artifact_content_id=content.id, verified_replica_id=replica.id, @@ -486,7 +461,9 @@ async def publish_verified( str(selected_lineage.predecessor_submission_id) if selected_lineage is not None and selected_lineage.predecessor_submission_id is not None - else evidence.predecessor_submission_id if evidence is not None else None + else evidence.predecessor_submission_id + if evidence is not None + else None ), predecessor_submission_version=( selected_lineage.predecessor_submission_version @@ -502,7 +479,9 @@ async def publish_verified( selected_lineage.guide_id if selected_lineage is not None else evidence.guide_id ), guide_version=( - selected_lineage.guide_version if selected_lineage is not None else evidence.guide_version + selected_lineage.guide_version + if selected_lineage is not None + else evidence.guide_version ), source_snapshot_id=str( selected_lineage.source_snapshot_id @@ -540,19 +519,13 @@ async def publish_verified( else evidence.effective_plan_sha256 ), selected_rules_sha256=( - selected_lineage.rules_sha256 - if selected_lineage is not None - else None + selected_lineage.rules_sha256 if selected_lineage is not None else None ), selected_post_submit_policy_sha256=( - selected_lineage.post_submit_policy_sha256 - if selected_lineage is not None - else None + selected_lineage.post_submit_policy_sha256 if selected_lineage is not None else None ), selected_post_submit_policy_body=( - selected_lineage.post_submit_policy_body - if selected_lineage is not None - else None + selected_lineage.post_submit_policy_body if selected_lineage is not None else None ), packet_sha256=( selected_lineage.packet_sha256 @@ -612,10 +585,7 @@ def _matches_verified_bytes( and receipt.verification_job_id == job.id and receipt.execution_generation == job.execution_generation and receipt.outcome == "verified" - and receipt.observed_sha256 - == attempt.sha256 - == content.sha256 - == archive_sha256 + and receipt.observed_sha256 == attempt.sha256 == content.sha256 == archive_sha256 and receipt.observed_byte_count == attempt.byte_count == content.byte_count @@ -715,13 +685,6 @@ class SubmissionBundlePreparationRuntime: selected_execution: SelectedPreSubmitExecutionService | None = None storage_scheme: str | None = None artifact_deadline_ms: int = 0 - catalogue: EffectivePreSubmissionPlanningPort | None = None - evidence: PreparedBundlePreSubmitEvidenceService | None = None - checker_service: PreSubmissionEvaluationPort | None = None - evaluation_content: Callable[ - [TaskSubmissionContextFacts, ProjectLockedPolicyContextFacts, SubmissionPacketView, - tuple[SubmissionBundleFile, ...], str], PostSubmissionEvaluationContent, - ] | None = None class PreparedSubmissionBundlePreparationCommand: @@ -767,9 +730,7 @@ async def prepare( async with self._session.begin(): task_context, project_context = await self._lock_authorized_context(request) predecessor = await self._load_predecessor(task_context) - predecessor_rules_sha256 = await self._load_predecessor_rules( - task_context - ) + predecessor_rules_sha256 = await self._load_predecessor_rules(task_context) prepared = await runtime.preparation.prepare( request.byte_source, media_type="application/zip", @@ -802,9 +763,7 @@ async def prepare( manifest=manifest, predecessor=predecessor, predecessor_rules_sha256=predecessor_rules_sha256, - predecessor_exists=( - request.predecessor_submission_id is not None - ), + predecessor_exists=(request.predecessor_submission_id is not None), packet=packet, ) attempt_id = new_record_id() @@ -822,9 +781,7 @@ async def prepare( identity_link_id=request.actor.identity_link_id, task_id=request.task_id, assignment_id=request.assignment_id, - predecessor_submission_id=( - request.predecessor_submission_id - ), + predecessor_submission_id=(request.predecessor_submission_id), idempotency_key=request.idempotency_key, archive_sha256=prepared.commitment.sha256, archive_byte_count=prepared.commitment.byte_count, @@ -862,16 +819,10 @@ async def prepare( default_checker_input=selected.default_input, selected_reservation=reservation, ) - current = await runtime.selected_coordinator.read_current( - reservation - ) + current = await runtime.selected_coordinator.read_current(reservation) if current is None: - await runtime.materialization.authorize_inspected( - materialization_request - ) - reserved_id = await runtime.selected_coordinator.reserve( - reservation - ) + await runtime.materialization.authorize_inspected(materialization_request) + reserved_id = await runtime.selected_coordinator.reserve(reservation) if reserved_id != reservation.attempt_id: raise RuntimeError("selected PRE reservation identity changed") if current is not None: @@ -909,9 +860,7 @@ async def prepare( "pre_submission_checked_custody_unavailable" ) if not terminal.execution.eligible: - raise SubmissionBundlePreparationCheckFailed( - terminal.execution - ) + raise SubmissionBundlePreparationCheckFailed(terminal.execution) if completion.capability is None: raise SubmissionBundlePreparationInfrastructureUnavailable( "pre_submission_checked_custody_unavailable" @@ -957,8 +906,7 @@ async def _selected_replay_result( ) if terminal.outcome == "infrastructure_failed": raise SubmissionBundlePreparationInfrastructureUnavailable( - terminal.infrastructure_failure_code - or "pre_submission_checked_custody_unavailable" + terminal.infrastructure_failure_code or "pre_submission_checked_custody_unavailable" ) execution = terminal.execution if execution is None: @@ -976,17 +924,14 @@ async def _selected_replay_result( ) .join( ArtifactPutAttempt, - ArtifactPutAttempt.id - == SubmissionBundleDurableIntent.put_attempt_id, + ArtifactPutAttempt.id == SubmissionBundleDurableIntent.put_attempt_id, ) .outerjoin( SubmissionBundleAdmission, - SubmissionBundleAdmission.durable_intent_id - == SubmissionBundleDurableIntent.id, + SubmissionBundleAdmission.durable_intent_id == SubmissionBundleDurableIntent.id, ) .where( - SubmissionBundleDurableIntent.selected_pre_submit_run_id - == str(current.run_id) + SubmissionBundleDurableIntent.selected_pre_submit_run_id == str(current.run_id) ) ) ).one_or_none() @@ -1007,9 +952,7 @@ async def _selected_replay_result( return SubmissionBundlePreparationResult( put_attempt_id=UUID(attempt.id), admission_id=admission_id, - submission_bundle_preparation_status=SubmissionBundlePreparationStatus( - status - ), + submission_bundle_preparation_status=SubmissionBundlePreparationStatus(status), replayed=True, ) @@ -1087,21 +1030,29 @@ async def _matching_replay_intent(self, evidence_id: UUID) -> UUID | None: def _evidence_failure(exc: PreSubmitEvidenceConflict) -> RuntimeError: """Separate changed client context from unavailable canonical execution evidence.""" if str(exc) == "pre_submit_locked_context_changed": - return SubmissionBundlePreparationRejected("submission_bundle_preparation_context_changed") + return SubmissionBundlePreparationRejected( + "submission_bundle_preparation_context_changed" + ) if str(exc) == "pre_submit_attempt_request_conflict": - return SubmissionBundlePreparationRejected("submission_bundle_preparation_request_conflict") - code = ("pre_submission_attempt_outcome_unresolved" - if str(exc) == "pre_submit_attempt_outcome_unresolved" - else "pre_submission_checked_custody_unavailable") + return SubmissionBundlePreparationRejected( + "submission_bundle_preparation_request_conflict" + ) + code = ( + "pre_submission_attempt_outcome_unresolved" + if str(exc) == "pre_submit_attempt_outcome_unresolved" + else "pre_submission_checked_custody_unavailable" + ) return SubmissionBundlePreparationInfrastructureUnavailable(code) async def _lock_authorized_context( - self, request: SubmissionBundlePreparationRequest, + self, + request: SubmissionBundlePreparationRequest, ) -> tuple[TaskSubmissionContextFacts, ProjectLockedPolicyContextFacts]: """Lock TASK, actor identity, PROJECT, then the current submitter grant.""" task, project = await self._lock_context(request) await self._authority.revalidate( - request=request, project_id=task.locked_project_context.project_id, + request=request, + project_id=task.locked_project_context.project_id, ) return task, project @@ -1139,49 +1090,6 @@ async def _lock_context( ) from exc return task_context, project_context - @staticmethod - def _compile_plan( - task_context: TaskSubmissionContextFacts, - project_context: ProjectLockedPolicyContextFacts, - planner: EffectivePreSubmissionPlanningPort, - ) -> EffectivePreSubmissionExecutionPlan: - """Compile the sole CHECKER plan from exact public PROJECT facts.""" - try: - effective_policy = json.loads(project_context.effective_policy.value) - compiled_bundle = json.loads( - project_context.compiled_pre_submit_bundle.value - ) - except (TypeError, ValueError) as exc: - raise SubmissionBundlePreparationRejected( - "submission_bundle_preparation_context_changed" - ) from exc - if ( - project_context.project_id - != task_context.locked_project_context.project_id - or not isinstance(effective_policy, dict) - or not isinstance(compiled_bundle, dict) - ): - raise SubmissionBundlePreparationRejected( - "submission_bundle_preparation_context_changed" - ) - return planner.compile_effective_plan( - lineage=EffectivePreSubmissionPlanLineage( - project_id=project_context.project_id, - guide_id=project_context.guide_id, - guide_version=project_context.guide_version, - source_snapshot_id=project_context.source_snapshot_id, - source_snapshot_hash=project_context.source_snapshot_hash, - effective_policy_id=project_context.effective_policy_id, - effective_policy_hash=project_context.effective_policy_hash, - pre_submit_policy_id=project_context.pre_submit_policy_id, - pre_submit_policy_bundle_hash=( - project_context.pre_submit_policy_bundle_hash - ), - ), - effective_policy=effective_policy, - compiled_bundle=compiled_bundle, - ) - async def _existing_durable_result( self, evidence_id: UUID ) -> SubmissionBundlePreparationResult | None: @@ -1270,18 +1178,13 @@ async def _load_predecessor_rules( raise SubmissionBundlePreparationRejected( "submission_canonical_predecessor_unavailable" ) - return ( - admission.selected_rules_sha256 - or admission.locked_policy_context_hash - ) + return admission.selected_rules_sha256 or admission.locked_policy_context_hash @staticmethod def _result(result: SubmissionBundleDurablePutResult) -> SubmissionBundlePreparationResult: return SubmissionBundlePreparationResult( put_attempt_id=result.put_attempt_id, admission_id=result.admission_id, - submission_bundle_preparation_status=SubmissionBundlePreparationStatus( - result.status - ), + submission_bundle_preparation_status=SubmissionBundlePreparationStatus(result.status), replayed=result.replayed, ) diff --git a/backend/app/modules/artifacts/submission_materialization.py b/backend/app/modules/artifacts/submission_materialization.py index 3820f600a..8c6cf778d 100644 --- a/backend/app/modules/artifacts/submission_materialization.py +++ b/backend/app/modules/artifacts/submission_materialization.py @@ -74,6 +74,7 @@ from app.modules.projects.api import ProjectLockedPolicyContextFacts from app.modules.tasks.api import TaskSubmissionContextFacts, TaskSubmissionContextPort + @dataclass(frozen=True, slots=True) class PreparedBundleMaterializationRequest: """ART-private process-local prepared bytes and exact execution facts.""" @@ -161,9 +162,16 @@ def issue( checked = ExternalCheckerExecutionRequest.model_validate(request) identity = checked.identity source = self._request + project_id = ( + source.selected_reservation.project_id + if source.selected_reservation is not None + else source.effective_plan.lineage.project_id + if source.effective_plan is not None + else None + ) if ( not isinstance(identity, PreSubmitExternalCheckerIdentity) - or identity.project_id != source.effective_plan.lineage.project_id + or identity.project_id != project_id or identity.task_id != source.task_id or identity.assignment_id != source.assignment_id or identity.prepared_generation_id != source.prepared_artifact.generation_id @@ -224,7 +232,10 @@ class PreSubmissionEvaluationPort(Protocol): """Finish ART's committed selection through the composed checker phase service.""" async def evaluate_pre_submission( - self, request: PreparedBundleMaterializationRequest, reservation: object, *, + self, + request: PreparedBundleMaterializationRequest, + reservation: object, + *, preparation_request: SubmissionBundlePreparationRequest, ) -> PreSubmitEvidencePersistenceResult: ... @@ -234,9 +245,7 @@ class PreSubmitCheckerProcessor(Protocol): def abort(self) -> None: ... - async def process( - self, reader: object, workspace: object - ) -> PreSubmissionExecutionFacts: ... + async def process(self, reader: object, workspace: object) -> PreSubmissionExecutionFacts: ... class PreSubmitCheckerExecutionFactory(Protocol): @@ -467,14 +476,11 @@ async def materialize_selected_pre_submit( or request.task_id != reservation.task_id or request.assignment_id != reservation.assignment_id or request.selected_reservation != reservation - or request.prepared_artifact.generation_id - != reservation.prepared_generation_id + or request.prepared_artifact.generation_id != reservation.prepared_generation_id or request.external_policy is None or request.external_policy.policy_sha256 != reservation.policy_sha256 or request.default_checker_input is None - or canonical_json_hash( - workstream_default_input_body(request.default_checker_input) - ) + or canonical_json_hash(workstream_default_input_body(request.default_checker_input)) != reservation.default_input_sha256 or commitment.sha256 != reservation.archive_sha256 or commitment.byte_count != reservation.archive_byte_count @@ -527,7 +533,11 @@ async def authorize_inspected(self, request: PreparedBundleMaterializationReques ) async def authorize_original_replay( - self, request: PreparedBundleMaterializationRequest, *, generation_id: UUID, key: UUID, + self, + request: PreparedBundleMaterializationRequest, + *, + generation_id: UUID, + key: UUID, ) -> None: """Check original stored service facts; this grants no retry-byte capability.""" facts = replace(self._authority_facts(request), prepared_generation_id=generation_id) @@ -585,8 +595,7 @@ async def prepare_selected_authorization( or references.effective_policy_id != project.effective_policy_id or references.effective_policy_hash != project.effective_policy_hash or references.pre_submit_policy_id != project.pre_submit_policy_id - or references.pre_submit_policy_bundle_hash - != project.pre_submit_policy_bundle_hash + or references.pre_submit_policy_bundle_hash != project.pre_submit_policy_bundle_hash or external_policy.policy_sha256 != canonical_json_hash( external_policy.model_dump(mode="json", exclude={"policy_sha256"}) @@ -675,12 +684,10 @@ def _preparation_facts( or external_policy is None or task_id != selected_reservation.task_id or assignment_id != selected_reservation.assignment_id - or prepared_artifact.generation_id - != selected_reservation.prepared_generation_id + or prepared_artifact.generation_id != selected_reservation.prepared_generation_id or submission_artifact_policy_id != lineage.effective_policy_id or checker_policy_id != lineage.pre_submit_policy_id - or external_policy.policy_sha256 - != selected_reservation.policy_sha256 + or external_policy.policy_sha256 != selected_reservation.policy_sha256 or commitment.sha256 != selected_reservation.archive_sha256 or commitment.byte_count != selected_reservation.archive_byte_count ): @@ -701,9 +708,7 @@ def _preparation_facts( checker_policy_hash=lineage.pre_submit_policy_sha256, prepared_generation_id=prepared_artifact.generation_id, plan_sha256=selected_reservation.policy_sha256, - catalogue_manifest_sha256=( - selected_reservation.default_behavior_sha256 - ), + catalogue_manifest_sha256=(selected_reservation.default_behavior_sha256), archive_sha256=commitment.sha256, archive_byte_count=commitment.byte_count, storage_scheme=self._storage_scheme, @@ -736,9 +741,7 @@ def _preparation_facts( or external_policy.workstream_default.behavior_sha256 != WORKSTREAM_DEFAULT_BEHAVIOR_SHA256 ): - raise PreSubmissionInfrastructureUnavailableError( - "external_pre_submit_policy_invalid" - ) + raise PreSubmissionInfrastructureUnavailableError("external_pre_submit_policy_invalid") commitment = prepared_artifact.commitment return PreSubmitMaterializationPreparationFacts( task_id=task_id, @@ -784,7 +787,8 @@ def __init__( def _evidence_service(self) -> PreSubmitEvidenceService: """Use the sole evidence owner for both lineage reads and completion.""" return PreSubmitEvidenceService( - self._session, task_contexts=self._task_contexts, + self._session, + task_contexts=self._task_contexts, project_contexts=self._project_contexts, ) @@ -804,16 +808,20 @@ def _input( return PreSubmitEvidenceInput( actor_profile_id=preparation_request.actor.actor_profile_id, identity_link_id=preparation_request.actor.identity_link_id, - task_id=request.task_id, assignment_id=request.assignment_id, + task_id=request.task_id, + assignment_id=request.assignment_id, predecessor_submission_id=preparation_request.predecessor_submission_id, expected_predecessor_submission_version=request.predecessor_submission_version, prepared_generation_id=request.prepared_artifact.generation_id, - archive_sha256=commitment.sha256, archive_byte_count=commitment.byte_count, - semantic_manifest_sha256=request.manifest.sha256, plan=request.effective_plan, + archive_sha256=commitment.sha256, + archive_byte_count=commitment.byte_count, + semantic_manifest_sha256=request.manifest.sha256, + plan=request.effective_plan, ) async def _lock_authorized_context( - self, request: PreparedBundleMaterializationRequest, + self, + request: PreparedBundleMaterializationRequest, preparation_request: SubmissionBundlePreparationRequest, ) -> PreSubmitEvidenceContext: """Match TASK, AUTH role issuance and revocation without reversing their locks.""" @@ -822,35 +830,47 @@ async def _lock_authorized_context( task_context = await evidence.lock_task_context(values) await self._preparation_authorization.lock_actor(request=preparation_request) context = await evidence.lock_project_context( - values, task_context=task_context, + values, + task_context=task_context, storage_scheme=self._materialization._storage_scheme, ) await self._preparation_authorization.revalidate(request=preparation_request) return context async def reserve( - self, request: PreparedBundleMaterializationRequest, *, + self, + request: PreparedBundleMaterializationRequest, + *, preparation_request: SubmissionBundlePreparationRequest, ) -> object: """Consume inspected authority and reserve; the caller must commit before execution.""" context = await self._lock_authorized_context(request, preparation_request) await self._materialization.authorize_inspected(request) selected = await self._attempts.reserve( - context=context, plan=request.effective_plan, packet=request.packet, - idempotency_key=preparation_request.idempotency_key, request=request, + context=context, + plan=request.effective_plan, + packet=request.packet, + idempotency_key=preparation_request.idempotency_key, + request=request, ) if isinstance(selected, PreSubmitExecutionAttempt): await self._materialization.authorize_original_replay( - request, generation_id=UUID(selected.prepared_generation_id), + request, + generation_id=UUID(selected.prepared_generation_id), key=preparation_request.idempotency_key, ) return await self._attempts.read_completed( - row=selected, context=context, plan=request.effective_plan, + row=selected, + context=context, + plan=request.effective_plan, ) return selected async def execute_reserved( - self, request: PreparedBundleMaterializationRequest, reservation: object, *, + self, + request: PreparedBundleMaterializationRequest, + reservation: object, + *, preparation_request: SubmissionBundlePreparationRequest, ) -> PreSubmitEvidencePersistenceResult: """Run a committed winning claim, then atomically persist its canonical evidence.""" @@ -861,7 +881,8 @@ async def execute_reserved( async with self._session.begin(): await self._lock_authorized_context(request, preparation_request) handle = await self._materialization.prepare_authorization( - task_id=request.task_id, assignment_id=request.assignment_id, + task_id=request.task_id, + assignment_id=request.assignment_id, submission_artifact_policy_id=request.submission_artifact_policy_id, checker_policy_id=request.checker_policy_id, prepared_artifact=request.prepared_artifact, @@ -871,17 +892,23 @@ async def execute_reserved( ) authorized_request = replace(request, prepared_authorization=handle) await self._materialization.authorize_prepared_bundle( - authorized_request, claim=claim, + authorized_request, + claim=claim, ) assert authorized_request is not None execution = await self._materialization.materialize_prepared_bundle( - replace(authorized_request, prepared_authorization=None), claim=claim, + replace(authorized_request, prepared_authorization=None), + claim=claim, ) async with self._session.begin(): await self._session.execute(text("set transaction isolation level read committed")) values = self._input(request, preparation_request) await self._lock_authorized_context(request, preparation_request) - return await self._evidence_service().persist(PreSubmitEvidencePersistenceRequest( - **{name: getattr(values, name) for name in values.__dataclass_fields__}, - execution=execution, attempt=claim, manifest=request.manifest, - )) + return await self._evidence_service().persist( + PreSubmitEvidencePersistenceRequest( + **{name: getattr(values, name) for name in values.__dataclass_fields__}, + execution=execution, + attempt=claim, + manifest=request.manifest, + ) + ) diff --git a/backend/app/modules/checkers/api/external.py b/backend/app/modules/checkers/api/external.py index 52c0b8a8a..85e0c72c4 100644 --- a/backend/app/modules/checkers/api/external.py +++ b/backend/app/modules/checkers/api/external.py @@ -68,13 +68,15 @@ def _canonical_json(value: object) -> str: """Match PostgreSQL JSONB canonical scalars without changing shared hashes.""" if isinstance(value, Mapping): if any(type(key) is not str or "\x00" in key for key in value): - raise ExternalCheckerContractError( - "external checker value is not canonical JSON" + raise ExternalCheckerContractError("external checker value is not canonical JSON") + return ( + "{" + + ",".join( + f"{json.dumps(key, ensure_ascii=False)}:{_canonical_json(item)}" + for key, item in sorted(value.items()) ) - return "{" + ",".join( - f"{json.dumps(key, ensure_ascii=False)}:{_canonical_json(item)}" - for key, item in sorted(value.items()) - ) + "}" + + "}" + ) if isinstance(value, (list, tuple)): return "[" + ",".join(_canonical_json(item) for item in value) + "]" if value is None: @@ -85,17 +87,13 @@ def _canonical_json(value: object) -> str: return str(value) if type(value) is float: if not isfinite(value): - raise ExternalCheckerContractError( - "external checker value is not canonical JSON" - ) + raise ExternalCheckerContractError("external checker value is not canonical JSON") if value == 0.0: return "0.0" return format(Decimal(str(value)), "f") if type(value) is str: if "\x00" in value: - raise ExternalCheckerContractError( - "external checker value is not canonical JSON" - ) + raise ExternalCheckerContractError("external checker value is not canonical JSON") return json.dumps(value, ensure_ascii=False) raise ExternalCheckerContractError("external checker value is not canonical JSON") @@ -216,9 +214,7 @@ class ExternalCheckerRegistryEntry(ExternalCheckerRegistrySpec): def validate_registry_entry_id(cls, value: UUID) -> UUID: """Require the server-selected registry identity to be canonical UUIDv7.""" if value.version != 7 or value.variant != RFC_4122: - raise ExternalCheckerContractError( - "external checker registry entry ID must be UUIDv7" - ) + raise ExternalCheckerContractError("external checker registry entry ID must be UUIDv7") return value @model_validator(mode="after") @@ -256,9 +252,7 @@ class ExternalCheckerRegistrationRequest(ExternalCheckerValue): def validate_registry_entry_id(cls, value: UUID) -> UUID: """Require the requested durable identity to be canonical UUIDv7.""" if value.version != 7 or value.variant != RFC_4122: - raise ExternalCheckerContractError( - "external checker registry entry ID must be UUIDv7" - ) + raise ExternalCheckerContractError("external checker registry entry ID must be UUIDv7") return value @model_validator(mode="after") @@ -316,6 +310,67 @@ async def read_identity( ) -> ExternalCheckerRegistryEntry: """Resolve the one immutable registered phase identity during approval.""" + async def list_entries(self) -> tuple[ExternalCheckerRegistryEntry, ...]: + """Return every immutable identity in canonical phase/name/version order.""" + + +class ExternalCheckerCapabilityDefinition(ExternalCheckerValue): + """One model-facing capability backed by code or an immutable registry row.""" + + capability_id: Identifier + capability_version: SchemaVersion + phase: ExternalCheckerPhase + selectable: bool + registry_entry: ExternalCheckerRegistryEntry | None = None + + @model_validator(mode="after") + def validate_source(self) -> Self: + """Keep the sole code-owned default distinct from selectable project images.""" + if self.selectable != (self.registry_entry is not None): + raise ExternalCheckerContractError("external checker capability source is invalid") + if self.registry_entry is not None and ( + self.capability_id, + self.capability_version, + self.phase, + ) != ( + self.registry_entry.capability_id, + self.registry_entry.capability_version, + self.registry_entry.phase, + ): + raise ExternalCheckerContractError("external checker capability identity is invalid") + return self + + +class ExternalCheckerCapabilityProjection(ExternalCheckerValue): + """Complete immutable compiler input with one default and registered images.""" + + schema_version: Literal["external_checker_capabilities.v1"] = "external_checker_capabilities.v1" + definitions: tuple[ExternalCheckerCapabilityDefinition, ...] + manifest_sha256: Sha256 + + @model_validator(mode="after") + def validate_projection(self) -> Self: + identities = [ + (item.phase, item.capability_id, item.capability_version) for item in self.definitions + ] + if identities != sorted(identities) or len(identities) != len(set(identities)): + raise ExternalCheckerContractError( + "external checker capability projection is not canonical" + ) + defaults = [item for item in self.definitions if not item.selectable] + if len(defaults) != 1 or ( + defaults[0].capability_id, + defaults[0].capability_version, + defaults[0].phase, + ) != ("workstream.default", "v1", "pre_submit"): + raise ExternalCheckerContractError("external checker default capability is invalid") + body = self.model_dump(mode="json", exclude={"manifest_sha256"}) + if self.manifest_sha256 != external_checker_json_hash(body): + raise ExternalCheckerContractError( + "external checker capability projection digest mismatch" + ) + return self + class PreSubmitExternalCheckerMaterial(ExternalCheckerValue): """Verified prepared bytes that exist before a Submission or ART binding.""" @@ -326,9 +381,7 @@ class PreSubmitExternalCheckerMaterial(ExternalCheckerValue): attempt_id: UUID = Field(strict=True) attempt_request_digest: Sha256 archive_sha256: Sha256 - archive_byte_count: Annotated[ - StrictInt, Field(ge=0, le=9_223_372_036_854_775_807) - ] + archive_byte_count: Annotated[StrictInt, Field(ge=0, le=9_223_372_036_854_775_807)] semantic_manifest_sha256: Sha256 media_type: Annotated[ StrictStr, Field(min_length=1, max_length=255, pattern=r"^[^\s/]+/[^\s/]+$") @@ -405,9 +458,7 @@ class PostSubmitExternalCheckerIdentity(ExternalCheckerValue): class ExternalCheckerExecutionRequest(ExternalCheckerValue): """One bounded normalized invocation selected by a later owner operation.""" - schema_version: Literal["external_checker_request.v1"] = ( - EXTERNAL_CHECKER_REQUEST_SCHEMA_VERSION - ) + schema_version: Literal["external_checker_request.v1"] = EXTERNAL_CHECKER_REQUEST_SCHEMA_VERSION registry: ExternalCheckerRegistryEntry identity: ExternalCheckerExecutionIdentity configuration: dict[str, JsonValue] @@ -453,9 +504,7 @@ def validate_request(self) -> Self: "external checker submission material identity mismatch" ) if self.configuration_sha256 != external_checker_json_hash(self.configuration): - raise ExternalCheckerContractError( - "external checker configuration digest mismatch" - ) + raise ExternalCheckerContractError("external checker configuration digest mismatch") if self.input_sha256 != external_checker_json_hash(self.input): raise ExternalCheckerContractError("external checker input digest mismatch") if len(_canonical_bytes(self.configuration)) > MAX_CONFIGURATION_BYTES: @@ -482,9 +531,7 @@ class ExternalCheckerFinding(ExternalCheckerValue): class ExternalCheckerExecutionResult(ExternalCheckerValue): """Normalized completed or infrastructure result bound to one exact request.""" - schema_version: Literal["external_checker_result.v1"] = ( - EXTERNAL_CHECKER_RESULT_SCHEMA_VERSION - ) + schema_version: Literal["external_checker_result.v1"] = EXTERNAL_CHECKER_RESULT_SCHEMA_VERSION request_digest: Sha256 registry_entry_id: UUID = Field(strict=True) registry_entry_digest: Sha256 @@ -508,7 +555,11 @@ class ExternalCheckerExecutionResult(ExternalCheckerValue): def validate_result(self) -> Self: """Keep work verdicts distinct from bounded infrastructure outcomes.""" if self.outcome == "infrastructure_failed": - if self.verdict is not None or self.findings or self.infrastructure_failure_code is None: + if ( + self.verdict is not None + or self.findings + or self.infrastructure_failure_code is None + ): raise ExternalCheckerContractError( "external checker infrastructure result shape is invalid" ) @@ -519,9 +570,7 @@ def validate_result(self) -> Self: ) has_error = any(item.level == "error" for item in self.findings) if (self.verdict == "failed") != has_error: - raise ExternalCheckerContractError( - "external checker verdict and findings disagree" - ) + raise ExternalCheckerContractError("external checker verdict and findings disagree") body = self.model_dump(mode="json", exclude={"result_digest"}) if len(_canonical_bytes(body)) > MAX_RESULT_BYTES: raise ExternalCheckerContractError("external checker result is too large") @@ -600,15 +649,11 @@ def make_external_checker_execution_request( **fields: object, ) -> ExternalCheckerExecutionRequest: """Build one external execution request with a derived canonical digest.""" - return _make_derived( - ExternalCheckerExecutionRequest, _REQUEST_FIELDS, "request_digest", fields - ) + return _make_derived(ExternalCheckerExecutionRequest, _REQUEST_FIELDS, "request_digest", fields) def make_external_checker_execution_result( **fields: object, ) -> ExternalCheckerExecutionResult: """Build one normalized result with a derived canonical digest.""" - return _make_derived( - ExternalCheckerExecutionResult, _RESULT_FIELDS, "result_digest", fields - ) + return _make_derived(ExternalCheckerExecutionResult, _RESULT_FIELDS, "result_digest", fields) diff --git a/backend/app/modules/checkers/api/external_policy.py b/backend/app/modules/checkers/api/external_policy.py index 8be1debdd..fd64c268c 100644 --- a/backend/app/modules/checkers/api/external_policy.py +++ b/backend/app/modules/checkers/api/external_policy.py @@ -7,11 +7,6 @@ from pydantic import BaseModel, ConfigDict, Field, JsonValue, model_validator from app.core.hashing import canonical_json_hash -from app.interfaces.project_agents import ( - PostSubmissionBindingProposal, - ProjectGuideCompilationResult, - RequirementDisposition, -) from app.modules.checkers.api.default_checker import ( WORKSTREAM_DEFAULT_BEHAVIOR_SHA256, WORKSTREAM_DEFAULT_CHECKER_ID, @@ -83,12 +78,8 @@ def validate_behavior(self) -> Self: class LockedExternalPreSubmitPolicy(_PolicyValue): """One default followed by every required project pre-submit image.""" - schema_version: Literal["external_pre_submit_policy.v1"] = ( - "external_pre_submit_policy.v1" - ) - workstream_default: LockedWorkstreamDefault = Field( - default_factory=LockedWorkstreamDefault - ) + schema_version: Literal["external_pre_submit_policy.v1"] = "external_pre_submit_policy.v1" + workstream_default: LockedWorkstreamDefault = Field(default_factory=LockedWorkstreamDefault) entries: tuple[LockedExternalCheckerBinding, ...] policy_sha256: str = Field(pattern=r"^sha256:[0-9a-f]{64}$") @@ -105,9 +96,7 @@ def validate_policy(self) -> Self: class LockedExternalPostSubmitPolicy(_PolicyValue): """Every required post-submit image; checkers retain no acceptance authority.""" - schema_version: Literal["external_post_submit_policy.v1"] = ( - "external_post_submit_policy.v1" - ) + schema_version: Literal["external_post_submit_policy.v1"] = "external_post_submit_policy.v1" entries: tuple[LockedExternalCheckerBinding, ...] policy_sha256: str = Field(pattern=r"^sha256:[0-9a-f]{64}$") @@ -124,9 +113,7 @@ def validate_policy(self) -> Self: class LockedExternalCheckerPolicies(_PolicyValue): """Complete approval-time pre/post policy custody for one guide generation.""" - schema_version: Literal["external_checker_policies.v1"] = ( - "external_checker_policies.v1" - ) + schema_version: Literal["external_checker_policies.v1"] = "external_checker_policies.v1" pre_submit: LockedExternalPreSubmitPolicy post_submit: LockedExternalPostSubmitPolicy policies_sha256: str = Field(pattern=r"^sha256:[0-9a-f]{64}$") @@ -158,29 +145,27 @@ def _validate_entries( async def compile_external_checker_policies( - result: ProjectGuideCompilationResult, + result: object, registry: ExternalCheckerRegistryPort, ) -> tuple[LockedExternalPreSubmitPolicy, LockedExternalPostSubmitPolicy]: """Resolve every supported binding to exact immutable registry custody.""" + from app.interfaces.project_agents import ProjectGuideCompilationResult + result = ProjectGuideCompilationResult.model_validate(result) if result.status == "guide_blocked": raise ExternalCheckerPolicyError("checker capability coverage is incomplete") requirements = {item.requirement_id: item for item in result.requirements} if len(requirements) != len(result.requirements): raise ExternalCheckerPolicyError("checker requirements are duplicated") - pre = await _resolve( - result.pre_submit_bindings, requirements, registry, "pre_submit" - ) - post = await _resolve( - result.post_submit_bindings, requirements, registry, "post_submit" - ) + pre = await _resolve(result.pre_submit_bindings, requirements, registry, "pre_submit") + post = await _resolve(result.post_submit_bindings, requirements, registry, "post_submit") return _make_policy(LockedExternalPreSubmitPolicy, pre), _make_policy( LockedExternalPostSubmitPolicy, post ) async def compile_external_checker_policy_bundle( - result: ProjectGuideCompilationResult, + result: object, registry: ExternalCheckerRegistryPort, ) -> LockedExternalCheckerPolicies: """Lock both execution phases into one immutable approval-time value.""" @@ -198,6 +183,11 @@ async def compile_external_checker_policy_bundle( async def _resolve(bindings, requirements, registry, phase): + from app.interfaces.project_agents import ( + PostSubmissionBindingProposal, + RequirementDisposition, + ) + expected = ( RequirementDisposition.SUPPORTED_PRE_SUBMIT if phase == "pre_submit" @@ -205,9 +195,8 @@ async def _resolve(bindings, requirements, registry, phase): ) resolved = [] for binding in sorted( - bindings, key=lambda item: ( - item.requirement_id, item.capability_id, item.capability_version - ), + bindings, + key=lambda item: (item.requirement_id, item.capability_id, item.capability_version), ): if ( requirements.get(binding.requirement_id) is None @@ -227,10 +216,7 @@ async def _resolve(bindings, requirements, registry, phase): ): raise ExternalCheckerPolicyError("checker registry identity mismatch") configuration = ( - { - parameter.name: parameter.value - for parameter in binding.parameters - } + {parameter.name: parameter.value for parameter in binding.parameters} if isinstance(binding, PostSubmissionBindingProposal) else {} ) @@ -244,9 +230,7 @@ async def _resolve(bindings, requirements, registry, phase): ) ) expected_ids = { - item.requirement_id - for item in requirements.values() - if item.disposition is expected + item.requirement_id for item in requirements.values() if item.disposition is expected } if {item.requirement_id for item in resolved} != expected_ids: raise ExternalCheckerPolicyError("checker requirement coverage is incomplete") @@ -283,14 +267,11 @@ def selected_pre_submit_execution_budget_ms( ): raise ExternalCheckerPolicyError("selected PRE execution budget is invalid") required = WORKSTREAM_DEFAULT_EXECUTION_BUDGET_MS + sum( - binding.registry.resources.deadline_ms - + EXTERNAL_CHECKER_EXECUTION_CLEANUP_MARGIN_MS + binding.registry.resources.deadline_ms + EXTERNAL_CHECKER_EXECUTION_CLEANUP_MARGIN_MS for binding in policy.entries ) if required > artifact_deadline_ms: - raise ExternalCheckerPolicyError( - "selected PRE execution exceeds ART custody deadline" - ) + raise ExternalCheckerPolicyError("selected PRE execution exceeds ART custody deadline") return required @@ -301,12 +282,9 @@ def selected_post_submit_execution_budget_ms( if type(policy) is not LockedExternalPostSubmitPolicy: raise ExternalCheckerPolicyError("selected POST execution budget is invalid") required = SELECTED_POST_MATERIALIZATION_BUDGET_MS + sum( - binding.registry.resources.deadline_ms - + EXTERNAL_CHECKER_EXECUTION_CLEANUP_MARGIN_MS + binding.registry.resources.deadline_ms + EXTERNAL_CHECKER_EXECUTION_CLEANUP_MARGIN_MS for binding in policy.entries ) if required > MAXIMUM_SELECTED_POST_EXECUTION_BUDGET_MS: - raise ExternalCheckerPolicyError( - "selected POST execution exceeds durable worker deadline" - ) + raise ExternalCheckerPolicyError("selected POST execution exceeds durable worker deadline") return required diff --git a/backend/app/modules/checkers/execution.py b/backend/app/modules/checkers/execution.py index 348937157..4f95f1971 100644 --- a/backend/app/modules/checkers/execution.py +++ b/backend/app/modules/checkers/execution.py @@ -54,14 +54,9 @@ stored_result, ) from app.modules.checkers.execution_results import classify_result -from app.modules.checkers.post_submit_contracts import make_post_submit_result -from app.modules.checkers.post_submit_implementations import ( - bounded_structural_result, - detached_checker_context, -) -from app.modules.checkers.runner import UnknownChecker, CheckerRegistry from app.modules.checkers.api.materialization import ( - PostSubmissionMaterializationPort, PostSubmissionMaterializationFailure, + PostSubmissionMaterializationPort, + PostSubmissionMaterializationFailure, ) from app.modules.outbox.api import OutboxAppendPort from app.modules.outbox.api import OutboxAppendInput @@ -87,64 +82,6 @@ def _evidence(value, expected_type, facts): return value.evidence_id -class _StructuralConsumer: - """Run registered structural checks while ART owns the verified private view.""" - - def __init__(self, registry, lease): - """Bind the installed registry and reserved attempt identities.""" - self._registry, self._lease = registry, lease - - async def evaluate(self, request, material): - # ART retains the verified private view for this callback. These registered - # rules inspect structural facts whose exact archive manifest ART verified. - """Validate installed definitions and convert bounded outcomes to closed results.""" - del material - identity = dict( - request_id=request.evaluation_request_id, - request_digest=request.request_sha256, - attempt_id=self._lease.reservation.attempt_id, - result_id=self._lease.reservation.result_id, - evaluation_generation=request.evaluation_generation, - ) - try: - for entry in request.policy.entries: - if self._registry.resolve( - entry.checker_id - ).definition != request.catalogue.definition( - entry.checker_id, entry.definition_version - ): - raise ValueError("post-submit installed catalogue mismatch") - limits = request.catalogue.definitions[0].resources - async with asyncio.timeout(limits.phase_deadline_ms / 1000): - outcomes = await self._registry.run( - detached_checker_context(request), request.policy.entries - ) - members = tuple( - bounded_structural_result( - request.catalogue.definition(entry.checker_id, entry.definition_version), - outcome, - ) - for entry, outcome in zip(request.policy.entries, outcomes, strict=True) - ) - result = make_post_submit_result( - **identity, outcome="completed", member_results=members - ) - result.validate_request(request) - return result - except TimeoutError: - code = "deadline_exceeded" - except UnknownChecker: - code = "implementation_unavailable" - except ValueError: - code = "invalid_output" - return make_post_submit_result( - **identity, - outcome="infrastructure_failed", - member_results=(), - infrastructure_failure_code=code, - ) - - class _SelectedExternalConsumer: """Run the selected POST policy through the existing ART callback lifetime.""" @@ -212,14 +149,13 @@ def __init__( execute_authority: Callable[[AsyncSession], ExecutionAuthorityPort], finalize_authority: Callable[[AsyncSession], FinalizationAuthorityPort], materialization: PostSubmissionMaterializationPort, - registry: CheckerRegistry, selected_execution: ExternalCheckerExecutionAdapter | None = None, outbox: Callable[[AsyncSession], OutboxAppendPort], ): """Receive explicit session, authority, materialization and publication ports.""" self._sessions = sessions self._execute_authority, self._finalize_authority = execute_authority, finalize_authority - self._materialization, self._registry, self._outbox = materialization, registry, outbox + self._materialization, self._outbox = materialization, outbox self._selected_execution = selected_execution @staticmethod @@ -231,11 +167,9 @@ def _execution_budget_seconds(request: PostSubmissionExecutionRequest) -> int: def _consumer(self, request, lease): if isinstance(request, SelectedPostSubmissionEvaluationRequest): if self._selected_execution is None: - raise CheckerExecutionUnavailable( - "checker_external_execution_unavailable" - ) + raise CheckerExecutionUnavailable("checker_external_execution_unavailable") return _SelectedExternalConsumer(self._selected_execution, lease) - return _StructuralConsumer(self._registry, lease) + raise CheckerExecutionUnavailable("checker_legacy_execution_retired") async def _claim(self, request): """Authorize replay or acquire the next database-timed lease atomically.""" @@ -266,13 +200,17 @@ async def _claim(self, request): ), output_binding_ids=(), ) + if not isinstance(request, SelectedPostSubmissionEvaluationRequest): + raise CheckerExecutionUnavailable("checker_legacy_execution_retired") now = await repo.now() if run.status == "running" and run.worker_lease_expires_at > now: raise CheckerExecutionUnavailable("checker_execution_lease_unavailable") execution_seconds = self._execution_budget_seconds(request) - lease_seconds = execution_seconds + math.ceil( - SELECTED_POST_FINALIZATION_MARGIN_MS / 1000 - ) if isinstance(request, SelectedPostSubmissionEvaluationRequest) else LEASE_SECONDS + lease_seconds = ( + execution_seconds + math.ceil(SELECTED_POST_FINALIZATION_MARGIN_MS / 1000) + if isinstance(request, SelectedPostSubmissionEvaluationRequest) + else LEASE_SECONDS + ) lease = ExecutionLease( reservation=reservation(run), lease_id=new_record_id(), @@ -298,6 +236,8 @@ async def evaluate_post_submission( lease, replay = await self._claim(request) if replay is not None: return await self.finalize(replay) + if not isinstance(request, SelectedPostSubmissionEvaluationRequest): + raise CheckerExecutionUnavailable("checker_legacy_execution_retired") material = None input_materialization_evidence_id = None try: @@ -329,16 +269,9 @@ async def evaluate_post_submission( else "material_unavailable" ), ) - result = ( - make_selected_post_submit_result( - **values, - execution=None, - ) - if isinstance(request, SelectedPostSubmissionEvaluationRequest) - else make_post_submit_result( - **values, - member_results=(), - ) + result = make_selected_post_submit_result( + **values, + execution=None, ) return await self.finalize( FinalizeFacts( @@ -390,7 +323,8 @@ async def finalize(self, facts: FinalizeFacts) -> PostSubmissionExecutionResult: if run.execute_evidence_id is None: raise CheckerExecutionUnavailable("checker_execution_evidence_unavailable") authority_facts = FinalizeAuthorityFacts( - **facts.model_dump(), execute_evidence_id=UUID(run.execute_evidence_id), + **facts.model_dump(), + execute_evidence_id=UUID(run.execute_evidence_id), ) if run.status in {"completed", "infrastructure_failed"}: if ( @@ -409,7 +343,9 @@ async def finalize(self, facts: FinalizeFacts) -> PostSubmissionExecutionResult: await prepared.validate_replay(authority_facts, UUID(run.finalize_evidence_id)) return stored_result(run) run = await repo.require_lease(request, facts.lease) - evidence_id = _evidence(await prepared.consume(authority_facts), FinalizeEvidence, authority_facts) + evidence_id = _evidence( + await prepared.consume(authority_facts), FinalizeEvidence, authority_facts + ) completed_at = await repo.now() await repo.write_members(run, result) if result.outcome == "completed": diff --git a/backend/app/modules/checkers/external_registry.py b/backend/app/modules/checkers/external_registry.py index f5f335dcf..8f5f7fca1 100644 --- a/backend/app/modules/checkers/external_registry.py +++ b/backend/app/modules/checkers/external_registry.py @@ -90,9 +90,7 @@ async def lock_registration_scopes( {"scope": value}, ) - async def by_operation( - self, operation_id: UUID - ) -> ExternalCheckerRegistryEntryRecord | None: + async def by_operation(self, operation_id: UUID) -> ExternalCheckerRegistryEntryRecord | None: """Read the row reserved by one idempotent registration operation.""" return await self._session.scalar( select(ExternalCheckerRegistryEntryRecord).where( @@ -122,6 +120,18 @@ async def by_exact_id( populate_existing=True, ) + async def all_entries(self) -> tuple[ExternalCheckerRegistryEntryRecord, ...]: + """Read the complete immutable inventory in one deterministic order.""" + return tuple( + await self._session.scalars( + select(ExternalCheckerRegistryEntryRecord).order_by( + ExternalCheckerRegistryEntryRecord.phase, + ExternalCheckerRegistryEntryRecord.capability_id, + ExternalCheckerRegistryEntryRecord.capability_version, + ) + ) + ) + async def add(self, row: ExternalCheckerRegistryEntryRecord) -> None: """Flush and refresh one row without committing the caller transaction.""" self._session.add(row) @@ -143,23 +153,17 @@ def _require_root_transaction(self) -> None: or not transaction.is_active or self._session.in_nested_transaction() ): - raise ExternalCheckerRegistryUnavailable( - "external_checker_registry_unavailable" - ) + raise ExternalCheckerRegistryUnavailable("external_checker_registry_unavailable") async def read_exact( self, registry_entry_id: UUID, entry_digest: str ) -> ExternalCheckerRegistryEntry: self._require_root_transaction() if type(registry_entry_id) is not UUID or type(entry_digest) is not str: - raise ExternalCheckerRegistryUnavailable( - "external_checker_registry_unavailable" - ) + raise ExternalCheckerRegistryUnavailable("external_checker_registry_unavailable") row = await self._repository.by_exact_id(registry_entry_id) if row is None or row.entry_digest != entry_digest: - raise ExternalCheckerRegistryUnavailable( - "external_checker_registry_unavailable" - ) + raise ExternalCheckerRegistryUnavailable("external_checker_registry_unavailable") return _row_entry(row) async def read_identity( @@ -171,20 +175,21 @@ async def read_identity( or type(capability_version) is not str or phase not in {"pre_submit", "post_submit"} ): - raise ExternalCheckerRegistryUnavailable( - "external_checker_registry_unavailable" - ) + raise ExternalCheckerRegistryUnavailable("external_checker_registry_unavailable") row = await self._repository.by_identity( capability_id=capability_id, capability_version=capability_version, phase=phase, ) if row is None: - raise ExternalCheckerRegistryUnavailable( - "external_checker_registry_unavailable" - ) + raise ExternalCheckerRegistryUnavailable("external_checker_registry_unavailable") return _row_entry(row) + async def list_entries(self) -> tuple[ExternalCheckerRegistryEntry, ...]: + """Expose every immutable capability to a new compilation attempt.""" + self._require_root_transaction() + return tuple(_row_entry(row) for row in await self._repository.all_entries()) + class ExternalCheckerRegistryService: """Publish immutable registry metadata without granting execution authority.""" @@ -207,9 +212,7 @@ def _require_root_transaction(self) -> None: or not transaction.is_active or self._session.in_nested_transaction() ): - raise ExternalCheckerRegistryUnavailable( - "external_checker_registry_unavailable" - ) + raise ExternalCheckerRegistryUnavailable("external_checker_registry_unavailable") async def register( self, request: ExternalCheckerRegistrationRequest @@ -233,9 +236,7 @@ async def register( "external_checker_registry_unavailable" ) from exc if authority.actor_profile_id != request.actor_profile_id: - raise ExternalCheckerRegistryUnavailable( - "external_checker_registry_unavailable" - ) + raise ExternalCheckerRegistryUnavailable("external_checker_registry_unavailable") await self._repository.lock_registration_scopes( request.operation_id, capability_id=request.spec.capability_id, @@ -245,15 +246,16 @@ async def register( replay = await self._repository.by_operation(request.operation_id) if replay is not None: if not self._matches_request(replay, request): - raise ExternalCheckerRegistryConflict( - "external_checker_registry_conflict" - ) + raise ExternalCheckerRegistryConflict("external_checker_registry_conflict") return _row_entry(replay) - if await self._repository.by_identity( - capability_id=request.spec.capability_id, - capability_version=request.spec.capability_version, - phase=request.spec.phase, - ) is not None: + if ( + await self._repository.by_identity( + capability_id=request.spec.capability_id, + capability_version=request.spec.capability_version, + phase=request.spec.phase, + ) + is not None + ): raise ExternalCheckerRegistryConflict("external_checker_registry_conflict") spec = request.spec values = { @@ -270,9 +272,7 @@ async def register( **spec.resources.model_dump(), "entry_digest": spec.spec_digest, "registered_by_actor_profile_id": str(request.actor_profile_id), - "authorization_decision_event_id": str( - authority.authorization_decision_event_id - ), + "authorization_decision_event_id": str(authority.authorization_decision_event_id), } row = ExternalCheckerRegistryEntryRecord(**values) await self._repository.add(row) @@ -296,6 +296,10 @@ async def read_identity( phase=phase, ) + async def list_entries(self) -> tuple[ExternalCheckerRegistryEntry, ...]: + """Expose the complete immutable capability inventory.""" + return await ExternalCheckerRegistryReader(self._session).list_entries() + @staticmethod def _matches_request( row: ExternalCheckerRegistryEntryRecord, diff --git a/backend/app/modules/projects/api/guide_proposals.py b/backend/app/modules/projects/api/guide_proposals.py index ee359426b..8b9c5d115 100644 --- a/backend/app/modules/projects/api/guide_proposals.py +++ b/backend/app/modules/projects/api/guide_proposals.py @@ -201,31 +201,39 @@ def __init__( super().__init__(code) - - # Composition binds external capabilities; the public PROJECTS contract imports no other owner. _ActorT = TypeVar("_ActorT", contravariant=True) _MaterialT = TypeVar("_MaterialT", contravariant=True) -_PreCapabilitiesT = TypeVar("_PreCapabilitiesT", contravariant=True) -_PostCapabilitiesT = TypeVar("_PostCapabilitiesT", contravariant=True) -_PlannerT = TypeVar("_PlannerT", contravariant=True) +_CapabilitiesT = TypeVar("_CapabilitiesT", contravariant=True) -class GuideProposalOperationsPort(Protocol[_ActorT, _MaterialT, _PreCapabilitiesT, _PostCapabilitiesT, _PlannerT]): +class GuideProposalOperationsPort(Protocol[_ActorT, _MaterialT, _CapabilitiesT]): """Caller-owned transaction for exact finalized proposal operations.""" async def review_package( - self, selection: GuideProposalSelection, *, actor: _ActorT, request_id: UUID, + self, + selection: GuideProposalSelection, + *, + actor: _ActorT, + request_id: UUID, ) -> "GuideProposalReviewPackage": ... async def approve( - self, command: GuideProposalApproval, *, actor: _ActorT, request_id: UUID, - material: _MaterialT, pre_capabilities: _PreCapabilitiesT, - post_capabilities: _PostCapabilitiesT, planner: _PlannerT, + self, + command: GuideProposalApproval, + *, + actor: _ActorT, + request_id: UUID, + material: _MaterialT, + capabilities: _CapabilitiesT, ) -> GuideProposalApprovalReceipt: ... async def request_correction( - self, command: GuideProposalCorrection, *, actor: _ActorT, request_id: UUID, + self, + command: GuideProposalCorrection, + *, + actor: _ActorT, + request_id: UUID, ) -> GuideProposalCorrectionReceipt: ... @@ -233,6 +241,9 @@ class GuideCorrectionDispatchPort(Protocol[_ActorT]): """Own human correction admission and publication after commit.""" async def dispatch( - self, selection: GuideProposalSelection, correction_operation_id: UUID, *, + self, + selection: GuideProposalSelection, + correction_operation_id: UUID, + *, actor: _ActorT, ) -> GuideProposalDispatchResponse: ... diff --git a/backend/app/modules/projects/guide_activation/service.py b/backend/app/modules/projects/guide_activation/service.py index 87c26251b..f631aba4d 100644 --- a/backend/app/modules/projects/guide_activation/service.py +++ b/backend/app/modules/projects/guide_activation/service.py @@ -6,7 +6,6 @@ from app.core.identifiers import new_record_id from app.modules.authorization.api import ActorKind -from app.modules.checkers.api.pre_submit import EffectivePreSubmissionPlanLineage from app.modules.checkers.api.external_policy import LockedExternalCheckerPolicies from app.modules.checkers.api.external import ExternalCheckerRegistryPort from app.modules.projects.api.guide_activation import ( @@ -19,7 +18,6 @@ ) from app.modules.projects.api.guide_proposals import GuideProposalError from app.modules.projects.api.post_policy import PostPolicySelection -from app.modules.projects.guide_compilation.proposal_approval import require_catalogues from app.modules.projects.guide_compilation.proposal_service import GuideProposalService from app.modules.projects.guide_mutation_repository import GuideMutationRepository from app.modules.projects.post_policy.repository import PostPolicyRepository @@ -41,17 +39,16 @@ class GuideActivationService: """AUTH-12H supplies live manager authority; composition without it denies.""" def __init__( - self, session, *, contribution, planner, pre_catalogue, post_catalogue, - authorization=None, registry: ExternalCheckerRegistryPort | None = None, + self, + session, + *, + contribution, + authorization=None, + registry: ExternalCheckerRegistryPort | None = None, ): self.session = session self.authorization = authorization self.contribution = contribution - self.planner, self.pre_catalogue, self.post_catalogue = ( - planner, - pre_catalogue, - post_catalogue, - ) self.projects = ProjectRepository(session) self.replay = GuideMutationRepository(session) self.post = PostPolicyRepository(session) @@ -154,9 +151,7 @@ async def activate( GuideActivationBlocked, persisted_items=source_items, ) - await self._readiness( - command, locked, policy, post_custody, review, revision - ) + await self._readiness(command, locked, policy, post_custody, review, revision) except ProjectServiceError: raise GuideProposalError("approval_blocked") from None try: @@ -225,31 +220,27 @@ async def activate( return receipt async def _readiness(self, command, locked, policy, post, review, revision): - target, approval = command.target.proposal, locked.view.approval_custody + approval = locked.view.approval_custody external = ( approval.operation.effective_pre_submit_plan.get("schema_version") == "external_checker_policies.v1" ) - if external: - if self.registry is None: - raise GuideProposalError("approval_blocked") - policies = LockedExternalCheckerPolicies.model_validate( - approval.operation.effective_pre_submit_plan + if not external or self.registry is None: + raise GuideProposalError("approval_blocked") + policies = LockedExternalCheckerPolicies.model_validate( + approval.operation.effective_pre_submit_plan + ) + if policies.pre_submit.model_dump(mode="json") != approval.pre.compiled_bundle: + raise GuideProposalError("approval_blocked") + for binding in (*policies.pre_submit.entries, *policies.post_submit.entries): + current = await self.registry.read_exact( + binding.registry.registry_entry_id, + binding.registry.entry_digest, ) - if policies.pre_submit.model_dump(mode="json") != approval.pre.compiled_bundle: - raise GuideProposalError("approval_blocked") - for binding in (*policies.pre_submit.entries, *policies.post_submit.entries): - current = await self.registry.read_exact( - binding.registry.registry_entry_id, - binding.registry.entry_digest, - ) - if current != binding.registry: - raise GuideProposalError("approval_blocked") - if locked.result.capability_suggestions: + if current != binding.registry: raise GuideProposalError("approval_blocked") - else: - require_catalogues(target, self.pre_catalogue, self.post_catalogue) - post.compiled.validate_catalogue(self.post_catalogue) + if locked.result.capability_suggestions: + raise GuideProposalError("approval_blocked") ProjectService(self.session).validate_activation_ready( locked.view.guide, locked.view.snapshot, @@ -263,26 +254,3 @@ async def _readiness(self, command, locked, policy, post, review, revision): approval_custody=approval, post_policy_custody=post, ) - if external: - return - upstream = command.target.upstream - plan = self.planner.compile_effective_plan( - lineage=EffectivePreSubmissionPlanLineage( - project_id=target.project_id, - guide_id=target.guide_id, - guide_version=target.guide_version, - source_snapshot_id=target.source_snapshot_id, - source_snapshot_hash=target.source_snapshot_hash, - effective_policy_id=upstream.effective_policy_id, - effective_policy_hash=upstream.effective_policy_hash, - pre_submit_policy_id=upstream.pre_submit_policy_id, - pre_submit_policy_bundle_hash=upstream.pre_submit_bundle_hash, - ), - effective_policy=approval.effective.effective_policy, - compiled_bundle=approval.pre.compiled_bundle, - ) - if ( - plan.plan_sha256 != upstream.effective_pre_submit_plan_hash - or plan.catalogue_manifest_sha256 != target.pre_catalogue_manifest_hash - ): - raise GuideProposalError("approval_blocked") diff --git a/backend/app/modules/projects/guide_compilation/context.py b/backend/app/modules/projects/guide_compilation/context.py index 07ad01471..9ba81cf09 100644 --- a/backend/app/modules/projects/guide_compilation/context.py +++ b/backend/app/modules/projects/guide_compilation/context.py @@ -17,12 +17,7 @@ ProjectGuideCompilationContext, canonical_project_guide_compilation_context_bytes, ) -from app.modules.checkers.api.pre_submit_catalogue import ( - PreSubmissionCapabilityProjection, -) -from app.modules.checkers.api.post_submit_catalogue import ( - PostSubmitCatalogue, -) +from app.modules.checkers.api.external import ExternalCheckerCapabilityProjection from app.modules.projects.models import GuideSourceSnapshot, ProjectGuide from app.modules.projects.api.task_examples import require_task_example_commitment @@ -36,8 +31,7 @@ async def build_project_guide_compilation_context( *, state: CompilationExecutionState, material: GuideDocumentManifestPort, - pre_submission_capabilities: PreSubmissionCapabilityProjection, - post_submission_capabilities: PostSubmitCatalogue, + checker_capabilities: ExternalCheckerCapabilityProjection, ) -> ProjectGuideCompilationContext: """Return an immutable context only when every current fact matches custody.""" if session.in_transaction(): @@ -82,8 +76,7 @@ async def build_project_guide_compilation_context( loaded=loaded, setup_run_id=identity.setup_run_id, setup_generation=identity.setup_generation, - pre_submission_capabilities=pre_submission_capabilities, - post_submission_capabilities=post_submission_capabilities, + checker_capabilities=checker_capabilities, runtime_configuration=state.runtime_configuration, correction_feedback=await _correction_feedback(session, identity.setup_run_id), ) @@ -99,8 +92,7 @@ def compilation_context_from_material( loaded, setup_run_id, setup_generation, - pre_submission_capabilities: PreSubmissionCapabilityProjection, - post_submission_capabilities: PostSubmitCatalogue, + checker_capabilities: ExternalCheckerCapabilityProjection, runtime_configuration: ProjectGuideRuntimeConfiguration, correction_feedback=None, ) -> ProjectGuideCompilationContext: @@ -133,8 +125,7 @@ def compilation_context_from_material( agent_identity=PROJECT_GUIDE_COMPILATION_AGENT_IDENTITY, agent_version=PROJECT_GUIDE_COMPILATION_AGENT_VERSION, runtime_configuration=runtime_configuration, - pre_submission_capabilities=pre_submission_capabilities, - post_submission_capabilities=post_submission_capabilities, + checker_capabilities=checker_capabilities, ) if ( len(canonical_project_guide_compilation_context_bytes(context)) diff --git a/backend/app/modules/projects/guide_compilation/contracts.py b/backend/app/modules/projects/guide_compilation/contracts.py index 08c917145..ed31e6dec 100644 --- a/backend/app/modules/projects/guide_compilation/contracts.py +++ b/backend/app/modules/projects/guide_compilation/contracts.py @@ -111,14 +111,14 @@ def from_context(cls, context: ProjectGuideCompilationContext) -> CompilationAtt json.loads(canonical_project_guide_compilation_context_bytes(context)) ), guide_material_hash=material.sha256, - pre_catalogue_id=context.pre_submission_capabilities.catalogue_id, - pre_catalogue_version=context.pre_submission_capabilities.version, - pre_catalogue_schema_version=context.pre_submission_capabilities.schema_version, - pre_catalogue_manifest_hash=context.pre_submission_capabilities.manifest_sha256, - post_catalogue_id=context.post_submission_capabilities.catalogue_id, - post_catalogue_version=context.post_submission_capabilities.source_version, - post_catalogue_schema_version=context.post_submission_capabilities.schema_version, - post_catalogue_manifest_hash=context.post_submission_capabilities.manifest_sha256, + pre_catalogue_id="workstream.external_checker_capabilities", + pre_catalogue_version="v1", + pre_catalogue_schema_version=context.checker_capabilities.schema_version, + pre_catalogue_manifest_hash=context.checker_capabilities.manifest_sha256, + post_catalogue_id="workstream.external_checker_capabilities", + post_catalogue_version="v1", + post_catalogue_schema_version=context.checker_capabilities.schema_version, + post_catalogue_manifest_hash=context.checker_capabilities.manifest_sha256, agent_identity=context.agent_identity, agent_version=context.agent_version, instruction_version=context.instruction_version, diff --git a/backend/app/modules/projects/guide_compilation/live.py b/backend/app/modules/projects/guide_compilation/live.py index eb15387be..e66df72db 100644 --- a/backend/app/modules/projects/guide_compilation/live.py +++ b/backend/app/modules/projects/guide_compilation/live.py @@ -17,8 +17,7 @@ ActorIdentityFacts, ProjectGuideCompilationAuthorizationPort, ) -from app.modules.checkers.api.pre_submit_catalogue import PreSubmissionCapabilityProjection -from app.modules.checkers.api.post_submit_catalogue import PostSubmitCatalogue +from app.modules.checkers.api.external import ExternalCheckerCapabilityProjection from app.modules.projects.api.guide_compilation import ( ProjectGuideCompilationDelivery, ProjectGuideCompilationDeliveryError, @@ -59,8 +58,7 @@ def __init__( session_factory: async_sessionmaker[AsyncSession], *, material_factory: Callable[[AsyncSession], GuideDocumentManifestPort], - pre_capabilities: PreSubmissionCapabilityProjection, - post_capabilities: PostSubmitCatalogue, + checker_capabilities: ExternalCheckerCapabilityProjection, request_authority: RequestAuthority, configuration_factory: Callable[[], ProjectGuideRuntimeConfiguration], execution: ProjectGuideCompilationExecutionPort, @@ -69,8 +67,7 @@ def __init__( ) -> None: self._sessions = session_factory self._material = material_factory - self._pre = pre_capabilities - self._post = post_capabilities + self._checker_capabilities = checker_capabilities self._request_authority = request_authority self._configuration = configuration_factory self._execution = execution @@ -107,8 +104,7 @@ async def run(self, delivery: ProjectGuideCompilationDelivery) -> dict: authority, request_inputs=CompilationRequestInputs( self._material(session), - self._pre, - self._post, + self._checker_capabilities, configuration, ), ).request_automatic(actor=actor, setup_run_id=delivery.setup_run_id) @@ -236,7 +232,12 @@ async def _admit(self, delivery: ProjectGuideCompilationDelivery): from .delivery_request import manual_delivery_attempt manual_attempt = await manual_delivery_attempt(session, setup, attempt) - return None, attempt is not None, attempt.runtime_configuration if attempt else None, manual_attempt + return ( + None, + attempt is not None, + attempt.runtime_configuration if attempt else None, + manual_attempt, + ) async def _finalize(self, command: ProjectGuideSetupFinalizationCommand) -> dict: """Create or replay the existing finalizer's receipt under fresh authority.""" diff --git a/backend/app/modules/projects/guide_compilation/orchestrator.py b/backend/app/modules/projects/guide_compilation/orchestrator.py index 180890c39..b025f7392 100644 --- a/backend/app/modules/projects/guide_compilation/orchestrator.py +++ b/backend/app/modules/projects/guide_compilation/orchestrator.py @@ -11,7 +11,10 @@ from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker -from app.modules.projects.api.guide_documents import GuideDocumentManifestPort, GuideDocumentUnavailable +from app.modules.projects.api.guide_documents import ( + GuideDocumentManifestPort, + GuideDocumentUnavailable, +) from app.interfaces.project_agents import ( ProjectGuideAgentRuntime, ProjectGuideCompilationContext, @@ -20,12 +23,7 @@ require_complete_project_guide_compilation_result, validate_project_guide_compilation_result, ) -from app.modules.checkers.api.pre_submit_catalogue import ( - PreSubmissionCapabilityProjection, -) -from app.modules.checkers.api.post_submit_catalogue import ( - PostSubmitCatalogue, -) +from app.modules.checkers.api.external import ExternalCheckerCapabilityProjection from app.modules.authorization.api import ( ActorIdentityFacts, AuthorizationDenied, @@ -56,7 +54,10 @@ load_compilation_execution_state, ) from app.interfaces.project_guide_runtime import ProjectGuideRuntimeConfiguration -from app.modules.projects.api.guide_documents import GuideDocumentAccessFactory, GuideRuntimeCapabilities +from app.modules.projects.api.guide_documents import ( + GuideDocumentAccessFactory, + GuideRuntimeCapabilities, +) from .runtime_resources import SqlAlchemyGuideRuntimeCustody from app.interfaces.external_services import ExternalServiceAdapterError from app.interfaces.project_agents import ( @@ -89,16 +90,14 @@ def __init__( session_factory: async_sessionmaker[AsyncSession], *, material_factory: Callable[[AsyncSession], GuideDocumentManifestPort], - pre_submission_capabilities: PreSubmissionCapabilityProjection, - post_submission_capabilities: PostSubmitCatalogue, + checker_capabilities: ExternalCheckerCapabilityProjection, authorization_context: GuideCompilationAuthorizationContext, document_access_factory: GuideDocumentAccessFactory, ) -> None: """Store the owner-supplied ports used by each short transaction.""" self._session_factory = session_factory self._material_factory = material_factory - self._pre_submission_capabilities = pre_submission_capabilities - self._post_submission_capabilities = post_submission_capabilities + self._checker_capabilities = checker_capabilities self._authorization_context = authorization_context self._document_access_factory = document_access_factory @@ -106,12 +105,16 @@ def __init__( async def capabilities(self, state, context): """Issue resources only from the orchestrator's winning dispatch branch.""" async with self._document_access_factory( - state.preflight_facts.attempt_id, context.material, context.runtime_configuration, + state.preflight_facts.attempt_id, + context.material, + context.runtime_configuration, ) as documents: yield GuideRuntimeCapabilities( documents=documents, resources=SqlAlchemyGuideRuntimeCustody( - self._session_factory, state.preflight_facts.attempt_id, context.material, + self._session_factory, + state.preflight_facts.attempt_id, + context.material, context.runtime_configuration.runtime_key, ), ) @@ -134,8 +137,7 @@ async def context(self, state: CompilationExecutionState) -> ProjectGuideCompila session, state=state, material=self._material_factory(session), - pre_submission_capabilities=self._pre_submission_capabilities, - post_submission_capabilities=self._post_submission_capabilities, + checker_capabilities=self._checker_capabilities, ) except GuideDocumentUnavailable: raise ProjectGuideCompilationExecutionError("context_unavailable") from None @@ -216,8 +218,7 @@ def project_guide_compilation_execution_port( session_factory: async_sessionmaker[AsyncSession], *, material_factory: Callable[[AsyncSession], GuideDocumentManifestPort], - pre_submission_capabilities: PreSubmissionCapabilityProjection, - post_submission_capabilities: PostSubmitCatalogue, + checker_capabilities: ExternalCheckerCapabilityProjection, authorization_context: GuideCompilationAuthorizationContext, runtime_factory: Callable[[ProjectGuideRuntimeConfiguration], ProjectGuideAgentRuntime], document_access_factory: GuideDocumentAccessFactory, @@ -226,8 +227,7 @@ def project_guide_compilation_execution_port( backend = SqlAlchemyGuideCompilationExecutionBackend( session_factory, material_factory=material_factory, - pre_submission_capabilities=pre_submission_capabilities, - post_submission_capabilities=post_submission_capabilities, + checker_capabilities=checker_capabilities, authorization_context=authorization_context, document_access_factory=document_access_factory, ) @@ -237,8 +237,9 @@ def project_guide_compilation_execution_port( class GuideCompilationExecutionBackend(Protocol): """Exact persistence/context operations required by the state machine.""" - def capabilities(self, state: CompilationExecutionState, - context: ProjectGuideCompilationContext) -> AbstractAsyncContextManager[GuideRuntimeCapabilities]: ... + def capabilities( + self, state: CompilationExecutionState, context: ProjectGuideCompilationContext + ) -> AbstractAsyncContextManager[GuideRuntimeCapabilities]: ... async def load(self, attempt_id: UUID) -> CompilationExecutionState: ... @@ -314,12 +315,16 @@ async def execute( try: result = await runtime.compile_project_guide(context, capabilities) except ProjectGuideCompilationInvalidOutputError as exc: - terminal_receipt = await self._backend.record_invalid(state, exc.failure_code) + terminal_receipt = await self._backend.record_invalid( + state, exc.failure_code + ) else: try: _require_valid_result(context, result) except (TypeError, ValueError): - terminal_receipt = await self._backend.record_invalid(state, "schema_invalid") + terminal_receipt = await self._backend.record_invalid( + state, "schema_invalid" + ) else: await self._backend.record_accepted(state, context, result) accepted = True diff --git a/backend/app/modules/projects/guide_compilation/proposal_approval.py b/backend/app/modules/projects/guide_compilation/proposal_approval.py index 31e468af8..e84db5181 100644 --- a/backend/app/modules/projects/guide_compilation/proposal_approval.py +++ b/backend/app/modules/projects/guide_compilation/proposal_approval.py @@ -15,10 +15,9 @@ GuideProposalAuthorizationLocator, PreparedGuideProposalOperation, ) -from app.modules.checkers.api.policy_compilation import ( - CompiledPreSubmitCheckerPolicy, PreSubmissionPolicyCompilationPort, -) +from app.modules.checkers.api.policy_compilation import CompiledPreSubmitCheckerPolicy from app.modules.checkers.api.external import ExternalCheckerRegistryPort +from app.modules.checkers.api.external import ExternalCheckerCapabilityProjection from app.modules.checkers.api.external_policy import ( LockedExternalCheckerPolicies, compile_external_checker_policy_bundle, @@ -63,16 +62,12 @@ async def approve_proposal( actor, request_id, material, - pre_capabilities, - post_capabilities, - planner: PreSubmissionPolicyCompilationPort, + capabilities: ExternalCheckerCapabilityProjection, registry: ExternalCheckerRegistryPort, ) -> GuideProposalApprovalReceipt: """Compile and persist in the caller transaction after exact authority closes.""" target = command.target - selector_id = approval_authorization_selector( - actor.actor_profile_id, command.idempotency_key - ) + selector_id = approval_authorization_selector(actor.actor_profile_id, command.idempotency_key) locator = GuideProposalAuthorizationLocator( project_id=target.project_id, guide_id=target.guide_id, @@ -105,8 +100,7 @@ async def approve_proposal( locked, package, command, - pre_capabilities, - post_capabilities, + capabilities, ) outputs = await _compile_approval( session, @@ -114,9 +108,7 @@ async def approve_proposal( command, new_record_id(), material, - pre_capabilities, - post_capabilities, - planner, + capabilities, registry, ) receipt = outputs.receipt @@ -175,13 +167,12 @@ async def _validate_new_approval( locked, package, command, - pre_capabilities, - post_capabilities, + capabilities, ): """Validate current proposal and predecessor facts before compiling outputs.""" if not locked.current: raise GuideProposalError("proposal_stale") - require_catalogues(command.target, pre_capabilities, post_capabilities) + require_capabilities(command.target, capabilities) if ( locked.result.status == "guide_blocked" or locked.view.policy is None @@ -190,15 +181,12 @@ async def _validate_new_approval( raise GuideProposalError("approval_blocked") if ( locked.view.policy.lifecycle_status != "draft" - or package.current_approval_operation_id - != command.expected_previous_approval_operation_id + or package.current_approval_operation_id != command.expected_previous_approval_operation_id or package.current_approval_output_digest != command.expected_previous_approval_output_digest ): raise GuideProposalError("proposal_stale") - return await _previous_outputs( - session, command.expected_previous_approval_operation_id - ) + return await _previous_outputs(session, command.expected_previous_approval_operation_id) @dataclass(frozen=True) @@ -217,16 +205,13 @@ async def _compile_approval( command, operation_id, material, - pre_capabilities, - post_capabilities, - planner, + capabilities, registry, ) -> _CompiledApproval: target = command.target inputs = CompilationRequestInputs( material, - pre_capabilities, - post_capabilities, + capabilities, ProjectGuideRuntimeConfiguration.model_validate(locked.view.attempt.runtime_configuration), ) context = await inputs.context_for_setup(session, locked.view.setup) @@ -246,8 +231,7 @@ async def _compile_approval( *(entry.registry.capability_id for entry in external_pre.entries), ], checker_configs={ - entry.requirement_id: entry.configuration - for entry in external_pre.entries + entry.requirement_id: entry.configuration for entry in external_pre.entries }, ) effective_id, pre_id = new_record_id(), new_record_id() @@ -262,9 +246,7 @@ async def _compile_approval( effective_pre_submit_plan_hash=policies.policies_sha256, acknowledged_warning_hashes=command.acknowledged_warning_hashes, ) - return _CompiledApproval( - effective_body, compiled, policies, receipt - ) + return _CompiledApproval(effective_body, compiled, policies, receipt) async def _persist_approval( @@ -343,23 +325,29 @@ def _facts(locator, target, request_digest, receipt, command): ) -def require_catalogues(target, pre, post): +def require_capabilities(target, capabilities): + """Bind approval to the exact registry-backed compiler input snapshot.""" + capabilities = ExternalCheckerCapabilityProjection.model_validate(capabilities) if ( - not pre.available - or (pre.catalogue_id, pre.version, pre.schema_version, pre.manifest_sha256) - != ( - target.pre_catalogue_id, - target.pre_catalogue_version, - target.pre_catalogue_schema_version, - target.pre_catalogue_manifest_hash, - ) - or (post.catalogue_id, post.source_version, post.schema_version, post.manifest_sha256) - != ( - target.post_catalogue_id, - target.post_catalogue_version, - target.post_catalogue_schema_version, - target.post_catalogue_manifest_hash, - ) + "workstream.external_checker_capabilities", + "v1", + capabilities.schema_version, + capabilities.manifest_sha256, + ) != ( + target.pre_catalogue_id, + target.pre_catalogue_version, + target.pre_catalogue_schema_version, + target.pre_catalogue_manifest_hash, + ) or ( + "workstream.external_checker_capabilities", + "v1", + capabilities.schema_version, + capabilities.manifest_sha256, + ) != ( + target.post_catalogue_id, + target.post_catalogue_version, + target.post_catalogue_schema_version, + target.post_catalogue_manifest_hash, ): raise GuideProposalError("proposal_stale") diff --git a/backend/app/modules/projects/guide_compilation/proposal_service.py b/backend/app/modules/projects/guide_compilation/proposal_service.py index 6da362815..00374e2a3 100644 --- a/backend/app/modules/projects/guide_compilation/proposal_service.py +++ b/backend/app/modules/projects/guide_compilation/proposal_service.py @@ -30,9 +30,7 @@ GuideProposalCorrectionReceipt, ) from app.modules.projects.api.guide_documents import GuideDocumentManifestPort -from app.modules.checkers.api.pre_submit_catalogue import PreSubmissionCapabilityProjection -from app.modules.checkers.api.post_submit_catalogue import PostSubmitCatalogue -from app.modules.checkers.api.policy_compilation import PreSubmissionPolicyCompilationPort +from app.modules.checkers.api.external import ExternalCheckerCapabilityProjection from app.modules.checkers.api.external import ExternalCheckerRegistryPort from app.modules.projects.api.guide_proposal_package import GuideProposalReviewPackage @@ -104,9 +102,7 @@ async def approve( actor: ActorIdentityFacts, request_id: UUID, material: GuideDocumentManifestPort, - pre_capabilities: PreSubmissionCapabilityProjection, - post_capabilities: PostSubmitCatalogue, - planner: PreSubmissionPolicyCompilationPort, + capabilities: ExternalCheckerCapabilityProjection, ) -> GuideProposalApprovalReceipt: """Approve through the sole approval owner, without committing or invoking a model.""" from .proposal_approval import approve_proposal @@ -122,9 +118,7 @@ async def approve( actor=actor, request_id=request_id, material=material, - pre_capabilities=pre_capabilities, - post_capabilities=post_capabilities, - planner=planner, + capabilities=capabilities, registry=self.registry, ) diff --git a/backend/app/modules/projects/guide_compilation/request_inputs.py b/backend/app/modules/projects/guide_compilation/request_inputs.py index d9be2c9bb..2e25335b6 100644 --- a/backend/app/modules/projects/guide_compilation/request_inputs.py +++ b/backend/app/modules/projects/guide_compilation/request_inputs.py @@ -11,12 +11,7 @@ GuideDocumentManifestPort, GuideDocumentManifestRequest, ) -from app.modules.checkers.api.pre_submit_catalogue import ( - PreSubmissionCapabilityProjection, -) -from app.modules.checkers.api.post_submit_catalogue import ( - PostSubmitCatalogue, -) +from app.modules.checkers.api.external import ExternalCheckerCapabilityProjection from app.modules.authorization.api import ( ProjectGuideCompilationRequestFacts, ProjectGuideCompilationRequestOrigin, @@ -42,8 +37,7 @@ class CompilationRequestInputs: """Composition supplies material access and canonical CHECKERS projections, never a runtime.""" material: GuideDocumentManifestPort - pre_submission_capabilities: PreSubmissionCapabilityProjection - post_submission_capabilities: PostSubmitCatalogue + checker_capabilities: ExternalCheckerCapabilityProjection runtime_configuration: ProjectGuideRuntimeConfiguration | None async def resolve( @@ -137,8 +131,7 @@ async def context_for_setup(self, session: AsyncSession, setup: ProjectSetupRun) loaded=loaded, setup_run_id=setup_run_id, setup_generation=setup.setup_generation, - pre_submission_capabilities=self.pre_submission_capabilities, - post_submission_capabilities=self.post_submission_capabilities, + checker_capabilities=self.checker_capabilities, runtime_configuration=self.runtime_configuration, correction_feedback=await load_correction_feedback(session, setup_run_id), ) diff --git a/backend/app/modules/projects/post_policy/compiler.py b/backend/app/modules/projects/post_policy/compiler.py index b906deecc..e6850c1c3 100644 --- a/backend/app/modules/projects/post_policy/compiler.py +++ b/backend/app/modules/projects/post_policy/compiler.py @@ -1,43 +1,41 @@ -"""Connect validated saved bindings to the sole canonical policy compiler.""" - -from uuid import UUID +"""Project one approved immutable external POST policy without a catalogue.""" from app.interfaces.project_agents import ( ProjectGuideCompilationResult, - validate_post_submission_bindings, + RequirementDisposition, ) -from app.modules.checkers.api.post_submit_catalogue import CompiledPostSubmitPolicy, PostSubmitCatalogue -from app.modules.projects.post_submit_policy import ( - build_project_post_submit_checker_spec, - compile_project_post_submit_checker_spec, +from app.modules.checkers.api.external_policy import ( + LockedExternalCheckerPolicies, + LockedExternalPostSubmitPolicy, ) def compile_saved_post_policy( - *, project_id: UUID, guide_version: str, - result: ProjectGuideCompilationResult, catalogue: PostSubmitCatalogue, -) -> CompiledPostSubmitPolicy: - """Preserve every supported requirement while executing each shared member once.""" - validate_post_submission_bindings(result, catalogue) + *, + result: ProjectGuideCompilationResult, + policies: LockedExternalCheckerPolicies, +) -> LockedExternalPostSubmitPolicy: + """Require the saved result and approved exact bindings to describe one policy.""" + result = ProjectGuideCompilationResult.model_validate(result) + policies = LockedExternalCheckerPolicies.model_validate(policies) if result.status == "guide_blocked" or result.submission_artifact_policy is None: raise ValueError("blocked guide cannot project post-submit policy") - selected = {binding.capability_id for binding in result.post_submit_bindings} - compiled = compile_project_post_submit_checker_spec( - project_id=str(project_id), guide_version=guide_version, - spec=build_project_post_submit_checker_spec( - project_id=str(project_id), guide_version=guide_version, - required_checkers=sorted(selected), - ), - ) - compiled.validate_catalogue(catalogue) - entries = {entry.checker_id: entry for entry in compiled.entries} - for binding in result.post_submit_bindings: - entry = entries.get(binding.capability_id) + requirements = { + item.requirement_id: item + for item in result.requirements + if item.disposition is RequirementDisposition.SUPPORTED_POST_SUBMIT + } + bindings = {item.requirement_id: item for item in result.post_submit_bindings} + entries = {item.requirement_id: item for item in policies.post_submit.entries} + if requirements.keys() != bindings.keys() or bindings.keys() != entries.keys(): + raise ValueError("approved post-submit policy omits a required binding") + for requirement_id, binding in bindings.items(): + entry = entries[requirement_id] if ( - entry is None or entry.classification != "project_required" - or entry.definition_version != binding.capability_version - or entry.configuration.model_dump(mode="json") - != {parameter.name: parameter.value for parameter in binding.parameters} + entry.registry.capability_id != binding.capability_id + or entry.registry.capability_version != binding.capability_version + or entry.stage != binding.stage.value + or entry.configuration != {item.name: item.value for item in binding.parameters} ): - raise ValueError("compiled post-submit policy omits or changes a required binding") - return compiled + raise ValueError("approved post-submit policy changes a required binding") + return policies.post_submit diff --git a/backend/app/modules/projects/post_policy/custody.py b/backend/app/modules/projects/post_policy/custody.py index 719049976..c5d1b8012 100644 --- a/backend/app/modules/projects/post_policy/custody.py +++ b/backend/app/modules/projects/post_policy/custody.py @@ -7,6 +7,7 @@ from app.core.hashing import canonical_json_hash from app.modules.checkers.api.post_submit_catalogue import CompiledPostSubmitPolicy +from app.modules.checkers.api.external_policy import LockedExternalPostSubmitPolicy from app.modules.authorization.api import ActorKind from app.modules.authorization.api.post_policy import PostPolicyAuthorityReceipt from app.modules.projects.api.guide_proposals import GuideProposalError @@ -16,7 +17,6 @@ post_policy_derive_authorization_selector, post_policy_human_authorization_selector, ) -from app.modules.checkers.api.post_submit_catalogue import current_post_submit_catalogue from app.modules.projects.post_submit_policy import parse_locked_post_submit_checker_policy_body from .models import PostPolicyOperation @@ -27,7 +27,7 @@ class PostPolicyCustody: """One policy and its exact immutable receipts; no current-successor substitution.""" target: PostPolicyTarget - compiled: CompiledPostSubmitPolicy + compiled: CompiledPostSubmitPolicy | LockedExternalPostSubmitPolicy projection: PostPolicyOperation approval: PostPolicyOperation | None correction: PostPolicyOperation | None @@ -38,9 +38,14 @@ def operation_receipt(operation: PostPolicyOperation) -> PostPolicyReceipt: receipt = PostPolicyReceipt.model_validate(operation.receipt_json) target = receipt.target facts = operation.resource_context_json - action = "project.post_submit_checker_policy." + { - "derive": "derive", "approve": "approve", "correction": "correction.request", - }[operation.kind] + action = ( + "project.post_submit_checker_policy." + + { + "derive": "derive", + "approve": "approve", + "correction": "correction.request", + }[operation.kind] + ) selector_id = ( post_policy_derive_authorization_selector(operation.upstream_approval_operation_id) if operation.kind == "derive" @@ -49,7 +54,8 @@ def operation_receipt(operation: PostPolicyOperation) -> PostPolicyReceipt: ) ) if ( - receipt.operation_id != operation.operation_id or receipt.kind != operation.kind + receipt.operation_id != operation.operation_id + or receipt.kind != operation.kind or target.model_dump(mode="json") != operation.target_json or target.digest != operation.target_digest or canonical_json_hash(operation.request_json) != operation.request_digest @@ -60,13 +66,20 @@ def operation_receipt(operation: PostPolicyOperation) -> PostPolicyReceipt: or str(target.proposal.guide_id) != operation.guide_id or target.proposal.compilation_id != operation.compilation_id or target.upstream.operation_id != operation.upstream_approval_operation_id - or (facts.get("lifecycle_status") not in ({"compiled", "approved"} if operation.kind == "correction" else {"compiled"})) - or facts != { + or ( + facts.get("lifecycle_status") + not in ({"compiled", "approved"} if operation.kind == "correction" else {"compiled"}) + ) + or facts + != { "locator": dict( - project_id=operation.project_id, guide_id=operation.guide_id, + project_id=operation.project_id, + guide_id=operation.guide_id, compilation_id=str(operation.compilation_id), - actor_profile_id=operation.actor_profile_id, identity_link_id=operation.identity_link_id, - action_id=action, operation_id=str(selector_id), + actor_profile_id=operation.actor_profile_id, + identity_link_id=operation.identity_link_id, + action_id=action, + operation_id=str(selector_id), ), "policy_id": operation.policy_id, "finalization_id": str(target.proposal.finalization_id), @@ -87,8 +100,10 @@ def operation_receipt(operation: PostPolicyOperation) -> PostPolicyReceipt: "pre_submit_bundle_hash": target.upstream.pre_submit_bundle_hash, "projection_operation_id": str(target.projection_operation_id), "lifecycle_status": facts.get("lifecycle_status"), - "policy_hash": target.policy_hash, "target_digest": target.digest, - "request_digest": operation.request_digest, "output_digest": operation.output_digest, + "policy_hash": target.policy_hash, + "target_digest": target.digest, + "request_digest": operation.request_digest, + "output_digest": operation.output_digest, } ): raise GuideProposalError("proposal_unavailable") @@ -97,30 +112,56 @@ def operation_receipt(operation: PostPolicyOperation) -> PostPolicyReceipt: async def load_post_policy_custody(session, policy) -> PostPolicyCustody: """Require complete projection/approval/supersession evidence, even for reads.""" - operations = {row.kind: row for row in await session.scalars( - select(PostPolicyOperation).where(PostPolicyOperation.policy_id == policy.id).with_for_update().execution_options(populate_existing=True) - )} + operations = { + row.kind: row + for row in await session.scalars( + select(PostPolicyOperation) + .where(PostPolicyOperation.policy_id == policy.id) + .with_for_update() + .execution_options(populate_existing=True) + ) + } projection = operations.get("derive") if projection is None or policy.projection_operation_id != projection.operation_id: raise GuideProposalError("proposal_unavailable") target = operation_receipt(projection).target - compiled = parse_locked_post_submit_checker_policy_body( - policy.policy_body, project_id=policy.project_id, - guide_version=policy.guide_version, policy_hash=policy.policy_hash or "", - ) - if ( - compiled.catalogue_id, compiled.catalogue_source_version, - compiled.catalogue_schema_version, compiled.catalogue_manifest_sha256, - ) != ( - target.proposal.post_catalogue_id, target.proposal.post_catalogue_version, - target.proposal.post_catalogue_schema_version, target.proposal.post_catalogue_manifest_hash, - ): - raise GuideProposalError("proposal_unavailable") - compiled.validate_sidecars(required_checkers=policy.required_checkers, - warning_checkers=policy.warning_checkers, - blocking_severities=policy.blocking_severities) + if policy.policy_body.get("schema_version") == "external_post_submit_policy.v1": + compiled = LockedExternalPostSubmitPolicy.model_validate(policy.policy_body) + if ( + compiled.policy_sha256 != policy.policy_hash + or policy.required_checkers + != [item.registry.capability_id for item in compiled.entries] + or policy.warning_checkers != [] + or policy.blocking_severities != ["critical", "high"] + ): + raise GuideProposalError("proposal_unavailable") + else: + compiled = parse_locked_post_submit_checker_policy_body( + policy.policy_body, + project_id=policy.project_id, + guide_version=policy.guide_version, + policy_hash=policy.policy_hash or "", + ) + if ( + compiled.catalogue_id, + compiled.catalogue_source_version, + compiled.catalogue_schema_version, + compiled.catalogue_manifest_sha256, + ) != ( + target.proposal.post_catalogue_id, + target.proposal.post_catalogue_version, + target.proposal.post_catalogue_schema_version, + target.proposal.post_catalogue_manifest_hash, + ): + raise GuideProposalError("proposal_unavailable") + compiled.validate_sidecars( + required_checkers=policy.required_checkers, + warning_checkers=policy.warning_checkers, + blocking_severities=policy.blocking_severities, + ) expected = { - "project_id": str(target.proposal.project_id), "guide_id": str(target.proposal.guide_id), + "project_id": str(target.proposal.project_id), + "guide_id": str(target.proposal.guide_id), "guide_version": target.proposal.guide_version, "source_snapshot_id": str(target.proposal.source_snapshot_id), "source_snapshot_hash": target.proposal.source_snapshot_hash, @@ -129,7 +170,9 @@ async def load_post_policy_custody(session, policy) -> PostPolicyCustody: "pre_submit_checker_policy_id": str(target.upstream.pre_submit_policy_id), "pre_submit_checker_bundle_hash": target.upstream.pre_submit_bundle_hash, "policy_hash": target.policy_hash, - "supersedes_policy_id": str(target.predecessor_policy_id) if target.predecessor_policy_id else None, + "supersedes_policy_id": str(target.predecessor_policy_id) + if target.predecessor_policy_id + else None, } if any(getattr(policy, key) != value for key, value in expected.items()): raise GuideProposalError("proposal_unavailable") @@ -142,18 +185,24 @@ async def load_post_policy_custody(session, policy) -> PostPolicyCustody: or (policy.approved_at is not None) != (approval is not None) or (policy.lifecycle_status == "approved" and approval is None) or (policy.lifecycle_status == "compiled" and approval is not None) - or (policy.lifecycle_status == "superseded") != (policy.supersession_operation_id is not None) + or (policy.lifecycle_status == "superseded") + != (policy.supersession_operation_id is not None) or (policy.lifecycle_status == "superseded") != (policy.superseded_at is not None) ): raise GuideProposalError("proposal_unavailable") if policy.lifecycle_status == "superseded": - successor = await session.get(PostPolicyOperation, policy.supersession_operation_id, populate_existing=True) + successor = await session.get( + PostPolicyOperation, policy.supersession_operation_id, populate_existing=True + ) if successor is None: raise GuideProposalError("proposal_unavailable") receipt = operation_receipt(successor) if not ( (successor.kind == "correction" and successor is correction) - or (successor.kind == "derive" and receipt.target.predecessor_policy_id == UUID(policy.id)) + or ( + successor.kind == "derive" + and receipt.target.predecessor_policy_id == UUID(policy.id) + ) ): raise GuideProposalError("proposal_unavailable") return PostPolicyCustody(target, compiled, projection, approval, correction) @@ -171,23 +220,35 @@ def require_post_authority(receipt, facts, actor): or receipt.permission_id != "project.effective_policy.manage" or receipt.resource_context_digest != facts.digest or not isinstance(receipt.authorization_decision_event_id, UUID) - or (derive and ( - actor.actor_kind is not ActorKind.SERVICE - or actor.service_identity != "workstream.project.setup" - or receipt.service_identity != "workstream.project.setup" - or receipt.admin_role_grant_id is not None - )) - or (not derive and ( - actor.actor_kind is not ActorKind.HUMAN or receipt.service_identity is not None - or not isinstance(receipt.admin_role_grant_id, UUID) - )) + or ( + derive + and ( + actor.actor_kind is not ActorKind.SERVICE + or actor.service_identity != "workstream.project.setup" + or receipt.service_identity != "workstream.project.setup" + or receipt.admin_role_grant_id is not None + ) + ) + or ( + not derive + and ( + actor.actor_kind is not ActorKind.HUMAN + or receipt.service_identity is not None + or not isinstance(receipt.admin_role_grant_id, UUID) + ) + ) ): raise GuideProposalError("authority_unavailable") def validate_activation_post_policy( - guide, source_snapshot, effective_policy, pre_submit_checker_policy, - post_submit_checker_policy, approval_custody, post_policy_custody, + guide, + source_snapshot, + effective_policy, + pre_submit_checker_policy, + post_submit_checker_policy, + approval_custody, + post_policy_custody, ): """Validate the exact post-policy portion of active-guide readiness.""" if post_submit_checker_policy is None: @@ -199,13 +260,8 @@ def validate_activation_post_policy( if post_submit_checker_policy.source_snapshot_hash != source_snapshot.bundle_hash: raise ValueError("post-submit checker policy snapshot hash mismatch") if post_submit_checker_policy.effective_policy_id != effective_policy.id: - raise ValueError( - "post-submit checker policy is bound to the wrong effective policy" - ) - if ( - post_submit_checker_policy.effective_policy_hash - != effective_policy.effective_policy_hash - ): + raise ValueError("post-submit checker policy is bound to the wrong effective policy") + if post_submit_checker_policy.effective_policy_hash != effective_policy.effective_policy_hash: raise ValueError("post-submit checker policy effective hash mismatch") if post_submit_checker_policy.pre_submit_checker_policy_id != pre_submit_checker_policy.id: raise ValueError( @@ -221,28 +277,43 @@ def validate_activation_post_policy( if ( post_policy_custody is None or post_policy_custody.approval is None - or post_submit_checker_policy.approval_operation_id != post_policy_custody.approval.operation_id - or post_submit_checker_policy.projection_operation_id != post_policy_custody.projection.operation_id + or post_submit_checker_policy.approval_operation_id + != post_policy_custody.approval.operation_id + or post_submit_checker_policy.projection_operation_id + != post_policy_custody.projection.operation_id or post_submit_checker_policy.approved_at is None - or post_policy_custody.target.upstream.operation_id != approval_custody.operation.operation_id + or post_policy_custody.target.upstream.operation_id + != approval_custody.operation.operation_id or post_policy_custody.target.policy_hash != post_submit_checker_policy.policy_hash ): raise ValueError("post-submit checker approval custody is required") try: - parsed_post_submit_policy = parse_locked_post_submit_checker_policy_body( - post_submit_checker_policy.policy_body, - project_id=post_submit_checker_policy.project_id, - guide_version=post_submit_checker_policy.guide_version, - policy_hash=post_submit_checker_policy.policy_hash or "", - ) - parsed_post_submit_policy.validate_catalogue(current_post_submit_catalogue()) - except ValueError as exc: - raise ValueError("post-submit checker policy hash is invalid") from exc - try: - parsed_post_submit_policy.validate_sidecars( - required_checkers=post_submit_checker_policy.required_checkers, - warning_checkers=post_submit_checker_policy.warning_checkers, - blocking_severities=post_submit_checker_policy.blocking_severities, - ) + if ( + post_submit_checker_policy.policy_body.get("schema_version") + == "external_post_submit_policy.v1" + ): + parsed = LockedExternalPostSubmitPolicy.model_validate( + post_submit_checker_policy.policy_body + ) + if ( + parsed.policy_sha256 != post_submit_checker_policy.policy_hash + or post_submit_checker_policy.required_checkers + != [item.registry.capability_id for item in parsed.entries] + or post_submit_checker_policy.warning_checkers != [] + or post_submit_checker_policy.blocking_severities != ["critical", "high"] + ): + raise ValueError("selected post policy sidecars differ") + else: + parsed = parse_locked_post_submit_checker_policy_body( + post_submit_checker_policy.policy_body, + project_id=post_submit_checker_policy.project_id, + guide_version=post_submit_checker_policy.guide_version, + policy_hash=post_submit_checker_policy.policy_hash or "", + ) + parsed.validate_sidecars( + required_checkers=post_submit_checker_policy.required_checkers, + warning_checkers=post_submit_checker_policy.warning_checkers, + blocking_severities=post_submit_checker_policy.blocking_severities, + ) except ValueError as exc: raise ValueError("post-submit checker policy hash is invalid") from exc diff --git a/backend/app/modules/projects/post_policy/delivery.py b/backend/app/modules/projects/post_policy/delivery.py index 35559d7bf..02fde43ed 100644 --- a/backend/app/modules/projects/post_policy/delivery.py +++ b/backend/app/modules/projects/post_policy/delivery.py @@ -9,11 +9,11 @@ from app.modules.authorization.api import ActorIdentityFacts, AuthorizationDenied from app.modules.authorization.api.post_policy import PostPolicyAuthorizationPort -from app.modules.checkers.api.post_submit_catalogue import PostSubmitCatalogue from app.modules.projects.api.guide_proposals import GuideProposalError, GuideProposalSelection from app.modules.projects.api.post_policy import PostPolicyDelivery, PostPolicyDerive from app.modules.projects.guide_compilation.models import ( - ProjectGuideCompilation, ProjectGuideProposalApproval, + ProjectGuideCompilation, + ProjectGuideProposalApproval, ) from app.modules.projects.models import ProjectSetupRun, SubmissionArtifactPolicy @@ -27,7 +27,10 @@ async def pending_approval_ids( - session: AsyncSession, *, after: UUID | None, limit: int, + session: AsyncSession, + *, + after: UUID | None, + limit: int, ) -> list[UUID]: """Page metadata only; current custody and authority are rechecked on delivery.""" approval = ProjectGuideProposalApproval @@ -44,7 +47,8 @@ async def pending_approval_ids( .join(SubmissionArtifactPolicy, SubmissionArtifactPolicy.id == approval.artifact_policy_id) .join(ProjectGuideCompilation, ProjectGuideCompilation.id == approval.compilation_id) .where(SubmissionArtifactPolicy.lifecycle_status == "approved", ~completed, ~newer_setup) - .order_by(approval.operation_id).limit(limit) + .order_by(approval.operation_id) + .limit(limit) ) if after is not None: query = query.where(approval.operation_id > after) @@ -55,26 +59,35 @@ class PostPolicyDeliveryService: """Run the existing derive operation in its own fresh authorized transaction.""" def __init__( - self, sessions: async_sessionmaker[AsyncSession], *, - authority: PostPolicyServiceAuthority, catalogue: PostSubmitCatalogue, + self, + sessions: async_sessionmaker[AsyncSession], + *, + authority: PostPolicyServiceAuthority, ) -> None: - self.sessions, self.authority, self.catalogue = sessions, authority, catalogue + self.sessions, self.authority = sessions, authority async def run(self, delivery: PostPolicyDelivery) -> dict: """Reload immutable selection, then leave all policy decisions to its owner.""" delivery = PostPolicyDelivery.model_validate(delivery) async with self.sessions() as session: approval = ProjectGuideProposalApproval - row = (await session.execute(select( - approval.project_id, approval.guide_id, approval.compilation_id, - approval.output_digest, - ).where(approval.operation_id == delivery.approval_operation_id))).one_or_none() + row = ( + await session.execute( + select( + approval.project_id, + approval.guide_id, + approval.compilation_id, + approval.output_digest, + ).where(approval.operation_id == delivery.approval_operation_id) + ) + ).one_or_none() await session.rollback() if row is None: return {"status": "delivery_rejected"} command = PostPolicyDerive( selection=GuideProposalSelection( - project_id=row.project_id, guide_id=row.guide_id, + project_id=row.project_id, + guide_id=row.guide_id, compilation_id=row.compilation_id, ), upstream_approval_operation_id=delivery.approval_operation_id, @@ -83,12 +96,17 @@ async def run(self, delivery: PostPolicyDelivery) -> dict: try: async with self.authority(session, delivery.task_id) as (authority, actor): async with session.begin(): - receipt = await PostPolicyService(session, authority, self.catalogue).derive( - command, actor=actor, request_id=delivery.task_id, + receipt = await PostPolicyService(session, authority).derive( + command, + actor=actor, + request_id=delivery.task_id, ) return {"status": "policy_draft_ready", "policy_id": str(receipt.target.policy_id)} except AuthorizationDenied: return {"status": "delivery_rejected"} except GuideProposalError as exc: - return {"status": "derivation_unavailable" if exc.code == "storage_unavailable" - else "delivery_rejected"} + return { + "status": "derivation_unavailable" + if exc.code == "storage_unavailable" + else "delivery_rejected" + } diff --git a/backend/app/modules/projects/post_policy/service.py b/backend/app/modules/projects/post_policy/service.py index 4a004c95c..b60866207 100644 --- a/backend/app/modules/projects/post_policy/service.py +++ b/backend/app/modules/projects/post_policy/service.py @@ -10,15 +10,28 @@ from app.core.hashing import canonical_json_hash from app.modules.authorization.api import ActorIdentityFacts from app.modules.authorization.api.guide_proposal_review import GuideProposalAuthorizationPort -from app.modules.checkers.api.post_submit_catalogue import CompiledPostSubmitPolicy, PostSubmitCatalogue +from app.modules.checkers.api.external_policy import ( + LockedExternalCheckerPolicies, + LockedExternalPostSubmitPolicy, +) from app.modules.authorization.api.post_policy import ( - PostPolicyAuthorizationFacts, PostPolicyAuthorizationLocator, PreparedPostPolicyOperation, + PostPolicyAuthorizationFacts, + PostPolicyAuthorizationLocator, + PreparedPostPolicyOperation, PostPolicyAuthorizationPort, ) -from app.modules.projects.api.guide_proposals import GuideProposalApprovalReceipt, GuideProposalError +from app.modules.projects.api.guide_proposals import ( + GuideProposalApprovalReceipt, + GuideProposalError, +) from app.modules.projects.api.post_policy import ( - PostPolicyReceipt, PostPolicyReviewPackage, PostPolicySelection, PostPolicyTarget, - PostPolicyApproval, PostPolicyCorrection, PostPolicyDerive, + PostPolicyReceipt, + PostPolicyReviewPackage, + PostPolicySelection, + PostPolicyTarget, + PostPolicyApproval, + PostPolicyCorrection, + PostPolicyDerive, post_policy_derive_authorization_selector, post_policy_human_authorization_selector, ) @@ -26,7 +39,9 @@ from app.modules.projects.models import PostSubmitCheckerPolicy from app.modules.projects.repository import ProjectRepository from app.modules.projects.api.guide_activation_context import ( - GuideActivationContext, GuidePolicySelection, GuideContributionDiscoveryPort, + GuideActivationContext, + GuidePolicySelection, + GuideContributionDiscoveryPort, ) from .compiler import compile_saved_post_policy @@ -38,16 +53,23 @@ class PostPolicyService: """Use caller-owned root transactions and explicitly supplied nominal authority.""" - def __init__(self, session: AsyncSession, authorization: PostPolicyAuthorizationPort, catalogue: PostSubmitCatalogue) -> None: - self.session, self.authorization, self.catalogue = session, authorization, catalogue + def __init__(self, session: AsyncSession, authorization: PostPolicyAuthorizationPort) -> None: + self.session, self.authorization = session, authorization self.repository = PostPolicyRepository(session) def _require_transaction(self): - if (not self.session.in_transaction() or self.session.in_nested_transaction() - or self.session.new or self.session.dirty or self.session.deleted): + if ( + not self.session.in_transaction() + or self.session.in_nested_transaction() + or self.session.new + or self.session.dirty + or self.session.deleted + ): raise GuideProposalError("proposal_unavailable") - async def derive(self, command: PostPolicyDerive, *, actor: ActorIdentityFacts, request_id: UUID) -> PostPolicyReceipt: + async def derive( + self, command: PostPolicyDerive, *, actor: ActorIdentityFacts, request_id: UUID + ) -> PostPolicyReceipt: """Project one exact approved result once; no document/runtime dependency exists.""" self._require_transaction() selector_id = post_policy_derive_authorization_selector( @@ -63,18 +85,23 @@ async def derive(self, command: PostPolicyDerive, *, actor: ActorIdentityFacts, ) if existing: receipt = operation_receipt(existing) - _, _, custody = await self.repository.lock_policy(self._selection(receipt.target)) + _, _, custody = await self.repository.lock_policy( + self._selection(receipt.target) + ) if custody.projection.operation_id != existing.operation_id: raise GuideProposalError("operation_conflict") return await self._replay(existing, command, actor, locator, prepared) upstream = await self.repository.require_current_upstream(locked) - if (upstream.operation_id != command.upstream_approval_operation_id - or upstream.output_digest != command.upstream_approval_output_digest): + if ( + upstream.operation_id != command.upstream_approval_operation_id + or upstream.output_digest != command.upstream_approval_output_digest + ): raise GuideProposalError("proposal_stale") - self._require_catalogue(locked.target) compiled = compile_saved_post_policy( - project_id=locked.target.project_id, guide_version=locked.target.guide_version, - result=locked.result, catalogue=self.catalogue, + result=locked.result, + policies=LockedExternalCheckerPolicies.model_validate( + upstream.effective_pre_submit_plan + ), ) previous = await self.repository.latest_policy(locked.target.guide_id) if previous: @@ -83,9 +110,12 @@ async def derive(self, command: PostPolicyDerive, *, actor: ActorIdentityFacts, raise GuideProposalError("proposal_stale") operation_id = new_record_id() target = PostPolicyTarget( - proposal=locked.target, upstream=GuideProposalApprovalReceipt.model_validate(upstream.receipt_json), - upstream_output_digest=upstream.output_digest, policy_id=new_record_id(), - projection_operation_id=operation_id, policy_hash=compiled.policy_hash, + proposal=locked.target, + upstream=GuideProposalApprovalReceipt.model_validate(upstream.receipt_json), + upstream_output_digest=upstream.output_digest, + policy_id=new_record_id(), + projection_operation_id=operation_id, + policy_hash=compiled.policy_hash, predecessor_policy_id=UUID(previous.id) if previous else None, ) receipt = PostPolicyReceipt(operation_id=operation_id, kind="derive", target=target) @@ -97,10 +127,14 @@ async def derive(self, command: PostPolicyDerive, *, actor: ActorIdentityFacts, self._supersede(previous, operation_id, now, "upstream_policy_changed") await self.session.flush() self.session.add(self._policy_row(target, compiled, actor)) - await self._persist(command, actor, receipt, facts, authority, command.upstream_approval_operation_id) + await self._persist( + command, actor, receipt, facts, authority, command.upstream_approval_operation_id + ) return receipt - async def approve(self, command: PostPolicyApproval, *, actor: ActorIdentityFacts, request_id: UUID) -> PostPolicyReceipt: + async def approve( + self, command: PostPolicyApproval, *, actor: ActorIdentityFacts, request_id: UUID + ) -> PostPolicyReceipt: """Record separate human approval without accepting replacement policy content.""" self._require_transaction() selector_id = self._human_operation_id(actor, command.idempotency_key, "approve") @@ -118,17 +152,20 @@ async def approve(self, command: PostPolicyApproval, *, actor: ActorIdentityFact if existing: return await self._replay(existing, command, actor, locator, prepared) await self.repository.require_current_upstream(locked) - self._require_catalogue(target.proposal) if policy.lifecycle_status != "compiled" or custody.approval is not None: raise GuideProposalError("proposal_stale") compiled = compile_saved_post_policy( - project_id=target.proposal.project_id, guide_version=target.proposal.guide_version, - result=locked.result, catalogue=self.catalogue, + result=locked.result, + policies=LockedExternalCheckerPolicies.model_validate( + locked.view.approval_custody.operation.effective_pre_submit_plan + ), ) if compiled.policy_hash != target.policy_hash: raise GuideProposalError("approval_blocked") operation_id = new_record_id() - receipt = PostPolicyReceipt(operation_id=operation_id, kind="approve", target=target) + receipt = PostPolicyReceipt( + operation_id=operation_id, kind="approve", target=target + ) facts = self._facts(locator, command, receipt) authority = await prepared.consume_new(facts) require_post_authority(authority, facts, actor) @@ -138,10 +175,19 @@ async def approve(self, command: PostPolicyApproval, *, actor: ActorIdentityFact await self._persist(command, actor, receipt, facts, authority, command.idempotency_key) return receipt - async def review_package(self, selection: PostPolicySelection, *, actor: ActorIdentityFacts, request_id: UUID, contribution: GuideContributionDiscoveryPort) -> PostPolicyReviewPackage[CompiledPostSubmitPolicy]: + async def review_package( + self, + selection: PostPolicySelection, + *, + actor: ActorIdentityFacts, + request_id: UUID, + contribution: GuideContributionDiscoveryPort, + ) -> PostPolicyReviewPackage[LockedExternalPostSubmitPolicy]: """Disclose the complete exact policy and safe findings through existing read authority.""" self._require_transaction() - locator = self._locator(selection, actor, request_id, uuid5(request_id, "post-policy-read"), "read") + locator = self._locator( + selection, actor, request_id, uuid5(request_id, "post-policy-read"), "read" + ) async with GuideProposalService._bounded_errors(): async with self.authorization.prepare_post_policy_operation(locator) as prepared: self._require_prepared(prepared) @@ -153,41 +199,79 @@ async def review_package(self, selection: PostPolicySelection, *, actor: ActorId guide = locked.view.guide review = await projects.lock_review_policy(guide.project_id, guide.version) revision = await projects.lock_revision_policy(guide.project_id, guide.version) + def selected(row): - return None if row is None else GuidePolicySelection( - policy_id=row.id, generation=row.policy_generation, policy_hash=row.policy_hash, + return ( + None + if row is None + else GuidePolicySelection( + policy_id=row.id, + generation=row.policy_generation, + policy_hash=row.policy_hash, + ) ) + activation = GuideActivationContext( guide_mutation_generation=guide.mutation_generation, - review=selected(review), revision=selected(revision), + review=selected(review), + revision=selected(revision), contribution=await contribution.published_selection(selection.project_id), expected_previous_active_guide_id=previous.id if previous else None, - expected_previous_active_guide_generation=previous.mutation_generation if previous else None, - post_approval_operation_id=custody.approval.operation_id if custody.approval else None, - post_approval_output_digest=custody.approval.output_digest if custody.approval else None, + expected_previous_active_guide_generation=previous.mutation_generation + if previous + else None, + post_approval_operation_id=custody.approval.operation_id + if custody.approval + else None, + post_approval_output_digest=custody.approval.output_digest + if custody.approval + else None, ) proposal = await self.repository.proposals.package(locked) - package = PostPolicyReviewPackage[CompiledPostSubmitPolicy]( - target=custody.target, policy=custody.compiled, proposal=proposal, + package = PostPolicyReviewPackage[LockedExternalPostSubmitPolicy]( + target=custody.target, + policy=custody.compiled, + proposal=proposal, activation_context=activation, lifecycle_status=policy.lifecycle_status, - current=locked.current and policy.lifecycle_status != "superseded" - and proposal.current_approval_operation_id == custody.target.upstream.operation_id, + current=locked.current + and policy.lifecycle_status != "superseded" + and proposal.current_approval_operation_id + == custody.target.upstream.operation_id, approval_operation_id=policy.approval_operation_id, - correction=operation_receipt(custody.correction).correction if custody.correction else None, + correction=operation_receipt(custody.correction).correction + if custody.correction + else None, + ) + facts = self._facts( + locator, + selection, + package, + target=custody.target, + lifecycle_status=policy.lifecycle_status, ) - facts = self._facts(locator, selection, package, target=custody.target, lifecycle_status=policy.lifecycle_status) await prepared.authorize_read(facts) return package - async def request_correction(self, command: PostPolicyCorrection, *, actor: ActorIdentityFacts, request_id: UUID, guide_authorization: GuideProposalAuthorizationPort) -> PostPolicyReceipt: + async def request_correction( + self, + command: PostPolicyCorrection, + *, + actor: ActorIdentityFacts, + request_id: UUID, + guide_authorization: GuideProposalAuthorizationPort, + ) -> PostPolicyReceipt: """Both authorities precede product locks; the existing successor owner persists once.""" from .correction import request_post_policy_correction self._require_transaction() async with GuideProposalService._bounded_errors(): return await request_post_policy_correction( - self, command, actor, request_id, guide_authorization, + self, + command, + actor, + request_id, + guide_authorization, ) @staticmethod @@ -195,19 +279,13 @@ def _require_prepared(prepared): if not isinstance(prepared, PreparedPostPolicyOperation): raise GuideProposalError("authority_unavailable") - def _require_catalogue(self, proposal): - catalogue = self.catalogue - if (catalogue.catalogue_id, catalogue.source_version, catalogue.schema_version, catalogue.manifest_sha256) != ( - proposal.post_catalogue_id, proposal.post_catalogue_version, - proposal.post_catalogue_schema_version, proposal.post_catalogue_manifest_hash, - ): - raise GuideProposalError("proposal_stale") - @staticmethod def _selection(target): return PostPolicySelection( - project_id=target.proposal.project_id, guide_id=target.proposal.guide_id, - compilation_id=target.proposal.compilation_id, policy_id=target.policy_id, + project_id=target.proposal.project_id, + guide_id=target.proposal.guide_id, + compilation_id=target.proposal.compilation_id, + policy_id=target.policy_id, ) @staticmethod @@ -216,41 +294,68 @@ def _human_operation_id(actor, key, kind): @staticmethod def _locator(selection, actor, request_id, operation_id, kind): - action = "project.guide_compilation.review_package.read" if kind == "read" else ( - "project.post_submit_checker_policy." + ("correction.request" if kind == "correction" else kind) + action = ( + "project.guide_compilation.review_package.read" + if kind == "read" + else ( + "project.post_submit_checker_policy." + + ("correction.request" if kind == "correction" else kind) + ) ) return PostPolicyAuthorizationLocator( - project_id=selection.project_id, guide_id=selection.guide_id, compilation_id=selection.compilation_id, - actor_profile_id=actor.actor_profile_id, identity_link_id=actor.identity_link_id, - request_id=request_id, operation_id=operation_id, action_id=action, + project_id=selection.project_id, + guide_id=selection.guide_id, + compilation_id=selection.compilation_id, + actor_profile_id=actor.actor_profile_id, + identity_link_id=actor.identity_link_id, + request_id=request_id, + operation_id=operation_id, + action_id=action, ) @staticmethod def _facts(locator, command, output, *, target=None, lifecycle_status="compiled"): target = target if target is not None else output.target return PostPolicyAuthorizationFacts( - locator=locator, policy_id=target.policy_id, finalization_id=target.proposal.finalization_id, - setup_run_id=target.proposal.setup_run_id, setup_generation=target.proposal.setup_generation, + locator=locator, + policy_id=target.policy_id, + finalization_id=target.proposal.finalization_id, + setup_run_id=target.proposal.setup_run_id, + setup_generation=target.proposal.setup_generation, upstream_approval_operation_id=target.upstream.operation_id, - upstream_approval_output_digest=target.upstream_output_digest, policy_hash=target.policy_hash, - guide_version=target.proposal.guide_version, source_snapshot_id=target.proposal.source_snapshot_id, - source_snapshot_hash=target.proposal.source_snapshot_hash, result_hash=target.proposal.result_hash, + upstream_approval_output_digest=target.upstream_output_digest, + policy_hash=target.policy_hash, + guide_version=target.proposal.guide_version, + source_snapshot_id=target.proposal.source_snapshot_id, + source_snapshot_hash=target.proposal.source_snapshot_hash, + result_hash=target.proposal.result_hash, post_component_hash=target.proposal.component_hashes.post_submit_hash, requirement_inventory_hash=target.proposal.component_hashes.requirement_inventory_hash, catalogue_manifest_hash=target.proposal.post_catalogue_manifest_hash, - effective_policy_id=target.upstream.effective_policy_id, effective_policy_hash=target.upstream.effective_policy_hash, - pre_submit_policy_id=target.upstream.pre_submit_policy_id, pre_submit_bundle_hash=target.upstream.pre_submit_bundle_hash, - projection_operation_id=target.projection_operation_id, lifecycle_status=lifecycle_status, - target_digest=target.digest, request_digest=canonical_json_hash(command.model_dump(mode="json")), + effective_policy_id=target.upstream.effective_policy_id, + effective_policy_hash=target.upstream.effective_policy_hash, + pre_submit_policy_id=target.upstream.pre_submit_policy_id, + pre_submit_bundle_hash=target.upstream.pre_submit_bundle_hash, + projection_operation_id=target.projection_operation_id, + lifecycle_status=lifecycle_status, + target_digest=target.digest, + request_digest=canonical_json_hash(command.model_dump(mode="json")), output_digest=canonical_json_hash(output.model_dump(mode="json")), ) async def _replay(self, existing, command, actor, locator, prepared): receipt = operation_receipt(existing) - facts = self._facts(locator, command, receipt, lifecycle_status=existing.resource_context_json["lifecycle_status"]) - if (existing.actor_profile_id != str(actor.actor_profile_id) - or existing.identity_link_id != str(actor.identity_link_id) - or facts.digest != existing.resource_context_digest): + facts = self._facts( + locator, + command, + receipt, + lifecycle_status=existing.resource_context_json["lifecycle_status"], + ) + if ( + existing.actor_profile_id != str(actor.actor_profile_id) + or existing.identity_link_id != str(actor.identity_link_id) + or facts.digest != existing.resource_context_digest + ): raise GuideProposalError("operation_conflict") await prepared.validate_replay(facts, UUID(existing.authorization_decision_event_id)) return receipt @@ -266,35 +371,57 @@ def _supersede(policy, operation_id, now, kind): def _policy_row(target, compiled, actor): proposal, upstream = target.proposal, target.upstream return PostSubmitCheckerPolicy( - id=str(target.policy_id), project_id=str(proposal.project_id), guide_id=str(proposal.guide_id), - guide_version=proposal.guide_version, source_snapshot_id=str(proposal.source_snapshot_id), - source_snapshot_hash=proposal.source_snapshot_hash, effective_policy_id=str(upstream.effective_policy_id), + id=str(target.policy_id), + project_id=str(proposal.project_id), + guide_id=str(proposal.guide_id), + guide_version=proposal.guide_version, + source_snapshot_id=str(proposal.source_snapshot_id), + source_snapshot_hash=proposal.source_snapshot_hash, + effective_policy_id=str(upstream.effective_policy_id), effective_policy_hash=upstream.effective_policy_hash, pre_submit_checker_policy_id=str(upstream.pre_submit_policy_id), pre_submit_checker_bundle_hash=upstream.pre_submit_bundle_hash, - required_checkers=compiled.required_checkers, warning_checkers=compiled.warning_checkers, - blocking_severities=list(compiled.blocking_severities), policy_body=compiled.policy_body, - policy_hash=compiled.policy_hash, lifecycle_status="compiled", + required_checkers=[item.registry.capability_id for item in compiled.entries], + warning_checkers=[], + blocking_severities=["critical", "high"], + policy_body=compiled.model_dump(mode="json"), + policy_hash=compiled.policy_sha256, + lifecycle_status="compiled", projection_operation_id=target.projection_operation_id, - supersedes_policy_id=str(target.predecessor_policy_id) if target.predecessor_policy_id else None, + supersedes_policy_id=str(target.predecessor_policy_id) + if target.predecessor_policy_id + else None, created_by=str(actor.actor_profile_id), ) async def _persist(self, command, actor, receipt, facts, authority, key): target = receipt.target - self.session.add(PostPolicyOperation( - operation_id=receipt.operation_id, kind=receipt.kind, idempotency_key=key, - project_id=str(target.proposal.project_id), guide_id=str(target.proposal.guide_id), - compilation_id=target.proposal.compilation_id, policy_id=str(target.policy_id), - upstream_approval_operation_id=target.upstream.operation_id, - target_json=target.model_dump(mode="json"), target_digest=target.digest, - request_json=command.model_dump(mode="json"), request_digest=facts.request_digest, - resource_context_json=facts.resource_json(), resource_context_digest=facts.digest, - receipt_json=receipt.model_dump(mode="json"), output_digest=facts.output_digest, - actor_profile_id=str(actor.actor_profile_id), identity_link_id=str(actor.identity_link_id), - admin_role_grant_id=authority.admin_role_grant_id, service_identity=authority.service_identity, - authorization_decision_event_id=str(authority.authorization_decision_event_id), - )) + self.session.add( + PostPolicyOperation( + operation_id=receipt.operation_id, + kind=receipt.kind, + idempotency_key=key, + project_id=str(target.proposal.project_id), + guide_id=str(target.proposal.guide_id), + compilation_id=target.proposal.compilation_id, + policy_id=str(target.policy_id), + upstream_approval_operation_id=target.upstream.operation_id, + target_json=target.model_dump(mode="json"), + target_digest=target.digest, + request_json=command.model_dump(mode="json"), + request_digest=facts.request_digest, + resource_context_json=facts.resource_json(), + resource_context_digest=facts.digest, + receipt_json=receipt.model_dump(mode="json"), + output_digest=facts.output_digest, + actor_profile_id=str(actor.actor_profile_id), + identity_link_id=str(actor.identity_link_id), + admin_role_grant_id=authority.admin_role_grant_id, + service_identity=authority.service_identity, + authorization_decision_event_id=str(authority.authorization_decision_event_id), + ) + ) await self.session.flush() - post_policy_derive_authorization_selector, - post_policy_human_authorization_selector, + + (post_policy_derive_authorization_selector,) + (post_policy_human_authorization_selector,) diff --git a/backend/app/modules/tasks/repository.py b/backend/app/modules/tasks/repository.py index 304f18456..67fd87374 100644 --- a/backend/app/modules/tasks/repository.py +++ b/backend/app/modules/tasks/repository.py @@ -6,6 +6,7 @@ from collections.abc import Sequence from app.modules.tasks.api.transition_audit import TaskPolicyLineage +from app.modules.checkers.api.external_policy import LockedExternalPostSubmitPolicy from app.modules.checkers.api.post_submit_catalogue import CompiledPostSubmitPolicy from uuid import UUID @@ -16,10 +17,15 @@ from app.modules.audit.repository import AuditRepository from app.modules.tasks.api import ( - AuditTaskEvidence, AuditTaskEvidencePage, AuditTaskEvidenceRequest, - TaskEvidenceCursor, TaskEvidenceInvalid, - ContributorTaskDetail, ContributorTaskDetailRequest, - ManagementTaskDetail, ManagementTaskDetailRequest, + AuditTaskEvidence, + AuditTaskEvidencePage, + AuditTaskEvidenceRequest, + TaskEvidenceCursor, + TaskEvidenceInvalid, + ContributorTaskDetail, + ContributorTaskDetailRequest, + ManagementTaskDetail, + ManagementTaskDetailRequest, ManagementTaskPage, ManagementTaskSummary, OperationalTaskPage, @@ -39,7 +45,8 @@ TaskSubmissionContextUnavailable, ) from app.modules.tasks.api.assignment_invalidation import ( - AssignmentInvalidationTarget, AssignmentInvalidationTargetsRequest, + AssignmentInvalidationTarget, + AssignmentInvalidationTargetsRequest, AssignmentInvalidationTargetsPage, ) from app.modules.tasks.models import ( @@ -54,9 +61,14 @@ def _unassigned_ready_task(): """Shared ready visibility for queue discovery and contributor detail.""" task = WorkstreamTask - active_assignment = select(TaskAssignment.id).where( - TaskAssignment.task_id == task.id, TaskAssignment.status == "active", - ).exists() + active_assignment = ( + select(TaskAssignment.id) + .where( + TaskAssignment.task_id == task.id, + TaskAssignment.status == "active", + ) + .exists() + ) return and_(task.status == "ready", task.assigned_to.is_(None), ~active_assignment) @@ -64,10 +76,20 @@ def _task_detail_columns(): """Fixed common detail projection; never select a task ORM entity.""" task = WorkstreamTask return ( - task.id.label("task_id"), task.project_id, task.title, task.description, - task.task_type, task.difficulty, task.skill_tags, task.estimated_time_minutes, - task.status, task.acceptance_criteria, task.rejection_criteria, - task.deadline_at, task.created_at, task.updated_at, + task.id.label("task_id"), + task.project_id, + task.title, + task.description, + task.task_type, + task.difficulty, + task.skill_tags, + task.estimated_time_minutes, + task.status, + task.acceptance_criteria, + task.rejection_criteria, + task.deadline_at, + task.created_at, + task.updated_at, ) @@ -127,20 +149,33 @@ def response_terms(value) -> TaskContributionTerms: return mapped async def read_assignment_invalidation_targets_page( - self, request: AssignmentInvalidationTargetsRequest, + self, + request: AssignmentInvalidationTargetsRequest, ) -> AssignmentInvalidationTargetsPage: """Nonlocking fixed projection; AUTH owns serialization and the root transaction.""" request = AssignmentInvalidationTargetsRequest.model_validate(request.model_dump()) assignment, task = TaskAssignment, WorkstreamTask - statement = select( - assignment.id, assignment.task_id, assignment.project_id, assignment.contributor_id, - ).join(task, and_(task.id == assignment.task_id, task.project_id == assignment.project_id)).where( - assignment.contributor_id == str(request.contributor_id), - assignment.status == "active", assignment.released_at.is_(None), - assignment.assigned_at <= request.invalidated_at, - task.status.in_(("claimed", "in_progress")), task.assigned_to == assignment.contributor_id, - assignment.submitter_contribution_policy_version_id == task.locked_contribution_policy_version_id, - ~select(Submission.id).where(Submission.task_id == task.id).exists(), + statement = ( + select( + assignment.id, + assignment.task_id, + assignment.project_id, + assignment.contributor_id, + ) + .join( + task, and_(task.id == assignment.task_id, task.project_id == assignment.project_id) + ) + .where( + assignment.contributor_id == str(request.contributor_id), + assignment.status == "active", + assignment.released_at.is_(None), + assignment.assigned_at <= request.invalidated_at, + task.status.in_(("claimed", "in_progress")), + task.assigned_to == assignment.contributor_id, + assignment.submitter_contribution_policy_version_id + == task.locked_contribution_policy_version_id, + ~select(Submission.id).where(Submission.task_id == task.id).exists(), + ) ) if request.project_id is not None: statement = statement.where(assignment.project_id == str(request.project_id)) @@ -149,11 +184,16 @@ async def read_assignment_invalidation_targets_page( with self._session.no_autoflush: rows = (await self._session.execute(statement.order_by(assignment.id).limit(101))).all() return AssignmentInvalidationTargetsPage( - items=tuple(AssignmentInvalidationTarget( - project_id=UUID(row.project_id), task_id=UUID(row.task_id), assignment_id=UUID(row.id), - contributor_id=UUID(row.contributor_id), - authority_invalidation_event_id=request.invalidation_event_id, - ) for row in rows[:100]), + items=tuple( + AssignmentInvalidationTarget( + project_id=UUID(row.project_id), + task_id=UUID(row.task_id), + assignment_id=UUID(row.id), + contributor_id=UUID(row.contributor_id), + authority_invalidation_event_id=request.invalidation_event_id, + ) + for row in rows[:100] + ), next_after=UUID(rows[99].id) if len(rows) > 100 else None, ) @@ -165,8 +205,14 @@ async def read_ready_tasks(self, request: TaskQueueRequest) -> ReadyTaskPage: """ task = WorkstreamTask statement = select( - task.id, task.project_id, task.title, task.task_type, task.difficulty, - task.skill_tags, task.estimated_time_minutes, task.created_at, + task.id, + task.project_id, + task.title, + task.task_type, + task.difficulty, + task.skill_tags, + task.estimated_time_minutes, + task.created_at, task.locked_contribution_policy_version_id, ).where(_unassigned_ready_task()) rows, continuation = await self._read_task_queue_rows(request, statement) @@ -176,9 +222,13 @@ async def read_ready_tasks(self, request: TaskQueueRequest) -> ReadyTaskPage: ) items = tuple( ReadyTaskSummary( - task_id=UUID(row.id), project_id=UUID(row.project_id), title=row.title, - task_type=row.task_type, difficulty=row.difficulty, - skill_tags=tuple(row.skill_tags), estimated_time_minutes=row.estimated_time_minutes, + task_id=UUID(row.id), + project_id=UUID(row.project_id), + title=row.title, + task_type=row.task_type, + difficulty=row.difficulty, + skill_tags=tuple(row.skill_tags), + estimated_time_minutes=row.estimated_time_minutes, created_at=row.created_at, compensation=compensation[row.locked_contribution_policy_version_id], ) @@ -189,33 +239,69 @@ async def read_ready_tasks(self, request: TaskQueueRequest) -> ReadyTaskPage: async def read_management_tasks(self, request: TaskQueueRequest) -> ManagementTaskPage: """Return all project tasks with fixed planning fields and no work content.""" task = WorkstreamTask - rows, cursor = await self._read_task_queue_rows(request, select( - task.id, task.project_id, task.title, task.task_type, task.difficulty, - task.skill_tags, task.estimated_time_minutes, task.status, task.deadline_at, - task.created_at, task.updated_at, - )) - items = tuple(ManagementTaskSummary( - task_id=UUID(row.id), project_id=UUID(row.project_id), title=row.title, - task_type=row.task_type, difficulty=row.difficulty, skill_tags=tuple(row.skill_tags), - estimated_time_minutes=row.estimated_time_minutes, status=row.status, - deadline_at=row.deadline_at, created_at=row.created_at, updated_at=row.updated_at, - ) for row in rows) + rows, cursor = await self._read_task_queue_rows( + request, + select( + task.id, + task.project_id, + task.title, + task.task_type, + task.difficulty, + task.skill_tags, + task.estimated_time_minutes, + task.status, + task.deadline_at, + task.created_at, + task.updated_at, + ), + ) + items = tuple( + ManagementTaskSummary( + task_id=UUID(row.id), + project_id=UUID(row.project_id), + title=row.title, + task_type=row.task_type, + difficulty=row.difficulty, + skill_tags=tuple(row.skill_tags), + estimated_time_minutes=row.estimated_time_minutes, + status=row.status, + deadline_at=row.deadline_at, + created_at=row.created_at, + updated_at=row.updated_at, + ) + for row in rows + ) return ManagementTaskPage(request.project_id, items, cursor) async def read_operational_tasks(self, request: TaskQueueRequest) -> OperationalTaskPage: """Select status-only columns, without loading private task content.""" task = WorkstreamTask - rows, cursor = await self._read_task_queue_rows(request, select( - task.id, task.project_id, task.status, task.created_at, task.updated_at, - )) - items = tuple(OperationalTaskSummary( - task_id=UUID(row.id), project_id=UUID(row.project_id), status=row.status, - created_at=row.created_at, updated_at=row.updated_at, - ) for row in rows) + rows, cursor = await self._read_task_queue_rows( + request, + select( + task.id, + task.project_id, + task.status, + task.created_at, + task.updated_at, + ), + ) + items = tuple( + OperationalTaskSummary( + task_id=UUID(row.id), + project_id=UUID(row.project_id), + status=row.status, + created_at=row.created_at, + updated_at=row.updated_at, + ) + for row in rows + ) return OperationalTaskPage(request.project_id, items, cursor) async def _read_task_queue_rows( - self, request: TaskQueueRequest, statement: Select, + self, + request: TaskQueueRequest, + statement: Select, ) -> tuple[Sequence[Row], TaskQueueCursor | None]: """Apply one exact project and live position before the bounded query. @@ -228,34 +314,49 @@ async def _read_task_queue_rows( statement = statement.where(task.project_id == str(request.project_id)) if request.after is not None: statement = statement.where( - tuple_(task.created_at, task.id) > tuple_( - request.after.created_at, request.after.task_id, + tuple_(task.created_at, task.id) + > tuple_( + request.after.created_at, + request.after.task_id, ), ) statement = statement.order_by(task.created_at, task.id).limit(request.limit + 1) with self._session.no_autoflush: rows = (await self._session.execute(statement)).all() continuation = ( - TaskQueueCursor(request.project_id, rows[request.limit - 1].created_at, UUID(rows[request.limit - 1].id)) - if len(rows) > request.limit else None + TaskQueueCursor( + request.project_id, + rows[request.limit - 1].created_at, + UUID(rows[request.limit - 1].id), + ) + if len(rows) > request.limit + else None ) - return rows[:request.limit], continuation + return rows[: request.limit], continuation - async def read_contributor_task_detail(self, request: ContributorTaskDetailRequest) -> ContributorTaskDetail | None: + async def read_contributor_task_detail( + self, request: ContributorTaskDetailRequest + ) -> ContributorTaskDetail | None: """Read visible work facts in one scoped query; caller supplies authority.""" if type(request) is not ContributorTaskDetailRequest: raise ValueError("task detail request is invalid") task, assignment = WorkstreamTask, TaskAssignment - own_assignment = select(assignment.id).where( - assignment.task_id == task.id, - assignment.project_id == task.project_id, - assignment.status == "active", - assignment.contributor_id == str(request.contributor_id), - ).exists() - statement = select(*_task_detail_columns()).where(or_( - _unassigned_ready_task(), - and_(task.assigned_to == str(request.contributor_id), own_assignment), - )) + own_assignment = ( + select(assignment.id) + .where( + assignment.task_id == task.id, + assignment.project_id == task.project_id, + assignment.status == "active", + assignment.contributor_id == str(request.contributor_id), + ) + .exists() + ) + statement = select(*_task_detail_columns()).where( + or_( + _unassigned_ready_task(), + and_(task.assigned_to == str(request.contributor_id), own_assignment), + ) + ) statement = statement.add_columns(task.locked_contribution_policy_version_id) values = await self._read_task_detail_values(request, statement) if values is None: @@ -269,36 +370,53 @@ async def contributor_task_visible(self, request: ContributorTaskDetailRequest) if type(request) is not ContributorTaskDetailRequest: raise ValueError("task detail request is invalid") task, assignment = WorkstreamTask, TaskAssignment - own_assignment = select(assignment.id).where( - assignment.task_id == task.id, - assignment.project_id == task.project_id, - assignment.status == "active", - assignment.contributor_id == str(request.contributor_id), - ).exists() - statement = select(task.id).where(or_( - _unassigned_ready_task(), - and_(task.assigned_to == str(request.contributor_id), own_assignment), - )) + own_assignment = ( + select(assignment.id) + .where( + assignment.task_id == task.id, + assignment.project_id == task.project_id, + assignment.status == "active", + assignment.contributor_id == str(request.contributor_id), + ) + .exists() + ) + statement = select(task.id).where( + or_( + _unassigned_ready_task(), + and_(task.assigned_to == str(request.contributor_id), own_assignment), + ) + ) statement = statement.where( - task.project_id == str(request.project_id), task.id == str(request.task_id), + task.project_id == str(request.project_id), + task.id == str(request.task_id), ) with self._session.no_autoflush: return await self._session.scalar(statement) is not None - async def read_management_task_detail(self, request: ManagementTaskDetailRequest) -> ManagementTaskDetail | None: + async def read_management_task_detail( + self, request: ManagementTaskDetailRequest + ) -> ManagementTaskDetail | None: """Read exact-project management facts without broad ORM loading.""" if type(request) is not ManagementTaskDetailRequest: raise ValueError("task detail request is invalid") task = WorkstreamTask statement = select( - *_task_detail_columns(), task.source_type, task.source_ref, task.source_payload_hash, - task.import_batch_id, task.external_task_id, task.created_by, task.assigned_to, + *_task_detail_columns(), + task.source_type, + task.source_ref, + task.source_payload_hash, + task.import_batch_id, + task.external_task_id, + task.created_by, + task.assigned_to, ) values = await self._read_task_detail_values(request, statement) return ManagementTaskDetail(**values) if values is not None else None async def _read_task_detail_values( - self, request: ContributorTaskDetailRequest | ManagementTaskDetailRequest, statement: Select, + self, + request: ContributorTaskDetailRequest | ManagementTaskDetailRequest, + statement: Select, ) -> dict | None: """Keep exact scope, one query and transaction behavior common to both reads.""" statement = statement.where( @@ -310,16 +428,21 @@ async def _read_task_detail_values( if row is None: return None return dict(row) | { - "task_id": UUID(row["task_id"]), "project_id": UUID(row["project_id"]), + "task_id": UUID(row["task_id"]), + "project_id": UUID(row["project_id"]), "skill_tags": tuple(row["skill_tags"]), } - async def read_audit_task_evidence(self, request: AuditTaskEvidenceRequest) -> AuditTaskEvidencePage | None: + async def read_audit_task_evidence( + self, request: AuditTaskEvidenceRequest + ) -> AuditTaskEvidencePage | None: """Map one AUDIT-owned scoped statement into immutable TASK evidence.""" if type(request) is not AuditTaskEvidenceRequest: raise ValueError("task evidence request is invalid") rows = await self._audit_repository.read_task_evidence_rows( - request.project_id, request.task_id, request.limit, + request.project_id, + request.task_id, + request.limit, request.after.created_at if request.after else None, request.after.event_id if request.after else None, ) @@ -327,10 +450,17 @@ async def read_audit_task_evidence(self, request: AuditTaskEvidenceRequest) -> A return None if rows[0].event_id is None: return AuditTaskEvidencePage(request.project_id, request.task_id, (), None) - items = tuple(self._task_evidence_item(row, request) for row in rows[:request.limit]) - cursor = TaskEvidenceCursor( - request.project_id, request.task_id, items[-1].created_at, items[-1].event_id, - ) if len(rows) > request.limit else None + items = tuple(self._task_evidence_item(row, request) for row in rows[: request.limit]) + cursor = ( + TaskEvidenceCursor( + request.project_id, + request.task_id, + items[-1].created_at, + items[-1].event_id, + ) + if len(rows) > request.limit + else None + ) return AuditTaskEvidencePage(request.project_id, request.task_id, items, cursor) @staticmethod @@ -338,7 +468,15 @@ def _task_evidence_item(row: Row, request: AuditTaskEvidenceRequest) -> AuditTas """Require exact transition references without exposing stored diagnostics.""" assignment_id = decision_id = None try: - if row.event_type in {"TaskCreated", "TaskScreened", "TaskReleased", "TaskClaimed", "TaskStarted", "TaskStartOverridden", "TaskAssignmentAuthorityRevoked"}: + if row.event_type in { + "TaskCreated", + "TaskScreened", + "TaskReleased", + "TaskClaimed", + "TaskStarted", + "TaskStartOverridden", + "TaskAssignmentAuthorityRevoked", + }: if ( UUID(row.reference_project_id) != request.project_id or UUID(row.reference_task_id) != request.task_id @@ -351,8 +489,14 @@ def _task_evidence_item(row: Row, request: AuditTaskEvidenceRequest) -> AuditTas assignment_id = UUID(row.assignment_id) decision_id = UUID(row.authorization_decision_id) return AuditTaskEvidence( - UUID(row.event_id), row.event_type, row.from_status, row.to_status, - row.actor_id, row.created_at, assignment_id, decision_id, + UUID(row.event_id), + row.event_type, + row.from_status, + row.to_status, + row.actor_id, + row.created_at, + assignment_id, + decision_id, ) except (TypeError, ValueError, AttributeError): raise TaskEvidenceInvalid("task audit evidence is invalid") from None @@ -389,18 +533,19 @@ async def get_task( statement = select(WorkstreamTask).where(WorkstreamTask.id == task_id) if for_update: statement = statement.with_for_update() - return await self._session.scalar( - statement.execution_options(populate_existing=True) - ) + return await self._session.scalar(statement.execution_options(populate_existing=True)) async def lock_project_task(self, project_id: UUID, task_id: UUID) -> WorkstreamTask | None: """Conceal foreign tasks before taking their lock or resolving policy custody.""" with self._session.no_autoflush: return await self._session.scalar( - select(WorkstreamTask).where( + select(WorkstreamTask) + .where( WorkstreamTask.project_id == str(project_id), WorkstreamTask.id == str(task_id), - ).with_for_update().execution_options(populate_existing=True) + ) + .with_for_update() + .execution_options(populate_existing=True) ) async def lock_accepted_assignment( @@ -413,11 +558,14 @@ async def lock_accepted_assignment( """Lock only the requested project/task assignment after its Task lock.""" with self._session.no_autoflush: return await self._session.scalar( - select(TaskAssignment).where( + select(TaskAssignment) + .where( TaskAssignment.id == str(assignment_id), TaskAssignment.task_id == str(task_id), TaskAssignment.project_id == str(project_id), - ).with_for_update().execution_options(populate_existing=True) + ) + .with_for_update() + .execution_options(populate_existing=True) ) async def read_routing_manifest( @@ -476,27 +624,32 @@ async def get_active_assignment( ) if for_update: statement = statement.with_for_update() - result = await self._session.execute( - statement.execution_options(populate_existing=True) - ) + result = await self._session.execute(statement.execution_options(populate_existing=True)) return result.scalar_one_or_none() async def lock_invalidation_assignment(self, target) -> TaskAssignment | None: """Lock the event's original assignment, never a replacement active claim.""" return await self._session.scalar( - select(TaskAssignment).where( + select(TaskAssignment) + .where( TaskAssignment.id == str(target.assignment_id), TaskAssignment.task_id == str(target.task_id), TaskAssignment.project_id == str(target.project_id), TaskAssignment.contributor_id == str(target.contributor_id), - ).with_for_update().execution_options(populate_existing=True) + ) + .with_for_update() + .execution_options(populate_existing=True) ) async def has_submission(self, task_id: UUID) -> bool: """Any retained Submission excludes ordinary pre-submit release.""" - return bool(await self._session.scalar(select( - select(Submission.id).where(Submission.task_id == str(task_id)).exists(), - ))) + return bool( + await self._session.scalar( + select( + select(Submission.id).where(Submission.task_id == str(task_id)).exists(), + ) + ) + ) async def lock_submission_context( self, @@ -532,7 +685,8 @@ async def lock_submission_context( or assignment is None or assignment.project_id != task.project_id or assignment.submitter_contribution_policy_version_id is None - or assignment.submitter_contribution_policy_version_id != task.locked_contribution_policy_version_id + or assignment.submitter_contribution_policy_version_id + != task.locked_contribution_policy_version_id or assignment.task_id != str(request.task_id) or assignment.contributor_id != contributor_id or assignment.status != "active" @@ -553,8 +707,7 @@ async def lock_submission_context( (task.status == "in_progress" and latest_submission is not None) or (task.status == "needs_revision" and latest_submission is None) or ( - latest_submission is not None - and latest_submission.contributor_id != contributor_id + latest_submission is not None and latest_submission.contributor_id != contributor_id ) ): raise TaskSubmissionContextUnavailable("task_submission_context_invalid") @@ -572,18 +725,32 @@ async def lock_submission_context( if any(value is None for value in locked_values): raise TaskSubmissionContextUnavailable("task_submission_context_invalid") try: - locked_policy = TaskPolicyLineage.model_validate_json(json.dumps({ - key: str(value) if isinstance(value, UUID) else value - for key in TaskPolicyLineage.model_fields - for value in (getattr(task, key),) - })) - post_policy = CompiledPostSubmitPolicy.model_validate_json( - json.dumps(task.locked_post_submit_checker_policy_body), + locked_policy = TaskPolicyLineage.model_validate_json( + json.dumps( + { + key: str(value) if isinstance(value, UUID) else value + for key in TaskPolicyLineage.model_fields + for value in (getattr(task, key),) + } + ) ) - if (post_policy.policy_hash != locked_policy.locked_post_submit_checker_policy_hash - or post_policy.project_id != UUID(task.project_id) - or post_policy.guide_version != locked_policy.locked_guide_version): - raise ValueError("task post-submit policy body differs from locked identity") + post_body = task.locked_post_submit_checker_policy_body + if post_body.get("schema_version") == "external_post_submit_policy.v1": + selected_post = LockedExternalPostSubmitPolicy.model_validate(post_body) + if ( + selected_post.policy_sha256 + != locked_policy.locked_post_submit_checker_policy_hash + ): + raise ValueError("task post-submit policy body differs from locked identity") + else: + historical_post = CompiledPostSubmitPolicy.model_validate(post_body) + if ( + historical_post.policy_hash + != locked_policy.locked_post_submit_checker_policy_hash + or historical_post.project_id != UUID(task.project_id) + or historical_post.guide_version != locked_policy.locked_guide_version + ): + raise ValueError("task post-submit policy body differs from locked identity") locked_project_context = TaskLockedProjectContextReferences( project_id=UUID(task.project_id), locked_contribution_policy_version_id=task.locked_contribution_policy_version_id, @@ -620,9 +787,7 @@ async def lock_submission_context( submitter_contribution_policy_version_id=assignment.submitter_contribution_policy_version_id, ) except (TypeError, ValueError) as exc: - raise TaskSubmissionContextUnavailable( - "task_submission_context_invalid" - ) from exc + raise TaskSubmissionContextUnavailable("task_submission_context_invalid") from exc async def add_submission(self, submission: Submission) -> Submission: """Persist a submission packet and its evidence items. @@ -638,7 +803,6 @@ async def add_submission(self, submission: Submission) -> Submission: await self._session.refresh(submission) return submission - async def get_latest_submission_for_task( self, task_id: str, @@ -670,7 +834,6 @@ async def get_latest_submission_for_task( result = await self._session.execute(statement) return result.scalar_one_or_none() - async def add_audit_event(self, event: AuditEvent) -> AuditEvent: """Persist an audit event. diff --git a/backend/app/modules/tasks/service.py b/backend/app/modules/tasks/service.py index 23df13499..2ad1f1bb0 100644 --- a/backend/app/modules/tasks/service.py +++ b/backend/app/modules/tasks/service.py @@ -3,7 +3,6 @@ from __future__ import annotations import json -from collections.abc import Callable from dataclasses import dataclass from typing import Any from uuid import UUID @@ -11,14 +10,17 @@ from sqlalchemy.ext.asyncio import AsyncSession from pydantic import ValidationError -from app.modules.checkers.api.pre_submit import ( - EffectivePreSubmissionPlanningPort, EffectivePreSubmissionPlanLineage, -) from app.modules.tasks.api import TaskSubmissionContextFacts -from app.modules.checkers.api.post_submit_catalogue import CompiledPostSubmitPolicy, PostSubmitCatalogue +from app.modules.checkers.api.external_policy import ( + LockedExternalCheckerPolicies, + LockedExternalPostSubmitPolicy, +) +from app.modules.checkers.api.post_submit_catalogue import CompiledPostSubmitPolicy from app.modules.projects.api.locked_policy import ( - ProjectLockedPolicyContextFacts, ProjectLockedPolicyContextPort, - ProjectLockedPolicyContextRequest, ProjectLockedPolicyContextUnavailable, + ProjectLockedPolicyContextFacts, + ProjectLockedPolicyContextPort, + ProjectLockedPolicyContextRequest, + ProjectLockedPolicyContextUnavailable, ) from app.modules.tasks.lifecycle import ( InvalidTaskTransition, @@ -135,8 +137,10 @@ class TaskService: """Coordinates task lifecycle rules, assignment, and audit writes.""" def __init__( - self, session: AsyncSession, *, project_contexts: ProjectLockedPolicyContextPort, - pre_submit_planner: EffectivePreSubmissionPlanningPort, post_submit_catalogue: Callable[[], PostSubmitCatalogue], + self, + session: AsyncSession, + *, + project_contexts: ProjectLockedPolicyContextPort, ) -> None: """Create a service instance bound to one database session. @@ -144,20 +148,25 @@ def __init__( session: Async SQLAlchemy session for the current request. """ self._project_contexts = project_contexts - self._pre_submit_planner = pre_submit_planner - self._post_submit_catalogue = post_submit_catalogue self._session = session self._repo = TaskRepository(session) async def read_management_task_submission_requirements( - self, project_id: UUID, task_id: UUID, + self, + project_id: UUID, + task_id: UUID, ) -> ManagementTaskSubmissionRequirements: """Read hidden management requirements in the caller's authorized transaction.""" task, context = await self._read_locked_context(project_id, task_id) - return ManagementTaskSubmissionRequirements(**self._submission_requirement_values(task, context)) + return ManagementTaskSubmissionRequirements( + **self._submission_requirement_values(task, context) + ) async def read_contributor_task_submission_requirements( - self, project_id: UUID, task_id: UUID, contributor_id: UUID, + self, + project_id: UUID, + task_id: UUID, + contributor_id: UUID, ) -> ContributorTaskSubmissionRequirements: """Lock TASK, conceal invisible work, then validate historical policy custody.""" request = ContributorTaskDetailRequest(project_id, task_id, contributor_id) @@ -179,14 +188,15 @@ async def _lock_scoped_task(self, project_id: UUID, task_id: UUID) -> Workstream return task async def _read_locked_context( - self, project_id: UUID, task_id: UUID, + self, + project_id: UUID, + task_id: UUID, ) -> tuple[WorkstreamTask, LockedTaskContext]: """Resolve historical PROJECTS custody only after the shared TASK lock.""" with self._session.no_autoflush: task = await self._lock_scoped_task(project_id, task_id) return task, await self._load_locked_task_context(task) - async def _load_active_policy_context(self, project_id: str) -> ProjectLockedPolicyContextFacts: """Resolve exact activated custody and verify both installed checker plans.""" try: @@ -197,39 +207,38 @@ async def _load_active_policy_context(self, project_id: str) -> ProjectLockedPol raise TaskProjectNotReady("active guide policy context is unavailable") from exc def _validate_installed_plans(self, facts: ProjectLockedPolicyContextFacts) -> None: - """Check deployment capability before new readiness, without executing checks.""" + """Require newly ready tasks to use the activated selected-image policy.""" try: - self._pre_submit_planner.compile_effective_plan( - lineage=EffectivePreSubmissionPlanLineage( - project_id=facts.project_id, guide_id=facts.guide_id, - guide_version=facts.guide_version, source_snapshot_id=facts.source_snapshot_id, - source_snapshot_hash=facts.source_snapshot_hash, - effective_policy_id=facts.effective_policy_id, - effective_policy_hash=facts.effective_policy_hash, - pre_submit_policy_id=facts.pre_submit_policy_id, - pre_submit_policy_bundle_hash=facts.pre_submit_policy_bundle_hash, - ), - effective_policy=json.loads(facts.effective_policy.value), - compiled_bundle=json.loads(facts.compiled_pre_submit_bundle.value), + policies = LockedExternalCheckerPolicies.model_validate_json( + facts.external_checker_policies.value ) - CompiledPostSubmitPolicy.model_validate_json( - facts.compiled_post_submit_policy.value, - ).validate_catalogue(self._post_submit_catalogue()) - except ValueError as exc: - raise TaskProjectNotReady("installed checkers cannot execute the locked policies") from exc + post = LockedExternalPostSubmitPolicy.model_validate_json( + facts.compiled_post_submit_policy.value + ) + if post != policies.post_submit: + raise ValueError("activated POST policy differs from selected images") + except (ValidationError, ValueError) as exc: + raise TaskProjectNotReady( + "installed checkers cannot execute the locked policies" + ) from exc async def _load_locked_task_context(self, task: WorkstreamTask) -> LockedTaskContext: """Resolve frozen custody without selecting current policy or deployment capabilities.""" missing = self._missing_locked_context_fields(task) if missing: - raise TaskLockedContextInvalid("task locked context is incomplete", {"missing_fields": missing}) + raise TaskLockedContextInvalid( + "task locked context is incomplete", {"missing_fields": missing} + ) try: facts = await self._project_contexts.lock_locked_policy_context( ProjectLockedPolicyContextRequest( - project_id=UUID(task.project_id), guide_version=task.locked_guide_version, + project_id=UUID(task.project_id), + guide_version=task.locked_guide_version, source_snapshot_id=UUID(task.locked_guide_source_snapshot_id), source_snapshot_hash=task.locked_guide_source_snapshot_hash, - effective_policy_id=UUID(task.locked_effective_project_submission_artifact_policy_id), + effective_policy_id=UUID( + task.locked_effective_project_submission_artifact_policy_id + ), effective_policy_hash=task.locked_effective_project_submission_artifact_policy_hash, pre_submit_policy_id=UUID(task.locked_pre_submit_checker_policy_id), pre_submit_policy_bundle_hash=task.locked_pre_submit_checker_bundle_hash, @@ -238,17 +247,44 @@ async def _load_locked_task_context(self, task: WorkstreamTask) -> LockedTaskCon expected = self._policy_stamps(facts) if any(getattr(task, name) != value for name, value in expected.items()): raise ValueError("task policy stamps differ from activation receipt") - parsed = CompiledPostSubmitPolicy.model_validate_json(facts.compiled_post_submit_policy.value) + parsed = self._parse_post_submit_policy_summary(facts) except (ProjectLockedPolicyContextUnavailable, ValueError, TypeError) as exc: raise TaskLockedContextInvalid("task locked policy custody is invalid") from exc return LockedTaskContext( facts=facts, - locked_post_submit_policy_body=PostSubmitPolicyBodySummary( - schema_version=parsed.schema_version, default_checkers=tuple(parsed.default_checkers), - required_checkers=tuple(parsed.required_checkers), warning_checkers=tuple(parsed.warning_checkers), - execution_checkers=tuple(parsed.execution_checkers), - blocking_severities=tuple(parsed.blocking_severities), - ), + locked_post_submit_policy_body=parsed, + ) + + @staticmethod + def _parse_post_submit_policy_summary( + facts: ProjectLockedPolicyContextFacts, + ) -> PostSubmitPolicyBodySummary: + """Decode selected policy bodies while retaining historical read custody.""" + body = json.loads(facts.compiled_post_submit_policy.value) + if body.get("schema_version") == "external_post_submit_policy.v1": + selected = LockedExternalPostSubmitPolicy.model_validate(body) + policies = LockedExternalCheckerPolicies.model_validate_json( + facts.external_checker_policies.value + ) + if selected != policies.post_submit: + raise ValueError("locked selected POST policy differs from approval") + checkers = tuple(item.registry.capability_id for item in selected.entries) + return PostSubmitPolicyBodySummary( + schema_version=selected.schema_version, + default_checkers=(), + required_checkers=checkers, + warning_checkers=(), + execution_checkers=checkers, + blocking_severities=("critical", "high"), + ) + historical = CompiledPostSubmitPolicy.model_validate(body) + return PostSubmitPolicyBodySummary( + schema_version=historical.schema_version, + default_checkers=tuple(historical.default_checkers), + required_checkers=tuple(historical.required_checkers), + warning_checkers=tuple(historical.warning_checkers), + execution_checkers=tuple(historical.execution_checkers), + blocking_severities=tuple(historical.blocking_severities), ) def _missing_locked_context_fields(self, task: WorkstreamTask) -> list[str]: @@ -256,10 +292,14 @@ def _missing_locked_context_fields(self, task: WorkstreamTask) -> list[str]: return [field for field in LOCKED_CONTEXT_REQUIRED_FIELDS if not getattr(task, field)] def _contributor_submission_requirements_response( - self, task: WorkstreamTask, context: LockedTaskContext, + self, + task: WorkstreamTask, + context: LockedTaskContext, ) -> ContributorTaskSubmissionRequirements: """Compose the contributor projection shared by hidden and retained reads.""" - return ContributorTaskSubmissionRequirements(**self._submission_requirement_values(task, context)) + return ContributorTaskSubmissionRequirements( + **self._submission_requirement_values(task, context) + ) def _submission_requirement_values( self, @@ -375,10 +415,14 @@ def _submission_requirement_values( ), packaging=self._packaging_requirements(policy), maximum_archive_entries=self._optional_policy_non_negative_int( - policy, "maximum_archive_entries", minimum=1, + policy, + "maximum_archive_entries", + minimum=1, ), maximum_archive_size_bytes=self._optional_policy_non_negative_int( - policy, "maximum_archive_size_bytes", minimum=1, + policy, + "maximum_archive_size_bytes", + minimum=1, ), ) @@ -453,7 +497,8 @@ def _optional_policy_non_negative_int( self, policy: dict[str, Any], field: str, - *, minimum: int = 0, + *, + minimum: int = 0, ) -> int | None: """Return an optional non-negative integer from the locked policy.""" value = policy.get(field) @@ -552,7 +597,9 @@ def _locked_context_reference_values(task: WorkstreamTask) -> dict[str, object]: "locked_guide_version": task.locked_guide_version, "locked_guide_source_snapshot_id": UUID(task.locked_guide_source_snapshot_id), "locked_guide_source_snapshot_hash": task.locked_guide_source_snapshot_hash, - "locked_effective_project_submission_artifact_policy_id": UUID(task.locked_effective_project_submission_artifact_policy_id), + "locked_effective_project_submission_artifact_policy_id": UUID( + task.locked_effective_project_submission_artifact_policy_id + ), "locked_effective_project_submission_artifact_policy_hash": task.locked_effective_project_submission_artifact_policy_hash, "locked_pre_submit_checker_policy_id": UUID(task.locked_pre_submit_checker_policy_id), "locked_pre_submit_checker_bundle_hash": task.locked_pre_submit_checker_bundle_hash, @@ -569,7 +616,9 @@ def _locked_context_reference_values(task: WorkstreamTask) -> dict[str, object]: } def _management_locked_context_response( - self, task: WorkstreamTask, context: LockedTaskContext, + self, + task: WorkstreamTask, + context: LockedTaskContext, ) -> ManagementTaskLockedContext: """Compose the sole management projection, shared by hidden and retained reads.""" return ManagementTaskLockedContext( @@ -628,7 +677,9 @@ def _policy_stamps(facts: ProjectLockedPolicyContextFacts) -> dict[str, object]: "locked_post_submit_checker_policy_id": str(command.target.policy_id), "locked_post_submit_checker_policy_version": facts.guide_version, "locked_post_submit_checker_policy_hash": command.target.policy_hash, - "locked_post_submit_checker_policy_body": json.loads(facts.compiled_post_submit_policy.value), + "locked_post_submit_checker_policy_body": json.loads( + facts.compiled_post_submit_policy.value + ), "locked_review_policy_id": str(command.review.policy_id), "locked_review_policy_generation": command.review.generation, "locked_review_policy_hash": command.review.policy_hash, @@ -637,14 +688,18 @@ def _policy_stamps(facts: ProjectLockedPolicyContextFacts) -> dict[str, object]: "locked_revision_policy_hash": command.revision.policy_hash, "locked_guide_source_snapshot_id": str(facts.source_snapshot_id), "locked_guide_source_snapshot_hash": facts.source_snapshot_hash, - "locked_effective_project_submission_artifact_policy_id": str(facts.effective_policy_id), + "locked_effective_project_submission_artifact_policy_id": str( + facts.effective_policy_id + ), "locked_effective_project_submission_artifact_policy_hash": facts.effective_policy_hash, "locked_pre_submit_checker_policy_id": str(facts.pre_submit_policy_id), "locked_pre_submit_checker_bundle_hash": facts.pre_submit_policy_bundle_hash, } @staticmethod - def validate_submission_policy_context(task_context: TaskSubmissionContextFacts, project_context: ProjectLockedPolicyContextFacts) -> None: + def validate_submission_policy_context( + task_context: TaskSubmissionContextFacts, project_context: ProjectLockedPolicyContextFacts + ) -> None: """Reconcile every locked TASK policy stamp with its exact PROJECTS receipt.""" from app.modules.tasks.api.transition_audit import TaskPolicyLineage @@ -658,7 +713,9 @@ def validate_submission_policy_context(task_context: TaskSubmissionContextFacts, if getattr(task_context.locked_policy, key) != value: raise ValueError("task submission policy differs") - def _stamp_locked_context(self, task: WorkstreamTask, facts: ProjectLockedPolicyContextFacts) -> None: + def _stamp_locked_context( + self, task: WorkstreamTask, facts: ProjectLockedPolicyContextFacts + ) -> None: """Copy the exact activated guide and contribution-policy context.""" for name, value in self._policy_stamps(facts).items(): setattr(task, name, value) @@ -676,7 +733,6 @@ def _ensure_locked_context(self, task: WorkstreamTask) -> None: if missing: raise TaskTransitionBlocked(f"task missing locked context: {', '.join(missing)}") - @staticmethod def task_response_for_authority(task: WorkstreamTask, *, can_manage: bool) -> TaskResponse: """Use an explicit authorized projection, never inferred token roles.""" @@ -696,7 +752,6 @@ def task_response_for_authority(task: WorkstreamTask, *, can_manage: bool) -> Ta response.locked_pre_submit_checker_bundle_hash = None return response - def _ensure_transition_allowed(self, from_status: str, to_status: str) -> None: """Map lifecycle transition validation into service-layer errors. diff --git a/backend/app/workers/post_policy.py b/backend/app/workers/post_policy.py index e3d935ee3..3cedc548e 100644 --- a/backend/app/workers/post_policy.py +++ b/backend/app/workers/post_policy.py @@ -7,11 +7,11 @@ from app.adapters.auth import post_policy_service_authority from app.adapters.projects import ( - dispatch_post_policy_derivation_after_commit, pending_post_policy_approvals, + dispatch_post_policy_derivation_after_commit, + pending_post_policy_approvals, project_post_policy_delivery_port, ) from app.db.session import get_database_url -from app.modules.checkers.api.post_submit_catalogue import current_post_submit_catalogue from app.modules.projects.api.post_policy import PostPolicyDelivery from app.workers.async_runner import run_async_task from app.workers.celery_app import celery_app @@ -21,21 +21,27 @@ @celery_app.task( - name="workstream.project_setup.derive_post_policy", bind=True, - acks_late=True, reject_on_worker_lost=True, + name="workstream.project_setup.derive_post_policy", + bind=True, + acks_late=True, + reject_on_worker_lost=True, ) def derive_post_policy(self, approval_operation_id): """Fence the actual broker task identity and retry bounded infrastructure failures.""" try: delivery = PostPolicyDelivery( - approval_operation_id=approval_operation_id, task_id=self.request.id, + approval_operation_id=approval_operation_id, + task_id=self.request.id, ) except (TypeError, ValueError): return {"status": "delivery_rejected"} outcome = run_async_task(lambda: _derive(delivery)) if outcome["status"] == "derivation_unavailable": - raise self.retry(exc=RuntimeError("post-policy derivation unavailable"), - countdown=30 * (2 ** self.request.retries), max_retries=3) + raise self.retry( + exc=RuntimeError("post-policy derivation unavailable"), + countdown=30 * (2**self.request.retries), + max_retries=3, + ) return outcome @@ -45,7 +51,7 @@ async def _derive(delivery: PostPolicyDelivery) -> dict: try: return await project_post_policy_delivery_port( async_sessionmaker(engine, expire_on_commit=False), - authority=post_policy_service_authority, catalogue=current_post_submit_catalogue(), + authority=post_policy_service_authority, ).run(delivery) except Exception: logger.warning("post-policy derivation unavailable") @@ -68,8 +74,11 @@ def scan_post_policy_approvals(self, after=None): return result except Exception as exc: logger.warning("post-policy recovery scan unavailable") - raise self.retry(exc=RuntimeError("post-policy scan unavailable"), - countdown=30 * (2 ** self.request.retries), max_retries=3) from exc + raise self.retry( + exc=RuntimeError("post-policy scan unavailable"), + countdown=30 * (2**self.request.retries), + max_retries=3, + ) from exc async def _scan(after: UUID | None) -> dict: @@ -78,13 +87,18 @@ async def _scan(after: UUID | None) -> dict: try: candidates = await pending_post_policy_approvals( async_sessionmaker(engine, expire_on_commit=False), - after=after, limit=POST_POLICY_SCAN_PAGE_SIZE, + after=after, + limit=POST_POLICY_SCAN_PAGE_SIZE, ) published = 0 for approval_id in candidates: published += bool(await dispatch_post_policy_derivation_after_commit(approval_id)) - return {"selected": len(candidates), "published": published, - "next_after": str(candidates[-1]) - if len(candidates) == POST_POLICY_SCAN_PAGE_SIZE else None} + return { + "selected": len(candidates), + "published": published, + "next_after": str(candidates[-1]) + if len(candidates) == POST_POLICY_SCAN_PAGE_SIZE + else None, + } finally: await engine.dispose() diff --git a/backend/app/workers/project_setup.py b/backend/app/workers/project_setup.py index 2a25d59ab..7ce0dda5d 100644 --- a/backend/app/workers/project_setup.py +++ b/backend/app/workers/project_setup.py @@ -18,9 +18,8 @@ setup_finalization_authorization, ) from app.adapters.projects import project_guide_compilation_delivery_port -from app.adapters.checkers import project_guide_pre_submission_catalogue +from app.adapters.checkers import external_checker_capability_projection from app.adapters.artifacts import guide_document_manifest_port, guide_document_access_runtime -from app.modules.checkers.api.post_submit_catalogue import current_post_submit_catalogue from app.modules.projects.api.guide_compilation import ( ProjectGuideCompilationDelivery, ProjectGuideCompilationDeliveryError, @@ -32,14 +31,15 @@ logger = get_task_logger(__name__) -def _coordinator(session_factory): +async def _coordinator(session_factory): """Compose owner ports and the sole registered runtime at the worker boundary.""" + async with session_factory() as session, session.begin(): + capabilities = await external_checker_capability_projection(session) return project_guide_compilation_delivery_port( session_factory, material_factory=guide_document_manifest_port, document_access_factory=partial(guide_document_access_runtime, session_factory), - pre_capabilities=project_guide_pre_submission_catalogue(), - post_capabilities=current_post_submit_catalogue(), + checker_capabilities=capabilities, request_authority=guide_compilation_request_authority, execution_authority=guide_compilation_execution_authority, configuration_factory=lambda: project_guide_runtime_configuration(get_settings()), @@ -84,7 +84,8 @@ async def _run_project_guide_compilation(delivery: ProjectGuideCompilationDelive """Own the worker connection lifecycle and return only bounded failures.""" engine = create_async_engine(get_database_url(), pool_pre_ping=True) try: - return await _coordinator(async_sessionmaker(engine, expire_on_commit=False)).run(delivery) + coordinator = await _coordinator(async_sessionmaker(engine, expire_on_commit=False)) + return await coordinator.run(delivery) except ProjectGuideCompilationDeliveryError: return {"status": "delivery_rejected", "error_code": "stale_compilation_delivery"} except Exception: diff --git a/backend/tests/checkers/execution/support.py b/backend/tests/checkers/execution/support.py index dc8f5d8d4..8d19c5881 100644 --- a/backend/tests/checkers/execution/support.py +++ b/backend/tests/checkers/execution/support.py @@ -20,35 +20,48 @@ def forbidden_post_submission(): async def provision_post_submit_service(factory, identity=ServiceIdentity.CHECKER_POST_SUBMIT): """Create fixture principal once without resetting an existing lifecycle decision.""" async with factory() as session, session.begin(): - existing = await session.scalar(select(ActorProfile).where( - ActorProfile.service_identity == identity.value, - )) + existing = await session.scalar( + select(ActorProfile).where( + ActorProfile.service_identity == identity.value, + ) + ) if existing is not None: return existing.id actor_id, link_id = str(new_record_id()), str(new_record_id()) - session.add(ActorProfile( - id=actor_id, actor_kind="service", status="active", - provisioning_method="manual_service_provisioning", - service_identity=identity.value, created_by="checker-test", - )) - session.add(ActorIdentityLink( - id=link_id, actor_profile_id=actor_id, issuer="flow-test", subject=actor_id, - subject_kind="service", status="active", linked_by="checker-test", - )) + session.add( + ActorProfile( + id=actor_id, + actor_kind="service", + status="active", + provisioning_method="manual_service_provisioning", + service_identity=identity.value, + created_by="checker-test", + ) + ) + session.add( + ActorIdentityLink( + id=link_id, + actor_profile_id=actor_id, + issuer="flow-test", + subject=actor_id, + subject_kind="service", + status="active", + linked_by="checker-test", + ) + ) return actor_id -def live_executor(h, *, registry=None, outbox=None): +def live_executor(h, *, outbox=None): from app.adapters.auth import post_submit_execution_authority from app.adapters.outbox import outbox_append from app.modules.checkers.execution import PostSubmissionExecutor - from app.modules.checkers.runner import default_checker_registry return PostSubmissionExecutor( - sessions=h.factory, materialization=h.service, + sessions=h.factory, + materialization=h.service, execute_authority=post_submit_execution_authority, finalize_authority=post_submit_execution_authority, - registry=registry if registry is not None else default_checker_registry(), outbox=outbox if outbox is not None else outbox_append, ) @@ -75,17 +88,24 @@ async def material_execution(h): async def service_link_state(factory, identity, *, active): """Change real persisted service lifecycle in an independent transaction.""" from sqlalchemy import text + async with factory() as session, session.begin(): if active: - await session.execute(text( - "update actor_identity_links set status='active', revoked_by=null, revoked_at=null, " - "revoked_reason=null, reactivated_by='test', reactivated_at=clock_timestamp(), " - "reactivation_reason='test' where actor_profile_id=" - "(select id from actor_profiles where service_identity=:identity)" - ), {"identity": identity.value}) + await session.execute( + text( + "update actor_identity_links set status='active', revoked_by=null, revoked_at=null, " + "revoked_reason=null, reactivated_by='test', reactivated_at=clock_timestamp(), " + "reactivation_reason='test' where actor_profile_id=" + "(select id from actor_profiles where service_identity=:identity)" + ), + {"identity": identity.value}, + ) else: - await session.execute(text( - "update actor_identity_links set status='revoked', revoked_by='test', " - "revoked_at=clock_timestamp(), revoked_reason='test' where actor_profile_id=" - "(select id from actor_profiles where service_identity=:identity)" - ), {"identity": identity.value}) + await session.execute( + text( + "update actor_identity_links set status='revoked', revoked_by='test', " + "revoked_at=clock_timestamp(), revoked_reason='test' where actor_profile_id=" + "(select id from actor_profiles where service_identity=:identity)" + ), + {"identity": identity.value}, + ) diff --git a/backend/tests/checkers/execution/test_execution.py b/backend/tests/checkers/execution/test_execution.py index ef8d8b6ea..2c5145a57 100644 --- a/backend/tests/checkers/execution/test_execution.py +++ b/backend/tests/checkers/execution/test_execution.py @@ -75,8 +75,16 @@ async def observe_receipt(*args, **kwargs): run = await session.get(CheckerRun, str(result.attempt_id)) assert [str(receipt) for receipt in receipts] == [run.input_materialization_evidence_id] assert run.input_materialization_evidence_id is not None - assert len({run.input_materialization_evidence_id, run.execute_evidence_id, - run.finalize_evidence_id}) == 3 + assert ( + len( + { + run.input_materialization_evidence_id, + run.execute_evidence_id, + run.finalize_evidence_id, + } + ) + == 3 + ) assert run.material_custody == { "submission_id": str(h.created.submission_id), "submission_version": h.created.submission_version, @@ -110,20 +118,20 @@ async def observe_receipt(*args, **kwargs): assert list((h.scratch / "workspaces").iterdir()) == [] -async def test_infrastructure_failure_is_terminal(tmp_path, isolated_database_env, autoflush_clock): - from app.modules.checkers.runner import CheckerRegistry - +async def test_unresolved_legacy_request_is_refused_without_leasing_or_materialization( + tmp_path, isolated_database_env, autoflush_clock +): async with material_fixture(tmp_path, isolated_database_env) as h: await reserve(h) - executor = live_executor(h, registry=CheckerRegistry()) - failed = await executor.evaluate_post_submission(h.request) - assert failed.outcome == "infrastructure_failed" - assert failed.infrastructure_failure_code == "implementation_unavailable" - assert failed.member_results == () - opens = len(h.store.opens) - assert await executor.evaluate_post_submission(h.request) == failed - assert len(h.store.opens) == opens == 1 + executor = live_executor(h) + with pytest.raises(CheckerExecutionUnavailable, match="checker_legacy_execution_retired"): + await executor.evaluate_post_submission(h.request) + assert h.store.opens == [] async with h.factory() as session, session.begin(): + run = await session.scalar(select(CheckerRun)) + assert run.status == "queued" + assert run.worker_lease_id is None + assert run.execute_evidence_id is None assert ( await session.scalar( select(func.count()) @@ -132,8 +140,6 @@ async def test_infrastructure_failure_is_terminal(tmp_path, isolated_database_en ) == 0 ) - with pytest.raises(CheckerExecutionUnavailable, match="current_result"): - await evaluation_coordinator(session).read_current_result(h.request) @pytest.mark.parametrize("substitution", ["prepared", "receipt"]) @@ -281,11 +287,19 @@ async def append(self, value): assert await self.session.scalar( select(func.count()).select_from(CheckerResult) ) == len(h.request.policy.entries) - assert await self.session.scalar(select(func.count()).select_from(AuditEvent)) == before[1] + 1 - assert await self.session.scalar(select(AuditEvent.action_id).where( - AuditEvent.action_id == "checker.post_submit.finalize", - AuditEvent.resource_id == str(lease.reservation.attempt_id), - )) == "checker.post_submit.finalize" + assert ( + await self.session.scalar(select(func.count()).select_from(AuditEvent)) + == before[1] + 1 + ) + assert ( + await self.session.scalar( + select(AuditEvent.action_id).where( + AuditEvent.action_id == "checker.post_submit.finalize", + AuditEvent.resource_id == str(lease.reservation.attempt_id), + ) + ) + == "checker.post_submit.finalize" + ) return await outbox_append(self.session).append(value) executor._outbox = ObservingAppend @@ -375,12 +389,16 @@ async def retain_finalization(facts): assert len(h.store.opens) == opened async with h.factory() as session, session.begin(): run = await session.get(CheckerRun, str(reservation.attempt_id)) - assert run.status == "infrastructure_failed" and run.failure_code == "material_unavailable" + assert ( + run.status == "infrastructure_failed" and run.failure_code == "material_unavailable" + ) assert run.material_custody is None and run.completion_event_id is None assert run.finalize_evidence_id is not None assert run.routing_recommendation == "not_evaluated" assert await session.scalar(select(func.count()).select_from(CheckerResult)) == 0 - assert list(await session.scalars(select(OutboxEvent.event_id))) == [h.created.evaluation_event_id] + assert list(await session.scalars(select(OutboxEvent.event_id))) == [ + h.created.evaluation_event_id + ] with pytest.raises(CheckerExecutionUnavailable, match="current_result"): await evaluation_coordinator(session).read_current_result(h.request) @@ -392,17 +410,22 @@ async def test_nonrecordable_material_failure_leaves_attempt_recoverable( import asyncio from app.modules.artifacts.preparation import ArtifactScratchIntegrityError from app.modules.checkers.api.materialization import ( - PostSubmissionMaterializationUnavailable, PostSubmissionMaterializationFailure, + PostSubmissionMaterializationUnavailable, + PostSubmissionMaterializationFailure, ) async with material_fixture(tmp_path, isolated_database_env) as h: if failure == "cleanup": from tests.checkers.post_submit.support import change_request - h.request = change_request(h.request, evaluation_request_id=new_record_id(), - evaluation_generation=2, structural_input=h.request.structural_input.model_copy( - update={"manifest": ()}, - )) + h.request = change_request( + h.request, + evaluation_request_id=new_record_id(), + evaluation_generation=2, + structural_input=h.request.structural_input.model_copy( + update={"manifest": ()}, + ), + ) reservation = await reserve(h) executor = live_executor(h) if failure == "authority": @@ -449,4 +472,6 @@ async def fail_prepare(*args, **kwargs): assert run.status == "running" and run.result_json is None assert run.finalize_evidence_id is None and run.completion_event_id is None assert await session.scalar(select(func.count()).select_from(CheckerResult)) == 0 - assert list(await session.scalars(select(OutboxEvent.event_id))) == [h.created.evaluation_event_id] + assert list(await session.scalars(select(OutboxEvent.event_id))) == [ + h.created.evaluation_event_id + ] diff --git a/backend/tests/checkers/external/support.py b/backend/tests/checkers/external/support.py index 5d7c7a331..cade082db 100644 --- a/backend/tests/checkers/external/support.py +++ b/backend/tests/checkers/external/support.py @@ -10,6 +10,8 @@ POST_SUBMIT_INPUT_SCHEMA_ID, PRE_SUBMIT_INPUT_SCHEMA_ID, RESULT_SCHEMA_ID, + ExternalCheckerCapabilityDefinition, + ExternalCheckerCapabilityProjection, ExternalCheckerRegistryEntry, ExternalCheckerRegistrySpec, ExternalCheckerResourceLimits, @@ -21,6 +23,10 @@ external_checker_json_hash, make_external_checker_registration_request, ) +from app.modules.checkers.api.default_checker import ( + WORKSTREAM_DEFAULT_CHECKER_ID, + WORKSTREAM_DEFAULT_CHECKER_VERSION, +) SHA = "sha256:" + "a" * 64 @@ -51,9 +57,7 @@ def registry_spec( image_digest=SHA, configuration_schema=schema("acme.safe_archive.configuration"), input_schema=schema( - PRE_SUBMIT_INPUT_SCHEMA_ID - if phase == "pre_submit" - else POST_SUBMIT_INPUT_SCHEMA_ID, + PRE_SUBMIT_INPUT_SCHEMA_ID if phase == "pre_submit" else POST_SUBMIT_INPUT_SCHEMA_ID, required=("task_version",), ), output_schema=schema(RESULT_SCHEMA_ID), @@ -81,6 +85,43 @@ def registry_entry( ) +def capability_projection( + *entries: ExternalCheckerRegistryEntry, +) -> ExternalCheckerCapabilityProjection: + """Build the one code-owned default plus exact immutable registry entries.""" + definitions = tuple( + sorted( + ( + ExternalCheckerCapabilityDefinition( + capability_id=WORKSTREAM_DEFAULT_CHECKER_ID, + capability_version=WORKSTREAM_DEFAULT_CHECKER_VERSION, + phase="pre_submit", + selectable=False, + ), + *( + ExternalCheckerCapabilityDefinition( + capability_id=entry.capability_id, + capability_version=entry.capability_version, + phase=entry.phase, + selectable=True, + registry_entry=entry, + ) + for entry in entries + ), + ), + key=lambda item: (item.phase, item.capability_id, item.capability_version), + ) + ) + body = { + "schema_version": "external_checker_capabilities.v1", + "definitions": [item.model_dump(mode="json") for item in definitions], + } + return ExternalCheckerCapabilityProjection( + definitions=definitions, + manifest_sha256=external_checker_json_hash(body), + ) + + def registration_request(phase: str = "pre_submit", *, actor_profile_id=None): return make_external_checker_registration_request( actor_profile_id=actor_profile_id or uuid4(), diff --git a/backend/tests/projects/guide_compilation/helpers.py b/backend/tests/projects/guide_compilation/helpers.py index 7e49458b7..435640897 100644 --- a/backend/tests/projects/guide_compilation/helpers.py +++ b/backend/tests/projects/guide_compilation/helpers.py @@ -2,8 +2,6 @@ from __future__ import annotations -from app.modules.checkers.catalogue import project_guide_pre_submission_capabilities - from dataclasses import replace import hashlib import json @@ -19,14 +17,20 @@ from app.db import models as _all_models # noqa: F401 from app.modules.artifacts.models import ( - ArtifactContent, ArtifactReplica, ArtifactStorageNamespace, ArtifactPutAttempt, + ArtifactContent, + ArtifactReplica, + ArtifactStorageNamespace, + ArtifactPutAttempt, ArtifactOperationReceipt, ) from app.modules.projects.models import GuideSourceArtifactIngest from app.modules.projects.api.guide_documents import GuideDocumentManifest, GuideDocumentVersion from app.interfaces.project_agents import ( - CompilationFinding, GuideEvidenceRef, ProjectGuideCompilationContext, - ProjectGuideCompilationResult, SubmissionArtifactPolicyProposal, + CompilationFinding, + GuideEvidenceRef, + ProjectGuideCompilationContext, + ProjectGuideCompilationResult, + SubmissionArtifactPolicyProposal, ) from app.modules.authorization.api import ( ActorIdentityFacts, @@ -34,14 +38,11 @@ ProjectGuideCompilationExecutePersistFacts, project_guide_compilation_execute_resource_digest, ) -from app.modules.checkers.catalogue import ( - build_pre_submission_checker_catalogue, -) from app.modules.projects.guide_compilation.contracts import ( CompilationAttemptIdentity, accepted_compilation_result, ) -from app.modules.checkers.api.post_submit_catalogue import current_post_submit_catalogue +from tests.checkers.external.support import capability_projection from app.modules.projects.api.setup_identity import project_guide_compilation_task_id from app.core.hashing import canonical_json_hash @@ -49,7 +50,10 @@ from app.modules.projects.api.task_examples import task_examples_hash, validate_task_examples TASK_EXAMPLES = validate_task_examples([{"content": "Review a claim using the project guide."}]) -TASK_EXAMPLE_MANIFEST = {"task_examples_hash": task_examples_hash(TASK_EXAMPLES), "task_examples_count": len(TASK_EXAMPLES)} +TASK_EXAMPLE_MANIFEST = { + "task_examples_hash": task_examples_hash(TASK_EXAMPLES), + "task_examples_count": len(TASK_EXAMPLES), +} SHA256 = canonical_json_hash(TASK_EXAMPLE_MANIFEST) SOURCE_ITEM_ID = new_record_id() DOCUMENT_VERSION_ID = new_record_id() @@ -98,18 +102,33 @@ def runtime_configuration(): ) -def context(values: dict[str, UUID], *, generation: int = 1, guide_version="v1") -> ProjectGuideCompilationContext: +def context( + values: dict[str, UUID], *, generation: int = 1, guide_version="v1" +) -> ProjectGuideCompilationContext: """Build one exact committed-original metadata context.""" material = GuideDocumentManifest( - project_id=values["project"], guide_id=values["guide"], guide_version=guide_version, - source_snapshot_id=values["snapshot"], source_snapshot_hash=SHA256, - setup_run_id=values[f"setup_{generation}"], setup_generation=generation, - documents=(GuideDocumentVersion( - source_item_id=SOURCE_ITEM_ID, ingest_id=DOCUMENT_VERSION_ID, item_order=0, - put_attempt_id=PUT_ATTEMPT_ID, content_id=CONTENT_ID, replica_id=REPLICA_ID, - storage_namespace_id="primary", namespace_fingerprint=SOURCE_SHA256, - sha256=SOURCE_SHA256, byte_count=len(SOURCE_BYTES), media_type="application/pdf", - ),), + project_id=values["project"], + guide_id=values["guide"], + guide_version=guide_version, + source_snapshot_id=values["snapshot"], + source_snapshot_hash=SHA256, + setup_run_id=values[f"setup_{generation}"], + setup_generation=generation, + documents=( + GuideDocumentVersion( + source_item_id=SOURCE_ITEM_ID, + ingest_id=DOCUMENT_VERSION_ID, + item_order=0, + put_attempt_id=PUT_ATTEMPT_ID, + content_id=CONTENT_ID, + replica_id=REPLICA_ID, + storage_namespace_id="primary", + namespace_fingerprint=SOURCE_SHA256, + sha256=SOURCE_SHA256, + byte_count=len(SOURCE_BYTES), + media_type="application/pdf", + ), + ), ) return ProjectGuideCompilationContext( task_examples=({"content": "Review a claim using the project guide."},), @@ -120,10 +139,7 @@ def context(values: dict[str, UUID], *, generation: int = 1, guide_version="v1") instruction_version="v1", agent_identity="project-guide-compilation-agent-v1", agent_version="v1", - pre_submission_capabilities=project_guide_pre_submission_capabilities( - build_pre_submission_checker_catalogue() - ), - post_submission_capabilities=current_post_submit_catalogue(), + checker_capabilities=capability_projection(), ) @@ -132,9 +148,18 @@ def result() -> ProjectGuideCompilationResult: return ProjectGuideCompilationResult( status="draft_ready", findings=( - CompilationFinding(severity="info", code="guide.ready", message="Guide is complete.", - evidence_refs=(GuideEvidenceRef(source_item_id=SOURCE_ITEM_ID, - document_version_id=DOCUMENT_VERSION_ID, sha256=SOURCE_SHA256),)), + CompilationFinding( + severity="info", + code="guide.ready", + message="Guide is complete.", + evidence_refs=( + GuideEvidenceRef( + source_item_id=SOURCE_ITEM_ID, + document_version_id=DOCUMENT_VERSION_ID, + sha256=SOURCE_SHA256, + ), + ), + ), ), submission_artifact_policy=SubmissionArtifactPolicyProposal( maximum_file_size_bytes=1_000, @@ -326,53 +351,103 @@ async def _seed_snapshot_item(engine: AsyncEngine, values: dict[str, UUID]) -> N ) -async def _seed_artifact_custody(session: AsyncSession, values: dict[str, UUID], namespace=None) -> None: +async def _seed_artifact_custody( + session: AsyncSession, values: dict[str, UUID], namespace=None +) -> None: from datetime import datetime, timezone + namespace_row = ArtifactStorageNamespace( - id="primary", backend=namespace.backend if namespace else "local", + id="primary", + backend=namespace.backend if namespace else "local", adapter=namespace.adapter if namespace else "local", provider_profile=namespace.provider_profile if namespace else "test", - namespace_descriptor=namespace.namespace_descriptor if namespace else {"root": "guide-compilation-fixture"}, + namespace_descriptor=namespace.namespace_descriptor + if namespace + else {"root": "guide-compilation-fixture"}, namespace_fingerprint=namespace.namespace_fingerprint if namespace else SOURCE_SHA256, ) - session.add_all([ - namespace_row, - ArtifactContent(id=str(CONTENT_ID), sha256=SOURCE_SHA256, - byte_count=len(SOURCE_BYTES), media_type="application/pdf", - normalized_display_name="guide.pdf"), - GuideSourceArtifactIngest(id=str(DOCUMENT_VERSION_ID), source_item_id=str(SOURCE_ITEM_ID), - actor_profile_id=str(values["actor"]), sha256=SOURCE_SHA256, - byte_count=len(SOURCE_BYTES), media_type="application/pdf"), - ]) + session.add_all( + [ + namespace_row, + ArtifactContent( + id=str(CONTENT_ID), + sha256=SOURCE_SHA256, + byte_count=len(SOURCE_BYTES), + media_type="application/pdf", + normalized_display_name="guide.pdf", + ), + GuideSourceArtifactIngest( + id=str(DOCUMENT_VERSION_ID), + source_item_id=str(SOURCE_ITEM_ID), + actor_profile_id=str(values["actor"]), + sha256=SOURCE_SHA256, + byte_count=len(SOURCE_BYTES), + media_type="application/pdf", + ), + ] + ) await session.flush() - replica = ArtifactReplica(id=str(REPLICA_ID), content_id=str(CONTENT_ID), - storage_namespace_id="primary", namespace_fingerprint=namespace_row.namespace_fingerprint, - adapter=namespace_row.adapter, provider_profile=namespace_row.provider_profile, provider_object_ref=f"fixtures/{CONTENT_ID}", - verification_state="pending", availability_state="unknown", integrity_state="unknown") + replica = ArtifactReplica( + id=str(REPLICA_ID), + content_id=str(CONTENT_ID), + storage_namespace_id="primary", + namespace_fingerprint=namespace_row.namespace_fingerprint, + adapter=namespace_row.adapter, + provider_profile=namespace_row.provider_profile, + provider_object_ref=f"fixtures/{CONTENT_ID}", + verification_state="pending", + availability_state="unknown", + integrity_state="unknown", + ) session.add(replica) await session.flush() - put = ArtifactPutAttempt(id=str(PUT_ATTEMPT_ID), producer_request_type="guide", - producer_type="actor_profile", producer_ref=str(values["actor"]), - project_id=str(values["project"]), guide_source_item_id=str(SOURCE_ITEM_ID), - sha256=SOURCE_SHA256, byte_count=len(SOURCE_BYTES), media_type="application/pdf", - storage_namespace_id="primary", namespace_fingerprint=namespace_row.namespace_fingerprint, + put = ArtifactPutAttempt( + id=str(PUT_ATTEMPT_ID), + producer_request_type="guide", + producer_type="actor_profile", + producer_ref=str(values["actor"]), + project_id=str(values["project"]), + guide_source_item_id=str(SOURCE_ITEM_ID), + sha256=SOURCE_SHA256, + byte_count=len(SOURCE_BYTES), + media_type="application/pdf", + storage_namespace_id="primary", + namespace_fingerprint=namespace_row.namespace_fingerprint, canonical_target=f"sha256/{SOURCE_SHA256[7:9]}/{SOURCE_SHA256[9:]}", - operation_identity=SOURCE_SHA256, request_digest=SOURCE_SHA256, - status="object_confirmed", terminal_result_code="document_stored", - replica_id=str(REPLICA_ID), terminal_at=datetime.now(timezone.utc)) + operation_identity=SOURCE_SHA256, + request_digest=SOURCE_SHA256, + status="object_confirmed", + terminal_result_code="document_stored", + replica_id=str(REPLICA_ID), + terminal_at=datetime.now(timezone.utc), + ) session.add(put) await session.flush() - session.add(ArtifactOperationReceipt(id=str(RECEIPT_ID), contract_version=2, - put_attempt_id=put.id, guide_source_item_id=str(SOURCE_ITEM_ID), - replica_id=replica.id, operation="put", idempotency_key=put.operation_identity, - request_digest=put.request_digest, provider_object_ref=replica.provider_object_ref, - replayed=False, outcome="document_stored", attempt_number=1, - correlation_id=str(uuid4()), details=[])) + session.add( + ArtifactOperationReceipt( + id=str(RECEIPT_ID), + contract_version=2, + put_attempt_id=put.id, + guide_source_item_id=str(SOURCE_ITEM_ID), + replica_id=replica.id, + operation="put", + idempotency_key=put.operation_identity, + request_digest=put.request_digest, + provider_object_ref=replica.provider_object_ref, + replayed=False, + outcome="document_stored", + attempt_number=1, + correlation_id=str(uuid4()), + details=[], + ) + ) await session.flush() put.receipt_id = str(RECEIPT_ID) -async def seed_database(database_url: str, *, generations: int = 1, guide_version="v1", namespace=None) -> dict[str, UUID]: +async def seed_database( + database_url: str, *, generations: int = 1, guide_version="v1", namespace=None +) -> dict[str, UUID]: """Seed only canonical parent rows needed by hidden persistence tests.""" values = ids() engine = create_async_engine(database_url) diff --git a/backend/tests/projects/guide_compilation/test_context_builder.py b/backend/tests/projects/guide_compilation/test_context_builder.py index 5c6c8541d..00a18ee59 100644 --- a/backend/tests/projects/guide_compilation/test_context_builder.py +++ b/backend/tests/projects/guide_compilation/test_context_builder.py @@ -2,8 +2,6 @@ from __future__ import annotations -from app.modules.checkers.catalogue import project_guide_pre_submission_capabilities - from tests.projects.guide_compilation.helpers import runtime_configuration from app.modules.authorization.api import ProjectGuideCompilationRequestOrigin @@ -17,9 +15,6 @@ guide_document_manifest_port, ) from app.modules.authorization.api import ActorIdentityFacts, ActorKind -from app.modules.checkers.catalogue import ( - build_pre_submission_checker_catalogue, -) from app.modules.projects.guide_compilation.context import ( build_project_guide_compilation_context, ) @@ -30,7 +25,6 @@ from app.modules.projects.guide_compilation.service import ( load_compilation_execution_state, ) -from app.modules.checkers.api.post_submit_catalogue import current_post_submit_catalogue from .helpers import context, identity, seed_database, DOCUMENT_VERSION_ID, PUT_ATTEMPT_ID from .test_authorized_request_service import _authorized_service, _request, _seed_human @@ -61,10 +55,7 @@ async def test_context_rebuilds_the_exact_authorized_art_backed_identity( session, state=state, material=guide_document_manifest_port(session), - pre_submission_capabilities=project_guide_pre_submission_capabilities( - build_pre_submission_checker_catalogue() - ), - post_submission_capabilities=current_post_submit_catalogue(), + checker_capabilities=context(values).checker_capabilities, ) assert rebuilt == context(values) @@ -95,9 +86,8 @@ async def test_context_drift_fails_before_dispatch( ) async with factory() as session: state = await load_compilation_execution_state(session, request.attempt_id) - default_catalogue = build_pre_submission_checker_catalogue() - drifted_catalogue = build_pre_submission_checker_catalogue( - disabled_entry_ids={default_catalogue.entries[0].stable_id} + drifted_capabilities = context(values).checker_capabilities.model_copy( + update={"manifest_sha256": "sha256:" + "f" * 64} ) async with factory() as session: with pytest.raises(GuideCompilationIntegrityError, match="identity mismatch"): @@ -105,10 +95,7 @@ async def test_context_drift_fails_before_dispatch( session, state=state, material=guide_document_manifest_port(session), - pre_submission_capabilities=project_guide_pre_submission_capabilities( - drifted_catalogue - ), - post_submission_capabilities=(current_post_submit_catalogue()), + checker_capabilities=drifted_capabilities, ) finally: await engine.dispose() @@ -134,18 +121,14 @@ async def test_context_requires_fresh_session_and_current_lineage( ) async with factory() as session: state = await load_compilation_execution_state(session, request.attempt_id) - capabilities = project_guide_pre_submission_capabilities( - build_pre_submission_checker_catalogue() - ) - post_capabilities = current_post_submit_catalogue() + capabilities = context(values).checker_capabilities async with factory() as session, session.begin(): with pytest.raises(GuideCompilationIntegrityError, match="fresh root"): await build_project_guide_compilation_context( session, state=state, material=guide_document_manifest_port(session), - pre_submission_capabilities=capabilities, - post_submission_capabilities=post_capabilities, + checker_capabilities=capabilities, ) missing = replace( state, @@ -157,8 +140,7 @@ async def test_context_requires_fresh_session_and_current_lineage( session, state=missing, material=guide_document_manifest_port(session), - pre_submission_capabilities=capabilities, - post_submission_capabilities=post_capabilities, + checker_capabilities=capabilities, ) finally: await engine.dispose() @@ -196,16 +178,13 @@ async def test_context_enforces_the_canonical_prompt_limit( session, state=state, material=guide_document_manifest_port(session), - pre_submission_capabilities=project_guide_pre_submission_capabilities( - build_pre_submission_checker_catalogue() - ), - post_submission_capabilities=(current_post_submit_catalogue()), + checker_capabilities=context(values).checker_capabilities, ) finally: await engine.dispose() -@pytest.mark.parametrize('fault', ['manifest_lineage', 'missing_examples', 'changed_examples']) +@pytest.mark.parametrize("fault", ["manifest_lineage", "missing_examples", "changed_examples"]) def test_context_constructor_rejects_input_drift_after_valid_control(fault): from types import SimpleNamespace from app.modules.projects.guide_compilation.context import compilation_context_from_material @@ -213,31 +192,45 @@ def test_context_constructor_rejects_input_drift_after_valid_control(fault): from .helpers import ids expected = context(ids()) - examples = [item.model_dump(mode='json') for item in expected.task_examples] - guide = SimpleNamespace(id=str(expected.material.guide_id), - project_id=str(expected.material.project_id), version=expected.material.guide_version, - task_examples=examples, task_examples_hash=task_examples_hash(expected.task_examples)) - snapshot = SimpleNamespace(id=str(expected.material.source_snapshot_id), + examples = [item.model_dump(mode="json") for item in expected.task_examples] + guide = SimpleNamespace( + id=str(expected.material.guide_id), + project_id=str(expected.material.project_id), + version=expected.material.guide_version, + task_examples=examples, + task_examples_hash=task_examples_hash(expected.task_examples), + ) + snapshot = SimpleNamespace( + id=str(expected.material.source_snapshot_id), bundle_hash=expected.material.source_snapshot_hash, - manifest_json={'task_examples_hash': guide.task_examples_hash, - 'task_examples_count': len(examples)}) - values = dict(guide=guide, snapshot=snapshot, loaded=expected.material, - setup_run_id=expected.setup_run_id, setup_generation=expected.setup_generation, - pre_submission_capabilities=expected.pre_submission_capabilities, - post_submission_capabilities=expected.post_submission_capabilities, - runtime_configuration=expected.runtime_configuration) + manifest_json={ + "task_examples_hash": guide.task_examples_hash, + "task_examples_count": len(examples), + }, + ) + values = dict( + guide=guide, + snapshot=snapshot, + loaded=expected.material, + setup_run_id=expected.setup_run_id, + setup_generation=expected.setup_generation, + checker_capabilities=expected.checker_capabilities, + runtime_configuration=expected.runtime_configuration, + ) assert compilation_context_from_material(**values) == expected - if fault == 'manifest_lineage': + if fault == "manifest_lineage": snapshot.id = str(uuid4()) - message = 'manifest lineage mismatch' + message = "manifest lineage mismatch" else: - guide.task_examples = None if fault == 'missing_examples' else [{'content': 'Changed task'}] - message = 'task examples are unavailable' + guide.task_examples = None if fault == "missing_examples" else [{"content": "Changed task"}] + message = "task examples are unavailable" with pytest.raises(GuideCompilationIntegrityError, match=message): compilation_context_from_material(**values) -async def test_setup_repository_reads_preserve_scope_without_fabricating_policy(clean_postgres_database): +async def test_setup_repository_reads_preserve_scope_without_fabricating_policy( + clean_postgres_database, +): from app.modules.projects.repository import ProjectRepository values = await seed_database(clean_postgres_database) @@ -246,14 +239,33 @@ async def test_setup_repository_reads_preserve_scope_without_fabricating_policy( try: async with sessions() as session, session.begin(): repository = ProjectRepository(session) - setup = await repository.get_project_setup_run(str(values['setup_1'])) + setup = await repository.get_project_setup_run(str(values["setup_1"])) assert setup is not None - assert await repository.get_latest_project_setup_run(str(values['project']), str(values['guide'])) is setup - assert await repository.get_latest_project_setup_run(str(uuid4()), str(values['guide'])) is None - assert await repository.next_project_setup_generation(str(values['guide'])) == setup.setup_generation + 1 + assert ( + await repository.get_latest_project_setup_run( + str(values["project"]), str(values["guide"]) + ) + is setup + ) + assert ( + await repository.get_latest_project_setup_run(str(uuid4()), str(values["guide"])) + is None + ) + assert ( + await repository.next_project_setup_generation(str(values["guide"])) + == setup.setup_generation + 1 + ) assert await repository.get_project_setup_run(str(uuid4())) is None - assert await repository.get_pre_submit_checker_policy_for_effective_policy(str(uuid4())) is None + assert ( + await repository.get_pre_submit_checker_policy_for_effective_policy(str(uuid4())) + is None + ) assert await repository.lock_compiled_pre_submit_checker_policy(str(uuid4())) is None - assert await repository.lock_post_submit_checker_policy_for_guide(str(values['project']), setup.guide_version) is None + assert ( + await repository.lock_post_submit_checker_policy_for_guide( + str(values["project"]), setup.guide_version + ) + is None + ) finally: await engine.dispose() diff --git a/backend/tests/test_project_guide_compilation_contracts.py b/backend/tests/test_project_guide_compilation_contracts.py index 94b58fbcd..0e3b1015a 100644 --- a/backend/tests/test_project_guide_compilation_contracts.py +++ b/backend/tests/test_project_guide_compilation_contracts.py @@ -1,17 +1,16 @@ - from __future__ import annotations from app.core.config import get_settings from app.adapters.tasks import task_service -from app.modules.checkers.catalogue import project_guide_pre_submission_capabilities - from tests.projects.guide_compilation.helpers import runtime_configuration +from tests.checkers.external.support import registry_spec +from datetime import UTC, datetime +import json from uuid import uuid4 -from app.core.hashing import canonical_json_hash from app.core.identifiers import new_record_id import pytest @@ -32,31 +31,44 @@ validate_project_guide_compilation_result, ) from app.modules.projects.api.guide_documents import GuideDocumentManifest, GuideDocumentVersion -from app.modules.checkers.catalogue import ( - PreSubmissionCheckerClassification, - build_pre_submission_checker_catalogue, +from app.modules.checkers.api.default_checker import ( + WORKSTREAM_DEFAULT_CHECKER_ID, + WORKSTREAM_DEFAULT_CHECKER_VERSION, +) +from app.modules.checkers.api.external import ( + ExternalCheckerCapabilityDefinition, + ExternalCheckerCapabilityProjection, + ExternalCheckerRegistryEntry, + external_checker_json_hash, ) -from app.modules.checkers.api.post_submit_catalogue import current_post_submit_catalogue -from app.modules.projects.post_submit_policy import DEFAULT_DURABLE_CHECKERS SHA256 = "sha256:" + "a" * 64 -@pytest.mark.parametrize("project_limit, default_limit, expected", [ - (100, None, 100), (None, 50, 50), (100, 50, 50), (20, 50, 20), (None, None, None), -]) +@pytest.mark.parametrize( + "project_limit, default_limit, expected", + [ + (100, None, 100), + (None, 50, 50), + (100, 50, 50), + (20, 50, 20), + (None, None, None), + ], +) @pytest.mark.parametrize("field", ["maximum_archive_entries", "maximum_archive_size_bytes"]) -def test_archive_limit_projection_and_default_floor(monkeypatch, project_limit, default_limit, expected, field): +def test_archive_limit_projection_and_default_floor( + monkeypatch, project_limit, default_limit, expected, field +): from app.modules.projects import service from app.modules.projects.guide_compilation.projection_payloads import policy_body proposal = SubmissionArtifactPolicyProposal( - maximum_file_size_bytes=1000, maximum_package_size_bytes=2000, + maximum_file_size_bytes=1000, + maximum_package_size_bytes=2000, **{field: project_limit}, ) - monkeypatch.setitem(service.WORKSTREAM_DEFAULT_SUBMISSION_ARTIFACT_POLICY, - field, default_limit) + monkeypatch.setitem(service.WORKSTREAM_DEFAULT_SUBMISSION_ARTIFACT_POLICY, field, default_limit) body = policy_body(None, proposal) assert body[field] == project_limit effective = service.ProjectService(None)._merge_effective_submission_artifact_policy(body) @@ -66,11 +78,20 @@ def test_archive_limit_projection_and_default_floor(monkeypatch, project_limit, @pytest.mark.parametrize("field", ["required_evidence", "attestation_terms"]) -@pytest.mark.parametrize("value, valid", [ - ("results", True), ("a" + "b" * 99, True), ("results.v0_1-ok", True), - ("", False), ("a" + "b" * 100, False), ("Provide results", False), - ("evidence/results", False), ("9results", False), ("Results", False), -]) +@pytest.mark.parametrize( + "value, valid", + [ + ("results", True), + ("a" + "b" * 99, True), + ("results.v0_1-ok", True), + ("", False), + ("a" + "b" * 100, False), + ("Provide results", False), + ("evidence/results", False), + ("9results", False), + ("Results", False), + ], +) def test_policy_identifier_schema_matches_existing_validator(field, value, valid): import re from app.interfaces.project_agents import _SAFE_IDENTIFIER @@ -93,7 +114,9 @@ def test_model_schema_describes_existing_expanded_byte_limit(): properties = SubmissionArtifactPolicyProposal.model_json_schema()["properties"] assert "expanded bytes" in properties["maximum_package_size_bytes"]["description"] assert "not compressed upload bytes" in properties["maximum_package_size_bytes"]["description"] - assert "entire submitted compressed ZIP" in properties["maximum_archive_size_bytes"]["description"] + assert ( + "entire submitted compressed ZIP" in properties["maximum_archive_size_bytes"]["description"] + ) assert "directory entries" in properties["maximum_archive_entries"]["description"] assert "ZIP root" in properties["required_artifacts"]["description"] @@ -107,8 +130,7 @@ def test_omitted_optional_archive_limit_preserves_default_floor(monkeypatch, def owner = service.ProjectService(None) policy = owner._canonical_policy_body(SubmissionArtifactPolicyInput().model_dump()) del policy[field] - monkeypatch.setitem(service.WORKSTREAM_DEFAULT_SUBMISSION_ARTIFACT_POLICY, - field, default_limit) + monkeypatch.setitem(service.WORKSTREAM_DEFAULT_SUBMISSION_ARTIFACT_POLICY, field, default_limit) effective = owner._merge_effective_submission_artifact_policy(policy) assert effective[field] == default_limit assert field not in policy @@ -128,31 +150,99 @@ def test_task_requirements_response_carries_valid_locked_archive_limit(limit, fi ) policy[field] = limit from app.modules.projects.api.locked_policy import CanonicalJsonObject - context = SimpleNamespace(facts=SimpleNamespace(effective_policy=CanonicalJsonObject.from_mapping(policy))) + + context = SimpleNamespace( + facts=SimpleNamespace(effective_policy=CanonicalJsonObject.from_mapping(policy)) + ) task = SimpleNamespace(id=str(uuid4()), project_id=str(uuid4()), locked_guide_version="v0.1") if limit is not None and (type(limit) is not int or limit <= 0): with pytest.raises(TaskLockedContextInvalid): - task_service(None, settings=get_settings())._contributor_submission_requirements_response(task, context) + task_service( + None, settings=get_settings() + )._contributor_submission_requirements_response(task, context) else: - response = task_service(None, settings=get_settings())._contributor_submission_requirements_response(task, context) + response = task_service( + None, settings=get_settings() + )._contributor_submission_requirements_response(task, context) assert response.model_dump(mode="json")[field] == limit + + SOURCE_ITEM_ID = new_record_id() DOCUMENT_VERSION_ID = new_record_id() +def _registered_capability(capability_id: str, phase: str): + spec = registry_spec(phase).model_copy(update={"capability_id": capability_id}) + spec = type(spec).model_validate(spec.model_dump()) + entry = ExternalCheckerRegistryEntry( + **spec.model_dump(), + registry_entry_id=new_record_id(), + entry_digest=spec.spec_digest, + registration_operation_id=uuid4(), + registered_by_actor_profile_id=uuid4(), + authorization_decision_event_id=uuid4(), + created_at=datetime.now(UTC), + ) + return ExternalCheckerCapabilityDefinition( + capability_id=capability_id, + capability_version=spec.capability_version, + phase=phase, + selectable=True, + registry_entry=entry, + ) + + +def _capabilities() -> ExternalCheckerCapabilityProjection: + definitions = tuple( + sorted( + ( + ExternalCheckerCapabilityDefinition( + capability_id=WORKSTREAM_DEFAULT_CHECKER_ID, + capability_version=WORKSTREAM_DEFAULT_CHECKER_VERSION, + phase="pre_submit", + selectable=False, + ), + _registered_capability("acme.pre", "pre_submit"), + _registered_capability("acme.post", "post_submit"), + ), + key=lambda item: (item.phase, item.capability_id, item.capability_version), + ) + ) + body = { + "schema_version": "external_checker_capabilities.v1", + "definitions": [item.model_dump(mode="json") for item in definitions], + } + return ExternalCheckerCapabilityProjection( + definitions=definitions, + manifest_sha256=external_checker_json_hash(body), + ) + + def _context() -> ProjectGuideCompilationContext: setup_id = new_record_id() material = GuideDocumentManifest( - project_id=new_record_id(), guide_id=new_record_id(), guide_version="v1", - source_snapshot_id=new_record_id(), source_snapshot_hash=SHA256, - setup_run_id=setup_id, setup_generation=1, - documents=(GuideDocumentVersion( - source_item_id=SOURCE_ITEM_ID, ingest_id=DOCUMENT_VERSION_ID, item_order=0, - put_attempt_id=new_record_id(), content_id=new_record_id(), - replica_id=new_record_id(), - storage_namespace_id="primary", namespace_fingerprint=SHA256, - sha256=SHA256, byte_count=100, media_type="application/pdf", - ),), + project_id=new_record_id(), + guide_id=new_record_id(), + guide_version="v1", + source_snapshot_id=new_record_id(), + source_snapshot_hash=SHA256, + setup_run_id=setup_id, + setup_generation=1, + documents=( + GuideDocumentVersion( + source_item_id=SOURCE_ITEM_ID, + ingest_id=DOCUMENT_VERSION_ID, + item_order=0, + put_attempt_id=new_record_id(), + content_id=new_record_id(), + replica_id=new_record_id(), + storage_namespace_id="primary", + namespace_fingerprint=SHA256, + sha256=SHA256, + byte_count=100, + media_type="application/pdf", + ), + ), ) return ProjectGuideCompilationContext( task_examples=({"content": "Review a claim using the project guide."},), @@ -162,10 +252,7 @@ def _context() -> ProjectGuideCompilationContext: instruction_version="v1", agent_identity="project-guide-compilation-agent-v1", agent_version="v1", - pre_submission_capabilities=project_guide_pre_submission_capabilities( - build_pre_submission_checker_catalogue() - ), - post_submission_capabilities=current_post_submit_catalogue(), + checker_capabilities=_capabilities(), runtime_configuration=runtime_configuration(), ) @@ -188,125 +275,47 @@ def _artifact_policy() -> SubmissionArtifactPolicyProposal: ) -def test_pre_submission_projection_preserves_exact_manifest_and_selectability() -> None: - catalogue = build_pre_submission_checker_catalogue( - disabled_entry_ids=frozenset({"artifact.quality.placeholder_signal"}) - ) - projection = project_guide_pre_submission_capabilities(catalogue) +def test_checker_projection_has_one_default_and_exact_registry_entries() -> None: + projection = _capabilities() + defaults = [item for item in projection.definitions if not item.selectable] + registered = [item for item in projection.definitions if item.selectable] - assert projection.manifest_sha256 == catalogue.manifest_sha256 - assert len(projection.definitions) == len(catalogue.entries) - assert [item.stable_id for item in projection.definitions] == [ - item.stable_id for item in catalogue.entries + assert [(item.capability_id, item.phase) for item in defaults] == [ + ("workstream.default", "pre_submit") ] - for definition, source in zip(projection.definitions, catalogue.entries, strict=True): - projected = definition.model_dump(mode="json") - selectable = projected.pop("selectable") - assert projected == source.manifest_entry() - assert selectable is ( - source.state.value == "enabled" - and source.dispatch_kind.value == "policy_primitive" - and source.phase.value == "project_policy" - ) - disabled = next( - item - for item in projection.definitions - if item.stable_id == "artifact.quality.placeholder_signal" - ) - assert disabled.state == "disabled" - assert disabled.selectable is False - assert projection.available is True - - -def test_pre_submission_projection_reports_disabled_mandatory_unavailable() -> None: - catalogue = build_pre_submission_checker_catalogue( - disabled_entry_ids=frozenset({"artifact.outer_zip.valid"}) - ) - projection = project_guide_pre_submission_capabilities(catalogue) - assert projection.available is False - assert projection.definitions[0].classification == ( - PreSubmissionCheckerClassification.MANDATORY_SECURITY.value - ) - assert projection.definitions[0].selectable is False - - -@pytest.mark.parametrize("disabled", [False, True]) -def test_archive_encryption_guard_is_described_as_mandatory_platform_coverage(disabled): - from app.interfaces.project_agents import project_guide_compilation_prompt_bytes - - capability_id = "artifact.archive.entries_safe" - catalogue = build_pre_submission_checker_catalogue( - disabled_entry_ids=frozenset({capability_id}) if disabled else frozenset() - ) - projection = project_guide_pre_submission_capabilities(catalogue) - definition = next(item for item in projection.definitions if item.stable_id == capability_id) - expected = "Reject encrypted ZIP entries, symbolic links and special files" - assert definition.public_name == expected - manifest_entry = next(item for item in catalogue.manifest["entries"] - if item["stable_id"] == capability_id) - assert manifest_entry["public_name"] == expected - assert definition.classification == "mandatory_security" - assert definition.dispatch_kind == "platform_capability" - assert definition.dispatch_capability == "submission_archive.entries_safe" - assert definition.selectable is False - assert definition.state == ("disabled" if disabled else "enabled") - assert projection.available is (not disabled) - context = _context().model_copy(update={"pre_submission_capabilities": projection}) - assert expected.encode() in project_guide_compilation_prompt_bytes(context) - - -def test_compilation_rejects_unavailable_mandatory_pre_submission_projection() -> None: - context = _context().model_copy( - update={ - "pre_submission_capabilities": project_guide_pre_submission_capabilities( - build_pre_submission_checker_catalogue( - disabled_entry_ids=frozenset({"artifact.outer_zip.valid"}) - ) - ) - } - ) - result = ProjectGuideCompilationResult( - status="draft_ready", - findings=( - CompilationFinding(severity="info", code="guide.ready", message="Guide is complete."), - ), - submission_artifact_policy=_artifact_policy(), - agent_version="v1", - ) - with pytest.raises(ValueError, match="projection is unavailable"): - validate_project_guide_compilation_result(context, result) - - -def test_post_submission_projection_uses_registry_and_frozen_default_truth() -> None: - projection = current_post_submit_catalogue() - by_name = {item.capability_id: item for item in projection.definitions} - - assert projection.source_version == "v0.1" - assert set(DEFAULT_DURABLE_CHECKERS).issubset(by_name) - assert {name for name, item in by_name.items() if item.platform_default} == set( - DEFAULT_DURABLE_CHECKERS - ) - assert [item.capability_id for item in projection.definitions if item.selectable] == [ - "check_acceptance_criteria_present" + assert [(item.capability_id, item.phase) for item in registered] == [ + ("acme.post", "post_submit"), + ("acme.pre", "pre_submit"), ] - assert all(item.stage == "post_submit" for item in projection.definitions) - + assert all(item.registry_entry is not None for item in registered) -def test_post_submission_projection_rejects_sparse_definitions() -> None: - from app.modules.checkers.api.post_submit_catalogue import PostSubmitCatalogue - projection = current_post_submit_catalogue() +def test_checker_projection_rejects_a_second_code_owned_default() -> None: + projection = _capabilities() body = projection.model_dump(mode="json") - sparse_keys = {"capability_id", "capability_version", "stage", "platform_default", "selectable"} - body["definitions"] = [ - {key: value for key, value in item.items() if key in sparse_keys} - for item in body["definitions"] - ] - body["manifest_sha256"] = canonical_json_hash( - {key: value for key, value in body.items() if key != "manifest_sha256"} + body["definitions"] = ( + *body["definitions"], + { + "capability_id": "workstream.other", + "capability_version": "v1", + "phase": "post_submit", + "selectable": False, + "registry_entry": None, + }, + ) + body["definitions"] = tuple( + sorted( + body["definitions"], + key=lambda item: (item["phase"], item["capability_id"], item["capability_version"]), + ) ) - with pytest.raises(ValidationError, match="Field required"): - PostSubmitCatalogue.model_validate(body) + manifest = { + "schema_version": body["schema_version"], + "definitions": list(body["definitions"]), + } + body["manifest_sha256"] = external_checker_json_hash(manifest) + with pytest.raises(ValidationError, match="default capability"): + ExternalCheckerCapabilityProjection.model_validate_json(json.dumps(body)) @pytest.mark.parametrize( @@ -357,8 +366,13 @@ def test_guide_evidence_ref_rejects_non_lineage_fields(payload: dict[str, str], ) def test_model_produced_text_rejects_unsafe_shapes(unsafe: str) -> None: with pytest.raises(ValidationError): - CapabilitySuggestion(requirement_id="r001", stage="pre_submit", - title="new checker", rationale=unsafe, evidence_refs=(_evidence(),)) + CapabilitySuggestion( + requirement_id="r001", + stage="pre_submit", + title="new checker", + rationale=unsafe, + evidence_refs=(_evidence(),), + ) @pytest.mark.parametrize( @@ -370,8 +384,13 @@ def test_model_produced_text_rejects_unsafe_shapes(unsafe: str) -> None: ], ) def test_model_produced_text_allows_safe_security_policy_language(safe: str) -> None: - suggestion = CapabilitySuggestion(requirement_id="r001", stage="pre_submit", - title="security guidance", rationale=safe, evidence_refs=(_evidence(),)) + suggestion = CapabilitySuggestion( + requirement_id="r001", + stage="pre_submit", + title="security guidance", + rationale=safe, + evidence_refs=(_evidence(),), + ) assert suggestion.rationale == safe @@ -380,8 +399,13 @@ def test_compilation_context_requires_task_examples_and_preserves_all_input() -> import json payload = _context().model_dump(mode="json") - examples = [{"content": "A starting idea."}, {"content": " 修復 worker\n", "title": "Second", "labels": ["research", "repair"]}] - context = ProjectGuideCompilationContext.model_validate(payload | {"task_examples": examples}) + examples = [ + {"content": "A starting idea."}, + {"content": " 修復 worker\n", "title": "Second", "labels": ["research", "repair"]}, + ] + context = ProjectGuideCompilationContext.model_validate_json( + json.dumps(payload | {"task_examples": examples}) + ) sent = json.loads(project_guide_compilation_prompt_bytes(context)) assert sent["task_examples"] == [item.model_dump(mode="json") for item in context.task_examples] del payload["task_examples"] @@ -402,24 +426,46 @@ def test_maximum_examples_and_documents_fit_default_runtime_input_budgets() -> N from app.modules.projects.api.task_examples import MAXIMUM_TASK_EXAMPLE_BYTES context = _context() - examples = [{"content": "x" * 65_536, "title": None, "labels": []}, - {"content": "", "title": None, "labels": []}] + examples = [ + {"content": "x" * 65_536, "title": None, "labels": []}, + {"content": "", "title": None, "labels": []}, + ] overhead = len(json.dumps(examples, sort_keys=True, separators=(",", ":")).encode()) examples[1]["content"] = "y" * (MAXIMUM_TASK_EXAMPLE_BYTES - overhead) - assert len(json.dumps(examples, sort_keys=True, separators=(",", ":")).encode()) == MAXIMUM_TASK_EXAMPLE_BYTES + assert ( + len(json.dumps(examples, sort_keys=True, separators=(",", ":")).encode()) + == MAXIMUM_TASK_EXAMPLE_BYTES + ) prototype = context.material.documents[0].model_dump(mode="json") - documents = [prototype | { - "source_item_id": str(uuid4()), "ingest_id": str(uuid4()), - "put_attempt_id": str(uuid4()), "item_order": index, - } for index in range(100)] - material = context.material.model_dump(mode="json") | {"documents": documents, "guide_version": "g" * 50} - largest = ProjectGuideCompilationContext.model_validate( - context.model_dump(mode="json") | {"task_examples": examples, "material": material}, + documents = [ + prototype + | { + "source_item_id": str(uuid4()), + "ingest_id": str(uuid4()), + "put_attempt_id": str(uuid4()), + "item_order": index, + } + for index in range(100) + ] + material = context.material.model_dump(mode="json") | { + "documents": documents, + "guide_version": "g" * 50, + } + largest = ProjectGuideCompilationContext.model_validate_json( + json.dumps( + context.model_dump(mode="json") | {"task_examples": examples, "material": material} + ), ) assert len(largest.task_examples) == 2 assert len(largest.material.documents) == 100 - assert len(project_guide_compilation_prompt_bytes(largest)) <= largest.runtime_configuration.maximum_manifest_bytes - assert len(canonical_project_guide_compilation_context_bytes(largest)) <= MAXIMUM_PROJECT_GUIDE_COMPILATION_PROMPT_BYTES + assert ( + len(project_guide_compilation_prompt_bytes(largest)) + <= largest.runtime_configuration.maximum_manifest_bytes + ) + assert ( + len(canonical_project_guide_compilation_context_bytes(largest)) + <= MAXIMUM_PROJECT_GUIDE_COMPILATION_PROMPT_BYTES + ) def test_unified_result_accepts_exact_stage_capability_and_closed_parameters() -> None: @@ -446,16 +492,16 @@ def test_unified_result_accepts_exact_stage_capability_and_closed_parameters() - pre_submit_bindings=( PreSubmissionBindingProposal( requirement_id="requirement.packet", - capability_id="policy.file_size.limit", - capability_version="v1", + capability_id="acme.pre", + capability_version="v1.2.3", stage="pre_submit", ), ), post_submit_bindings=( PostSubmissionBindingProposal( requirement_id="requirement.acceptance", - capability_id="check_acceptance_criteria_present", - capability_version="v0.1", + capability_id="acme.post", + capability_version="v1.2.3", stage="post_submit", ), ), @@ -467,18 +513,18 @@ def test_unified_result_accepts_exact_stage_capability_and_closed_parameters() - @pytest.mark.parametrize( ("capability_id", "version", "stage", "expected_error"), [ - ("submission.packet.required_fields", "v1", "pre_submit", "binding is invalid"), - ("policy.submission_packet.validate", "stale", "pre_submit", "version is stale"), + ("workstream.default", "v1", "pre_submit", "binding is invalid"), + ("acme.pre", "stale", "pre_submit", "version is stale"), ("unknown.capability", "v1", "pre_submit", "binding is invalid"), ( - "check_submission_packet", - "v0.1", + "acme.pre", + "v1.2.3", "post_submit", "binding is invalid", ), ( - "check_acceptance_criteria_present", - "v0.1", + "acme.post", + "v1.2.3", "pre_submit", "binding is invalid", ), @@ -489,7 +535,9 @@ def test_unified_result_rejects_default_unknown_stale_and_wrong_stage_bindings( ) -> None: context = _context() disposition = "supported_post_submit" if stage == "post_submit" else "supported_pre_submit" - binding_type = PreSubmissionBindingProposal if stage == "pre_submit" else PostSubmissionBindingProposal + binding_type = ( + PreSubmissionBindingProposal if stage == "pre_submit" else PostSubmissionBindingProposal + ) binding = binding_type( requirement_id="requirement.one", capability_id=capability_id, @@ -549,10 +597,11 @@ def test_unified_result_rejects_open_nested_or_executable_configuration() -> Non ) -def test_pre_submission_projection_resource_budget_is_deeply_frozen() -> None: - projection = project_guide_pre_submission_capabilities(build_pre_submission_checker_catalogue()) +def test_external_registry_resource_budget_is_deeply_frozen() -> None: + projection = _capabilities() + registered = next(item for item in projection.definitions if item.registry_entry) with pytest.raises(ValidationError): - projection.definitions[0].resource_budget.maximum_results = 99 + registered.registry_entry.resources.deadline_ms = 99 @pytest.mark.parametrize("field", ["canonical_content", "content_markdown", "provider_url"]) @@ -562,7 +611,9 @@ def test_manifest_rejects_document_bodies_and_untrusted_storage_coordinates(fiel GuideDocumentManifest.model_validate(body | {field: "untrusted content"}) -@pytest.mark.parametrize("field", ["source_item_id", "ingest_id", "put_attempt_id", "replica_id", "sha256"]) +@pytest.mark.parametrize( + "field", ["source_item_id", "ingest_id", "put_attempt_id", "replica_id", "sha256"] +) def test_manifest_requires_exact_document_identity(field): body = _context().material.model_dump(mode="python") document = dict(body["documents"][0]) @@ -636,8 +687,8 @@ def test_post_submission_binding_rejects_unowned_parameters() -> None: context = _context() binding = PostSubmissionBindingProposal( requirement_id="requirement.one", - capability_id="check_acceptance_criteria_present", - capability_version="v0.1", + capability_id="acme.post", + capability_version="v1.2.3", stage="post_submit", parameters=(CapabilityParameter(name="unowned_parameter", value=True),), ) @@ -654,7 +705,7 @@ def test_post_submission_binding_rejects_unowned_parameters() -> None: post_submit_bindings=(binding,), agent_version="v1", ) - with pytest.raises(ValueError, match="Extra inputs"): + with pytest.raises(ValueError, match="value is invalid"): validate_project_guide_compilation_result(context, result) @@ -701,7 +752,7 @@ def test_result_status_must_match_findings_and_blocking_dispositions( @pytest.mark.parametrize( "invalid_capability_id", - ["policy.submission_packet.validate", "artifact.quality.placeholder_signal"], + ["acme.pre", "unknown.capability"], ) def test_platform_coverage_requires_exact_mandatory_platform_capability( invalid_capability_id: str, @@ -716,7 +767,7 @@ def test_platform_coverage_requires_exact_mandatory_platform_capability( statement="Validate the outer ZIP.", disposition="platform_covered", platform_coverage=PlatformCoverageRef( - capability_id="artifact.outer_zip.valid", + capability_id="workstream.default", capability_version="v1", stage="pre_submit", ), @@ -745,16 +796,8 @@ def test_platform_coverage_requires_exact_mandatory_platform_capability( validate_project_guide_compilation_result(context, invalid) -def test_platform_coverage_rejects_disabled_platform_capability() -> None: - context = _context().model_copy( - update={ - "pre_submission_capabilities": project_guide_pre_submission_capabilities( - build_pre_submission_checker_catalogue( - disabled_entry_ids=frozenset({"artifact.outer_zip.valid"}) - ) - ) - } - ) +def test_platform_coverage_rejects_registered_project_image() -> None: + context = _context() result = ProjectGuideCompilationResult( status="draft_ready", submission_artifact_policy=_artifact_policy(), @@ -764,19 +807,19 @@ def test_platform_coverage_rejects_disabled_platform_capability() -> None: statement="Validate the outer ZIP.", disposition="platform_covered", platform_coverage=PlatformCoverageRef( - capability_id="artifact.outer_zip.valid", - capability_version="v1", + capability_id="acme.pre", + capability_version="v1.2.3", stage="pre_submit", ), ), ), agent_version="v1", ) - with pytest.raises(ValueError, match="projection is unavailable"): + with pytest.raises(ValueError, match="canonical truth"): validate_project_guide_compilation_result(context, result) -def test_platform_coverage_accepts_exact_post_submit_default() -> None: +def test_platform_coverage_rejects_post_submit_project_image() -> None: result = ProjectGuideCompilationResult( status="draft_ready", submission_artifact_policy=_artifact_policy(), @@ -786,15 +829,16 @@ def test_platform_coverage_accepts_exact_post_submit_default() -> None: statement="Run the platform submission-packet check.", disposition="platform_covered", platform_coverage=PlatformCoverageRef( - capability_id="check_submission_packet", - capability_version="v0.1", + capability_id="acme.post", + capability_version="v1.2.3", stage="post_submit", ), ), ), agent_version="v1", ) - validate_project_guide_compilation_result(_context(), result) + with pytest.raises(ValueError, match="canonical truth"): + validate_project_guide_compilation_result(_context(), result) def test_platform_coverage_ref_is_required_only_for_platform_disposition() -> None: @@ -857,8 +901,11 @@ def test_pre_submission_binding_rejects_duplicate_policy_configuration(parameter """The sole intake configuration is the artifact policy, never a second copy.""" with pytest.raises(ValidationError, match="Extra inputs"): PreSubmissionBindingProposal( - requirement_id="requirement.size", capability_id="policy.file_size.limit", - capability_version="v1", stage="pre_submit", parameters=parameters, + requirement_id="requirement.size", + capability_id="policy.file_size.limit", + capability_version="v1", + stage="pre_submit", + parameters=parameters, ) @@ -866,4 +913,4 @@ def test_context_rejects_instruction_version_separate_from_snapshot() -> None: payload = _context().model_dump(mode="json") payload["instruction_version"] = "different" with pytest.raises(ValidationError, match="instruction configuration mismatch"): - ProjectGuideCompilationContext.model_validate(payload) + ProjectGuideCompilationContext.model_validate_json(json.dumps(payload)) From fcfc0a393a214fdbb42888f3a9932cf8936b26ce Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 21:45:46 +0100 Subject: [PATCH 088/283] [PILOT-04] isolate retained checker history --- backend/app/adapters/checkers/__init__.py | 218 +++++++++++++++++- backend/app/modules/checkers/api/__init__.py | 2 +- backend/app/modules/checkers/api/execution.py | 2 +- ...catalogue.py => historical_post_submit.py} | 0 .../modules/checkers/api/materialization.py | 2 +- .../modules/checkers/api/output_custody.py | 2 +- .../modules/checkers/api/policy_custody.py | 15 ++ .../app/modules/checkers/api/post_submit.py | 2 +- .../checkers/api/selected_post_submit.py | 2 +- backend/app/modules/checkers/execution.py | 2 +- .../modules/checkers/execution_repository.py | 2 +- .../modules/checkers/post_submit_catalogue.py | 2 +- .../checkers/post_submit_implementations.py | 2 +- backend/app/modules/checkers/runner.py | 2 +- .../guide_compilation/proposal_approval.py | 2 +- .../modules/projects/post_policy/custody.py | 2 +- .../modules/projects/post_submit_policy.py | 2 +- backend/app/modules/tasks/repository.py | 2 +- backend/app/modules/tasks/service.py | 2 +- .../guide_proposals/test_postgresql.py | 2 +- .../authorization/post_policy/pg_support.py | 2 +- .../task_locked_context/test_visibility.py | 2 +- .../execution/historical_execution.py | 2 +- .../execution/material_storage_helpers.py | 2 +- .../external/test_selected_pre_submit.py | 123 +++++++++- backend/tests/checkers/post_submit/support.py | 2 +- .../checkers/post_submit/test_catalogue.py | 2 +- .../post_submit/test_compiled_policy.py | 2 +- .../checkers/post_submit/test_input_bounds.py | 2 +- .../test_requirement_dispositions.py | 2 +- .../post_submit/test_result_contract.py | 2 +- backend/tests/committed_guide_fixtures.py | 2 +- .../guide_compilation/proposals/pg_support.py | 2 +- .../proposals/test_postgresql.py | 2 +- .../test_automatic_request.py | 2 +- .../test_hidden_orchestrator_postgresql.py | 2 +- .../tests/projects/post_policy/pg_support.py | 2 +- .../projects/post_policy/test_compiler.py | 2 +- .../projects/post_policy/test_direct_sql.py | 2 +- .../tests/projects/post_policy/test_guards.py | 2 +- .../projects/post_policy/test_postgresql.py | 2 +- .../projects/post_policy/test_public_api.py | 2 +- .../tests/projects/unified_policy_fixtures.py | 2 +- backend/tests/test_checkers.py | 4 +- backend/tests/test_tasks.py | 2 +- 45 files changed, 394 insertions(+), 46 deletions(-) rename backend/app/modules/checkers/api/{post_submit_catalogue.py => historical_post_submit.py} (100%) create mode 100644 backend/app/modules/checkers/api/policy_custody.py diff --git a/backend/app/adapters/checkers/__init__.py b/backend/app/adapters/checkers/__init__.py index 94e8d477f..0b01be9d7 100644 --- a/backend/app/adapters/checkers/__init__.py +++ b/backend/app/adapters/checkers/__init__.py @@ -1,12 +1,28 @@ """CHECKER-owned composition adapters.""" +import asyncio +import json from app.adapters.checkers.external_service import ( EXTERNAL_CHECKER_CAPABILITY_KEY, EXTERNAL_CHECKER_PROVIDER_KEY, UnixSocketExternalCheckerAdapter, ) from app.interfaces.external_services import ExternalServiceAdapterFactory +from app.modules.artifacts.api import SubmissionBundleFile from app.modules.tasks.api import TaskSubmissionContextFacts +from app.modules.projects.api import ProjectLockedPolicyContextFacts +from app.modules.checkers.api import SubmissionPacketView +from app.modules.checkers.api.artifact_paths import required_evidence_path +from app.modules.checkers.api.historical_post_submit import CompiledPostSubmitPolicy +from app.modules.checkers.api.post_submit import ( + ExpectedPostSubmitContext, + ObservedPostSubmitContext, + PostSubmissionEvaluationContent, + PostSubmissionStructuralInput, + PostSubmitEvidenceEntry, + PostSubmitManifestEntry, + PostSubmitPolicyInputs, +) from app.modules.checkers.api.external_policy import LockedExternalPostSubmitPolicy from app.modules.checkers.api.selected_post_submit import ( SelectedPostSubmissionContent, @@ -14,12 +30,19 @@ ) from app.modules.checkers.api.history import CheckerHistoryReadPort from app.modules.checkers.api.execution import EvaluationCoordinationPort -from typing import Any, Protocol +from typing import Any, BinaryIO, Protocol from pathlib import Path from app.modules.checkers.api import ( + PreSubmissionExecutionFacts, PreSubmissionInfrastructureUnavailableError, ) +from app.modules.checkers.catalogue import PreSubmissionCheckerCatalogue +from app.modules.checkers.pre_submit_execution import ( + DefaultPreSubmissionExecutionError, + DefaultPreSubmissionExecutionInput, + EffectivePreSubmissionProcessor, +) from app.modules.checkers.api.external import ( ExternalCheckerCapabilityDefinition, ExternalCheckerCapabilityProjection, @@ -89,6 +112,34 @@ def external_checker_registry_reader(session): return ExternalCheckerRegistryReader(session) +def project_guide_approval_compiler(*, disabled_checker_ids: str = ""): + """Build frozen catalogue fixtures for retained pre-cutover test evidence. + + Production proposal approval and activation use the immutable external + registry projection. This helper remains temporarily available to decode + and seed historical guide evidence while those fixtures are migrated. + """ + from app.modules.checkers.catalogue import ( + build_pre_submission_checker_catalogue, + parse_disabled_pre_submission_checker_ids, + project_guide_pre_submission_capabilities, + ) + from app.modules.checkers.api.historical_post_submit import ( + current_post_submit_catalogue, + ) + + planner = build_pre_submission_checker_catalogue( + disabled_entry_ids=parse_disabled_pre_submission_checker_ids( + disabled_checker_ids + ), + ) + return ( + planner, + project_guide_pre_submission_capabilities(planner), + current_post_submit_catalogue(), + ) + + async def external_checker_capability_projection( session, ) -> ExternalCheckerCapabilityProjection: @@ -159,6 +210,63 @@ class _ExecutionRequest(Protocol): storage_scheme: str +class _HistoricalFactsProcessor: + """Compatibility processor for retained pre-cutover fixture generation only.""" + + def __init__(self, processor: EffectivePreSubmissionProcessor) -> None: + self._processor = processor + + def abort(self) -> None: + self._processor.abort() + + async def process( + self, reader: BinaryIO, workspace: Path + ) -> PreSubmissionExecutionFacts: + try: + result = await asyncio.to_thread( + self._processor.process_blocking, reader, workspace + ) + return result.bounded_facts() + except DefaultPreSubmissionExecutionError as exc: + raise PreSubmissionInfrastructureUnavailableError(str(exc)) from exc + + +class PreSubmitCheckerExecutionAdapter: + """Build retained pre-cutover evidence in historical test fixtures only.""" + + def __init__( + self, *, catalogue: PreSubmissionCheckerCatalogue, archive_inspector: Any + ) -> None: + self._catalogue = catalogue + self._archive_inspector = archive_inspector + + @property + def catalogue_manifest_sha256(self) -> str: + return self._catalogue.manifest_sha256 + + def build(self, request: _ExecutionRequest) -> _HistoricalFactsProcessor: + if request.plan is None: + raise PreSubmissionInfrastructureUnavailableError( + "pre_submission_plan_identity_invalid" + ) + return _HistoricalFactsProcessor( + EffectivePreSubmissionProcessor( + archive_inspector=self._archive_inspector, + catalogue=self._catalogue, + execution_input=DefaultPreSubmissionExecutionInput( + plan=request.plan, + commitment=request.commitment, + inspection=request.inspection, + manifest=request.manifest, + change_gate=request.change_gate, + packet=request.packet, + prepared_generation_id=request.prepared_generation_id, + storage_scheme=request.storage_scheme, + ), + ) + ) + + class SelectedPreSubmitCheckerExecutionAdapter: """Build the selected default-plus-external PRE processor from exact ART facts.""" @@ -258,6 +366,114 @@ def current_post_submit_execution(session): return CurrentExecution(session) +def _historical_post_submit_catalogue(): + """Resolve the frozen pre-cutover catalogue for retained fixture decoding only.""" + from app.modules.checkers.api.historical_post_submit import ( + current_post_submit_catalogue, + ) + + return current_post_submit_catalogue() + + +def submission_evaluation_content( + task_context: TaskSubmissionContextFacts, + project_context: ProjectLockedPolicyContextFacts, + packet: SubmissionPacketView, + files: tuple[SubmissionBundleFile, ...], + archive_sha256: str, +) -> PostSubmissionEvaluationContent: + """Project immutable pre-cutover evidence for retained historical fixtures. + + New admission and execution callers use selected checker policies. This + compatibility projection exists only so historical Submission fixtures can + continue proving retained evidence without restoring catalogue eligibility. + """ + from app.adapters.tasks import validate_submission_policy_context + + validate_submission_policy_context(task_context, project_context) + stamps = task_context.locked_policy + expected = ExpectedPostSubmitContext( + guide_version=stamps.locked_guide_version, + source_id=stamps.locked_guide_source_snapshot_id, + source_hash=stamps.locked_guide_source_snapshot_hash, + effective_policy_id=( + stamps.locked_effective_project_submission_artifact_policy_id + ), + effective_policy_hash=( + stamps.locked_effective_project_submission_artifact_policy_hash + ), + pre_policy_id=stamps.locked_pre_submit_checker_policy_id, + pre_policy_hash=stamps.locked_pre_submit_checker_bundle_hash, + post_policy_id=stamps.locked_post_submit_checker_policy_id, + post_policy_version=stamps.locked_post_submit_checker_policy_version, + post_policy_hash=stamps.locked_post_submit_checker_policy_hash, + review_policy_id=stamps.locked_review_policy_id, + review_generation=stamps.locked_review_policy_generation, + review_hash=stamps.locked_review_policy_hash, + revision_policy_id=stamps.locked_revision_policy_id, + revision_generation=stamps.locked_revision_policy_generation, + revision_hash=stamps.locked_revision_policy_hash, + ) + effective = json.loads(project_context.effective_policy.value) + policy_inputs = PostSubmitPolicyInputs( + required_evidence_keys=tuple( + item["key"] + for item in effective.get("required_evidence", []) + if item.get("required", True) + ), + required_artifact_paths=tuple( + item["path"] + for item in effective.get("required_artifacts", []) + if item.get("required", True) + ), + forbidden_artifact_patterns=tuple( + item["pattern"] + for item in effective.get("forbidden_artifacts", []) + if item.get("pattern") + ), + required_attestation_terms=tuple( + term for term in effective.get("attestation_terms", []) if term + ), + ) + by_path = {item.normalized_path: item for item in files} + return PostSubmissionEvaluationContent( + project_id=project_context.project_id, + expected_context=expected, + catalogue=_historical_post_submit_catalogue(), + policy=CompiledPostSubmitPolicy.model_validate_json( + project_context.compiled_post_submit_policy.value + ), + structural_input=PostSubmissionStructuralInput( + summary=packet.summary, + worker_attestation=packet.contributor_attestation, + package_hash=archive_sha256, + criteria=task_context.acceptance_criteria or "", + manifest=tuple( + PostSubmitManifestEntry( + artifact=item.normalized_path, + hash=item.sha256, + size_bytes=item.byte_count, + ) + for item in files + ), + evidence=tuple( + PostSubmitEvidenceEntry( + label=key, + type="file", + key=key, + uri=item.normalized_path, + hash=item.sha256, + ) + for key in policy_inputs.required_evidence_keys + for item in (by_path.get(required_evidence_path(key)),) + if item is not None + ), + policy_inputs=policy_inputs, + observed_context=ObservedPostSubmitContext(**expected.model_dump()), + ), + ) + + def selected_submission_evaluation_content( task_context: TaskSubmissionContextFacts, policy: LockedExternalPostSubmitPolicy, diff --git a/backend/app/modules/checkers/api/__init__.py b/backend/app/modules/checkers/api/__init__.py index a34f325a0..aded93225 100644 --- a/backend/app/modules/checkers/api/__init__.py +++ b/backend/app/modules/checkers/api/__init__.py @@ -70,7 +70,7 @@ "SelectedPreSubmitInfrastructureUnavailable", ) -from app.modules.checkers.api.post_submit_catalogue import ( +from app.modules.checkers.api.historical_post_submit import ( CompiledPostSubmitPolicy, EmptyPostSubmitConfiguration, PostSubmitCatalogue, diff --git a/backend/app/modules/checkers/api/execution.py b/backend/app/modules/checkers/api/execution.py index 4dc348672..ebe9708af 100644 --- a/backend/app/modules/checkers/api/execution.py +++ b/backend/app/modules/checkers/api/execution.py @@ -14,7 +14,7 @@ PostSubmissionExecutionResult, ) from app.modules.checkers.api.post_submit import PostSubmitCurrentResultReference -from app.modules.checkers.api.post_submit_catalogue import ( +from app.modules.checkers.api.historical_post_submit import ( PostSubmitValue, ResourceId, Sha256, diff --git a/backend/app/modules/checkers/api/post_submit_catalogue.py b/backend/app/modules/checkers/api/historical_post_submit.py similarity index 100% rename from backend/app/modules/checkers/api/post_submit_catalogue.py rename to backend/app/modules/checkers/api/historical_post_submit.py diff --git a/backend/app/modules/checkers/api/materialization.py b/backend/app/modules/checkers/api/materialization.py index 01707588b..00097ce30 100644 --- a/backend/app/modules/checkers/api/materialization.py +++ b/backend/app/modules/checkers/api/materialization.py @@ -9,7 +9,7 @@ from app.core.hashing import canonical_json_hash from app.modules.checkers.api.execution import ExecuteFacts, execution_authority_digest, VerifiedMaterialFacts from app.modules.checkers.api.material import SubmissionMaterialEntry -from app.modules.checkers.api.post_submit_catalogue import PostSubmitValue, ResourceId, Sha256, VersionNumber +from app.modules.checkers.api.historical_post_submit import PostSubmitValue, ResourceId, Sha256, VersionNumber from app.modules.checkers.api.evaluation_contract import ( PostSubmissionExecutionRequest, diff --git a/backend/app/modules/checkers/api/output_custody.py b/backend/app/modules/checkers/api/output_custody.py index 49cd75bd6..288cd509c 100644 --- a/backend/app/modules/checkers/api/output_custody.py +++ b/backend/app/modules/checkers/api/output_custody.py @@ -8,7 +8,7 @@ from pydantic import Field, StrictInt, model_validator from app.modules.checkers.api.evaluation_contract import PostSubmissionExecutionRequest -from app.modules.checkers.api.post_submit_catalogue import ( +from app.modules.checkers.api.historical_post_submit import ( Identifier, PostSubmitValue, ResourceId, diff --git a/backend/app/modules/checkers/api/policy_custody.py b/backend/app/modules/checkers/api/policy_custody.py new file mode 100644 index 000000000..3b888e595 --- /dev/null +++ b/backend/app/modules/checkers/api/policy_custody.py @@ -0,0 +1,15 @@ +"""Persisted checker policy custody shared by selected policy owners.""" + +from dataclasses import dataclass +from typing import Any + + +@dataclass(frozen=True) +class CompiledPreSubmitCheckerPolicy: + """Compiled bundle plus index projections persisted on policy rows.""" + + compiler_version: str + compiled_bundle: dict[str, Any] + compiled_bundle_hash: str + checker_names: list[str] + checker_configs: dict[str, Any] diff --git a/backend/app/modules/checkers/api/post_submit.py b/backend/app/modules/checkers/api/post_submit.py index 181d87e61..3ef7e25ff 100644 --- a/backend/app/modules/checkers/api/post_submit.py +++ b/backend/app/modules/checkers/api/post_submit.py @@ -7,7 +7,7 @@ from pydantic import TypeAdapter, Field, StrictInt, StrictStr, model_validator from app.core.hashing import canonical_json_hash -from app.modules.checkers.api.post_submit_catalogue import ( +from app.modules.checkers.api.historical_post_submit import ( ByteCount, CompiledPostSubmitPolicy, GuideVersion, diff --git a/backend/app/modules/checkers/api/selected_post_submit.py b/backend/app/modules/checkers/api/selected_post_submit.py index 18bce8080..6fee3771e 100644 --- a/backend/app/modules/checkers/api/selected_post_submit.py +++ b/backend/app/modules/checkers/api/selected_post_submit.py @@ -11,7 +11,7 @@ from app.core.hashing import canonical_json_hash from app.modules.checkers.api.external import ExternalCheckerExecutionResult from app.modules.checkers.api.external_policy import LockedExternalPostSubmitPolicy -from app.modules.checkers.api.post_submit_catalogue import ( +from app.modules.checkers.api.historical_post_submit import ( ByteCount, PostSubmitValue, ResourceId, diff --git a/backend/app/modules/checkers/execution.py b/backend/app/modules/checkers/execution.py index 4f95f1971..87cd2e20f 100644 --- a/backend/app/modules/checkers/execution.py +++ b/backend/app/modules/checkers/execution.py @@ -47,7 +47,7 @@ SelectedPostSubmitProcessor, ) from app.interfaces.external_checker_execution import ExternalCheckerExecutionAdapter -from app.modules.checkers.api.post_submit_catalogue import canonical_post_submit_bytes +from app.modules.checkers.api.historical_post_submit import canonical_post_submit_bytes from app.modules.checkers.execution_repository import ( ExecutionRepository, reservation, diff --git a/backend/app/modules/checkers/execution_repository.py b/backend/app/modules/checkers/execution_repository.py index 9b705393c..69c7b11ee 100644 --- a/backend/app/modules/checkers/execution_repository.py +++ b/backend/app/modules/checkers/execution_repository.py @@ -22,7 +22,7 @@ from app.modules.checkers.api.selected_post_submit import ( SelectedPostSubmissionEvaluationResult, ) -from app.modules.checkers.api.post_submit_catalogue import canonical_post_submit_bytes +from app.modules.checkers.api.historical_post_submit import canonical_post_submit_bytes from app.modules.checkers.models import CheckerResult, CheckerRun, CheckerSubmissionFence diff --git a/backend/app/modules/checkers/post_submit_catalogue.py b/backend/app/modules/checkers/post_submit_catalogue.py index 8126f0b69..cf52802bc 100644 --- a/backend/app/modules/checkers/post_submit_catalogue.py +++ b/backend/app/modules/checkers/post_submit_catalogue.py @@ -2,7 +2,7 @@ from __future__ import annotations from typing import TYPE_CHECKING -from app.modules.checkers.api.post_submit_catalogue import ( +from app.modules.checkers.api.historical_post_submit import ( PostSubmitCatalogue, current_post_submit_catalogue, ) diff --git a/backend/app/modules/checkers/post_submit_implementations.py b/backend/app/modules/checkers/post_submit_implementations.py index 374172374..90ab9cfb2 100644 --- a/backend/app/modules/checkers/post_submit_implementations.py +++ b/backend/app/modules/checkers/post_submit_implementations.py @@ -10,7 +10,7 @@ PostSubmitEvidenceEntry, PostSubmitMemberResult, ) -from app.modules.checkers.api.post_submit_catalogue import PostSubmitDefinition +from app.modules.checkers.api.historical_post_submit import PostSubmitDefinition from app.modules.checkers.runner import ( CheckerContext, CheckerOutcome, diff --git a/backend/app/modules/checkers/runner.py b/backend/app/modules/checkers/runner.py index 5d330a3ef..0b7a1db1a 100644 --- a/backend/app/modules/checkers/runner.py +++ b/backend/app/modules/checkers/runner.py @@ -13,7 +13,7 @@ from typing import Awaitable from typing import Protocol -from app.modules.checkers.api.post_submit_catalogue import ( +from app.modules.checkers.api.historical_post_submit import ( PostSubmitDefinition, PostSubmitPolicyEntry, structural_definition, ) from app.modules.checkers.api.post_submit import ( diff --git a/backend/app/modules/projects/guide_compilation/proposal_approval.py b/backend/app/modules/projects/guide_compilation/proposal_approval.py index e84db5181..410ba637d 100644 --- a/backend/app/modules/projects/guide_compilation/proposal_approval.py +++ b/backend/app/modules/projects/guide_compilation/proposal_approval.py @@ -15,7 +15,7 @@ GuideProposalAuthorizationLocator, PreparedGuideProposalOperation, ) -from app.modules.checkers.api.policy_compilation import CompiledPreSubmitCheckerPolicy +from app.modules.checkers.api.policy_custody import CompiledPreSubmitCheckerPolicy from app.modules.checkers.api.external import ExternalCheckerRegistryPort from app.modules.checkers.api.external import ExternalCheckerCapabilityProjection from app.modules.checkers.api.external_policy import ( diff --git a/backend/app/modules/projects/post_policy/custody.py b/backend/app/modules/projects/post_policy/custody.py index c5d1b8012..73dca4b1d 100644 --- a/backend/app/modules/projects/post_policy/custody.py +++ b/backend/app/modules/projects/post_policy/custody.py @@ -6,7 +6,7 @@ from sqlalchemy import select from app.core.hashing import canonical_json_hash -from app.modules.checkers.api.post_submit_catalogue import CompiledPostSubmitPolicy +from app.modules.checkers.api.historical_post_submit import CompiledPostSubmitPolicy from app.modules.checkers.api.external_policy import LockedExternalPostSubmitPolicy from app.modules.authorization.api import ActorKind from app.modules.authorization.api.post_policy import PostPolicyAuthorityReceipt diff --git a/backend/app/modules/projects/post_submit_policy.py b/backend/app/modules/projects/post_submit_policy.py index 4db8fe36d..a7f43007b 100644 --- a/backend/app/modules/projects/post_submit_policy.py +++ b/backend/app/modules/projects/post_submit_policy.py @@ -4,7 +4,7 @@ import json from typing import Any from uuid import UUID -from app.modules.checkers.api.post_submit_catalogue import ( +from app.modules.checkers.api.historical_post_submit import ( CompiledPostSubmitPolicy, EmptyPostSubmitConfiguration, PostSubmitPolicyEntry, diff --git a/backend/app/modules/tasks/repository.py b/backend/app/modules/tasks/repository.py index 67fd87374..246db5ed5 100644 --- a/backend/app/modules/tasks/repository.py +++ b/backend/app/modules/tasks/repository.py @@ -7,7 +7,7 @@ from app.modules.tasks.api.transition_audit import TaskPolicyLineage from app.modules.checkers.api.external_policy import LockedExternalPostSubmitPolicy -from app.modules.checkers.api.post_submit_catalogue import CompiledPostSubmitPolicy +from app.modules.checkers.api.historical_post_submit import CompiledPostSubmitPolicy from uuid import UUID from sqlalchemy import Row, Select, and_, or_, select, tuple_ diff --git a/backend/app/modules/tasks/service.py b/backend/app/modules/tasks/service.py index 2ad1f1bb0..559c91cf1 100644 --- a/backend/app/modules/tasks/service.py +++ b/backend/app/modules/tasks/service.py @@ -15,7 +15,7 @@ LockedExternalCheckerPolicies, LockedExternalPostSubmitPolicy, ) -from app.modules.checkers.api.post_submit_catalogue import CompiledPostSubmitPolicy +from app.modules.checkers.api.historical_post_submit import CompiledPostSubmitPolicy from app.modules.projects.api.locked_policy import ( ProjectLockedPolicyContextFacts, ProjectLockedPolicyContextPort, diff --git a/backend/tests/authorization/guide_proposals/test_postgresql.py b/backend/tests/authorization/guide_proposals/test_postgresql.py index 92cab4e4c..ad06bebfd 100644 --- a/backend/tests/authorization/guide_proposals/test_postgresql.py +++ b/backend/tests/authorization/guide_proposals/test_postgresql.py @@ -19,7 +19,7 @@ build_pre_submission_checker_catalogue, project_guide_pre_submission_capabilities, ) -from app.modules.checkers.api.post_submit_catalogue import current_post_submit_catalogue +from app.modules.checkers.api.historical_post_submit import current_post_submit_catalogue from app.modules.projects.api.guide_proposals import ( GuideProposalApproval, GuideProposalCorrection, diff --git a/backend/tests/authorization/post_policy/pg_support.py b/backend/tests/authorization/post_policy/pg_support.py index 4f33a79df..46fd772c5 100644 --- a/backend/tests/authorization/post_policy/pg_support.py +++ b/backend/tests/authorization/post_policy/pg_support.py @@ -17,7 +17,7 @@ ) from app.modules.authorization.api import ActorKind from app.modules.actors.api import ServiceIdentity -from app.modules.checkers.api.post_submit_catalogue import current_post_submit_catalogue +from app.modules.checkers.api.historical_post_submit import current_post_submit_catalogue from app.modules.projects.post_policy.service import PostPolicyService from app.modules.projects.api.post_policy import ( PostPolicyApproval, diff --git a/backend/tests/authorization/task_locked_context/test_visibility.py b/backend/tests/authorization/task_locked_context/test_visibility.py index 3300c8e0b..9c5be7f8d 100644 --- a/backend/tests/authorization/task_locked_context/test_visibility.py +++ b/backend/tests/authorization/task_locked_context/test_visibility.py @@ -6,7 +6,7 @@ from app.db import session as db_session from app.modules.authorization.models import AdminRoleGrant -from app.modules.checkers.api.post_submit_catalogue import CompiledPostSubmitPolicy +from app.modules.checkers.api.historical_post_submit import CompiledPostSubmitPolicy from app.modules.tasks.lifecycle import ALLOWED_TASK_TRANSITIONS from app.modules.tasks.models import WorkstreamTask from tests.authorization.task_locked_context.support import KINDS, grant_for, path diff --git a/backend/tests/checkers/execution/historical_execution.py b/backend/tests/checkers/execution/historical_execution.py index dfd92d083..6728ebe39 100644 --- a/backend/tests/checkers/execution/historical_execution.py +++ b/backend/tests/checkers/execution/historical_execution.py @@ -25,7 +25,7 @@ PostSubmissionEvaluationResult, PostSubmitCurrentResultReference, ) -from app.modules.checkers.api.post_submit_catalogue import canonical_post_submit_bytes +from app.modules.checkers.api.historical_post_submit import canonical_post_submit_bytes from app.modules.checkers.execution_repository import request_text from app.modules.checkers.execution_results import classify_result from app.modules.checkers.models import CheckerRun, CheckerResult diff --git a/backend/tests/checkers/execution/material_storage_helpers.py b/backend/tests/checkers/execution/material_storage_helpers.py index a626e31c8..84f82e4e6 100644 --- a/backend/tests/checkers/execution/material_storage_helpers.py +++ b/backend/tests/checkers/execution/material_storage_helpers.py @@ -11,7 +11,7 @@ from app.core.identifiers import new_record_id from app.modules.checkers.api.execution import COMPLETION_EVENT, EvaluationCompletion from app.modules.checkers.api.post_submit import PostSubmitCurrentResultReference -from app.modules.checkers.api.post_submit_catalogue import canonical_post_submit_bytes +from app.modules.checkers.api.historical_post_submit import canonical_post_submit_bytes from app.modules.checkers.execution_results import classify_result from app.modules.checkers.models import CheckerResult, CheckerRun from app.modules.outbox.api import OutboxAppendInput diff --git a/backend/tests/checkers/external/test_selected_pre_submit.py b/backend/tests/checkers/external/test_selected_pre_submit.py index bfae5d516..92a62efec 100644 --- a/backend/tests/checkers/external/test_selected_pre_submit.py +++ b/backend/tests/checkers/external/test_selected_pre_submit.py @@ -5,9 +5,13 @@ from contextlib import contextmanager from dataclasses import replace from datetime import UTC, datetime, timedelta +from io import BytesIO import json +from pathlib import Path from types import SimpleNamespace +from typing import cast from unittest.mock import AsyncMock +import zipfile import pytest from app.core.hashing import canonical_json_hash @@ -47,17 +51,130 @@ from app.modules.checkers.selected_pre_submit_execution import SelectedPreSubmitProcessor from app.adapters.checkers import SelectedPreSubmitCheckerExecutionAdapter from app.modules.artifacts.pre_submit_attempts import PreSubmitAttemptClaim +from app.modules.artifacts.preparation import ( + HARD_MAXIMUM_ARTIFACT_BYTES, + ArtifactPreparationLimits, + ArtifactPreparationService, + ArtifactScratchManager, +) from app.modules.artifacts.selected_pre_submit_admission import ( bind_selected_pre_submit_admission, build_selected_pre_submit_reservation, ) -from app.modules.artifacts.submission_manifest import SubmissionCanonicalPredecessor +from app.modules.artifacts.submission_archive import ( + SubmissionArchiveInspector, + SubmissionArchiveLimits, +) +from app.modules.artifacts.submission_manifest import ( + SubmissionCanonicalPredecessor, + build_submission_manifest, + evaluate_submission_change, +) from app.modules.artifacts.submission_materialization import ( + PreparedBundleMaterializationRequest, PreparedBundleMaterializationService, ) -from app.modules.checkers.api.pre_submit import SubmissionPacketView +from app.modules.authorization.prepared import PreparedAuthorizationHandle +from app.modules.checkers.api.pre_submit import ( + EffectivePreSubmissionExecutionPlan, + EffectivePreSubmissionPlanLineage, + SubmissionPacketView, +) from tests.checkers.external.support import SHA, registry_entry -from tests.test_default_pre_submit_execution import _request + + +async def _bytes(value: bytes): + yield value + + +def _archive(primary_bytes: bytes) -> bytes: + output = BytesIO() + with zipfile.ZipFile(output, "w") as archive: + for name, value in ( + ("task.toml", primary_bytes), + ("evidence/results", b"verified\n"), + ): + entry = zipfile.ZipInfo(name, date_time=(1980, 1, 1, 0, 0, 0)) + archive.writestr(entry, value) + return output.getvalue() + + +def _limits() -> ArtifactPreparationLimits: + return ArtifactPreparationLimits( + aggregate_reserved_bytes=2 * HARD_MAXIMUM_ARTIFACT_BYTES, + maximum_files=2, + maximum_concurrency=2, + minimum_free_bytes=0, + reservation_ttl_seconds=30, + total_deadline_seconds=10, + cleanup_margin_seconds=5, + stream_buffer_bytes=1024, + maximum_source_bytes=1024 * 1024, + maximum_workspace_entries=2_000, + ) + + +class _PreparedHandle: + pass + + +async def _request( + tmp_path: Path, + *, + primary_bytes: bytes = b"[task]\nname='proof'\n", +): + lineage = EffectivePreSubmissionPlanLineage( + project_id=new_record_id(), + guide_id=new_record_id(), + guide_version="v1", + source_snapshot_id=new_record_id(), + source_snapshot_hash=SHA, + effective_policy_id=new_record_id(), + effective_policy_hash=SHA, + pre_submit_policy_id=new_record_id(), + pre_submit_policy_bundle_hash=SHA, + ) + plan = EffectivePreSubmissionExecutionPlan( + lineage=lineage, + catalogue_id="retired.test.fixture", + catalogue_version="v1", + catalogue_schema_version="retired", + catalogue_manifest_sha256=SHA, + entries=(), + plan_sha256=SHA, + ) + plan = replace(plan, plan_sha256=canonical_json_hash(plan.as_dict())) + inspector = SubmissionArchiveInspector(SubmissionArchiveLimits()) + manager = ArtifactScratchManager(root=tmp_path / "scratch", limits=_limits()) + preparation = ArtifactPreparationService(manager) + prepared = await preparation.prepare( + _bytes(_archive(primary_bytes)), media_type="application/zip" + ) + inspection = await prepared.inspect(inspector) + manifest = build_submission_manifest(inspection) + request = PreparedBundleMaterializationRequest( + prepared_authorization=cast(PreparedAuthorizationHandle, _PreparedHandle()), + task_id=new_record_id(), + assignment_id=new_record_id(), + submission_artifact_policy_id=lineage.effective_policy_id, + checker_policy_id=lineage.pre_submit_policy_id, + predecessor_submission_version=None, + prepared_artifact=prepared, + effective_plan=plan, + inspection=inspection, + manifest=manifest, + change_gate=evaluate_submission_change( + commitment=prepared.commitment, + manifest=manifest, + predecessor=None, + predecessor_exists=False, + ), + packet=SubmissionPacketView( + summary="Completed exact project work.", + contributor_attestation="rights_confirmed", + ), + ) + return request, inspector, manager, preparation, None def _open_input_schema() -> ExternalCheckerSchema: diff --git a/backend/tests/checkers/post_submit/support.py b/backend/tests/checkers/post_submit/support.py index 3d3c12817..886912264 100644 --- a/backend/tests/checkers/post_submit/support.py +++ b/backend/tests/checkers/post_submit/support.py @@ -12,7 +12,7 @@ PostSubmitManifestEntry, PostSubmitPolicyInputs, ) -from app.modules.checkers.api.post_submit_catalogue import PostSubmitCatalogue, PostSubmitDefinition +from app.modules.checkers.api.historical_post_submit import PostSubmitCatalogue, PostSubmitDefinition from app.modules.checkers.post_submit_catalogue import build_post_submit_catalogue from app.modules.checkers.api.post_submit import make_post_submit_request from app.modules.checkers.runner import default_checker_registry diff --git a/backend/tests/checkers/post_submit/test_catalogue.py b/backend/tests/checkers/post_submit/test_catalogue.py index a65e6635d..de8c29cc2 100644 --- a/backend/tests/checkers/post_submit/test_catalogue.py +++ b/backend/tests/checkers/post_submit/test_catalogue.py @@ -6,7 +6,7 @@ from pydantic import ValidationError from app.core.hashing import canonical_json_hash -from app.modules.checkers.api.post_submit_catalogue import ( +from app.modules.checkers.api.historical_post_submit import ( structural_definition, PostSubmitCatalogue, PostSubmitDefinition, diff --git a/backend/tests/checkers/post_submit/test_compiled_policy.py b/backend/tests/checkers/post_submit/test_compiled_policy.py index 60a0d15f1..15624f60d 100644 --- a/backend/tests/checkers/post_submit/test_compiled_policy.py +++ b/backend/tests/checkers/post_submit/test_compiled_policy.py @@ -7,7 +7,7 @@ from app.core.hashing import canonical_json_hash from app.modules.checkers.api import CompiledPostSubmitPolicy -from app.modules.checkers.api.post_submit_catalogue import current_post_submit_catalogue +from app.modules.checkers.api.historical_post_submit import current_post_submit_catalogue from app.modules.projects.post_submit_policy import build_project_post_submit_checker_spec, compile_project_post_submit_checker_spec, parse_locked_post_submit_checker_policy_body from tests.checkers.post_submit.support import PROJECT, altered_catalogue, catalogue, request diff --git a/backend/tests/checkers/post_submit/test_input_bounds.py b/backend/tests/checkers/post_submit/test_input_bounds.py index ae059510b..aaeaf2691 100644 --- a/backend/tests/checkers/post_submit/test_input_bounds.py +++ b/backend/tests/checkers/post_submit/test_input_bounds.py @@ -14,7 +14,7 @@ PostSubmitManifestEntry, PostSubmitPolicyInputs, ) -from app.modules.checkers.api.post_submit_catalogue import ( +from app.modules.checkers.api.historical_post_submit import ( PostSubmitResourceLimits, canonical_post_submit_bytes, ) diff --git a/backend/tests/checkers/post_submit/test_requirement_dispositions.py b/backend/tests/checkers/post_submit/test_requirement_dispositions.py index de0da34da..243277946 100644 --- a/backend/tests/checkers/post_submit/test_requirement_dispositions.py +++ b/backend/tests/checkers/post_submit/test_requirement_dispositions.py @@ -11,7 +11,7 @@ ProjectGuideCompilationResult, validate_project_guide_compilation_result, ) -from app.modules.checkers.api.post_submit_catalogue import ( +from app.modules.checkers.api.historical_post_submit import ( PostSubmitCatalogue, ) from tests.test_project_guide_compilation_contracts import _artifact_policy, _context, _evidence diff --git a/backend/tests/checkers/post_submit/test_result_contract.py b/backend/tests/checkers/post_submit/test_result_contract.py index 3528c968c..8ec701398 100644 --- a/backend/tests/checkers/post_submit/test_result_contract.py +++ b/backend/tests/checkers/post_submit/test_result_contract.py @@ -199,7 +199,7 @@ def test_consumers_revalidate_unchecked_copies(): def test_closed_result_shape_stays_below_declared_byte_ceilings(): - from app.modules.checkers.api.post_submit_catalogue import ( + from app.modules.checkers.api.historical_post_submit import ( PostSubmitResourceLimits, canonical_post_submit_bytes, ) diff --git a/backend/tests/committed_guide_fixtures.py b/backend/tests/committed_guide_fixtures.py index 315b9a7b1..2875df72b 100644 --- a/backend/tests/committed_guide_fixtures.py +++ b/backend/tests/committed_guide_fixtures.py @@ -95,7 +95,7 @@ async def create_compiled_report_fixture( """Project a scripted unified result under real service authority and custody.""" from app.adapters.auth import guide_compilation_request_authority, guide_compilation_execution_authority, guide_sufficiency_projection_authorization, artifact_policy_projection_authorization from app.modules.checkers.catalogue import build_pre_submission_checker_catalogue, project_guide_pre_submission_capabilities - from app.modules.checkers.api.post_submit_catalogue import current_post_submit_catalogue + from app.modules.checkers.api.historical_post_submit import current_post_submit_catalogue from app.modules.projects.api import ProjectGuideCompilationExecutionCommand, ProjectGuideProjectionCommand, ProjectGuideCompilationExecutionClassification from app.modules.projects.api.setup_identity import project_guide_compilation_task_id from app.modules.projects.guide_compilation.request_inputs import ( diff --git a/backend/tests/projects/guide_compilation/proposals/pg_support.py b/backend/tests/projects/guide_compilation/proposals/pg_support.py index d9be3102d..7ebeeca08 100644 --- a/backend/tests/projects/guide_compilation/proposals/pg_support.py +++ b/backend/tests/projects/guide_compilation/proposals/pg_support.py @@ -236,7 +236,7 @@ async def request_corrected_attempt(factory, actor, correction): build_pre_submission_checker_catalogue, project_guide_pre_submission_capabilities, ) - from app.modules.checkers.api.post_submit_catalogue import current_post_submit_catalogue + from app.modules.checkers.api.historical_post_submit import current_post_submit_catalogue from app.modules.projects.guide_compilation.request_inputs import CompilationRequestInputs from app.modules.projects.guide_compilation.service import GuideCompilationService from tests.projects.guide_compilation.helpers import runtime_configuration diff --git a/backend/tests/projects/guide_compilation/proposals/test_postgresql.py b/backend/tests/projects/guide_compilation/proposals/test_postgresql.py index f8e25f10e..44fc92f24 100644 --- a/backend/tests/projects/guide_compilation/proposals/test_postgresql.py +++ b/backend/tests/projects/guide_compilation/proposals/test_postgresql.py @@ -11,7 +11,7 @@ build_pre_submission_checker_catalogue, project_guide_pre_submission_capabilities, ) -from app.modules.checkers.api.post_submit_catalogue import current_post_submit_catalogue +from app.modules.checkers.api.historical_post_submit import current_post_submit_catalogue from app.modules.projects.api.guide_proposals import ( GuideProposalApproval, GuideProposalCorrection, diff --git a/backend/tests/projects/guide_compilation/test_automatic_request.py b/backend/tests/projects/guide_compilation/test_automatic_request.py index c80eb4f14..c03ef31ba 100644 --- a/backend/tests/projects/guide_compilation/test_automatic_request.py +++ b/backend/tests/projects/guide_compilation/test_automatic_request.py @@ -18,7 +18,7 @@ from app.modules.checkers.catalogue import project_guide_pre_submission_capabilities from app.modules.projects.guide_compilation.request_inputs import CompilationRequestInputs from app.modules.projects.models import ProjectSetupRun -from app.modules.checkers.api.post_submit_catalogue import current_post_submit_catalogue +from app.modules.checkers.api.historical_post_submit import current_post_submit_catalogue from tests.projects.client_fixtures import ( project_client as project_client, diff --git a/backend/tests/projects/guide_compilation/test_hidden_orchestrator_postgresql.py b/backend/tests/projects/guide_compilation/test_hidden_orchestrator_postgresql.py index 44ae4471e..1822d8b5c 100644 --- a/backend/tests/projects/guide_compilation/test_hidden_orchestrator_postgresql.py +++ b/backend/tests/projects/guide_compilation/test_hidden_orchestrator_postgresql.py @@ -46,7 +46,7 @@ from app.modules.checkers.catalogue import ( build_pre_submission_checker_catalogue, ) -from app.modules.checkers.api.post_submit_catalogue import current_post_submit_catalogue +from app.modules.checkers.api.historical_post_submit import current_post_submit_catalogue from .helpers import context, identity, result, seed_database from .runtime_fixtures import document_access, record_scripted_document_access diff --git a/backend/tests/projects/post_policy/pg_support.py b/backend/tests/projects/post_policy/pg_support.py index 85e97f439..b2afea955 100644 --- a/backend/tests/projects/post_policy/pg_support.py +++ b/backend/tests/projects/post_policy/pg_support.py @@ -127,7 +127,7 @@ async def prepare_post_policy(factory, command, actor, grant, setup_actor): async def operate(factory, actor, project_id, grant, operation, command, *, close_error=False, guide_close_error=False): - from app.modules.checkers.api.post_submit_catalogue import current_post_submit_catalogue + from app.modules.checkers.api.historical_post_submit import current_post_submit_catalogue from app.modules.projects.post_policy.service import PostPolicyService from tests.projects.guide_compilation.proposals.pg_support import ProposalAuthority diff --git a/backend/tests/projects/post_policy/test_compiler.py b/backend/tests/projects/post_policy/test_compiler.py index dcfebb6df..5bff9adcb 100644 --- a/backend/tests/projects/post_policy/test_compiler.py +++ b/backend/tests/projects/post_policy/test_compiler.py @@ -6,7 +6,7 @@ import pytest from app.interfaces.project_agents import ProjectGuideCompilationResult -from app.modules.checkers.api.post_submit_catalogue import current_post_submit_catalogue +from app.modules.checkers.api.historical_post_submit import current_post_submit_catalogue from app.modules.projects.post_policy.compiler import compile_saved_post_policy from tests.projects.guide_compilation.helpers import result diff --git a/backend/tests/projects/post_policy/test_direct_sql.py b/backend/tests/projects/post_policy/test_direct_sql.py index 39f3051e3..4a4f5d7b1 100644 --- a/backend/tests/projects/post_policy/test_direct_sql.py +++ b/backend/tests/projects/post_policy/test_direct_sql.py @@ -9,7 +9,7 @@ from sqlalchemy.exc import DBAPIError from app.core.identifiers import new_record_id -from app.modules.checkers.api.post_submit_catalogue import current_post_submit_catalogue +from app.modules.checkers.api.historical_post_submit import current_post_submit_catalogue from app.modules.projects.api.post_policy import PostPolicyApproval from app.modules.projects.post_policy.models import PostPolicyOperation from app.modules.projects.post_policy.service import PostPolicyService diff --git a/backend/tests/projects/post_policy/test_guards.py b/backend/tests/projects/post_policy/test_guards.py index 75fd74f65..c534c0ef1 100644 --- a/backend/tests/projects/post_policy/test_guards.py +++ b/backend/tests/projects/post_policy/test_guards.py @@ -7,7 +7,7 @@ from sqlalchemy import text from sqlalchemy.exc import DBAPIError -from app.modules.checkers.api.post_submit_catalogue import current_post_submit_catalogue +from app.modules.checkers.api.historical_post_submit import current_post_submit_catalogue from app.modules.projects.api.guide_proposals import GuideProposalError, GuideProposalSelection from app.modules.projects.api.post_policy import ( PostPolicyApproval, diff --git a/backend/tests/projects/post_policy/test_postgresql.py b/backend/tests/projects/post_policy/test_postgresql.py index 2e7cea042..64b24eb1b 100644 --- a/backend/tests/projects/post_policy/test_postgresql.py +++ b/backend/tests/projects/post_policy/test_postgresql.py @@ -9,7 +9,7 @@ from sqlalchemy import text -from app.modules.checkers.api.post_submit_catalogue import current_post_submit_catalogue +from app.modules.checkers.api.historical_post_submit import current_post_submit_catalogue from app.modules.projects.api.guide_proposals import GuideProposalApproval, GuideProposalSelection from app.modules.projects.api.post_policy import PostPolicyApproval, PostPolicyDerive, PostPolicySelection from app.modules.projects.post_policy.service import PostPolicyService diff --git a/backend/tests/projects/post_policy/test_public_api.py b/backend/tests/projects/post_policy/test_public_api.py index 8d78154f7..3da228a82 100644 --- a/backend/tests/projects/post_policy/test_public_api.py +++ b/backend/tests/projects/post_policy/test_public_api.py @@ -7,7 +7,7 @@ from app.main import create_app from app.modules.projects.post_policy.compiler import compile_saved_post_policy -from app.modules.checkers.api.post_submit_catalogue import current_post_submit_catalogue +from app.modules.checkers.api.historical_post_submit import current_post_submit_catalogue from app.interfaces.project_agents import ProjectGuideCompilationResult from tests.projects.guide_compilation.proposals.pg_support import revoke_review_grant, seed_review_actor from tests.projects.guide_compilation.proposals.public_support import proposal_client, proposal_path diff --git a/backend/tests/projects/unified_policy_fixtures.py b/backend/tests/projects/unified_policy_fixtures.py index 4bff86314..3c29491f5 100644 --- a/backend/tests/projects/unified_policy_fixtures.py +++ b/backend/tests/projects/unified_policy_fixtures.py @@ -18,7 +18,7 @@ build_pre_submission_checker_catalogue, project_guide_pre_submission_capabilities, ) -from app.modules.checkers.api.post_submit_catalogue import current_post_submit_catalogue +from app.modules.checkers.api.historical_post_submit import current_post_submit_catalogue from app.modules.projects.api import ( ProjectGuideProjectionCommand, ProjectGuideSetupFinalizationCommand, diff --git a/backend/tests/test_checkers.py b/backend/tests/test_checkers.py index d71bf137a..1c679c3ef 100644 --- a/backend/tests/test_checkers.py +++ b/backend/tests/test_checkers.py @@ -41,7 +41,7 @@ canonical_artifact_manifest_hash, ) from app.modules.checkers.api.history import CheckerRoutingRecommendation -from app.modules.checkers.api.post_submit_catalogue import current_post_submit_catalogue +from app.modules.checkers.api.historical_post_submit import current_post_submit_catalogue from app.modules.projects.post_submit_policy import ( DEFAULT_DURABLE_CHECKERS, POST_SUBMIT_CHECKER_POLICY_SPEC_SCHEMA_VERSION, @@ -1027,7 +1027,7 @@ def test_attestation_and_policy_projection_helpers_preserve_required_only_rules( @pytest.mark.asyncio async def test_checker_registry_preserves_policy_order_and_rejects_name_drift() -> None: - from app.modules.checkers.api.post_submit_catalogue import structural_definition + from app.modules.checkers.api.historical_post_submit import structural_definition registry = CheckerRegistry() async def outcome(name: str) -> CheckerOutcome: return CheckerOutcome(name, "passed", "info", f"{name} passed") diff --git a/backend/tests/test_tasks.py b/backend/tests/test_tasks.py index 3d51b14ee..89a2cf5ab 100644 --- a/backend/tests/test_tasks.py +++ b/backend/tests/test_tasks.py @@ -2931,7 +2931,7 @@ async def test_task_metadata_round_trips(task_client: AsyncClient) -> None: async def test_catalogue_rollout_blocks_task_transition_without_writes( task_client: AsyncClient, monkeypatch: pytest.MonkeyPatch, transition: str, phase: str, ) -> None: - from app.modules.checkers.api.post_submit_catalogue import current_post_submit_catalogue + from app.modules.checkers.api.historical_post_submit import current_post_submit_catalogue from app.modules.checkers.runner import default_checker_registry project = await create_active_project(task_client) From bccdd5fc38c02963c7ee03dff15fd45716cb7a14 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 21:48:33 +0100 Subject: [PATCH 089/283] [PILOT-04] migrate guide fixtures to registry projection --- backend/tests/committed_guide_fixtures.py | 24 +- .../projects/guide_compilation/helpers.py | 8 +- .../test_capability_growth.py | 309 ++++++++++++------ .../tests/projects/unified_policy_fixtures.py | 17 +- 4 files changed, 246 insertions(+), 112 deletions(-) diff --git a/backend/tests/committed_guide_fixtures.py b/backend/tests/committed_guide_fixtures.py index 2875df72b..321b02ae1 100644 --- a/backend/tests/committed_guide_fixtures.py +++ b/backend/tests/committed_guide_fixtures.py @@ -94,8 +94,7 @@ async def create_compiled_report_fixture( ) -> str: """Project a scripted unified result under real service authority and custody.""" from app.adapters.auth import guide_compilation_request_authority, guide_compilation_execution_authority, guide_sufficiency_projection_authorization, artifact_policy_projection_authorization - from app.modules.checkers.catalogue import build_pre_submission_checker_catalogue, project_guide_pre_submission_capabilities - from app.modules.checkers.api.historical_post_submit import current_post_submit_catalogue + from app.adapters.checkers import external_checker_capability_projection from app.modules.projects.api import ProjectGuideCompilationExecutionCommand, ProjectGuideProjectionCommand, ProjectGuideCompilationExecutionClassification from app.modules.projects.api.setup_identity import project_guide_compilation_task_id from app.modules.projects.guide_compilation.request_inputs import ( @@ -118,8 +117,8 @@ async def create_compiled_report_fixture( status, findings = diagnostic.status, diagnostic.findings manifest = await create_committed_document_fixture(source_snapshot_id) configuration = runtime_configuration() - pre = project_guide_pre_submission_capabilities(build_pre_submission_checker_catalogue()) - post = current_post_submit_catalogue() + async with sessions() as session: + capabilities = await external_checker_capability_projection(session) async with sessions() as session: setup = await session.get(ProjectSetupRun, str(manifest.setup_run_id)) setup.status = setup.current_step = "queued" @@ -130,7 +129,13 @@ async def create_compiled_report_fixture( session, automatic_request_selector(manifest.setup_run_id, manifest.setup_generation), ) as (authority, actor): - request = await GuideCompilationService(session, authority, request_inputs=CompilationRequestInputs(guide_document_manifest_port(session), pre, post, configuration)).request_automatic(actor=actor, setup_run_id=manifest.setup_run_id) + request = await GuideCompilationService( + session, + authority, + request_inputs=CompilationRequestInputs( + guide_document_manifest_port(session), capabilities, configuration + ), + ).request_automatic(actor=actor, setup_run_id=manifest.setup_run_id) class Runtime: identity = configuration.adapter_identity @@ -163,7 +168,14 @@ async def compile_project_guide(self, context, capabilities): patch["submission_artifact_policy"] = None return result().model_copy(update=patch) - execution = project_guide_compilation_execution_port(sessions, material_factory=guide_document_manifest_port, document_access_factory=document_access, pre_submission_capabilities=pre, post_submission_capabilities=post, authorization_context=guide_compilation_execution_authority, runtime_factory=lambda config: Runtime()) + execution = project_guide_compilation_execution_port( + sessions, + material_factory=guide_document_manifest_port, + document_access_factory=document_access, + checker_capabilities=capabilities, + authorization_context=guide_compilation_execution_authority, + runtime_factory=lambda config: Runtime(), + ) receipt = await execution.execute(ProjectGuideCompilationExecutionCommand(attempt_id=request.attempt_id)) assert receipt.classification is ProjectGuideCompilationExecutionClassification.PERSISTED projections = GuideCompilationProjectionService(sessions, material_factory=guide_document_manifest_port, sufficiency_authorization_factory=guide_sufficiency_projection_authorization, policy_authorization_factory=artifact_policy_projection_authorization) diff --git a/backend/tests/projects/guide_compilation/helpers.py b/backend/tests/projects/guide_compilation/helpers.py index 435640897..1da5900f3 100644 --- a/backend/tests/projects/guide_compilation/helpers.py +++ b/backend/tests/projects/guide_compilation/helpers.py @@ -103,7 +103,11 @@ def runtime_configuration(): def context( - values: dict[str, UUID], *, generation: int = 1, guide_version="v1" + values: dict[str, UUID], + *, + generation: int = 1, + guide_version="v1", + checker_capabilities=None, ) -> ProjectGuideCompilationContext: """Build one exact committed-original metadata context.""" material = GuideDocumentManifest( @@ -139,7 +143,7 @@ def context( instruction_version="v1", agent_identity="project-guide-compilation-agent-v1", agent_version="v1", - checker_capabilities=capability_projection(), + checker_capabilities=checker_capabilities or capability_projection(), ) diff --git a/backend/tests/projects/guide_compilation/test_capability_growth.py b/backend/tests/projects/guide_compilation/test_capability_growth.py index cdeeeece3..c69d3f565 100644 --- a/backend/tests/projects/guide_compilation/test_capability_growth.py +++ b/backend/tests/projects/guide_compilation/test_capability_growth.py @@ -1,77 +1,132 @@ """Catalogue growth reports retain exact matches without inventing executable checks.""" + from uuid import uuid4 import pytest from pydantic import ValidationError from app.interfaces.project_agents import ( - AtomicGuideRequirement, CapabilitySuggestion, CompilationFinding, - PostSubmissionBindingProposal, PreSubmissionBindingProposal, - ProjectGuideCompilationResult, validate_project_guide_compilation_result, + AtomicGuideRequirement, + CapabilitySuggestion, + CompilationFinding, + PostSubmissionBindingProposal, + PreSubmissionBindingProposal, + ProjectGuideCompilationResult, + validate_project_guide_compilation_result, ) from .helpers import context, ids, result +from tests.checkers.external.support import capability_projection, registry_entry + + +def _context(): + """Expose one exact selectable image in each phase for growth validation.""" + return context( + ids(), + checker_capabilities=capability_projection( + registry_entry("pre_submit"), registry_entry("post_submit") + ), + ) def growth_report(*, gaps=True): """Use current selectable definitions and distinct missing checks in both stages.""" - source = context(ids()) + source = _context() refs = result().findings[0].evidence_refs requirements, suggestions, pre, post = [], [], [], [] for stage in ("pre_submit", "post_submit"): key = f"supported_{stage}" - requirements.append(AtomicGuideRequirement( - requirement_id=key, statement="Require the registered structural check.", - disposition=f"supported_{stage}", evidence_refs=refs, - )) + requirements.append( + AtomicGuideRequirement( + requirement_id=key, + statement="Require the registered structural check.", + disposition=f"supported_{stage}", + evidence_refs=refs, + ) + ) if stage == "pre_submit": - definition = next(d for d in source.pre_submission_capabilities.definitions if d.selectable) - pre.append(PreSubmissionBindingProposal( - requirement_id=key, capability_id=definition.stable_id, - capability_version=definition.version, stage=stage, - )) + definition = next( + d + for d in source.checker_capabilities.definitions + if d.selectable and d.phase == stage + ) + pre.append( + PreSubmissionBindingProposal( + requirement_id=key, + capability_id=definition.capability_id, + capability_version=definition.capability_version, + stage=stage, + ) + ) else: - definition = next(d for d in source.post_submission_capabilities.definitions if d.selectable) - post.append(PostSubmissionBindingProposal( - requirement_id=key, capability_id=definition.capability_id, - capability_version=definition.capability_version, stage=stage, - )) + definition = next( + d + for d in source.checker_capabilities.definitions + if d.selectable and d.phase == stage + ) + post.append( + PostSubmissionBindingProposal( + requirement_id=key, + capability_id=definition.capability_id, + capability_version=definition.capability_version, + stage=stage, + ) + ) if gaps: key = f"gap_{stage}" - requirements.append(AtomicGuideRequirement( - requirement_id=key, statement="Require an unavailable automated semantic check.", - disposition=f"{stage}_capability_gap", evidence_refs=refs, - )) - suggestions.append(CapabilitySuggestion( - requirement_id=key, stage=stage, title="Automated semantic verification", - rationale="Engineering must implement and register the required semantic check.", - evidence_refs=refs, - )) - return result().model_copy(update={ - "status": "draft_ready_with_warnings" if gaps else "draft_ready", - "submission_artifact_policy": result().submission_artifact_policy, - "findings": (CompilationFinding( - severity="warning" if gaps else "info", code="catalogue.coverage", - message="Required automation is unavailable." if gaps else "All checks are supported.", - evidence_refs=refs, - ),), - "requirements": tuple(requirements), "capability_suggestions": tuple(suggestions), - "pre_submit_bindings": tuple(pre), "post_submit_bindings": tuple(post), - }) + requirements.append( + AtomicGuideRequirement( + requirement_id=key, + statement="Require an unavailable automated semantic check.", + disposition=f"{stage}_capability_gap", + evidence_refs=refs, + ) + ) + suggestions.append( + CapabilitySuggestion( + requirement_id=key, + stage=stage, + title="Automated semantic verification", + rationale="Engineering must implement and register the required semantic check.", + evidence_refs=refs, + ) + ) + return result().model_copy( + update={ + "status": "draft_ready_with_warnings" if gaps else "draft_ready", + "submission_artifact_policy": result().submission_artifact_policy, + "findings": ( + CompilationFinding( + severity="warning" if gaps else "info", + code="catalogue.coverage", + message="Required automation is unavailable." + if gaps + else "All checks are supported.", + evidence_refs=refs, + ), + ), + "requirements": tuple(requirements), + "capability_suggestions": tuple(suggestions), + "pre_submit_bindings": tuple(pre), + "post_submit_bindings": tuple(post), + } + ) @pytest.mark.parametrize("gaps", [True, False]) def test_exact_matches_and_gap_handoff(gaps): report = growth_report(gaps=gaps) parsed = ProjectGuideCompilationResult.model_validate_json(report.model_dump_json()) - validate_project_guide_compilation_result(context(ids()), parsed) + validate_project_guide_compilation_result(_context(), parsed) assert len(parsed.capability_suggestions) == (2 if gaps else 0) assert len(parsed.pre_submit_bindings) == len(parsed.post_submit_bindings) == 1 -@pytest.mark.parametrize("fault", ["missing", "duplicate", "orphan", "wrong_stage", "non_gap", "foreign_evidence"]) +@pytest.mark.parametrize( + "fault", ["missing", "duplicate", "orphan", "wrong_stage", "non_gap", "foreign_evidence"] +) def test_gap_handoff_rejects_invalid_linkage(fault): report = growth_report() - validate_project_guide_compilation_result(context(ids()), report) + validate_project_guide_compilation_result(_context(), report) suggestions = list(report.capability_suggestions) if fault == "missing": suggestions.pop() @@ -82,17 +137,28 @@ def test_gap_handoff_rejects_invalid_linkage(fault): "orphan": {"requirement_id": "absent"}, "wrong_stage": {"stage": "post_submit"}, "non_gap": {"requirement_id": "supported_pre_submit"}, - "foreign_evidence": {"evidence_refs": (suggestions[0].evidence_refs[0].model_copy( - update={"document_version_id": uuid4()}),)}, + "foreign_evidence": { + "evidence_refs": ( + suggestions[0] + .evidence_refs[0] + .model_copy(update={"document_version_id": uuid4()}), + ) + }, }[fault] suggestions[0] = CapabilitySuggestion.model_validate( suggestions[0].model_dump(mode="python") | update ) - report = ProjectGuideCompilationResult.model_validate(report.model_copy(update={ - "capability_suggestions": tuple(suggestions), - }).model_dump(mode="json")) - with pytest.raises(ValueError, match="source lineage" if fault == "foreign_evidence" else "suggestion"): - validate_project_guide_compilation_result(context(ids()), report) + report = ProjectGuideCompilationResult.model_validate( + report.model_copy( + update={ + "capability_suggestions": tuple(suggestions), + } + ).model_dump(mode="json") + ) + with pytest.raises( + ValueError, match="source lineage" if fault == "foreign_evidence" else "suggestion" + ): + validate_project_guide_compilation_result(_context(), report) @pytest.mark.parametrize("field", ["requirement_id", "stage", "evidence_refs"]) @@ -113,97 +179,150 @@ def test_suggestion_rejects_empty_evidence(): @pytest.mark.parametrize("disposition", ["human_review", "informational"]) def test_non_automated_requirements_need_no_suggestion(disposition): report = growth_report(gaps=False) - extra = AtomicGuideRequirement(requirement_id="human", statement="A reviewer assesses quality.", - disposition=disposition, evidence_refs=report.findings[0].evidence_refs) - report = report.model_copy(update={"requirements": (*report.requirements, extra), - "setup_notes": ("Consider an optional future reporting improvement.",)}) - validate_project_guide_compilation_result(context(ids()), report) + extra = AtomicGuideRequirement( + requirement_id="human", + statement="A reviewer assesses quality.", + disposition=disposition, + evidence_refs=report.findings[0].evidence_refs, + ) + report = report.model_copy( + update={ + "requirements": (*report.requirements, extra), + "setup_notes": ("Consider an optional future reporting improvement.",), + } + ) + validate_project_guide_compilation_result(_context(), report) assert report.capability_suggestions == () @pytest.mark.parametrize("stage", ["pre_submit", "post_submit"]) -@pytest.mark.parametrize("fault", ["missing", "duplicate", "unknown", "stale", "stage", "configuration"]) +@pytest.mark.parametrize( + "fault", ["missing", "duplicate", "unknown", "stale", "stage", "configuration"] +) def test_blocked_matches_still_require_exact_catalogue_validation(stage, fault): report = growth_report() field = f"{stage}_bindings" binding = getattr(report, field)[0] if fault == "configuration" and stage == "pre_submit": - payload = binding.model_dump(mode="json") | {"parameters": [{"name": "invented", "value": 1}]} + payload = binding.model_dump(mode="json") | { + "parameters": [{"name": "invented", "value": 1}] + } with pytest.raises(ValidationError, match="parameters"): PreSubmissionBindingProposal.model_validate(payload) return - updates = {"unknown": {"capability_id": "invented"}, "stale": {"capability_version": "absent"}, - "stage": {"stage": "post_submit" if stage == "pre_submit" else "pre_submit"}, - "configuration": {"parameters": [{"name": "invented", "value": 1}]}} + updates = { + "unknown": {"capability_id": "invented"}, + "stale": {"capability_version": "absent"}, + "stage": {"stage": "post_submit" if stage == "pre_submit" else "pre_submit"}, + "configuration": {"parameters": [{"name": "invented", "value": 1}]}, + } if fault in updates: binding = type(binding).model_validate(binding.model_dump(mode="json") | updates[fault]) - bindings = () if fault == "missing" else ((binding, binding) if fault == "duplicate" else (binding,)) + bindings = ( + () if fault == "missing" else ((binding, binding) if fault == "duplicate" else (binding,)) + ) with pytest.raises(ValueError): - validate_project_guide_compilation_result(context(ids()), report.model_copy(update={field: bindings})) + validate_project_guide_compilation_result( + _context(), report.model_copy(update={field: bindings}) + ) @pytest.mark.parametrize("count", [50, 51, 100, 101, 200, 201]) @pytest.mark.parametrize("kind", ["gap", "pre_submit", "post_submit"]) def test_requirement_and_handoff_limits_align(count, kind): base = growth_report(gaps=kind == "gap") - requirement = next(r for r in base.requirements if r.requirement_id == - ("gap_pre_submit" if kind == "gap" else f"supported_{kind}")) + requirement = next( + r + for r in base.requirements + if r.requirement_id == ("gap_pre_submit" if kind == "gap" else f"supported_{kind}") + ) field = "capability_suggestions" if kind == "gap" else f"{kind}_bindings" item = getattr(base, field)[0] payload = base.model_dump(mode="json") | { - "requirements": [requirement.model_dump(mode="json") | {"requirement_id": f"r{i}"} for i in range(count)], - "capability_suggestions": [], "pre_submit_bindings": [], "post_submit_bindings": [], + "requirements": [ + requirement.model_dump(mode="json") | {"requirement_id": f"r{i}"} for i in range(count) + ], + "capability_suggestions": [], + "pre_submit_bindings": [], + "post_submit_bindings": [], } - payload[field] = [item.model_dump(mode="json") | {"requirement_id": f"r{i}"} for i in range(count)] + payload[field] = [ + item.model_dump(mode="json") | {"requirement_id": f"r{i}"} for i in range(count) + ] if count > 200: with pytest.raises(ValidationError, match="at most 200"): ProjectGuideCompilationResult.model_validate(payload) else: parsed = ProjectGuideCompilationResult.model_validate(payload) - validate_project_guide_compilation_result(context(ids()), parsed) + validate_project_guide_compilation_result(_context(), parsed) @pytest.mark.parametrize("stage", ["pre_submit", "post_submit"]) def test_blocked_report_rejects_platform_defaults_as_project_bindings(stage): - source = context(ids()) + source = _context() report = growth_report() - definitions = (source.pre_submission_capabilities.definitions if stage == "pre_submit" - else source.post_submission_capabilities.definitions) + definitions = ( + source.checker_capabilities.definitions + if stage == "pre_submit" + else source.checker_capabilities.definitions + ) definition = next(d for d in definitions if not d.selectable) binding = getattr(report, f"{stage}_bindings")[0] - binding = binding.model_copy(update={ - "capability_id": definition.stable_id if stage == "pre_submit" else definition.capability_id, - "capability_version": definition.version if stage == "pre_submit" else definition.capability_version, - }) + binding = binding.model_copy( + update={ + "capability_id": definition.capability_id + if stage == "pre_submit" + else definition.capability_id, + "capability_version": definition.capability_version + if stage == "pre_submit" + else definition.capability_version, + } + ) with pytest.raises(ValueError, match="compilation capability binding is invalid"): - validate_project_guide_compilation_result(source, report.model_copy(update={f"{stage}_bindings": (binding,)})) + validate_project_guide_compilation_result( + source, report.model_copy(update={f"{stage}_bindings": (binding,)}) + ) def test_blocked_handoff_cannot_include_artifact_policy(): - report = result().model_copy(update={ - "status": "guide_blocked", - "submission_artifact_policy": None, - "findings": (CompilationFinding( - severity="blocking_gap", code="guide.invalid", - message="The guide cannot define a valid task policy.", - evidence_refs=result().findings[0].evidence_refs, - ),), - "requirements": (AtomicGuideRequirement( - requirement_id="guide_invalid", - statement="The guide must define a valid task policy.", - disposition="guide_blocker", - evidence_refs=result().findings[0].evidence_refs, - ),), - }) - validate_project_guide_compilation_result(context(ids()), report) + report = result().model_copy( + update={ + "status": "guide_blocked", + "submission_artifact_policy": None, + "findings": ( + CompilationFinding( + severity="blocking_gap", + code="guide.invalid", + message="The guide cannot define a valid task policy.", + evidence_refs=result().findings[0].evidence_refs, + ), + ), + "requirements": ( + AtomicGuideRequirement( + requirement_id="guide_invalid", + statement="The guide must define a valid task policy.", + disposition="guide_blocker", + evidence_refs=result().findings[0].evidence_refs, + ), + ), + } + ) + validate_project_guide_compilation_result(_context(), report) with pytest.raises(ValueError, match="blocked guide cannot publish policy proposals"): - validate_project_guide_compilation_result(context(ids()), report.model_copy(update={ - "submission_artifact_policy": result().submission_artifact_policy, - })) + validate_project_guide_compilation_result( + _context(), + report.model_copy( + update={ + "submission_artifact_policy": result().submission_artifact_policy, + } + ), + ) -@pytest.mark.parametrize("field", ["requirements", "capability_suggestions", - "pre_submit_bindings", "post_submit_bindings"]) +@pytest.mark.parametrize( + "field", + ["requirements", "capability_suggestions", "pre_submit_bindings", "post_submit_bindings"], +) def test_each_collection_ceiling_rejects_independently(field): """Schema proof keeps every other collection within bounds, before semantic checks.""" payload = growth_report().model_dump(mode="json") diff --git a/backend/tests/projects/unified_policy_fixtures.py b/backend/tests/projects/unified_policy_fixtures.py index 3c29491f5..cc4289318 100644 --- a/backend/tests/projects/unified_policy_fixtures.py +++ b/backend/tests/projects/unified_policy_fixtures.py @@ -14,11 +14,6 @@ from app.modules.actors.models import ActorIdentityLink, ActorProfile from app.modules.authorization.api import ActorIdentityFacts, ActorKind from app.modules.authorization.models import AdminRoleGrant -from app.modules.checkers.catalogue import ( - build_pre_submission_checker_catalogue, - project_guide_pre_submission_capabilities, -) -from app.modules.checkers.api.historical_post_submit import current_post_submit_catalogue from app.modules.projects.api import ( ProjectGuideProjectionCommand, ProjectGuideSetupFinalizationCommand, @@ -125,8 +120,13 @@ async def approve_unified_submission_policy(project_id, guide_id, policy_id, *, request_id=uuid4(), ) assert str(package.target.artifact_policy_id) == policy_id - planner = build_pre_submission_checker_catalogue() async with sessions() as session, session.begin(): + from app.adapters.checkers import ( + external_checker_capability_projection, + external_checker_registry_reader, + ) + + capabilities = await external_checker_capability_projection(session) receipt = await GuideProposalService( session, ProposalAuthority( @@ -135,6 +135,7 @@ async def approve_unified_submission_policy(project_id, guide_id, policy_id, *, UUID(project_id), grant_id, ), + external_checker_registry_reader(session), ).approve( GuideProposalApproval( target=package.target, @@ -146,9 +147,7 @@ async def approve_unified_submission_policy(project_id, guide_id, policy_id, *, actor=actor, request_id=uuid4(), material=guide_document_manifest_port(session), - pre_capabilities=project_guide_pre_submission_capabilities(planner), - post_capabilities=current_post_submit_catalogue(), - planner=planner, + capabilities=capabilities, ) async with sessions() as session: effective = await session.get( From f162977b7ca6ef155ef0538e80f2a782fb2fcbf6 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 21:49:13 +0100 Subject: [PATCH 090/283] [PILOT-04] select registry projection in compilation proofs --- .../test_automatic_request.py | 27 ++++---- .../test_hidden_orchestrator_postgresql.py | 63 ++++++++++--------- 2 files changed, 45 insertions(+), 45 deletions(-) diff --git a/backend/tests/projects/guide_compilation/test_automatic_request.py b/backend/tests/projects/guide_compilation/test_automatic_request.py index c03ef31ba..a5c0f4175 100644 --- a/backend/tests/projects/guide_compilation/test_automatic_request.py +++ b/backend/tests/projects/guide_compilation/test_automatic_request.py @@ -14,11 +14,9 @@ guide_document_manifest_port, ) from app.modules.authorization.api import ActorIdentityFacts, ActorKind, AuthorizationDenied -from app.modules.checkers.catalogue import build_pre_submission_checker_catalogue -from app.modules.checkers.catalogue import project_guide_pre_submission_capabilities from app.modules.projects.guide_compilation.request_inputs import CompilationRequestInputs from app.modules.projects.models import ProjectSetupRun -from app.modules.checkers.api.historical_post_submit import current_post_submit_catalogue +from tests.checkers.external.support import capability_projection from tests.projects.client_fixtures import ( project_client as project_client, @@ -78,8 +76,7 @@ def acknowledge_automatic_setup(setup): def automatic_service(session, actor): inputs = CompilationRequestInputs( guide_document_manifest_port(session), - project_guide_pre_submission_capabilities(build_pre_submission_checker_catalogue()), - current_post_submit_catalogue(), + capability_projection(), runtime_configuration=runtime_configuration(), ) return _execution_service(session, actor, request_inputs=inputs) @@ -93,7 +90,9 @@ async def test_automatic_source_requires_documents_then_persists_one_request_and from app.modules.projects.guide_compilation.repository import GuideCompilationIntegrityError async with factory() as session: - with pytest.raises(GuideCompilationIntegrityError, match="automatic compilation setup unavailable"): + with pytest.raises( + GuideCompilationIntegrityError, match="automatic compilation setup unavailable" + ): await automatic_service(session, actor).request_automatic( actor=actor, setup_run_id=setup_id ) @@ -252,9 +251,9 @@ async def test_sql_origin_rejects_each_missing_lineage_selector(automatic_source factory, actor, setup_id, snapshot = automatic_source await create_committed_document_fixture(snapshot["id"]) async with factory() as session, session.begin(): - facts, _identity, origin = await automatic_service( - session, actor - )._request_inputs.resolve(session, setup_id) + facts, _identity, origin = await automatic_service(session, actor)._request_inputs.resolve( + session, setup_id + ) async with factory() as session: changed = replace( facts, **{field: facts.setup_generation + 1 if field == "setup_generation" else uuid4()} @@ -482,7 +481,9 @@ async def revoke_between_reservation_rollback_and_recovery(service, **kwargs): ], ) async def test_stored_foreign_source_is_rejected_by_repository_and_insert( - automatic_source, project_client, field # noqa: F811 + automatic_source, + project_client, + field, # noqa: F811 ): from dataclasses import replace from sqlalchemy.exc import IntegrityError @@ -557,9 +558,7 @@ async def test_stored_foreign_source_is_rejected_by_repository_and_insert( if field in origin.__dataclass_fields__ else getattr(changed_facts, field) ) - stored_facts = replace( - changed_facts, operation_id=UUID(str(values["operation_id"])) - ) + stored_facts = replace(changed_facts, operation_id=UUID(str(values["operation_id"]))) forged = { **values, field: replacement if field.endswith("operation_id") else str(replacement), @@ -642,8 +641,6 @@ async def test_direct_insert_checks_exact_authority_digest(automatic_source, eve ) - - @pytest.mark.asyncio @pytest.mark.parametrize("authority", ["profile", "identity_link"]) async def test_automatic_replay_holds_authority_until_receipt_classification( diff --git a/backend/tests/projects/guide_compilation/test_hidden_orchestrator_postgresql.py b/backend/tests/projects/guide_compilation/test_hidden_orchestrator_postgresql.py index 1822d8b5c..9c1e472cb 100644 --- a/backend/tests/projects/guide_compilation/test_hidden_orchestrator_postgresql.py +++ b/backend/tests/projects/guide_compilation/test_hidden_orchestrator_postgresql.py @@ -2,8 +2,6 @@ from __future__ import annotations -from app.modules.checkers.catalogue import project_guide_pre_submission_capabilities - from tests.projects.guide_compilation.helpers import runtime_configuration from app.modules.authorization.api import ProjectGuideCompilationRequestOrigin @@ -43,10 +41,7 @@ SqlAlchemyGuideCompilationExecutionBackend, project_guide_compilation_execution_port, ) -from app.modules.checkers.catalogue import ( - build_pre_submission_checker_catalogue, -) -from app.modules.checkers.api.historical_post_submit import current_post_submit_catalogue +from tests.checkers.external.support import capability_projection from .helpers import context, identity, result, seed_database from .runtime_fixtures import document_access, record_scripted_document_access @@ -112,10 +107,7 @@ def _backend(factory): factory, material_factory=guide_document_manifest_port, document_access_factory=document_access, - pre_submission_capabilities=project_guide_pre_submission_capabilities( - build_pre_submission_checker_catalogue() - ), - post_submission_capabilities=current_post_submit_catalogue(), + checker_capabilities=capability_projection(), authorization_context=_fixed_service_authorization, ) @@ -125,10 +117,7 @@ def _port(factory, runtime): factory, material_factory=guide_document_manifest_port, document_access_factory=document_access, - pre_submission_capabilities=project_guide_pre_submission_capabilities( - build_pre_submission_checker_catalogue() - ), - post_submission_capabilities=current_post_submit_catalogue(), + checker_capabilities=capability_projection(), authorization_context=_fixed_service_authorization, runtime_factory=lambda configuration: runtime, ) @@ -552,11 +541,8 @@ async def test_unavailable_authority_returns_only_the_safe_public_code( port = project_guide_compilation_execution_port( factory, material_factory=guide_document_manifest_port, - document_access_factory=document_access, - pre_submission_capabilities=project_guide_pre_submission_capabilities( - build_pre_submission_checker_catalogue() - ), - post_submission_capabilities=current_post_submit_catalogue(), + document_access_factory=document_access, + checker_capabilities=capability_projection(), authorization_context=_unavailable_service_authorization, runtime_factory=lambda configuration: runtime, ) @@ -573,11 +559,19 @@ async def test_unavailable_authority_returns_only_the_safe_public_code( @pytest.mark.asyncio -@pytest.mark.parametrize("kind, failure_code", [ - ("malformed", "schema_invalid"), ("schema", "schema_invalid"), ("unsafe", "schema_invalid"), -]) +@pytest.mark.parametrize( + "kind, failure_code", + [ + ("malformed", "schema_invalid"), + ("schema", "schema_invalid"), + ("unsafe", "schema_invalid"), + ], +) async def test_sdk_parser_rejection_persists_terminal_without_reinvocation( - clean_postgres_database, monkeypatch, kind, failure_code, + clean_postgres_database, + monkeypatch, + kind, + failure_code, ): """Real SDK rejection persists its exact terminal class and replay makes no call.""" import json @@ -586,6 +580,7 @@ async def test_sdk_parser_rejection_persists_terminal_without_reinvocation( from app.adapters.project_agents.openai_agent_sdk import OpenAIAgentSdkProjectGuideRuntime from agents import _debug + monkeypatch.setattr(_debug, "DONT_LOG_MODEL_DATA", True) monkeypatch.setenv("OPENAI_API_KEY", "unit-test-only") payload = result().model_dump(mode="json") @@ -616,7 +611,8 @@ async def close(self): await self.capabilities.documents.close() monkeypatch.setattr( - "app.adapters.project_agents.openai_agent_sdk.OpenAIGuideWorkspace", ScriptedWorkspace, + "app.adapters.project_agents.openai_agent_sdk.OpenAIGuideWorkspace", + ScriptedWorkspace, ) values = await seed_database(clean_postgres_database) requested = await _authorized_attempt(clean_postgres_database, values) @@ -626,15 +622,22 @@ async def close(self): try: port = _port(factory, OpenAIAgentSdkProjectGuideRuntime(runtime_configuration())) first = await port.execute(command) - assert first.classification is ProjectGuideCompilationExecutionClassification.INVALID_TERMINAL + assert ( + first.classification is ProjectGuideCompilationExecutionClassification.INVALID_TERMINAL + ) assert await port.execute(command) == first assert calls == [1] async with factory() as session: - row = (await session.execute(text( - "select status,failure_code,canonical_result, " - "(select count(*) from project_guide_compilations) " - "from project_guide_compilation_attempts where id=:id" - ), {"id": requested.attempt_id})).one() + row = ( + await session.execute( + text( + "select status,failure_code,canonical_result, " + "(select count(*) from project_guide_compilations) " + "from project_guide_compilation_attempts where id=:id" + ), + {"id": requested.attempt_id}, + ) + ).one() assert row == ("compilation_invalid_terminal", failure_code, None, 0) finally: await engine.dispose() From 2e96c8afbc0686f7c3f07d622f5c16a482a8b90b Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 21:49:16 +0100 Subject: [PATCH 091/283] [PILOT-04] remove obsolete catalogue selection proofs --- .../proposals/test_selected_checks.py | 116 ------------------ 1 file changed, 116 deletions(-) delete mode 100644 backend/tests/projects/guide_compilation/proposals/test_selected_checks.py diff --git a/backend/tests/projects/guide_compilation/proposals/test_selected_checks.py b/backend/tests/projects/guide_compilation/proposals/test_selected_checks.py deleted file mode 100644 index 89de3cf35..000000000 --- a/backend/tests/projects/guide_compilation/proposals/test_selected_checks.py +++ /dev/null @@ -1,116 +0,0 @@ -"""Selected guide requirements must survive real policy compilation at approval.""" - -from types import SimpleNamespace -from uuid import uuid4 - -import pytest -from sqlalchemy import select, text - -from app.interfaces.project_agents import ProjectGuideCompilationResult -from app.core.identifiers import new_record_id -from app.modules.checkers.catalogue import build_pre_submission_checker_catalogue -from app.modules.projects.api.guide_proposals import GuideProposalApproval, GuideProposalError -from app.modules.projects.guide_compilation.models import ProjectGuideProposalApproval -from app.modules.projects.guide_compilation.projection_payloads import policy_body -from app.modules.projects.guide_compilation.proposal_approval import _compile_approval -from app.modules.projects.guide_compilation.request_inputs import CompilationRequestInputs -from tests.projects.guide_compilation.helpers import context, ids, result -from .pg_support import proposal_case, read_package -from .test_postgresql import approve - - -CASES = [ - ("required_evidence", "policy.evidence.minimum", "checker_log", "evidence_paths", "evidence/required-evidence-001"), - ("required_artifacts", "policy.file.require", "answer.md", "artifact_paths", "answer.md"), -] - - -def selected_result(field, capability, value, configured): - body = result().model_dump(mode="json") - body["submission_artifact_policy"][field] = [value] if configured else [] - body["requirements"] = [dict( - requirement_id="required-check", statement="Require the declared submission input.", - disposition="supported_pre_submit", evidence_refs=body["findings"][0]["evidence_refs"], - )] - body["pre_submit_bindings"] = [dict( - requirement_id="required-check", capability_id=capability, - capability_version="v1", stage="pre_submit", - )] - return ProjectGuideCompilationResult.model_validate(body) - - -@pytest.mark.parametrize("field,capability,value,config_key,expected", CASES) -@pytest.mark.parametrize("configured", [False, True]) -async def test_approval_reconciles_selection_with_real_compiled_configuration( - monkeypatch, field, capability, value, config_key, expected, configured, -): - compilation_context = context(ids()) - outcome = selected_result(field, capability, value, configured) - - async def loaded_context(self, session, setup): - return compilation_context - - monkeypatch.setattr(CompilationRequestInputs, "context_for_setup", loaded_context) - material = compilation_context.material - target = SimpleNamespace( - project_id=material.project_id, guide_id=material.guide_id, - guide_version=material.guide_version, source_snapshot_id=material.source_snapshot_id, - source_snapshot_hash=material.source_snapshot_hash, artifact_policy_id=new_record_id(), - digest="sha256:" + "a" * 64, - pre_catalogue_manifest_hash=compilation_context.pre_submission_capabilities.manifest_sha256, - ) - locked = SimpleNamespace(result=outcome, view=SimpleNamespace( - attempt=SimpleNamespace(runtime_configuration=compilation_context.runtime_configuration.model_dump(mode="json")), - setup=object(), policy=SimpleNamespace(policy_body=policy_body(None, outcome.submission_artifact_policy)), - )) - command = SimpleNamespace(target=target, acknowledged_warning_hashes=()) - args = (None, locked, command, new_record_id(), None, - compilation_context.pre_submission_capabilities, - compilation_context.post_submission_capabilities, - build_pre_submission_checker_catalogue()) - if not configured: - with pytest.raises(GuideProposalError) as error: - await _compile_approval(*args) - assert error.value.code == "approval_blocked" - else: - outputs = await _compile_approval(*args) - entries = [entry for entry in outputs.plan.entries if entry.definition_id == capability] - assert len(entries) == 1 - assert entries[0].definition_version == "v1" - assert entries[0].checker_definition_state == "enabled" - assert entries[0].configuration.as_dict()[config_key] == [expected] - assert any(entry.definition_id == "policy.hash.verify" for entry in outputs.plan.entries) - - -@pytest.mark.parametrize("field,capability,value,config_key,expected", CASES) -@pytest.mark.parametrize("configured", [False, True]) -async def test_selected_requirement_is_persisted_or_approval_rejects_without_writes( - clean_postgres_database, field, capability, value, config_key, expected, configured, -): - outcome = selected_result(field, capability, value, configured) - async with proposal_case(clean_postgres_database, outcome=outcome) as (_, factory, command, actor, grant): - package = await read_package(factory, command, actor, grant) - payload = GuideProposalApproval(target=package.target, idempotency_key=uuid4()) - async with factory() as session: - before_audit = await session.scalar(text("SELECT count(*) FROM audit_events")) - if not configured: - with pytest.raises(GuideProposalError) as error: - await approve(factory, command, actor, grant, payload) - assert error.value.code == "approval_blocked" - async with factory() as session: - for table in ("project_guide_proposal_approvals", "effective_project_submission_artifact_policies", - "pre_submit_checker_policies", "submission_policy_mutation_idempotency_records"): - assert await session.scalar(text(f"SELECT count(*) FROM {table}")) == 0 - assert await session.scalar(text("SELECT count(*) FROM audit_events")) == before_audit - assert (await read_package(factory, command, actor, grant)).artifact_policy_status == "draft" - else: - receipt = await approve(factory, command, actor, grant, payload) - async with factory() as session: - operation = await session.scalar(select(ProjectGuideProposalApproval).where( - ProjectGuideProposalApproval.operation_id == receipt.operation_id)) - entries = [entry for entry in operation.effective_pre_submit_plan["entries"] - if entry["definition_id"] == capability] - assert len(entries) == 1 - assert entries[0]["configuration"][config_key] == [expected] - assert operation.receipt_json == receipt.model_dump(mode="json") - assert await approve(factory, command, actor, grant, payload) == receipt From 47aeec4179f0bd554f3da030312a70cdf86cb01c Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 21:50:22 +0100 Subject: [PATCH 092/283] [PILOT-04] migrate proposal proofs to checker registry --- .../guide_proposals/test_postgresql.py | 20 +- .../guide_compilation/proposals/pg_support.py | 173 ++++++--- .../proposals/test_postgresql.py | 346 +++++++++++++----- 3 files changed, 394 insertions(+), 145 deletions(-) diff --git a/backend/tests/authorization/guide_proposals/test_postgresql.py b/backend/tests/authorization/guide_proposals/test_postgresql.py index ad06bebfd..75ec64d4a 100644 --- a/backend/tests/authorization/guide_proposals/test_postgresql.py +++ b/backend/tests/authorization/guide_proposals/test_postgresql.py @@ -15,11 +15,6 @@ HumanAuthorizationContext, IdentityLinkStatus, ) -from app.modules.checkers.catalogue import ( - build_pre_submission_checker_catalogue, - project_guide_pre_submission_capabilities, -) -from app.modules.checkers.api.historical_post_submit import current_post_submit_catalogue from app.modules.projects.api.guide_proposals import ( GuideProposalApproval, GuideProposalCorrection, @@ -52,9 +47,15 @@ async def service(factory, actor): correlation_id=uuid4(), ) try: + from app.adapters.checkers import external_checker_registry_reader + yield ( session, - GuideProposalService(session, GuideProposalAuthorizationAdapter(session, context)), + GuideProposalService( + session, + GuideProposalAuthorizationAdapter(session, context), + external_checker_registry_reader(session), + ), request, ) except GuideProposalError as exc: @@ -78,15 +79,14 @@ async def mutate(factory, actor, payload): async with service(factory, actor) as (session, owner, request): if isinstance(payload, GuideProposalCorrection): return await owner.request_correction(payload, actor=actor, request_id=request) - planner = build_pre_submission_checker_catalogue() + from app.adapters.checkers import external_checker_capability_projection + return await owner.approve( payload, actor=actor, request_id=request, material=guide_document_manifest_port(session), - pre_capabilities=project_guide_pre_submission_capabilities(planner), - post_capabilities=current_post_submit_catalogue(), - planner=planner, + capabilities=await external_checker_capability_projection(session), ) diff --git a/backend/tests/projects/guide_compilation/proposals/pg_support.py b/backend/tests/projects/guide_compilation/proposals/pg_support.py index 7ebeeca08..1a1729b47 100644 --- a/backend/tests/projects/guide_compilation/proposals/pg_support.py +++ b/backend/tests/projects/guide_compilation/proposals/pg_support.py @@ -120,7 +120,14 @@ async def validate_replay(self, facts, decision_event_id): class ProposalAuthority: def __init__( - self, session, actor, project_id, grant_id, *, on_consume=None, close_error=False, + self, + session, + actor, + project_id, + grant_id, + *, + on_consume=None, + close_error=False, resource_override=None, ): self.session, self.actor = session, actor @@ -168,7 +175,9 @@ async def prepare_proposal_operation(self, locator): @asynccontextmanager async def proposal_case(url, *, classification="draft_ready", guide_version="v1", outcome=None): - async with database_case(url, classification=classification, guide_version=guide_version, outcome=outcome) as (values, factory, command): + async with database_case( + url, classification=classification, guide_version=guide_version, outcome=outcome + ) as (values, factory, command): await finalize(factory, values, command) async with factory() as session: row = ( @@ -232,11 +241,7 @@ async def request_corrected_attempt(factory, actor, correction): HumanAuthorizationContext, IdentityLinkStatus, ) - from app.modules.checkers.catalogue import ( - build_pre_submission_checker_catalogue, - project_guide_pre_submission_capabilities, - ) - from app.modules.checkers.api.historical_post_submit import current_post_submit_catalogue + from tests.checkers.external.support import capability_projection from app.modules.projects.guide_compilation.request_inputs import CompilationRequestInputs from app.modules.projects.guide_compilation.service import GuideCompilationService from tests.projects.guide_compilation.helpers import runtime_configuration @@ -259,8 +264,7 @@ async def request_corrected_attempt(factory, actor, correction): ProjectGuideCompilationAuthorizationAdapter(kernel, prepared), request_inputs=CompilationRequestInputs( guide_document_manifest_port(session), - project_guide_pre_submission_capabilities(build_pre_submission_checker_catalogue()), - current_post_submit_catalogue(), + capability_projection(), runtime_configuration(), ), ) @@ -273,28 +277,34 @@ async def finalize_corrected_attempt(factory, values, actor, correction): """Run a scripted result through actual execution, projections and finalization.""" from app.adapters.artifacts import guide_document_manifest_port from app.adapters.auth import ( - artifact_policy_projection_authorization, guide_compilation_execution_authority, - guide_compilation_request_authority, guide_sufficiency_projection_authorization, + artifact_policy_projection_authorization, + guide_compilation_execution_authority, + guide_compilation_request_authority, + guide_sufficiency_projection_authorization, setup_finalization_authorization, ) - from app.adapters.checkers import project_guide_approval_compiler + from app.adapters.checkers import external_checker_capability_projection from app.adapters.projects import project_guide_compilation_delivery_port from app.modules.projects.api import ProjectGuideSetupFinalizationCommand from app.modules.projects.api.guide_compilation import ProjectGuideCompilationDelivery from app.modules.projects.api.setup_identity import project_guide_compilation_task_id from tests.projects.guide_compilation.helpers import runtime_configuration - from tests.projects.guide_compilation.runtime_fixtures import ScriptedGuideRuntime, document_access + from tests.projects.guide_compilation.runtime_fixtures import ( + ScriptedGuideRuntime, + document_access, + ) await request_corrected_attempt(factory, actor, correction) async with factory() as session: setup = await session.get(ProjectSetupRun, str(correction.successor_setup_run_id)) runtime = ScriptedGuideRuntime() - _, pre, post = project_guide_approval_compiler() + async with factory() as session: + capabilities = await external_checker_capability_projection(session) coordinator = project_guide_compilation_delivery_port( factory, material_factory=guide_document_manifest_port, document_access_factory=document_access, - pre_capabilities=pre, post_capabilities=post, + checker_capabilities=capabilities, request_authority=guide_compilation_request_authority, execution_authority=guide_compilation_execution_authority, configuration_factory=runtime_configuration, @@ -304,30 +314,37 @@ async def finalize_corrected_attempt(factory, values, actor, correction): finalization_authorization_factory=setup_finalization_authorization, ) delivery = ProjectGuideCompilationDelivery( - project_id=values["project"], guide_id=values["guide"], + project_id=values["project"], + guide_id=values["guide"], source_snapshot_id=setup.source_snapshot_id, setup_run_id=correction.successor_setup_run_id, setup_generation=correction.successor_setup_generation, - task_id=project_guide_compilation_task_id(str(correction.successor_setup_run_id), correction.successor_setup_generation), + task_id=project_guide_compilation_task_id( + str(correction.successor_setup_run_id), correction.successor_setup_generation + ), ) receipt = await coordinator.run(delivery) assert receipt["status"] == "policy_draft_ready", receipt assert runtime.calls == 1 from app.modules.projects.guide_compilation.models import ProjectGuideSetupFinalization + async with factory() as session: finalization = await session.get( ProjectGuideSetupFinalization, UUID(str(receipt["finalization_id"])) ) compilation_id = finalization.compilation_id return ProjectGuideSetupFinalizationCommand( - project_id=values["project"], guide_id=values["guide"], + project_id=values["project"], + guide_id=values["guide"], setup_run_id=correction.successor_setup_run_id, setup_generation=correction.successor_setup_generation, compilation_id=compilation_id, ) -async def seed_review_actor(factory, project_id, *, actor=None, role="project_manager", scope="project"): +async def seed_review_actor( + factory, project_id, *, actor=None, role="project_manager", scope="project" +): """Seed stored grant variants; request/approval authority guards remain enabled.""" from datetime import UTC, datetime from app.modules.actors.models import ActorProfile, ActorIdentityLink @@ -336,46 +353,98 @@ async def seed_review_actor(factory, project_id, *, actor=None, role="project_ma async with factory() as session, session.begin(): if actor is None: actor = ActorIdentityFacts(new_record_id(), new_record_id(), ActorKind.HUMAN) - session.add(ActorProfile(id=str(actor.actor_profile_id), actor_kind="human", status="active", - provisioning_method="automatic_first_access", created_by="proposal-fixture")) + session.add( + ActorProfile( + id=str(actor.actor_profile_id), + actor_kind="human", + status="active", + provisioning_method="automatic_first_access", + created_by="proposal-fixture", + ) + ) await session.flush() - session.add(ActorIdentityLink(id=str(actor.identity_link_id), actor_profile_id=str(actor.actor_profile_id), - issuer="https://identity.flowresearch.tech", subject=str(actor.actor_profile_id), - subject_kind="human", status="active", linked_by="proposal-fixture", - last_verified_at=datetime.now(UTC))) + session.add( + ActorIdentityLink( + id=str(actor.identity_link_id), + actor_profile_id=str(actor.actor_profile_id), + issuer="https://identity.flowresearch.tech", + subject=str(actor.actor_profile_id), + subject_kind="human", + status="active", + linked_by="proposal-fixture", + last_verified_at=datetime.now(UTC), + ) + ) await session.flush() - grant = await grant_fixture_admin_role(session, actor.actor_profile_id, role=role, scope=scope, - project_id=project_id if scope == "project" else None) + grant = await grant_fixture_admin_role( + session, + actor.actor_profile_id, + role=role, + scope=scope, + project_id=project_id if scope == "project" else None, + ) return actor, grant.id async def revoke_review_grant(factory, actor, grant): """Use the database's real revoke transition with an attributed administrator.""" - administrator, admin_grant = await seed_review_actor(factory, None, role="access_administrator", scope="system") + administrator, admin_grant = await seed_review_actor( + factory, None, role="access_administrator", scope="system" + ) async with factory() as session, session.begin(): - result = await session.execute(text( - "UPDATE admin_role_grants SET status='revoked',version=2,revoked_by_actor_profile_id=:actor," - "revoked_by_admin_role_grant_id=:authorizer,revoked_at=now(),revoked_reason='Manager turnover' WHERE id=:id AND target_actor_profile_id=:target" - ), {"actor": str(administrator.actor_profile_id), "authorizer": admin_grant, "id": grant, "target": str(actor.actor_profile_id)}) + result = await session.execute( + text( + "UPDATE admin_role_grants SET status='revoked',version=2,revoked_by_actor_profile_id=:actor," + "revoked_by_admin_role_grant_id=:authorizer,revoked_at=now(),revoked_reason='Manager turnover' WHERE id=:id AND target_actor_profile_id=:target" + ), + { + "actor": str(administrator.actor_profile_id), + "authorizer": admin_grant, + "id": grant, + "target": str(actor.actor_profile_id), + }, + ) assert result.rowcount == 1 -async def seed_selected_review_revision_inputs(factory, command, actor, *, human_review_required=True): +async def seed_selected_review_revision_inputs( + factory, command, actor, *, human_review_required=True +): """Select valid review/revision inputs through their authorized mutation owner.""" from app.modules.actors.models import ActorProfile, ActorIdentityLink from app.modules.actors.service import ResolvedActor from app.modules.authorization.kernel import AuthorizationService from app.modules.authorization.prepared import PreparedAuthorizationService from app.modules.authorization.repository import AdminAuthorizationRepository - from app.modules.authorization.runtime import ActorStatus, HumanAuthorizationContext, IdentityLinkStatus - from app.modules.projects.policy_mutation_service import ProjectPolicyMutationService, NO_CURRENT_POLICY_ETAG + from app.modules.authorization.runtime import ( + ActorStatus, + HumanAuthorizationContext, + IdentityLinkStatus, + ) + from app.modules.projects.policy_mutation_service import ( + ProjectPolicyMutationService, + NO_CURRENT_POLICY_ETAG, + ) from app.modules.projects.schemas import ReviewPolicyInput, RevisionPolicyInput for kind, payload in ( - ("review", ReviewPolicyInput(human_review_required=human_review_required, review_preference_window_seconds=3600, review_lease_duration_seconds=1800, - allowed_decisions=["accept", "needs_revision", "reject"])), - ("revision", RevisionPolicyInput(max_revision_rounds=2, revision_deadline_hours=48, - allowed_resubmission_states=["needs_revision"])), + ( + "review", + ReviewPolicyInput( + human_review_required=human_review_required, + review_preference_window_seconds=3600, + review_lease_duration_seconds=1800, + allowed_decisions=["accept", "needs_revision", "reject"], + ), + ), + ( + "revision", + RevisionPolicyInput( + max_revision_rounds=2, + revision_deadline_hours=48, + allowed_resubmission_states=["needs_revision"], + ), + ), ): async with factory() as session: resolved = ResolvedActor( @@ -383,14 +452,30 @@ async def seed_selected_review_revision_inputs(factory, command, actor, *, human await session.get(ActorIdentityLink, str(actor.identity_link_id)), ) ctx = HumanAuthorizationContext( - actor_profile_id=actor.actor_profile_id, actor_kind=ActorKind.HUMAN, - actor_status=ActorStatus.ACTIVE, identity_link_id=actor.identity_link_id, - identity_link_status=IdentityLinkStatus.ACTIVE, request_id=uuid4(), correlation_id=uuid4(), + actor_profile_id=actor.actor_profile_id, + actor_kind=ActorKind.HUMAN, + actor_status=ActorStatus.ACTIVE, + identity_link_id=actor.identity_link_id, + identity_link_status=IdentityLinkStatus.ACTIVE, + request_id=uuid4(), + correlation_id=uuid4(), ) repository = AdminAuthorizationRepository(session) kernel = AuthorizationService(session, ctx, admin_repository=repository) prepared = PreparedAuthorizationService(session, ctx, kernel, repository) service = ProjectPolicyMutationService(session) - mutate = service.replace_review_policy if kind == "review" else service.replace_revision_policy - await mutate(resolved, prepared, uuid4(), NO_CURRENT_POLICY_ETAG, command.project_id, command.guide_id, payload) + mutate = ( + service.replace_review_policy + if kind == "review" + else service.replace_revision_policy + ) + await mutate( + resolved, + prepared, + uuid4(), + NO_CURRENT_POLICY_ETAG, + command.project_id, + command.guide_id, + payload, + ) await session.commit() diff --git a/backend/tests/projects/guide_compilation/proposals/test_postgresql.py b/backend/tests/projects/guide_compilation/proposals/test_postgresql.py index 44fc92f24..f62b5a2a4 100644 --- a/backend/tests/projects/guide_compilation/proposals/test_postgresql.py +++ b/backend/tests/projects/guide_compilation/proposals/test_postgresql.py @@ -7,11 +7,6 @@ from app.core.identifiers import new_record_id from app.adapters.artifacts import guide_document_manifest_port -from app.modules.checkers.catalogue import ( - build_pre_submission_checker_catalogue, - project_guide_pre_submission_capabilities, -) -from app.modules.checkers.api.historical_post_submit import current_post_submit_catalogue from app.modules.projects.api.guide_proposals import ( GuideProposalApproval, GuideProposalCorrection, @@ -25,13 +20,18 @@ from app.modules.projects.guide_setup_continuation import retryable_compilation_dispatch_predicate from app.modules.projects.models import ProjectSetupRun from tests.projects.guide_compilation.finalization.pg_support import finalize, stored_state +from tests.checkers.external.support import capability_projection from .pg_support import ProposalAuthority, proposal_case, read_package async def approve(factory, command, actor, grant, payload): try: async with factory() as session, session.begin(): - planner = build_pre_submission_checker_catalogue() + from app.adapters.checkers import ( + external_checker_capability_projection, + external_checker_registry_reader, + ) + return await GuideProposalService( session, ProposalAuthority( @@ -40,14 +40,13 @@ async def approve(factory, command, actor, grant, payload): command.project_id, grant, ), + external_checker_registry_reader(session), ).approve( payload, actor=actor, request_id=uuid4(), material=guide_document_manifest_port(session), - pre_capabilities=project_guide_pre_submission_capabilities(planner), - post_capabilities=current_post_submit_catalogue(), - planner=planner, + capabilities=await external_checker_capability_projection(session), ) except GuideProposalError as exc: raise exc from exc.__context__ @@ -77,29 +76,61 @@ async def test_review_package_is_exact_complete_and_redacted(clean_postgres_data body = result().model_dump(mode="json") evidence = body["findings"][0]["evidence_refs"] body.update( - status="guide_blocked", submission_artifact_policy=None, + status="guide_blocked", + submission_artifact_policy=None, requirements=[ - dict(requirement_id="packet", statement="Limit artifact file size.", - disposition="supported_pre_submit", evidence_refs=evidence), - dict(requirement_id="coverage", statement="Check acceptance criteria coverage.", - disposition="supported_post_submit", evidence_refs=evidence), - dict(requirement_id="semantic", statement="Evaluate specialist correctness.", - disposition="post_submit_capability_gap", evidence_refs=evidence), + dict( + requirement_id="packet", + statement="Limit artifact file size.", + disposition="supported_pre_submit", + evidence_refs=evidence, + ), + dict( + requirement_id="coverage", + statement="Check acceptance criteria coverage.", + disposition="supported_post_submit", + evidence_refs=evidence, + ), + dict( + requirement_id="semantic", + statement="Evaluate specialist correctness.", + disposition="post_submit_capability_gap", + evidence_refs=evidence, + ), + ], + pre_submit_bindings=[ + dict( + requirement_id="packet", + capability_id="policy.file_size.limit", + capability_version="v1", + stage="pre_submit", + ) + ], + post_submit_bindings=[ + dict( + requirement_id="coverage", + capability_id="check_acceptance_criteria_present", + capability_version="v0.1", + stage="post_submit", + parameters=[], + ) + ], + capability_suggestions=[ + dict( + requirement_id="semantic", + stage="post_submit", + title="Specialist correctness evaluator", + rationale="The catalogue lacks this evaluation.", + evidence_refs=evidence, + ) ], - pre_submit_bindings=[dict(requirement_id="packet", capability_id="policy.file_size.limit", - capability_version="v1", stage="pre_submit")], - post_submit_bindings=[dict(requirement_id="coverage", capability_id="check_acceptance_criteria_present", - capability_version="v0.1", stage="post_submit", parameters=[])], - capability_suggestions=[dict(requirement_id="semantic", stage="post_submit", - title="Specialist correctness evaluator", rationale="The catalogue lacks this evaluation.", - evidence_refs=evidence)], setup_notes=["A project manager must review the specialist evaluation gap."], ) body["findings"][0]["severity"] = "blocking_gap" outcome = ProjectGuideCompilationResult.model_validate(body) - async with proposal_case(clean_postgres_database, classification="guide_blocked", outcome=outcome) as ( - _, factory, command, actor, grant - ): + async with proposal_case( + clean_postgres_database, classification="guide_blocked", outcome=outcome + ) as (_, factory, command, actor, grant): package = await read_package(factory, command, actor, grant) assert package.target.compilation_id == command.compilation_id assert package.target.setup_run_id == command.setup_run_id @@ -107,13 +138,25 @@ async def test_review_package_is_exact_complete_and_redacted(clean_postgres_data expected = outcome.model_dump(mode="json") for section in ("findings", "requirements", "capability_suggestions"): for item in expected[section]: - item["evidence_refs"] = [dict(document_number=1, start_page=ref["start_page"], - end_page=ref["end_page"], section=ref["section"]) - for ref in item["evidence_refs"]] + item["evidence_refs"] = [ + dict( + document_number=1, + start_page=ref["start_page"], + end_page=ref["end_page"], + section=ref["section"], + ) + for ref in item["evidence_refs"] + ] assert package.result.model_dump(mode="json") == expected serialized = package.model_dump_json() - for forbidden in ("source_item_id", "document_version_id", "provider_object_ref", - "runtime_configuration", "provider_idempotency_key", "put_attempt_id"): + for forbidden in ( + "source_item_id", + "document_version_id", + "provider_object_ref", + "runtime_configuration", + "provider_idempotency_key", + "put_attempt_id", + ): assert forbidden not in serialized @@ -234,11 +277,7 @@ async def test_correction_uses_canonical_human_request_and_binds_feedback(clean_ request_id=uuid4(), correlation_id=uuid4(), ) - planner = build_pre_submission_checker_catalogue() - pre, post = ( - project_guide_pre_submission_capabilities(planner), - current_post_submit_catalogue(), - ) + capabilities = capability_projection() receipts = [] for _ in range(2): async with factory() as session: @@ -250,8 +289,7 @@ async def test_correction_uses_canonical_human_request_and_binds_feedback(clean_ ProjectGuideCompilationAuthorizationAdapter(kernel, prepared), request_inputs=CompilationRequestInputs( guide_document_manifest_port(session), - pre, - post, + capabilities, runtime_configuration(), ), ) @@ -266,8 +304,7 @@ async def test_correction_uses_canonical_human_request_and_binds_feedback(clean_ attempt = await session.get(ProjectGuideCompilationAttempt, receipts[0].attempt_id) inputs = CompilationRequestInputs( guide_document_manifest_port(session), - pre, - post, + capabilities, runtime_configuration(), ) setup = await session.get(ProjectSetupRun, str(correction.successor_setup_run_id)) @@ -442,10 +479,14 @@ async def test_capability_close_failure_rolls_back_every_decision_effect(clean_p async with proposal_case(clean_postgres_database) as (_, factory, command, actor, grant): package = await read_package(factory, command, actor, grant) before = await stored_state(factory, command) - planner = build_pre_submission_checker_catalogue() for action in ("approve", "correct"): with pytest.raises(GuideProposalError, match="authority_unavailable"): async with factory() as session, session.begin(): + from app.adapters.checkers import ( + external_checker_capability_projection, + external_checker_registry_reader, + ) + service = GuideProposalService( session, ProposalAuthority( @@ -455,6 +496,7 @@ async def test_capability_close_failure_rolls_back_every_decision_effect(clean_p grant, close_error=True, ), + external_checker_registry_reader(session), ) if action == "approve": await service.approve( @@ -465,9 +507,7 @@ async def test_capability_close_failure_rolls_back_every_decision_effect(clean_p actor=actor, request_id=uuid4(), material=guide_document_manifest_port(session), - pre_capabilities=project_guide_pre_submission_capabilities(planner), - post_capabilities=current_post_submit_catalogue(), - planner=planner, + capabilities=await external_checker_capability_projection(session), ) else: await service.request_correction( @@ -595,7 +635,6 @@ async def test_unified_approval_postgresql_requires_reservation_and_operation( async with proposal_case(clean_postgres_database) as (_, factory, command, actor, grant): package = await read_package(factory, command, actor, grant) - planner = build_pre_submission_checker_catalogue() if omitted == "reservation": async def reserve_without_record(*_args, **_kwargs): @@ -627,6 +666,11 @@ def add_without_operation(row, **kwargs): add(row, **kwargs) monkeypatch.setattr(session, "add", add_without_operation) + from app.adapters.checkers import ( + external_checker_capability_projection, + external_checker_registry_reader, + ) + await GuideProposalService( session, ProposalAuthority( @@ -635,6 +679,7 @@ def add_without_operation(row, **kwargs): command.project_id, grant, ), + external_checker_registry_reader(session), ).approve( GuideProposalApproval( target=package.target, @@ -643,9 +688,7 @@ def add_without_operation(row, **kwargs): actor=actor, request_id=uuid4(), material=guide_document_manifest_port(session), - pre_capabilities=project_guide_pre_submission_capabilities(planner), - post_capabilities=current_post_submit_catalogue(), - planner=planner, + capabilities=await external_checker_capability_projection(session), ) # Reach this exact deferred guard with complete output pointers; # other constraints cannot mask the missing relation under test. @@ -848,7 +891,11 @@ async def test_projected_draft_content_cannot_be_changed_before_approval(clean_p @pytest.mark.parametrize("guide_version", ["v0.1", "example-proof"]) async def test_approval_preserves_opaque_guide_version(clean_postgres_database, guide_version): async with proposal_case(clean_postgres_database, guide_version=guide_version) as ( - values, factory, command, actor, grant + values, + factory, + command, + actor, + grant, ): package = await read_package(factory, command, actor, grant) payload = GuideProposalApproval(target=package.target, idempotency_key=uuid4()) @@ -861,8 +908,21 @@ async def test_approval_preserves_opaque_guide_version(clean_postgres_database, await finalize(factory, values, command) -@pytest.mark.parametrize("authority_change", ["revoked_grant", "suspended_actor", "revoked_link", "audit", "operator", "system_manager", "foreign_project"]) -async def test_stored_authority_variants_deny_review_replay_and_correction(clean_postgres_database, authority_change): +@pytest.mark.parametrize( + "authority_change", + [ + "revoked_grant", + "suspended_actor", + "revoked_link", + "audit", + "operator", + "system_manager", + "foreign_project", + ], +) +async def test_stored_authority_variants_deny_review_replay_and_correction( + clean_postgres_database, authority_change +): from sqlalchemy import text from .pg_support import seed_review_actor, revoke_review_grant from project_create_fixtures import seed_historical_project @@ -878,44 +938,95 @@ async def test_stored_authority_variants_deny_review_replay_and_correction(clean elif authority_change in {"suspended_actor", "revoked_link"}: async with factory() as session, session.begin(): if authority_change == "suspended_actor": - await session.execute(text("UPDATE actor_profiles SET status='suspended',suspended_by=:id,suspended_at=now(),suspension_reason='Test turnover' WHERE id=:id"), {"id": str(actor.actor_profile_id)}) + await session.execute( + text( + "UPDATE actor_profiles SET status='suspended',suspended_by=:id,suspended_at=now(),suspension_reason='Test turnover' WHERE id=:id" + ), + {"id": str(actor.actor_profile_id)}, + ) else: - await session.execute(text("UPDATE actor_identity_links SET status='revoked',revoked_by=:actor,revoked_at=now(),revoked_reason='Test turnover' WHERE id=:id"), {"actor": str(actor.actor_profile_id), "id": str(actor.identity_link_id)}) + await session.execute( + text( + "UPDATE actor_identity_links SET status='revoked',revoked_by=:actor,revoked_at=now(),revoked_reason='Test turnover' WHERE id=:id" + ), + {"actor": str(actor.actor_profile_id), "id": str(actor.identity_link_id)}, + ) else: project = command.project_id - role, scope = {"audit": ("audit_authority", "project"), "operator": ("operator", "system"), - "system_manager": ("project_manager", "system"), "foreign_project": ("project_manager", "project")}[authority_change] + role, scope = { + "audit": ("audit_authority", "project"), + "operator": ("operator", "system"), + "system_manager": ("project_manager", "system"), + "foreign_project": ("project_manager", "project"), + }[authority_change] if authority_change == "foreign_project": project = new_record_id() async with factory() as session, session.begin(): - await seed_historical_project(session, project_id=str(project), name="Foreign guide owner", slug=f"foreign-{project}") - _, denied_grant = await seed_review_actor(factory, project, actor=actor, role=role, scope=scope) + await seed_historical_project( + session, + project_id=str(project), + name="Foreign guide owner", + slug=f"foreign-{project}", + ) + _, denied_grant = await seed_review_actor( + factory, project, actor=actor, role=role, scope=scope + ) before = await stored_state(factory, command) async with factory() as session: - audit_before = (await session.execute(text("SELECT id FROM audit_events ORDER BY id"))).all() + audit_before = ( + await session.execute(text("SELECT id FROM audit_events ORDER BY id")) + ).all() for operation in ( read_package(factory, command, actor, denied_grant), approve(factory, command, actor, denied_grant, payload), - correct(factory, command, actor, denied_grant, GuideProposalCorrection( - target=package.target, idempotency_key=uuid4(), reason="Reconsider this proposal.")), + correct( + factory, + command, + actor, + denied_grant, + GuideProposalCorrection( + target=package.target, + idempotency_key=uuid4(), + reason="Reconsider this proposal.", + ), + ), ): with pytest.raises(GuideProposalError, match="authority_unavailable"): await operation assert await stored_state(factory, command) == before async with factory() as session: - assert (await session.execute(text("SELECT id FROM audit_events ORDER BY id"))).all() == audit_before - assert (await session.execute(text("SELECT count(*) FROM project_guide_proposal_corrections"))).scalar_one() == 0 + assert ( + await session.execute(text("SELECT id FROM audit_events ORDER BY id")) + ).all() == audit_before + assert ( + await session.execute( + text("SELECT count(*) FROM project_guide_proposal_corrections") + ) + ).scalar_one() == 0 -async def test_another_current_manager_can_admit_correction_after_creator_revocation(clean_postgres_database): +async def test_another_current_manager_can_admit_correction_after_creator_revocation( + clean_postgres_database, +): from .pg_support import seed_review_actor, revoke_review_grant, request_corrected_attempt - from app.modules.projects.guide_compilation.models import ProjectGuideCompilationRequestOperation + from app.modules.projects.guide_compilation.models import ( + ProjectGuideCompilationRequestOperation, + ) async with proposal_case(clean_postgres_database) as (_, factory, command, actor, grant): package = await read_package(factory, command, actor, grant) before = await stored_state(factory, command) - successor = await correct(factory, command, actor, grant, GuideProposalCorrection( - target=package.target, idempotency_key=uuid4(), reason="Recheck the guide requirement.")) + successor = await correct( + factory, + command, + actor, + grant, + GuideProposalCorrection( + target=package.target, + idempotency_key=uuid4(), + reason="Recheck the guide requirement.", + ), + ) second_actor, _ = await seed_review_actor(factory, command.project_id) await revoke_review_grant(factory, actor, grant) requested = await request_corrected_attempt(factory, second_actor, successor) @@ -923,8 +1034,13 @@ async def test_another_current_manager_can_admit_correction_after_creator_revoca async with factory() as session: correction = await session.get(ProjectGuideProposalCorrection, successor.operation_id) setup = await session.get(ProjectSetupRun, str(successor.successor_setup_run_id)) - operation = (await session.scalars(select(ProjectGuideCompilationRequestOperation).where( - ProjectGuideCompilationRequestOperation.attempt_id == requested.attempt_id))).one() + operation = ( + await session.scalars( + select(ProjectGuideCompilationRequestOperation).where( + ProjectGuideCompilationRequestOperation.attempt_id == requested.attempt_id + ) + ) + ).one() assert correction.actor_profile_id == str(actor.actor_profile_id) assert setup.authorized_by_actor_profile_id == str(actor.actor_profile_id) assert operation.actor_profile_id == str(second_actor.actor_profile_id) @@ -939,20 +1055,27 @@ async def assert_approval_replay_unchanged(factory, command, actor, grant, paylo async def counts(): async with factory() as session: - return (await session.execute(text( - "SELECT (SELECT count(*) FROM project_guide_proposal_approvals)," - "(SELECT count(*) FROM submission_policy_mutation_idempotency_records)," - "(SELECT count(*) FROM effective_project_submission_artifact_policies)," - "(SELECT count(*) FROM pre_submit_checker_policies)," - "(SELECT count(*) FROM audit_events)" - ))).one() + return ( + await session.execute( + text( + "SELECT (SELECT count(*) FROM project_guide_proposal_approvals)," + "(SELECT count(*) FROM submission_policy_mutation_idempotency_records)," + "(SELECT count(*) FROM effective_project_submission_artifact_policies)," + "(SELECT count(*) FROM pre_submit_checker_policies)," + "(SELECT count(*) FROM audit_events)" + ) + ) + ).one() + before = await counts() assert await approve(factory, command, actor, grant, payload) == receipt assert await counts() == before @pytest.mark.parametrize("activate_before_commit", [False, True]) -async def test_database_approval_requires_guide_to_remain_draft(clean_postgres_database, activate_before_commit): +async def test_database_approval_requires_guide_to_remain_draft( + clean_postgres_database, activate_before_commit +): from contextlib import nullcontext from sqlalchemy import text from sqlalchemy.exc import DBAPIError @@ -963,30 +1086,71 @@ async def test_database_approval_requires_guide_to_remain_draft(clean_postgres_d await seed_selected_review_revision_inputs(factory, command, actor) package = await read_package(factory, command, actor, grant) before = await stored_state(factory, command) - expected = pytest.raises(DBAPIError, match="proposal approval target is no longer current") if activate_before_commit else nullcontext() + expected = ( + pytest.raises(DBAPIError, match="proposal approval target is no longer current") + if activate_before_commit + else nullcontext() + ) with expected: async with factory() as session, session.begin(): if activate_before_commit: # Transaction rollback restores these unrelated activation prerequisites. - for trigger in ("guide_mutation_product_custody", "guide_lineage_lifecycle_guard"): - await session.execute(text(f"ALTER TABLE project_guides DISABLE TRIGGER {trigger}")) - planner = build_pre_submission_checker_catalogue() - await GuideProposalService(session, ProposalAuthority(session, actor, command.project_id, grant)).approve( - GuideProposalApproval(target=package.target, idempotency_key=uuid4()), actor=actor, request_id=uuid4(), + for trigger in ( + "guide_mutation_product_custody", + "guide_lineage_lifecycle_guard", + ): + await session.execute( + text(f"ALTER TABLE project_guides DISABLE TRIGGER {trigger}") + ) + from app.adapters.checkers import ( + external_checker_capability_projection, + external_checker_registry_reader, + ) + await GuideProposalService( + session, + ProposalAuthority(session, actor, command.project_id, grant), + external_checker_registry_reader(session), + ).approve( + GuideProposalApproval(target=package.target, idempotency_key=uuid4()), + actor=actor, + request_id=uuid4(), material=guide_document_manifest_port(session), - pre_capabilities=project_guide_pre_submission_capabilities(planner), - post_capabilities=current_post_submit_catalogue(), planner=planner, + capabilities=await external_checker_capability_projection(session), ) if activate_before_commit: # Stage lifecycle drift after valid approval assembly to reach the DB guard itself. - await session.execute(text("UPDATE project_guides SET status='active',approved_by=:actor,effective_at=now() WHERE id=:guide"), - {"actor": str(actor.actor_profile_id), "guide": str(command.guide_id)}) - await session.execute(text("SET CONSTRAINTS guide_proposal_approval_custody IMMEDIATE")) + await session.execute( + text( + "UPDATE project_guides SET status='active',approved_by=:actor,effective_at=now() WHERE id=:guide" + ), + {"actor": str(actor.actor_profile_id), "guide": str(command.guide_id)}, + ) + await session.execute( + text("SET CONSTRAINTS guide_proposal_approval_custody IMMEDIATE") + ) if activate_before_commit: assert await stored_state(factory, command) == before async with factory() as session: - assert await session.scalar(text("SELECT count(*) FROM pg_trigger WHERE tgrelid='project_guides'::regclass AND tgenabled='D'")) == 0 - for table in ("project_guide_proposal_approvals", "submission_policy_mutation_idempotency_records", - "effective_project_submission_artifact_policies", "pre_submit_checker_policies"): + assert ( + await session.scalar( + text( + "SELECT count(*) FROM pg_trigger WHERE tgrelid='project_guides'::regclass AND tgenabled='D'" + ) + ) + == 0 + ) + for table in ( + "project_guide_proposal_approvals", + "submission_policy_mutation_idempotency_records", + "effective_project_submission_artifact_policies", + "pre_submit_checker_policies", + ): assert await session.scalar(text(f"SELECT count(*) FROM {table}")) == 0 - assert await session.scalar(text("SELECT count(*) FROM audit_events WHERE action_id='project.submission_artifact_policy.approve'")) == 0 + assert ( + await session.scalar( + text( + "SELECT count(*) FROM audit_events WHERE action_id='project.submission_artifact_policy.approve'" + ) + ) + == 0 + ) From 70173f90679bea78081282383dc20333279efe03 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 21:51:14 +0100 Subject: [PATCH 093/283] [PILOT-04] use registry activation fixtures --- .../guide_activation/pg_support.py | 79 +++++++++++++------ .../projects/guide_activation/pg_support.py | 22 +++--- 2 files changed, 66 insertions(+), 35 deletions(-) diff --git a/backend/tests/authorization/guide_activation/pg_support.py b/backend/tests/authorization/guide_activation/pg_support.py index e8a5095a1..5b47ffa76 100644 --- a/backend/tests/authorization/guide_activation/pg_support.py +++ b/backend/tests/authorization/guide_activation/pg_support.py @@ -6,11 +6,14 @@ from sqlalchemy import text from app.adapters.auth import guide_activation_authorization -from app.adapters.checkers import project_guide_approval_compiler from app.adapters.contributions import contribution_policy_validation_port from app.adapters.projects import project_guide_activation_port from app.adapters.projects.contribution_validation import GuideContributionPolicyValidation -from app.modules.authorization.runtime import HumanAuthorizationContext, ActorStatus, IdentityLinkStatus +from app.modules.authorization.runtime import ( + HumanAuthorizationContext, + ActorStatus, + IdentityLinkStatus, +) @asynccontextmanager @@ -18,15 +21,19 @@ async def service(factory, actor): async with factory() as session, session.begin(): request = uuid4() context = HumanAuthorizationContext( - actor_profile_id=actor.actor_profile_id, identity_link_id=actor.identity_link_id, - actor_kind=actor.actor_kind, actor_status=ActorStatus.ACTIVE, - identity_link_status=IdentityLinkStatus.ACTIVE, request_id=request, correlation_id=uuid4(), + actor_profile_id=actor.actor_profile_id, + identity_link_id=actor.identity_link_id, + actor_kind=actor.actor_kind, + actor_status=ActorStatus.ACTIVE, + identity_link_status=IdentityLinkStatus.ACTIVE, + request_id=request, + correlation_id=uuid4(), ) - planner, pre, post = project_guide_approval_compiler() owner = project_guide_activation_port( session, - contribution=GuideContributionPolicyValidation(contribution_policy_validation_port(session)), - planner=planner, pre_catalogue=pre, post_catalogue=post, + contribution=GuideContributionPolicyValidation( + contribution_policy_validation_port(session) + ), authorization=guide_activation_authorization(session, context), ) yield session, owner, request, context @@ -40,18 +47,30 @@ async def activate(factory, actor, command): async def activation_state(factory): async with factory() as session: return { - "guides": (await session.execute(text( - "SELECT id,status,activation_operation_id,contribution_policy_version_id,mutation_generation " - "FROM project_guides ORDER BY id" - ))).all(), - "operations": (await session.execute(text( - "SELECT operation_id,resource_context_digest,activation_authority_json FROM guide_mutation_idempotency_records " - "WHERE action_id='project.guide.activate' ORDER BY operation_id" - ))).all(), - "events": (await session.execute(text( - "SELECT id,after_facts,matched_grant_id,correlation_id FROM audit_events " - "WHERE action_id='project.guide.activate' ORDER BY id" - ))).all(), + "guides": ( + await session.execute( + text( + "SELECT id,status,activation_operation_id,contribution_policy_version_id,mutation_generation " + "FROM project_guides ORDER BY id" + ) + ) + ).all(), + "operations": ( + await session.execute( + text( + "SELECT operation_id,resource_context_digest,activation_authority_json FROM guide_mutation_idempotency_records " + "WHERE action_id='project.guide.activate' ORDER BY operation_id" + ) + ) + ).all(), + "events": ( + await session.execute( + text( + "SELECT id,after_facts,matched_grant_id,correlation_id FROM audit_events " + "WHERE action_id='project.guide.activate' ORDER BY id" + ) + ) + ).all(), } @@ -61,16 +80,23 @@ async def revoke_manager_grant(session, context, grant): from app.modules.authorization.catalogue import ActionId from app.modules.authorization.kernel import AuthorizationService from app.modules.authorization.runtime import AdminRoleGrantResourceContext - from app.modules.authorization.schemas import AdminRoleGrantRevokeRequest, AuthorityOperation, derive_reason_digest + from app.modules.authorization.schemas import ( + AdminRoleGrantRevokeRequest, + AuthorityOperation, + derive_reason_digest, + ) reason = "Manager authority revoked" request = AdminRoleGrantRevokeRequest( - operation=AuthorityOperation.ADMIN_ROLE_GRANT_REVOKE, grant_id=grant, + operation=AuthorityOperation.ADMIN_ROLE_GRANT_REVOKE, + grant_id=grant, reason_digest=derive_reason_digest(reason), ) owner = AdminRoleGrantService(session) reservation = await owner.reserve( - idempotency_key=uuid4(), actor_profile_id=context.actor_profile_id, request=request, + idempotency_key=uuid4(), + actor_profile_id=context.actor_profile_id, + request=request, ) assert reservation.outcome == "claimed" decision = await AuthorizationService(session, context).require( @@ -78,6 +104,9 @@ async def revoke_manager_grant(session, context, grant): AdminRoleGrantResourceContext(resource_type="admin_role_grant", resource_id=grant), ) return await owner.complete_revoke( - claim=reservation.claim, request=request, decision=decision, - actor_profile_id=context.actor_profile_id, reason=reason, + claim=reservation.claim, + request=request, + decision=decision, + actor_profile_id=context.actor_profile_id, + reason=reason, ) diff --git a/backend/tests/projects/guide_activation/pg_support.py b/backend/tests/projects/guide_activation/pg_support.py index 7a1ba6e95..f58b4275c 100644 --- a/backend/tests/projects/guide_activation/pg_support.py +++ b/backend/tests/projects/guide_activation/pg_support.py @@ -125,20 +125,17 @@ async def validate_replay(self, facts, decision_event_id): def activation_service(session, actor, command, grant, *, authority=True, close_error=False): - from app.adapters.checkers import project_guide_approval_compiler + from app.adapters.checkers import external_checker_registry_reader from app.adapters.contributions import contribution_policy_validation_port from app.adapters.projects.contribution_validation import GuideContributionPolicyValidation from app.modules.projects.guide_activation.service import GuideActivationService - planner, pre, post = project_guide_approval_compiler() return GuideActivationService( session, contribution=GuideContributionPolicyValidation( contribution_policy_validation_port(session) ), - planner=planner, - pre_catalogue=pre, - post_catalogue=post, + registry=external_checker_registry_reader(session), authorization=ActivationAuthority( session, actor, command.target.proposal.project_id, grant, close_error=close_error ) @@ -242,14 +239,19 @@ async def publish_policy(factory, project_id, *, compensated=False, contribution award_bindings = () if contribution_awards: from .compensation_fixtures import create_binding - award_bindings = tuple([ - (instrument, await create_binding(factory, world, instrument_type=instrument)) - for instrument in contribution_awards - ]) + + award_bindings = tuple( + [ + (instrument, await create_binding(factory, world, instrument_type=instrument)) + for instrument in contribution_awards + ] + ) policy = None for operation in ("create_draft", "update_draft", "publish"): async with factory() as session, session.begin(): policy = await getattr(world.service(session), operation)( - world.request(operation, policy, compensated=compensated, award_bindings=award_bindings) + world.request( + operation, policy, compensated=compensated, award_bindings=award_bindings + ) ) return world, policy From 9a99515d4a8bd879981ee5e85937e36f7bc7b7ec Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 21:53:37 +0100 Subject: [PATCH 094/283] [PILOT-04] detach retained checker fixtures --- backend/tests/checkers/post_submit/support.py | 52 ++++++++++++++----- 1 file changed, 40 insertions(+), 12 deletions(-) diff --git a/backend/tests/checkers/post_submit/support.py b/backend/tests/checkers/post_submit/support.py index 886912264..60efb61b1 100644 --- a/backend/tests/checkers/post_submit/support.py +++ b/backend/tests/checkers/post_submit/support.py @@ -12,11 +12,15 @@ PostSubmitManifestEntry, PostSubmitPolicyInputs, ) -from app.modules.checkers.api.historical_post_submit import PostSubmitCatalogue, PostSubmitDefinition -from app.modules.checkers.post_submit_catalogue import build_post_submit_catalogue +from app.modules.checkers.api.historical_post_submit import ( + CompiledPostSubmitPolicy, + EmptyPostSubmitConfiguration, + PostSubmitCatalogue, + PostSubmitDefinition, + PostSubmitPolicyEntry, + current_post_submit_catalogue, +) from app.modules.checkers.api.post_submit import make_post_submit_request -from app.modules.checkers.runner import default_checker_registry -from app.modules.projects.post_submit_policy import build_project_post_submit_checker_spec, compile_project_post_submit_checker_spec HASH = "sha256:" + "a" * 64 OTHER_HASH = "sha256:" + "b" * 64 @@ -24,7 +28,37 @@ def catalogue(): - return build_post_submit_catalogue(default_checker_registry()) + """Return the frozen retained-history decoder, never an executable registry.""" + return current_post_submit_catalogue() + + +def _policy(*, project_id: UUID, snapshot: PostSubmitCatalogue) -> CompiledPostSubmitPolicy: + """Build a retained historical value without restoring its removed compiler.""" + selected = { + "check_acceptance_criteria_present": "project_required", + } + entries = tuple( + PostSubmitPolicyEntry( + checker_id=item.capability_id, + definition_version=item.capability_version, + implementation_version=item.implementation_version, + classification=( + "platform_default" + if item.platform_default + else selected[item.capability_id] + ), + configuration=EmptyPostSubmitConfiguration(), + ) + for item in snapshot.definitions + if item.platform_default or item.capability_id in selected + ) + return CompiledPostSubmitPolicy( + project_id=project_id, + guide_version="v1", + catalogue_manifest_sha256=snapshot.manifest_sha256, + entries=entries, + blocking_severities=("critical", "high"), + ) def altered_catalogue(original=None, *, index=8, **changes): @@ -39,13 +73,7 @@ def altered_catalogue(original=None, *, index=8, **changes): def request(*, snapshot=None, project_id=PROJECT): snapshot = snapshot or catalogue() - policy = compile_project_post_submit_checker_spec( - project_id=str(project_id), guide_version="v1", - spec=build_project_post_submit_checker_spec( - project_id=str(project_id), guide_version="v1", - required_checkers=["check_acceptance_criteria_present"], - ), - ) + policy = _policy(project_id=project_id, snapshot=snapshot) policy.validate_catalogue(snapshot) fields = {} for name in ExpectedPostSubmitContext.model_fields: From 9d1c27fbccf7ec32f19a2bcbbcfe9b79dde20225 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 21:53:59 +0100 Subject: [PATCH 095/283] [PILOT-04] isolate retained policy decoder --- .../checkers/api/historical_post_submit.py | 18 ++++++++++++++++++ .../modules/projects/post_policy/custody.py | 10 ++++++---- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/backend/app/modules/checkers/api/historical_post_submit.py b/backend/app/modules/checkers/api/historical_post_submit.py index 82dec5e32..e8d888bf8 100644 --- a/backend/app/modules/checkers/api/historical_post_submit.py +++ b/backend/app/modules/checkers/api/historical_post_submit.py @@ -376,3 +376,21 @@ def current_post_submit_catalogue() -> PostSubmitCatalogue: "definitions": [item.model_dump(mode="json") for item in definitions], } return PostSubmitCatalogue(**body, manifest_sha256=canonical_json_hash(body)) + + +def parse_locked_post_submit_policy( + body: object, + *, + project_id: str, + guide_version: str, + policy_hash: str, +) -> CompiledPostSubmitPolicy: + """Decode immutable pre-cutover policy evidence without restoring eligibility.""" + if not isinstance(body, dict): + raise ValueError("locked post-submit checker policy body is missing") + policy = CompiledPostSubmitPolicy.model_validate_json(json.dumps(body)) + if str(policy.project_id) != project_id or policy.guide_version != guide_version: + raise ValueError("locked post-submit checker policy guide context mismatch") + if policy.policy_hash != policy_hash: + raise ValueError("locked post-submit checker policy hash is invalid") + return policy diff --git a/backend/app/modules/projects/post_policy/custody.py b/backend/app/modules/projects/post_policy/custody.py index 73dca4b1d..4fe567492 100644 --- a/backend/app/modules/projects/post_policy/custody.py +++ b/backend/app/modules/projects/post_policy/custody.py @@ -6,7 +6,10 @@ from sqlalchemy import select from app.core.hashing import canonical_json_hash -from app.modules.checkers.api.historical_post_submit import CompiledPostSubmitPolicy +from app.modules.checkers.api.historical_post_submit import ( + CompiledPostSubmitPolicy, + parse_locked_post_submit_policy, +) from app.modules.checkers.api.external_policy import LockedExternalPostSubmitPolicy from app.modules.authorization.api import ActorKind from app.modules.authorization.api.post_policy import PostPolicyAuthorityReceipt @@ -17,7 +20,6 @@ post_policy_derive_authorization_selector, post_policy_human_authorization_selector, ) -from app.modules.projects.post_submit_policy import parse_locked_post_submit_checker_policy_body from .models import PostPolicyOperation @@ -136,7 +138,7 @@ async def load_post_policy_custody(session, policy) -> PostPolicyCustody: ): raise GuideProposalError("proposal_unavailable") else: - compiled = parse_locked_post_submit_checker_policy_body( + compiled = parse_locked_post_submit_policy( policy.policy_body, project_id=policy.project_id, guide_version=policy.guide_version, @@ -304,7 +306,7 @@ def validate_activation_post_policy( ): raise ValueError("selected post policy sidecars differ") else: - parsed = parse_locked_post_submit_checker_policy_body( + parsed = parse_locked_post_submit_policy( post_submit_checker_policy.policy_body, project_id=post_submit_checker_policy.project_id, guide_version=post_submit_checker_policy.guide_version, From 0219d651b4f0678da6ea47723f29a4d764f9ad2f Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 21:54:45 +0100 Subject: [PATCH 096/283] [PILOT-04] remove catalogue state from live admission fixture --- backend/tests/tasks/submission_lineage_support.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/backend/tests/tasks/submission_lineage_support.py b/backend/tests/tasks/submission_lineage_support.py index d6feaf9c9..1906a120a 100644 --- a/backend/tests/tasks/submission_lineage_support.py +++ b/backend/tests/tasks/submission_lineage_support.py @@ -19,7 +19,6 @@ SubmissionBundleAdmission, ) from app.modules.artifacts.service import ArtifactStorageOrchestrator -from app.modules.checkers.catalogue import build_pre_submission_checker_catalogue async def _seed_services(factory): @@ -60,12 +59,7 @@ async def _verified_admission(factory, store, namespace, settings, context, requ { "type": "http", "headers": [], - "app": SimpleNamespace( - state=SimpleNamespace( - settings=settings, - pre_submission_checker_catalogue=build_pre_submission_checker_catalogue(), - ) - ), + "app": SimpleNamespace(state=SimpleNamespace(settings=settings)), } ) async with factory() as session: From 592ac0b7e4415203e77f04f164c96b940fa42e4b Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 21:54:54 +0100 Subject: [PATCH 097/283] [PILOT-04] remove catalogue approval adapter --- backend/app/adapters/checkers/__init__.py | 28 ----------------------- 1 file changed, 28 deletions(-) diff --git a/backend/app/adapters/checkers/__init__.py b/backend/app/adapters/checkers/__init__.py index 0b01be9d7..c82f29758 100644 --- a/backend/app/adapters/checkers/__init__.py +++ b/backend/app/adapters/checkers/__init__.py @@ -112,34 +112,6 @@ def external_checker_registry_reader(session): return ExternalCheckerRegistryReader(session) -def project_guide_approval_compiler(*, disabled_checker_ids: str = ""): - """Build frozen catalogue fixtures for retained pre-cutover test evidence. - - Production proposal approval and activation use the immutable external - registry projection. This helper remains temporarily available to decode - and seed historical guide evidence while those fixtures are migrated. - """ - from app.modules.checkers.catalogue import ( - build_pre_submission_checker_catalogue, - parse_disabled_pre_submission_checker_ids, - project_guide_pre_submission_capabilities, - ) - from app.modules.checkers.api.historical_post_submit import ( - current_post_submit_catalogue, - ) - - planner = build_pre_submission_checker_catalogue( - disabled_entry_ids=parse_disabled_pre_submission_checker_ids( - disabled_checker_ids - ), - ) - return ( - planner, - project_guide_pre_submission_capabilities(planner), - current_post_submit_catalogue(), - ) - - async def external_checker_capability_projection( session, ) -> ExternalCheckerCapabilityProjection: From b7299948c52aaff8f425c759c74fe3c57e079c8c Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 21:55:26 +0100 Subject: [PATCH 098/283] [PILOT-04] remove legacy execution from checker composition --- backend/app/adapters/checkers/__init__.py | 71 +--------------------- backend/tests/pre_submit_test_helpers.py | 74 +++++++++++++++++++++-- 2 files changed, 72 insertions(+), 73 deletions(-) diff --git a/backend/app/adapters/checkers/__init__.py b/backend/app/adapters/checkers/__init__.py index c82f29758..316955d19 100644 --- a/backend/app/adapters/checkers/__init__.py +++ b/backend/app/adapters/checkers/__init__.py @@ -1,6 +1,5 @@ """CHECKER-owned composition adapters.""" -import asyncio import json from app.adapters.checkers.external_service import ( EXTERNAL_CHECKER_CAPABILITY_KEY, @@ -30,19 +29,10 @@ ) from app.modules.checkers.api.history import CheckerHistoryReadPort from app.modules.checkers.api.execution import EvaluationCoordinationPort -from typing import Any, BinaryIO, Protocol +from typing import Any, Protocol from pathlib import Path -from app.modules.checkers.api import ( - PreSubmissionExecutionFacts, - PreSubmissionInfrastructureUnavailableError, -) -from app.modules.checkers.catalogue import PreSubmissionCheckerCatalogue -from app.modules.checkers.pre_submit_execution import ( - DefaultPreSubmissionExecutionError, - DefaultPreSubmissionExecutionInput, - EffectivePreSubmissionProcessor, -) +from app.modules.checkers.api import PreSubmissionInfrastructureUnavailableError from app.modules.checkers.api.external import ( ExternalCheckerCapabilityDefinition, ExternalCheckerCapabilityProjection, @@ -182,63 +172,6 @@ class _ExecutionRequest(Protocol): storage_scheme: str -class _HistoricalFactsProcessor: - """Compatibility processor for retained pre-cutover fixture generation only.""" - - def __init__(self, processor: EffectivePreSubmissionProcessor) -> None: - self._processor = processor - - def abort(self) -> None: - self._processor.abort() - - async def process( - self, reader: BinaryIO, workspace: Path - ) -> PreSubmissionExecutionFacts: - try: - result = await asyncio.to_thread( - self._processor.process_blocking, reader, workspace - ) - return result.bounded_facts() - except DefaultPreSubmissionExecutionError as exc: - raise PreSubmissionInfrastructureUnavailableError(str(exc)) from exc - - -class PreSubmitCheckerExecutionAdapter: - """Build retained pre-cutover evidence in historical test fixtures only.""" - - def __init__( - self, *, catalogue: PreSubmissionCheckerCatalogue, archive_inspector: Any - ) -> None: - self._catalogue = catalogue - self._archive_inspector = archive_inspector - - @property - def catalogue_manifest_sha256(self) -> str: - return self._catalogue.manifest_sha256 - - def build(self, request: _ExecutionRequest) -> _HistoricalFactsProcessor: - if request.plan is None: - raise PreSubmissionInfrastructureUnavailableError( - "pre_submission_plan_identity_invalid" - ) - return _HistoricalFactsProcessor( - EffectivePreSubmissionProcessor( - archive_inspector=self._archive_inspector, - catalogue=self._catalogue, - execution_input=DefaultPreSubmissionExecutionInput( - plan=request.plan, - commitment=request.commitment, - inspection=request.inspection, - manifest=request.manifest, - change_gate=request.change_gate, - packet=request.packet, - prepared_generation_id=request.prepared_generation_id, - storage_scheme=request.storage_scheme, - ), - ) - ) - - class SelectedPreSubmitCheckerExecutionAdapter: """Build the selected default-plus-external PRE processor from exact ART facts.""" diff --git a/backend/tests/pre_submit_test_helpers.py b/backend/tests/pre_submit_test_helpers.py index 273c730ad..b4645d01a 100644 --- a/backend/tests/pre_submit_test_helpers.py +++ b/backend/tests/pre_submit_test_helpers.py @@ -1,8 +1,11 @@ """Shared dependency-safe construction for focused pre-submit tests.""" import json +import asyncio from dataclasses import replace +from pathlib import Path from types import SimpleNamespace +from typing import Any, BinaryIO from unittest.mock import AsyncMock import pytest @@ -11,7 +14,15 @@ from uuid import UUID, uuid4 from app.core.identifiers import new_record_id -from app.adapters.checkers import PreSubmitCheckerExecutionAdapter +from app.modules.checkers.api import ( + PreSubmissionExecutionFacts, + PreSubmissionInfrastructureUnavailableError, +) +from app.modules.checkers.pre_submit_execution import ( + DefaultPreSubmissionExecutionError, + DefaultPreSubmissionExecutionInput, + EffectivePreSubmissionProcessor, +) from app.modules.artifacts.api import SubmissionBundlePreparationRequest from app.modules.artifacts.submission_materialization import ( PreparedBundleMaterializationService, @@ -56,9 +67,64 @@ async def execute_evidence_workflow(workflow, request, *, preparation_request): return await workflow.execute_reserved(request, selected, preparation_request=preparation_request) -def checker_execution(inspector, catalogue) -> PreSubmitCheckerExecutionAdapter: - """Build the owner adapter used by ART materialization tests.""" - return PreSubmitCheckerExecutionAdapter( +class _HistoricalFactsProcessor: + """Execute only pre-cutover test evidence while its SQL fixtures are retained.""" + + def __init__(self, processor: EffectivePreSubmissionProcessor) -> None: + self._processor = processor + + def abort(self) -> None: + self._processor.abort() + + async def process( + self, reader: BinaryIO, workspace: Path + ) -> PreSubmissionExecutionFacts: + try: + result = await asyncio.to_thread( + self._processor.process_blocking, reader, workspace + ) + return result.bounded_facts() + except DefaultPreSubmissionExecutionError as exc: + raise PreSubmissionInfrastructureUnavailableError(str(exc)) from exc + + +class _HistoricalCheckerExecution: + """Test-only adapter for predecessor evidence; never a product composition root.""" + + def __init__(self, *, catalogue: Any, archive_inspector: Any) -> None: + self._catalogue = catalogue + self._archive_inspector = archive_inspector + + @property + def catalogue_manifest_sha256(self) -> str: + return self._catalogue.manifest_sha256 + + def build(self, request) -> _HistoricalFactsProcessor: + if request.plan is None: + raise PreSubmissionInfrastructureUnavailableError( + "pre_submission_plan_identity_invalid" + ) + return _HistoricalFactsProcessor( + EffectivePreSubmissionProcessor( + archive_inspector=self._archive_inspector, + catalogue=self._catalogue, + execution_input=DefaultPreSubmissionExecutionInput( + plan=request.plan, + commitment=request.commitment, + inspection=request.inspection, + manifest=request.manifest, + change_gate=request.change_gate, + packet=request.packet, + prepared_generation_id=request.prepared_generation_id, + storage_scheme=request.storage_scheme, + ), + ) + ) + + +def checker_execution(inspector, catalogue) -> _HistoricalCheckerExecution: + """Build the test-only predecessor evidence adapter.""" + return _HistoricalCheckerExecution( archive_inspector=inspector, catalogue=catalogue, ) From 661aafb368a16457af1d4a512a3804ed05443315 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 21:56:20 +0100 Subject: [PATCH 099/283] [PILOT-04] detach archive fixtures from old checker tests --- backend/tests/archive_fixtures.py | 31 +++++++++++++++++++ .../test_cross_owner_lock_order.py | 2 +- .../post_submit_materialization_helpers.py | 2 +- backend/tests/reviews/decision/support.py | 2 +- backend/tests/submission_capacity_fixtures.py | 2 +- backend/tests/tasks/invalidation_support.py | 2 +- .../tasks/post_submit_routing/support.py | 2 +- .../tests/tasks/test_submission_lineage.py | 2 +- backend/tests/test_approved_guide_intake.py | 2 +- ..._blocked_pre_submit_feedback_postgresql.py | 2 +- .../tests/test_post_submit_materialization.py | 2 +- .../test_pre_submit_attempt_lock_order.py | 4 +-- .../test_submission_evaluation_capacity.py | 2 +- 13 files changed, 44 insertions(+), 13 deletions(-) create mode 100644 backend/tests/archive_fixtures.py diff --git a/backend/tests/archive_fixtures.py b/backend/tests/archive_fixtures.py new file mode 100644 index 000000000..85c82fc41 --- /dev/null +++ b/backend/tests/archive_fixtures.py @@ -0,0 +1,31 @@ +"""Deterministic ZIP bytes shared by current ART and TASK integration tests.""" + +from io import BytesIO +from zipfile import ZipFile, ZipInfo + + +async def byte_source(value: bytes): + """Yield one immutable request body through the production async-byte port.""" + yield value + + +def submission_archive( + path: str = "task.toml", + *, + primary_bytes: bytes = b"[task]\nname='proof'\n", + extra_path: str | None = None, + evidence_path: str = "evidence/results", +) -> bytes: + """Return a timestamp-stable ZIP with one required artifact and evidence file.""" + output = BytesIO() + with ZipFile(output, "w") as archive: + def write(name: str, value: bytes) -> None: + archive.writestr(ZipInfo(name, date_time=(1980, 1, 1, 0, 0, 0)), value) + + write(path, primary_bytes) + if extra_path is not None: + write(extra_path, b"blocked\n") + if path != evidence_path: + write(evidence_path, b"verified\n") + return output.getvalue() + diff --git a/backend/tests/authorization/contribution_policies/test_cross_owner_lock_order.py b/backend/tests/authorization/contribution_policies/test_cross_owner_lock_order.py index 72c0de3c8..5d2bc8562 100644 --- a/backend/tests/authorization/contribution_policies/test_cross_owner_lock_order.py +++ b/backend/tests/authorization/contribution_policies/test_cross_owner_lock_order.py @@ -270,7 +270,7 @@ async def lock_locked_policy_context(self, request): async def test_dual_finance_submitter_profile_precedes_policy_project_lock( tmp_path: Path, isolated_database_env: str, monkeypatch, ) -> None: - import tests.test_default_pre_submit_execution as default_tests + import tests.archive_fixtures as default_tests original_limits = default_tests._limits monkeypatch.setattr(default_tests, "_limits", lambda: replace( diff --git a/backend/tests/post_submit_materialization_helpers.py b/backend/tests/post_submit_materialization_helpers.py index 5be6476d0..65e7762d8 100644 --- a/backend/tests/post_submit_materialization_helpers.py +++ b/backend/tests/post_submit_materialization_helpers.py @@ -29,7 +29,7 @@ from tests.tasks.submission_lineage_support import _seed_services, _verified_admission from tests.test_artifact_admission import _settings, _context, _seed_human_actor from tests.test_checker_materialization import _limits -from tests.test_default_pre_submit_execution import _archive, _bytes +from tests.archive_fixtures import byte_source as _bytes, submission_archive as _archive class CountedStore: diff --git a/backend/tests/reviews/decision/support.py b/backend/tests/reviews/decision/support.py index eecf4a34b..2b38a17a1 100644 --- a/backend/tests/reviews/decision/support.py +++ b/backend/tests/reviews/decision/support.py @@ -32,7 +32,7 @@ from tests.tasks.post_submit_routing.support import source_values from tests.tasks.submission_lineage_support import _verified_admission from tests.test_artifact_admission import _context -from tests.test_default_pre_submit_execution import _bytes +from tests.archive_fixtures import byte_source as _bytes @asynccontextmanager diff --git a/backend/tests/submission_capacity_fixtures.py b/backend/tests/submission_capacity_fixtures.py index 613167ea2..122c44d6f 100644 --- a/backend/tests/submission_capacity_fixtures.py +++ b/backend/tests/submission_capacity_fixtures.py @@ -13,7 +13,7 @@ from tests.tasks.lineage_fixtures import seed_started_task_for_artifact_test from tests.tasks.submission_lineage_support import _seed_services from tests.test_artifact_admission import _settings, _namespace, _local_store, _context, _seed_human_actor -from tests.test_default_pre_submit_execution import _archive, _bytes +from tests.archive_fixtures import byte_source as _bytes, submission_archive as _archive @asynccontextmanager diff --git a/backend/tests/tasks/invalidation_support.py b/backend/tests/tasks/invalidation_support.py index ea19214d4..a38180ba3 100644 --- a/backend/tests/tasks/invalidation_support.py +++ b/backend/tests/tasks/invalidation_support.py @@ -299,7 +299,7 @@ async def prepare_submission(s, settings): from app.modules.tasks.api import SubmissionCreationRequest from tests.tasks.submission_lineage_support import _seed_services, _verified_admission from tests.test_artifact_admission import _namespace, _local_store, _context - from tests.test_default_pre_submit_execution import _archive, _bytes + from tests.archive_fixtures import byte_source as _bytes, submission_archive as _archive from tests.test_tasks import complete_submission_payload context = _context( diff --git a/backend/tests/tasks/post_submit_routing/support.py b/backend/tests/tasks/post_submit_routing/support.py index cefbfa23a..98f1d5ee9 100644 --- a/backend/tests/tasks/post_submit_routing/support.py +++ b/backend/tests/tasks/post_submit_routing/support.py @@ -26,7 +26,7 @@ from tests.tasks.lineage_fixtures import seed_started_task_for_artifact_test from tests.tasks.submission_lineage_support import _verified_admission from tests.test_artifact_admission import _context -from tests.test_default_pre_submit_execution import _bytes +from tests.archive_fixtures import byte_source as _bytes SOURCE_COLUMNS = ( diff --git a/backend/tests/tasks/test_submission_lineage.py b/backend/tests/tasks/test_submission_lineage.py index a6d551fdd..dac06103a 100644 --- a/backend/tests/tasks/test_submission_lineage.py +++ b/backend/tests/tasks/test_submission_lineage.py @@ -33,7 +33,7 @@ _context, _seed_human_actor, ) -from tests.test_default_pre_submit_execution import _archive, _bytes +from tests.archive_fixtures import byte_source as _bytes, submission_archive as _archive from tests.tasks.submission_lineage_support import _seed_services, _verified_admission diff --git a/backend/tests/test_approved_guide_intake.py b/backend/tests/test_approved_guide_intake.py index 69ffe621f..a0110de13 100644 --- a/backend/tests/test_approved_guide_intake.py +++ b/backend/tests/test_approved_guide_intake.py @@ -193,7 +193,7 @@ async def test_command_holds_authorized_context_before_final_handoff(tmp_path, i ) from tests.checkers.execution.support import forbidden_post_submission from tests.authorization.test_pre_submit_attempt_authority import _seed_materializer - from tests.test_default_pre_submit_execution import _archive, _bytes + from tests.archive_fixtures import byte_source as _bytes, submission_archive as _archive harness = await _harness(tmp_path, isolated_database_env) try: diff --git a/backend/tests/test_blocked_pre_submit_feedback_postgresql.py b/backend/tests/test_blocked_pre_submit_feedback_postgresql.py index f5fa34219..13d768e7b 100644 --- a/backend/tests/test_blocked_pre_submit_feedback_postgresql.py +++ b/backend/tests/test_blocked_pre_submit_feedback_postgresql.py @@ -33,7 +33,7 @@ from app.modules.tasks.repository import TaskRepository from tests.authorization.test_pre_submit_attempt_authority import _seed_materializer from tests.checkers.execution.support import forbidden_post_submission -from tests.test_default_pre_submit_execution import _archive, _bytes +from tests.archive_fixtures import byte_source as _bytes, submission_archive as _archive from tests.test_pre_submit_attempt_recovery import _harness diff --git a/backend/tests/test_post_submit_materialization.py b/backend/tests/test_post_submit_materialization.py index 15a6f5858..8d988f5ff 100644 --- a/backend/tests/test_post_submit_materialization.py +++ b/backend/tests/test_post_submit_materialization.py @@ -229,7 +229,7 @@ async def test_async_exit_and_concurrent_drift_never_return_stale_material(tmp_p async def test_wrong_provider_bytes_or_manifest_never_reach_consumer(tmp_path, isolated_database_env): - from tests.test_default_pre_submit_execution import _bytes + from tests.archive_fixtures import byte_source as _bytes async with material_fixture(tmp_path, isolated_database_env) as h: execution = await material_execution(h) consumer = Consumer(h.files) diff --git a/backend/tests/test_pre_submit_attempt_lock_order.py b/backend/tests/test_pre_submit_attempt_lock_order.py index 7703dc414..ed187f5ab 100644 --- a/backend/tests/test_pre_submit_attempt_lock_order.py +++ b/backend/tests/test_pre_submit_attempt_lock_order.py @@ -33,7 +33,7 @@ from tests.authorization.test_pre_submit_attempt_authority import _seed_materializer from tests.pre_submit_test_helpers import submission_preparation_request from tests.submission_preparation_auth_helpers import install_submitter_grant -from tests.test_default_pre_submit_execution import _archive, _bytes +from tests.archive_fixtures import byte_source as _bytes, submission_archive as _archive from tests.test_pre_submit_attempt_authority_integration import _reserve_with_real_materializer from tests.test_pre_submit_attempt_recovery import _harness @@ -246,7 +246,7 @@ async def test_same_project_reservation_and_execution_complete_without_auth_proj ) -> None: # The fixture's ordinary ten-second scratch deadline is too short for an # intentional database barrier; only this test extends the temporary lease. - import tests.test_default_pre_submit_execution as default_tests + import tests.archive_fixtures as default_tests original_limits = default_tests._limits monkeypatch.setattr(default_tests, "_limits", lambda: replace( diff --git a/backend/tests/test_submission_evaluation_capacity.py b/backend/tests/test_submission_evaluation_capacity.py index 70c84e7c2..44640cbd0 100644 --- a/backend/tests/test_submission_evaluation_capacity.py +++ b/backend/tests/test_submission_evaluation_capacity.py @@ -31,7 +31,7 @@ from tests.submission_capacity_fixtures import capacity_fixture from tests.pre_submit_test_helpers import approved_pre_submit_fixture from tests.tasks.submission_lineage_support import _verified_admission -from tests.test_default_pre_submit_execution import _archive, _bytes +from tests.archive_fixtures import byte_source as _bytes, submission_archive as _archive from tests.checkers.post_submit.support import request as evaluation_request From 49ebc53fb953760b7e9ae46ff5f739649b402119 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 21:57:52 +0100 Subject: [PATCH 100/283] [PILOT-04] use selected policies in current flow fixtures --- .../post_submit_materialization_helpers.py | 10 ++- backend/tests/selected_policy_fixtures.py | 61 +++++++++++++++++++ backend/tests/submission_capacity_fixtures.py | 12 +++- .../tests/tasks/test_submission_lineage.py | 12 +++- backend/tests/test_artifact_admission.py | 15 ++++- 5 files changed, 99 insertions(+), 11 deletions(-) create mode 100644 backend/tests/selected_policy_fixtures.py diff --git a/backend/tests/post_submit_materialization_helpers.py b/backend/tests/post_submit_materialization_helpers.py index 65e7762d8..8efd65956 100644 --- a/backend/tests/post_submit_materialization_helpers.py +++ b/backend/tests/post_submit_materialization_helpers.py @@ -23,7 +23,7 @@ from app.modules.tasks.api import SubmissionCreationRequest from app.modules.tasks.api.submitted_bundle import SubmittedBundleRequest from tests.artifact_store_helpers import artifact_admission_limit_settings -from tests.pre_submit_test_helpers import approved_pre_submit_fixture +from tests.selected_policy_fixtures import approved_selected_policy_fixture from tests.submission_preparation_auth_helpers import install_submitter_grant from tests.tasks.lineage_fixtures import seed_started_task_for_artifact_test from tests.tasks.submission_lineage_support import _seed_services, _verified_admission @@ -131,7 +131,11 @@ async def _material_fixture( "artifact_scratch_minimum_free_bytes": 0, }) else: - settings = _settings(tmp_path, maximum_bytes=1024 * 1024) + settings = _settings( + tmp_path, + maximum_bytes=1024 * 1024, + external_checker=True, + ) bootstrap = create_artifact_store_bootstrap(settings) namespace = artifact_storage_namespace_spec(settings, bootstrap) store = bootstrap.initialize_after_namespace_claim(ArtifactStoreNamespaceClaim( @@ -139,7 +143,7 @@ async def _material_fixture( )) manager = ArtifactScratchManager(root=tmp_path / "post-scratch", limits=scratch_limits if scratch_limits is not None else _limits()) try: - plan, policy = await approved_pre_submit_fixture( + plan, policy = await approved_selected_policy_fixture( factory, namespace, guide_version="v1", diff --git a/backend/tests/selected_policy_fixtures.py b/backend/tests/selected_policy_fixtures.py new file mode 100644 index 000000000..63b5fad3b --- /dev/null +++ b/backend/tests/selected_policy_fixtures.py @@ -0,0 +1,61 @@ +"""Approved selected checker policy facts for current ART and TASK journeys.""" + +import json +from types import SimpleNamespace + +from sqlalchemy import select + + +async def approved_selected_policy_fixture( + factory, + namespace, + *, + guide_version, + contribution_awards=(), + human_review_required=True, +): + """Build an activated guide backed only by immutable external policy custody.""" + from app.interfaces.project_agents import SubmissionArtifactPolicyProposal + from app.modules.projects.models import ProjectGuide, PostSubmitCheckerPolicy + from tests.projects.unified_policy_fixtures import create_standalone_unified_policy + + values, effective, pre = await create_standalone_unified_policy( + factory, + namespace, + guide_version=guide_version, + contribution_awards=contribution_awards, + human_review_required=human_review_required, + artifact_proposal=SubmissionArtifactPolicyProposal( + maximum_file_size_bytes=1_000_000, + maximum_package_size_bytes=5_000_000, + required_artifacts=("task.toml",), + required_evidence=("results",), + attestation_terms=("rights_confirmed",), + ), + ) + async with factory() as session: + guide = await session.get(ProjectGuide, str(values["guide"])) + post = await session.scalar( + select(PostSubmitCheckerPolicy).where( + PostSubmitCheckerPolicy.effective_policy_id == effective["id"] + ) + ) + assert post is not None + assert pre.compiled_bundle.get("schema_version") == "external_pre_submit_policy.v1" + assert post.policy_body.get("schema_version") == "external_post_submit_policy.v1" + owner = SimpleNamespace(lineage=SimpleNamespace(project_id=values["project"])) + return owner, { + "post_policy": post.id, + "post_policy_hash": post.policy_hash, + "post_policy_body": json.dumps(post.policy_body), + "submission_policy": effective["submission_artifact_policy_id"], + "review_policy": guide.selected_review_policy_id, + "review_policy_hash": guide.selected_review_policy_hash, + "revision_policy": guide.selected_revision_policy_id, + "revision_policy_hash": guide.selected_revision_policy_hash, + "guide_version": guide_version, + "attestation_terms": effective["effective_policy"]["attestation_terms"], + "evidence_path": "evidence/" + + effective["effective_policy"]["required_evidence"][0]["key"], + } + diff --git a/backend/tests/submission_capacity_fixtures.py b/backend/tests/submission_capacity_fixtures.py index 122c44d6f..152fb74cc 100644 --- a/backend/tests/submission_capacity_fixtures.py +++ b/backend/tests/submission_capacity_fixtures.py @@ -8,7 +8,7 @@ from app.core.identifiers import new_record_id from app.modules.artifacts.api import SubmissionBundlePreparationRequest from app.modules.authorization.api import ActorIdentityFacts, ActorKind -from tests.pre_submit_test_helpers import approved_pre_submit_fixture +from tests.selected_policy_fixtures import approved_selected_policy_fixture from tests.submission_preparation_auth_helpers import install_submitter_grant from tests.tasks.lineage_fixtures import seed_started_task_for_artifact_test from tests.tasks.submission_lineage_support import _seed_services @@ -20,11 +20,17 @@ async def capacity_fixture(database_url, tmp_path): engine = create_async_engine(database_url) factory = async_sessionmaker(engine, expire_on_commit=False) - settings = _settings(tmp_path, maximum_bytes=1024 * 1024) + settings = _settings( + tmp_path, + maximum_bytes=1024 * 1024, + external_checker=True, + ) namespace = _namespace(settings) bootstrap, store = _local_store(settings, namespace) try: - plan, policy = await approved_pre_submit_fixture(factory, namespace, guide_version="v1") + plan, policy = await approved_selected_policy_fixture( + factory, namespace, guide_version="v1" + ) context = _context() await _seed_services(factory) task_id, assignment_id = new_record_id(), new_record_id() diff --git a/backend/tests/tasks/test_submission_lineage.py b/backend/tests/tasks/test_submission_lineage.py index dac06103a..eaf371ab3 100644 --- a/backend/tests/tasks/test_submission_lineage.py +++ b/backend/tests/tasks/test_submission_lineage.py @@ -23,7 +23,7 @@ from app.modules.authorization.api import ActorIdentityFacts, ActorKind from app.modules.tasks.api import SubmissionCreationRequest from app.modules.tasks.models import AuditEvent, Submission, TaskAssignment, WorkstreamTask -from tests.pre_submit_test_helpers import approved_pre_submit_fixture +from tests.selected_policy_fixtures import approved_selected_policy_fixture from tests.submission_preparation_auth_helpers import install_submitter_grant from tests.tasks.lineage_fixtures import seed_started_task_for_artifact_test from tests.test_artifact_admission import ( @@ -43,11 +43,17 @@ async def _prepared_packet(isolated_database_env, tmp_path): engine = create_async_engine(isolated_database_env) factory = async_sessionmaker(engine, expire_on_commit=False) - settings = _settings(tmp_path, maximum_bytes=1024 * 1024) + settings = _settings( + tmp_path, + maximum_bytes=1024 * 1024, + external_checker=True, + ) namespace = _namespace(settings) bootstrap, store = _local_store(settings, namespace) try: - plan, policy = await approved_pre_submit_fixture(factory, namespace, guide_version="v1") + plan, policy = await approved_selected_policy_fixture( + factory, namespace, guide_version="v1" + ) context = _context() await _seed_services(factory) task_id, assignment_id = new_record_id(), new_record_id() diff --git a/backend/tests/test_artifact_admission.py b/backend/tests/test_artifact_admission.py index 07ca8ab6b..9f9630c78 100644 --- a/backend/tests/test_artifact_admission.py +++ b/backend/tests/test_artifact_admission.py @@ -166,10 +166,15 @@ def admission_database_env(isolated_database_env: str) -> Iterator[str]: yield isolated_database_env -def _settings(tmp_path: Path, *, maximum_bytes: int = 1024) -> Settings: +def _settings( + tmp_path: Path, + *, + maximum_bytes: int = 1024, + external_checker: bool = False, +) -> Settings: durable_root = tmp_path / "durable" durable_root.mkdir(mode=0o700, parents=True) - return Settings( + values = dict( _env_file=None, **artifact_admission_limit_settings(maximum_bytes), environment="test", @@ -178,6 +183,12 @@ def _settings(tmp_path: Path, *, maximum_bytes: int = 1024) -> Settings: artifact_scratch_root=tmp_path / "scratch", artifact_scratch_minimum_free_bytes=0, ) + if external_checker: + values.update( + external_checker_service_socket=tmp_path / "checker.sock", + external_checker_material_root=tmp_path / "scratch", + ) + return Settings(**values) def _namespace(settings: Settings) -> ArtifactStorageNamespaceSpec: From e07e4145ba2521b9db0d8779f9e1e733fdf6a101 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 22:02:47 +0100 Subject: [PATCH 101/283] [PILOT-04] bind external policies in proposal custody --- .../versions/0037_selected_checker_flow.py | 146 ++++++++++++++++++ .../guide_compilation/approval_custody.py | 13 +- 2 files changed, 158 insertions(+), 1 deletion(-) diff --git a/backend/alembic/versions/0037_selected_checker_flow.py b/backend/alembic/versions/0037_selected_checker_flow.py index 0f8483453..a7427950c 100644 --- a/backend/alembic/versions/0037_selected_checker_flow.py +++ b/backend/alembic/versions/0037_selected_checker_flow.py @@ -437,6 +437,151 @@ def _selected_run_guards() -> None: op.execute("create constraint trigger selected_pre_submit_receipt_custody after insert or update on public.selected_pre_submit_runs deferrable initially deferred for each row execute function public.guard_selected_pre_submit_receipts()") +def _replace_guide_approval_custody() -> None: + op.execute(r""" +create function public.external_checker_locked_policies_valid(value jsonb, expected_hash text) +returns boolean language plpgsql stable strict +set search_path=pg_catalog,public,pg_temp as $$ +declare phase_name text; policy jsonb; binding jsonb; registry jsonb; + registry_row public.external_checker_registry_entries%rowtype; + prior_requirement text; prior_capability text; prior_version text; +begin + if jsonb_typeof(value)<>'object' or jsonb_object_length(value)<>4 + or value->>'schema_version'<>'external_checker_policies.v1' + or value->>'policies_sha256'<>expected_hash + or public.guide_proposal_hash(value-'policies_sha256')<>expected_hash then + return false; + end if; + if jsonb_typeof(value->'pre_submit')<>'object' + or jsonb_typeof(value->'post_submit')<>'object' then return false; end if; + foreach phase_name in array array['pre_submit','post_submit'] loop + policy:=value->phase_name; + if jsonb_object_length(policy)<>(case when phase_name='pre_submit' then 4 else 3 end) + or policy->>'schema_version'<>'external_'||phase_name||'_policy.v1' + or public.guide_proposal_hash(policy-'policy_sha256')<>policy->>'policy_sha256' + or jsonb_typeof(policy->'entries')<>'array' then return false; end if; + if phase_name='pre_submit' and policy->'workstream_default' is distinct from + jsonb_build_object('checker_id','workstream.default','checker_version','v1', + 'behavior_sha256','sha256:af2c604f792c4456d3b222036c772161b1503eace65ff90c3d3a23d9d348c28f') + then return false; end if; + prior_requirement:=null; prior_capability:=null; prior_version:=null; + for binding in select item from jsonb_array_elements(policy->'entries') item loop + if jsonb_typeof(binding)<>'object' or jsonb_object_length(binding)<>5 + or binding->>'stage'<>phase_name + or jsonb_typeof(binding->'configuration')<>'object' + or public.external_checker_registry_digest(binding->'configuration') + <>binding->>'configuration_sha256' then return false; end if; + registry:=binding->'registry'; + if jsonb_typeof(registry)<>'object' or jsonb_object_length(registry)<>14 then + return false; + end if; + select * into registry_row from public.external_checker_registry_entries + where id=(registry->>'registry_entry_id')::uuid + and entry_digest=registry->>'entry_digest'; + if not found + or registry_row.capability_id<>registry->>'capability_id' + or registry_row.capability_version<>registry->>'capability_version' + or registry_row.phase<>registry->>'phase' + or registry_row.phase<>phase_name + or registry_row.image_digest<>registry->>'image_digest' + or registry_row.registration_operation_id<>(registry->>'registration_operation_id')::uuid + or registry_row.registered_by_actor_profile_id<>(registry->>'registered_by_actor_profile_id')::uuid + or registry_row.authorization_decision_event_id<>(registry->>'authorization_decision_event_id')::uuid + or registry_row.created_at<>(registry->>'created_at')::timestamptz + or registry->'configuration_schema' is distinct from jsonb_build_object( + 'schema_id',registry_row.configuration_schema_id, + 'schema_version',registry_row.configuration_schema_version, + 'document',registry_row.configuration_schema_document, + 'schema_sha256',registry_row.configuration_schema_sha256) + or registry->'input_schema' is distinct from jsonb_build_object( + 'schema_id',registry_row.input_schema_id, + 'schema_version',registry_row.input_schema_version, + 'document',registry_row.input_schema_document, + 'schema_sha256',registry_row.input_schema_sha256) + or registry->'output_schema' is distinct from jsonb_build_object( + 'schema_id',registry_row.output_schema_id, + 'schema_version',registry_row.output_schema_version, + 'document',registry_row.output_schema_document, + 'schema_sha256',registry_row.output_schema_sha256) + or registry->'resources' is distinct from jsonb_build_object( + 'cpu_millis',registry_row.cpu_millis, + 'memory_bytes',registry_row.memory_bytes, + 'deadline_ms',registry_row.deadline_ms, + 'maximum_output_bytes',registry_row.maximum_output_bytes) + or (prior_requirement,prior_capability,prior_version) is not null + and row(binding->>'requirement_id',registry_row.capability_id, + registry_row.capability_version) + <= row(prior_requirement,prior_capability,prior_version) + then return false; end if; + prior_requirement:=binding->>'requirement_id'; + prior_capability:=registry_row.capability_id; + prior_version:=registry_row.capability_version; + end loop; + end loop; + return true; +exception when others then return false; +end $$ +""") + definition = op.get_bind().execute(sa.text( + "select pg_get_functiondef('public.require_guide_proposal_approval()'::regprocedure)" + )).scalar_one() + declaration = " prior project_guide_proposal_approvals%rowtype;" + if definition.count(declaration) != 1: + raise RuntimeError("guide approval declaration shape changed") + definition = definition.replace( + declaration, declaration + "\n external_plan boolean;" + ) + anchor = """ IF a.operation_id IS NULL THEN + RAISE EXCEPTION 'immutable proposal approval operation missing' USING ERRCODE='23514'; + END IF;""" + if definition.count(anchor) != 1: + raise RuntimeError("guide approval operation guard shape changed") + definition = definition.replace( + anchor, + anchor + """ + external_plan:=a.effective_pre_submit_plan::jsonb->>'schema_version' + ='external_checker_policies.v1';""", + ) + old_hashes = """ OR guide_proposal_hash(pre.compiled_bundle::jsonb) IS DISTINCT FROM pre.compiled_bundle_hash + OR guide_proposal_hash(a.effective_pre_submit_plan::jsonb) IS DISTINCT FROM a.effective_pre_submit_plan_hash""" + new_hashes = """ OR (NOT external_plan AND ( + guide_proposal_hash(pre.compiled_bundle::jsonb) IS DISTINCT FROM pre.compiled_bundle_hash + OR guide_proposal_hash(a.effective_pre_submit_plan::jsonb) IS DISTINCT FROM a.effective_pre_submit_plan_hash)) + OR (external_plan AND ( + pre.compiled_bundle::jsonb IS DISTINCT FROM a.effective_pre_submit_plan::jsonb->'pre_submit' + OR NOT public.external_checker_locked_policies_valid( + a.effective_pre_submit_plan::jsonb,a.effective_pre_submit_plan_hash)))""" + if definition.count(old_hashes) != 1: + raise RuntimeError("guide approval plan digest shape changed") + definition = definition.replace(old_hashes, new_hashes) + old_plan = """ OR a.effective_pre_submit_plan::jsonb->'lineage' IS DISTINCT FROM jsonb_build_object( + 'project_id',a.project_id,'guide_id',a.guide_id, + 'guide_version',a.target_json->>'guide_version', + 'source_snapshot_id',a.target_json->>'source_snapshot_id', + 'source_snapshot_hash',a.target_json->>'source_snapshot_hash', + 'effective_policy_id',e.id,'effective_policy_hash',e.effective_policy_hash, + 'pre_submit_policy_id',pre.id,'pre_submit_policy_bundle_hash',pre.compiled_bundle_hash) + OR a.effective_pre_submit_plan::jsonb->'catalogue' IS DISTINCT FROM jsonb_build_object( + 'id',a.target_json->>'pre_catalogue_id','version',a.target_json->>'pre_catalogue_version', + 'schema_version',a.target_json->>'pre_catalogue_schema_version', + 'manifest_sha256',a.target_json->>'pre_catalogue_manifest_hash')""" + new_plan = """ OR (NOT external_plan AND ( + a.effective_pre_submit_plan::jsonb->'lineage' IS DISTINCT FROM jsonb_build_object( + 'project_id',a.project_id,'guide_id',a.guide_id, + 'guide_version',a.target_json->>'guide_version', + 'source_snapshot_id',a.target_json->>'source_snapshot_id', + 'source_snapshot_hash',a.target_json->>'source_snapshot_hash', + 'effective_policy_id',e.id,'effective_policy_hash',e.effective_policy_hash, + 'pre_submit_policy_id',pre.id,'pre_submit_policy_bundle_hash',pre.compiled_bundle_hash) + OR a.effective_pre_submit_plan::jsonb->'catalogue' IS DISTINCT FROM jsonb_build_object( + 'id',a.target_json->>'pre_catalogue_id','version',a.target_json->>'pre_catalogue_version', + 'schema_version',a.target_json->>'pre_catalogue_schema_version', + 'manifest_sha256',a.target_json->>'pre_catalogue_manifest_hash')))""" + if definition.count(old_plan) != 1: + raise RuntimeError("guide approval legacy plan binding shape changed") + op.execute(definition.replace(old_plan, new_plan)) + + def upgrade() -> None: op.execute("set local search_path=pg_catalog,public,pg_temp") op.execute("lock table public.actor_profiles, public.actor_identity_links, public.audit_events, public.submissions, public.checker_runs, public.submission_bundle_durable_intents, public.submission_bundle_admissions in access exclusive mode") @@ -445,6 +590,7 @@ def upgrade() -> None: _alter_selected_lineage() _replace_admission_guards() _selected_run_guards() + _replace_guide_approval_custody() def downgrade() -> None: diff --git a/backend/app/modules/projects/guide_compilation/approval_custody.py b/backend/app/modules/projects/guide_compilation/approval_custody.py index 85f4627fa..8d5acf391 100644 --- a/backend/app/modules/projects/guide_compilation/approval_custody.py +++ b/backend/app/modules/projects/guide_compilation/approval_custody.py @@ -99,6 +99,13 @@ def approved_projection_digest(view) -> str: ) target = GuideProposalTarget.model_validate(operation.target_json) receipt = GuideProposalApprovalReceipt.model_validate(operation.receipt_json) + external_plan_hash = None + if operation.effective_pre_submit_plan.get("schema_version") == ( + "external_checker_policies.v1" + ): + external_plan_hash = LockedExternalCheckerPolicies.model_validate( + operation.effective_pre_submit_plan + ).policies_sha256 if ( target.digest != operation.target_digest or target.compilation_id != view.compilation.id @@ -145,7 +152,11 @@ def approved_projection_digest(view) -> str: or pre.effective_policy_id != effective.id or pre.effective_policy_hash != effective.effective_policy_hash or operation.effective_pre_submit_plan_hash != receipt.effective_pre_submit_plan_hash - or canonical_json_hash(operation.effective_pre_submit_plan) + or ( + external_plan_hash + if external_plan_hash is not None + else canonical_json_hash(operation.effective_pre_submit_plan) + ) != receipt.effective_pre_submit_plan_hash ): raise ValueError("approved proposal custody mismatch") From fb8089b540ecedb79f56bf7dc04dd25ba7d490b1 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 22:03:25 +0100 Subject: [PATCH 102/283] [PILOT-04] record external policy custody schema --- backend/tests/conftest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/tests/conftest.py b/backend/tests/conftest.py index 9c2b62254..b2e5b2245 100644 --- a/backend/tests/conftest.py +++ b/backend/tests/conftest.py @@ -23,7 +23,7 @@ DDL_LOCK_DIRECTORY = Path("/tmp") # Match the PostgreSQL 16 engine used by Backend CI. Catalog identity rendering # differs across major versions; regenerate only after comparing actual objects. -EXPECTED_PUBLIC_SCHEMA_SHA256 = "312484b62c1e6c6459f16bb7cb3530d0cd2e7bb88f4c273365e809ad4ee4989c" +EXPECTED_PUBLIC_SCHEMA_SHA256 = "dd799007424a4b2af029440f88db571d3c5c8f095f1e223519562cf19e585094" PROTECTED_TEST_TABLES = ( "actor_profile_migration_state", "alembic_version", From 1d370e47bcfdfe230a43230907ba63b09956560a Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 22:04:23 +0100 Subject: [PATCH 103/283] [PILOT-04] distinguish external policy custody failures --- .../versions/0037_selected_checker_flow.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/backend/alembic/versions/0037_selected_checker_flow.py b/backend/alembic/versions/0037_selected_checker_flow.py index a7427950c..059cf7067 100644 --- a/backend/alembic/versions/0037_selected_checker_flow.py +++ b/backend/alembic/versions/0037_selected_checker_flow.py @@ -542,6 +542,21 @@ def _replace_guide_approval_custody() -> None: external_plan:=a.effective_pre_submit_plan::jsonb->>'schema_version' ='external_checker_policies.v1';""", ) + selected_pre = """ SELECT * INTO pre FROM pre_submit_checker_policies WHERE id=a.pre_submit_policy_id;""" + if definition.count(selected_pre) != 1: + raise RuntimeError("guide approval pre policy lookup shape changed") + definition = definition.replace( + selected_pre, + selected_pre + """ + IF external_plan AND pre.compiled_bundle::jsonb IS DISTINCT FROM + a.effective_pre_submit_plan::jsonb->'pre_submit' THEN + RAISE EXCEPTION 'external proposal PRE policy custody mismatch' USING ERRCODE='23514'; + END IF; + IF external_plan AND NOT public.external_checker_locked_policies_valid( + a.effective_pre_submit_plan::jsonb,a.effective_pre_submit_plan_hash) THEN + RAISE EXCEPTION 'external proposal policy custody mismatch' USING ERRCODE='23514'; + END IF;""", + ) old_hashes = """ OR guide_proposal_hash(pre.compiled_bundle::jsonb) IS DISTINCT FROM pre.compiled_bundle_hash OR guide_proposal_hash(a.effective_pre_submit_plan::jsonb) IS DISTINCT FROM a.effective_pre_submit_plan_hash""" new_hashes = """ OR (NOT external_plan AND ( From db8824efbffc026824f6acdf298ce11647547057 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 22:04:53 +0100 Subject: [PATCH 104/283] [PILOT-04] refresh policy custody fingerprint --- backend/tests/conftest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/tests/conftest.py b/backend/tests/conftest.py index b2e5b2245..fc2acfb6b 100644 --- a/backend/tests/conftest.py +++ b/backend/tests/conftest.py @@ -23,7 +23,7 @@ DDL_LOCK_DIRECTORY = Path("/tmp") # Match the PostgreSQL 16 engine used by Backend CI. Catalog identity rendering # differs across major versions; regenerate only after comparing actual objects. -EXPECTED_PUBLIC_SCHEMA_SHA256 = "dd799007424a4b2af029440f88db571d3c5c8f095f1e223519562cf19e585094" +EXPECTED_PUBLIC_SCHEMA_SHA256 = "91b7296409b53f3c8cdc082993a7c7449ca784b45b5c64e6a59c43db8526e08c" PROTECTED_TEST_TABLES = ( "actor_profile_migration_state", "alembic_version", From 144a8a31b28085a2eabab5545c1aa19f6ff60202 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 22:05:49 +0100 Subject: [PATCH 105/283] [PILOT-04] classify locked policy custody failures --- .../versions/0037_selected_checker_flow.py | 30 +++++++++++++------ 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/backend/alembic/versions/0037_selected_checker_flow.py b/backend/alembic/versions/0037_selected_checker_flow.py index 059cf7067..ac0669428 100644 --- a/backend/alembic/versions/0037_selected_checker_flow.py +++ b/backend/alembic/versions/0037_selected_checker_flow.py @@ -450,30 +450,37 @@ def _replace_guide_approval_custody() -> None: or value->>'schema_version'<>'external_checker_policies.v1' or value->>'policies_sha256'<>expected_hash or public.guide_proposal_hash(value-'policies_sha256')<>expected_hash then - return false; + raise exception 'external checker policy envelope mismatch' using errcode='23514'; end if; if jsonb_typeof(value->'pre_submit')<>'object' - or jsonb_typeof(value->'post_submit')<>'object' then return false; end if; + or jsonb_typeof(value->'post_submit')<>'object' then + raise exception 'external checker phase policy is missing' using errcode='23514'; + end if; foreach phase_name in array array['pre_submit','post_submit'] loop policy:=value->phase_name; if jsonb_object_length(policy)<>(case when phase_name='pre_submit' then 4 else 3 end) or policy->>'schema_version'<>'external_'||phase_name||'_policy.v1' or public.guide_proposal_hash(policy-'policy_sha256')<>policy->>'policy_sha256' - or jsonb_typeof(policy->'entries')<>'array' then return false; end if; + or jsonb_typeof(policy->'entries')<>'array' then + raise exception 'external checker phase policy mismatch' using errcode='23514'; + end if; if phase_name='pre_submit' and policy->'workstream_default' is distinct from jsonb_build_object('checker_id','workstream.default','checker_version','v1', 'behavior_sha256','sha256:af2c604f792c4456d3b222036c772161b1503eace65ff90c3d3a23d9d348c28f') - then return false; end if; + then raise exception 'Workstream default checker identity mismatch' using errcode='23514'; + end if; prior_requirement:=null; prior_capability:=null; prior_version:=null; for binding in select item from jsonb_array_elements(policy->'entries') item loop if jsonb_typeof(binding)<>'object' or jsonb_object_length(binding)<>5 or binding->>'stage'<>phase_name or jsonb_typeof(binding->'configuration')<>'object' or public.external_checker_registry_digest(binding->'configuration') - <>binding->>'configuration_sha256' then return false; end if; + <>binding->>'configuration_sha256' then + raise exception 'external checker policy binding mismatch' using errcode='23514'; + end if; registry:=binding->'registry'; if jsonb_typeof(registry)<>'object' or jsonb_object_length(registry)<>14 then - return false; + raise exception 'external checker registry value mismatch' using errcode='23514'; end if; select * into registry_row from public.external_checker_registry_entries where id=(registry->>'registry_entry_id')::uuid @@ -508,18 +515,23 @@ def _replace_guide_approval_custody() -> None: 'memory_bytes',registry_row.memory_bytes, 'deadline_ms',registry_row.deadline_ms, 'maximum_output_bytes',registry_row.maximum_output_bytes) - or (prior_requirement,prior_capability,prior_version) is not null + then raise exception 'external checker registry custody mismatch' using errcode='23514'; + end if; + if (prior_requirement,prior_capability,prior_version) is not null and row(binding->>'requirement_id',registry_row.capability_id, registry_row.capability_version) <= row(prior_requirement,prior_capability,prior_version) - then return false; end if; + then raise exception 'external checker policy order mismatch' using errcode='23514'; + end if; prior_requirement:=binding->>'requirement_id'; prior_capability:=registry_row.capability_id; prior_version:=registry_row.capability_version; end loop; end loop; return true; -exception when others then return false; +exception when sqlstate '23514' then raise; + when others then + raise exception 'external checker policy value is invalid' using errcode='23514'; end $$ """) definition = op.get_bind().execute(sa.text( From 0e65dd81458caa4bbd7b1aac5a440dab6fa0e4ce Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 22:06:23 +0100 Subject: [PATCH 106/283] [PILOT-04] record classified custody schema --- backend/tests/conftest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/tests/conftest.py b/backend/tests/conftest.py index fc2acfb6b..2f933623c 100644 --- a/backend/tests/conftest.py +++ b/backend/tests/conftest.py @@ -23,7 +23,7 @@ DDL_LOCK_DIRECTORY = Path("/tmp") # Match the PostgreSQL 16 engine used by Backend CI. Catalog identity rendering # differs across major versions; regenerate only after comparing actual objects. -EXPECTED_PUBLIC_SCHEMA_SHA256 = "91b7296409b53f3c8cdc082993a7c7449ca784b45b5c64e6a59c43db8526e08c" +EXPECTED_PUBLIC_SCHEMA_SHA256 = "520c1020c14b1779ae36ff4db4569c8b9d19a209f68c52786ff7119212a32eec" PROTECTED_TEST_TABLES = ( "actor_profile_migration_state", "alembic_version", From 20f167ea55f4a795cc69a35358409499453b1281 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 22:07:02 +0100 Subject: [PATCH 107/283] [PILOT-04] expose invalid policy shape in custody error --- backend/alembic/versions/0037_selected_checker_flow.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/alembic/versions/0037_selected_checker_flow.py b/backend/alembic/versions/0037_selected_checker_flow.py index ac0669428..91ee6ee9a 100644 --- a/backend/alembic/versions/0037_selected_checker_flow.py +++ b/backend/alembic/versions/0037_selected_checker_flow.py @@ -531,7 +531,7 @@ def _replace_guide_approval_custody() -> None: return true; exception when sqlstate '23514' then raise; when others then - raise exception 'external checker policy value is invalid' using errcode='23514'; + raise exception 'external checker policy value is invalid: %',sqlerrm using errcode='23514'; end $$ """) definition = op.get_bind().execute(sa.text( From 7b995f5e4a9b5960c148581d9e39e471cb86a39c Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 22:07:31 +0100 Subject: [PATCH 108/283] [PILOT-04] refresh policy error schema fingerprint --- backend/tests/conftest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/tests/conftest.py b/backend/tests/conftest.py index 2f933623c..476ce71b5 100644 --- a/backend/tests/conftest.py +++ b/backend/tests/conftest.py @@ -23,7 +23,7 @@ DDL_LOCK_DIRECTORY = Path("/tmp") # Match the PostgreSQL 16 engine used by Backend CI. Catalog identity rendering # differs across major versions; regenerate only after comparing actual objects. -EXPECTED_PUBLIC_SCHEMA_SHA256 = "520c1020c14b1779ae36ff4db4569c8b9d19a209f68c52786ff7119212a32eec" +EXPECTED_PUBLIC_SCHEMA_SHA256 = "14706b0d0d42d8ab330f47bc3a96e5fc64571ff188cf8bccd9a93491b50f059f" PROTECTED_TEST_TABLES = ( "actor_profile_migration_state", "alembic_version", From c0b528cc83d2c948560694f708615afa88b5de2b Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 22:08:17 +0100 Subject: [PATCH 109/283] [PILOT-04] validate JSON object cardinality on PostgreSQL --- backend/alembic/versions/0037_selected_checker_flow.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/backend/alembic/versions/0037_selected_checker_flow.py b/backend/alembic/versions/0037_selected_checker_flow.py index 91ee6ee9a..f80778fe9 100644 --- a/backend/alembic/versions/0037_selected_checker_flow.py +++ b/backend/alembic/versions/0037_selected_checker_flow.py @@ -446,7 +446,7 @@ def _replace_guide_approval_custody() -> None: registry_row public.external_checker_registry_entries%rowtype; prior_requirement text; prior_capability text; prior_version text; begin - if jsonb_typeof(value)<>'object' or jsonb_object_length(value)<>4 + if jsonb_typeof(value)<>'object' or (select count(*) from jsonb_object_keys(value))<>4 or value->>'schema_version'<>'external_checker_policies.v1' or value->>'policies_sha256'<>expected_hash or public.guide_proposal_hash(value-'policies_sha256')<>expected_hash then @@ -458,7 +458,7 @@ def _replace_guide_approval_custody() -> None: end if; foreach phase_name in array array['pre_submit','post_submit'] loop policy:=value->phase_name; - if jsonb_object_length(policy)<>(case when phase_name='pre_submit' then 4 else 3 end) + if (select count(*) from jsonb_object_keys(policy))<>(case when phase_name='pre_submit' then 4 else 3 end) or policy->>'schema_version'<>'external_'||phase_name||'_policy.v1' or public.guide_proposal_hash(policy-'policy_sha256')<>policy->>'policy_sha256' or jsonb_typeof(policy->'entries')<>'array' then @@ -471,7 +471,7 @@ def _replace_guide_approval_custody() -> None: end if; prior_requirement:=null; prior_capability:=null; prior_version:=null; for binding in select item from jsonb_array_elements(policy->'entries') item loop - if jsonb_typeof(binding)<>'object' or jsonb_object_length(binding)<>5 + if jsonb_typeof(binding)<>'object' or (select count(*) from jsonb_object_keys(binding))<>5 or binding->>'stage'<>phase_name or jsonb_typeof(binding->'configuration')<>'object' or public.external_checker_registry_digest(binding->'configuration') @@ -479,7 +479,7 @@ def _replace_guide_approval_custody() -> None: raise exception 'external checker policy binding mismatch' using errcode='23514'; end if; registry:=binding->'registry'; - if jsonb_typeof(registry)<>'object' or jsonb_object_length(registry)<>14 then + if jsonb_typeof(registry)<>'object' or (select count(*) from jsonb_object_keys(registry))<>14 then raise exception 'external checker registry value mismatch' using errcode='23514'; end if; select * into registry_row from public.external_checker_registry_entries @@ -531,7 +531,7 @@ def _replace_guide_approval_custody() -> None: return true; exception when sqlstate '23514' then raise; when others then - raise exception 'external checker policy value is invalid: %',sqlerrm using errcode='23514'; + raise exception 'external checker policy value is invalid' using errcode='23514'; end $$ """) definition = op.get_bind().execute(sa.text( From 82181dd142dd6219431557f840e2d1094d6a1e44 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 22:08:52 +0100 Subject: [PATCH 110/283] [PILOT-04] record policy cardinality schema --- backend/tests/conftest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/tests/conftest.py b/backend/tests/conftest.py index 476ce71b5..e070013f8 100644 --- a/backend/tests/conftest.py +++ b/backend/tests/conftest.py @@ -23,7 +23,7 @@ DDL_LOCK_DIRECTORY = Path("/tmp") # Match the PostgreSQL 16 engine used by Backend CI. Catalog identity rendering # differs across major versions; regenerate only after comparing actual objects. -EXPECTED_PUBLIC_SCHEMA_SHA256 = "14706b0d0d42d8ab330f47bc3a96e5fc64571ff188cf8bccd9a93491b50f059f" +EXPECTED_PUBLIC_SCHEMA_SHA256 = "aa2f484e7fe779b90609f96bb4ee03e4aefe1f81998006da6440ecb7e589e3d7" PROTECTED_TEST_TABLES = ( "actor_profile_migration_state", "alembic_version", From 37474799b22da7b222665e6c516456044d057af1 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 22:10:04 +0100 Subject: [PATCH 111/283] [PILOT-04] use selected post policy service fixture --- backend/tests/projects/post_policy/pg_support.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/backend/tests/projects/post_policy/pg_support.py b/backend/tests/projects/post_policy/pg_support.py index b2afea955..2a6602f4f 100644 --- a/backend/tests/projects/post_policy/pg_support.py +++ b/backend/tests/projects/post_policy/pg_support.py @@ -127,12 +127,14 @@ async def prepare_post_policy(factory, command, actor, grant, setup_actor): async def operate(factory, actor, project_id, grant, operation, command, *, close_error=False, guide_close_error=False): - from app.modules.checkers.api.historical_post_submit import current_post_submit_catalogue from app.modules.projects.post_policy.service import PostPolicyService from tests.projects.guide_compilation.proposals.pg_support import ProposalAuthority async with factory() as session, session.begin(): - service = PostPolicyService(session, PostAuthority(session, actor, project_id, grant, close_error=close_error), current_post_submit_catalogue()) + service = PostPolicyService( + session, + PostAuthority(session, actor, project_id, grant, close_error=close_error), + ) kwargs = dict(actor=actor, request_id=uuid4()) if operation == "review_package": kwargs["contribution"] = GuideContributionPolicyDiscovery(published_contribution_policy_port(session)) From 74f75d3ccb4b140667dfae40d1b4ddd70086a1ae Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 22:12:08 +0100 Subject: [PATCH 112/283] [PILOT-04] validate self-hashed selected PRE custody --- .../guide_compilation/approval_custody.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/backend/app/modules/projects/guide_compilation/approval_custody.py b/backend/app/modules/projects/guide_compilation/approval_custody.py index 8d5acf391..99bf93d9e 100644 --- a/backend/app/modules/projects/guide_compilation/approval_custody.py +++ b/backend/app/modules/projects/guide_compilation/approval_custody.py @@ -99,13 +99,15 @@ def approved_projection_digest(view) -> str: ) target = GuideProposalTarget.model_validate(operation.target_json) receipt = GuideProposalApprovalReceipt.model_validate(operation.receipt_json) - external_plan_hash = None + external_plan_hash = external_pre_hash = None if operation.effective_pre_submit_plan.get("schema_version") == ( "external_checker_policies.v1" ): - external_plan_hash = LockedExternalCheckerPolicies.model_validate( + external_policies = LockedExternalCheckerPolicies.model_validate( operation.effective_pre_submit_plan - ).policies_sha256 + ) + external_plan_hash = external_policies.policies_sha256 + external_pre_hash = external_policies.pre_submit.policy_sha256 if ( target.digest != operation.target_digest or target.compilation_id != view.compilation.id @@ -146,7 +148,12 @@ def approved_projection_digest(view) -> str: or effective.effective_policy_hash != receipt.effective_policy_hash or canonical_json_hash(effective.effective_policy) != receipt.effective_policy_hash or pre.compiled_bundle_hash != receipt.pre_submit_bundle_hash - or canonical_json_hash(pre.compiled_bundle) != receipt.pre_submit_bundle_hash + or ( + external_pre_hash + if external_pre_hash is not None + else canonical_json_hash(pre.compiled_bundle) + ) + != receipt.pre_submit_bundle_hash or effective.submission_artifact_policy_id != policy.id or effective.submission_artifact_policy_hash != policy.policy_hash or pre.effective_policy_id != effective.id From 1ede6ff290660daf5c41b031c94a9bf453ec1ce5 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 22:13:05 +0100 Subject: [PATCH 113/283] [PILOT-04] use selected post policy digest --- backend/app/modules/projects/post_policy/service.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/app/modules/projects/post_policy/service.py b/backend/app/modules/projects/post_policy/service.py index b60866207..4e9efaa63 100644 --- a/backend/app/modules/projects/post_policy/service.py +++ b/backend/app/modules/projects/post_policy/service.py @@ -115,7 +115,7 @@ async def derive( upstream_output_digest=upstream.output_digest, policy_id=new_record_id(), projection_operation_id=operation_id, - policy_hash=compiled.policy_hash, + policy_hash=compiled.policy_sha256, predecessor_policy_id=UUID(previous.id) if previous else None, ) receipt = PostPolicyReceipt(operation_id=operation_id, kind="derive", target=target) @@ -160,7 +160,7 @@ async def approve( locked.view.approval_custody.operation.effective_pre_submit_plan ), ) - if compiled.policy_hash != target.policy_hash: + if compiled.policy_sha256 != target.policy_hash: raise GuideProposalError("approval_blocked") operation_id = new_record_id() receipt = PostPolicyReceipt( From b12e61119f0654648f08b3673e984866a223b609 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 22:13:54 +0100 Subject: [PATCH 114/283] [PILOT-04] bind selected POST projection custody --- .../versions/0037_selected_checker_flow.py | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/backend/alembic/versions/0037_selected_checker_flow.py b/backend/alembic/versions/0037_selected_checker_flow.py index f80778fe9..fe21411e4 100644 --- a/backend/alembic/versions/0037_selected_checker_flow.py +++ b/backend/alembic/versions/0037_selected_checker_flow.py @@ -609,6 +609,27 @@ def _replace_guide_approval_custody() -> None: op.execute(definition.replace(old_plan, new_plan)) +def _replace_post_policy_custody() -> None: + definition = op.get_bind().execute(sa.text( + "select pg_get_functiondef('public.require_post_policy_operation()'::regprocedure)" + )).scalar_one() + old_policy = """ OR p.policy_hash IS DISTINCT FROM guide_proposal_hash(p.policy_body::jsonb) + OR p.policy_body->>'catalogue_manifest_sha256' IS DISTINCT FROM t->'proposal'->>'post_catalogue_manifest_hash'""" + new_policy = """ OR (p.policy_body->>'schema_version'='external_post_submit_policy.v1' AND ( + p.policy_hash IS DISTINCT FROM p.policy_body->>'policy_sha256' + OR p.policy_hash IS DISTINCT FROM guide_proposal_hash( + p.policy_body::jsonb-'policy_sha256') + OR p.policy_body::jsonb IS DISTINCT FROM + a.effective_pre_submit_plan::jsonb->'post_submit')) + OR (p.policy_body->>'schema_version'<>'external_post_submit_policy.v1' AND ( + p.policy_hash IS DISTINCT FROM guide_proposal_hash(p.policy_body::jsonb) + OR p.policy_body->>'catalogue_manifest_sha256' IS DISTINCT FROM + t->'proposal'->>'post_catalogue_manifest_hash'))""" + if definition.count(old_policy) != 1: + raise RuntimeError("post policy custody shape changed") + op.execute(definition.replace(old_policy, new_policy)) + + def upgrade() -> None: op.execute("set local search_path=pg_catalog,public,pg_temp") op.execute("lock table public.actor_profiles, public.actor_identity_links, public.audit_events, public.submissions, public.checker_runs, public.submission_bundle_durable_intents, public.submission_bundle_admissions in access exclusive mode") @@ -618,6 +639,7 @@ def upgrade() -> None: _replace_admission_guards() _selected_run_guards() _replace_guide_approval_custody() + _replace_post_policy_custody() def downgrade() -> None: From 94a71803ed19786b136e9244365370f95dc09ffa Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 22:14:19 +0100 Subject: [PATCH 115/283] [PILOT-04] record selected POST custody schema --- backend/tests/conftest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/tests/conftest.py b/backend/tests/conftest.py index e070013f8..a41b3bff4 100644 --- a/backend/tests/conftest.py +++ b/backend/tests/conftest.py @@ -23,7 +23,7 @@ DDL_LOCK_DIRECTORY = Path("/tmp") # Match the PostgreSQL 16 engine used by Backend CI. Catalog identity rendering # differs across major versions; regenerate only after comparing actual objects. -EXPECTED_PUBLIC_SCHEMA_SHA256 = "aa2f484e7fe779b90609f96bb4ee03e4aefe1f81998006da6440ecb7e589e3d7" +EXPECTED_PUBLIC_SCHEMA_SHA256 = "d0b9ab67d8f1ec6358a8ee471609eee349616bc4bf10e5abcb7582bdfd761559" PROTECTED_TEST_TABLES = ( "actor_profile_migration_state", "alembic_version", From 3b8a10d87eca689afbaefe6a756f8240388381a4 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 22:15:15 +0100 Subject: [PATCH 116/283] [PILOT-04] validate selected PRE activation digest --- backend/app/modules/projects/service.py | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/backend/app/modules/projects/service.py b/backend/app/modules/projects/service.py index 0ce359314..7b5c0bbc9 100644 --- a/backend/app/modules/projects/service.py +++ b/backend/app/modules/projects/service.py @@ -1187,10 +1187,22 @@ def validate_activation_ready( ) if not isinstance(pre_submit_checker_policy.compiled_bundle, dict): raise GuideActivationBlocked("pre-submit checker compiled bundle must be an object") - if ( - self._hash_canonical_json(pre_submit_checker_policy.compiled_bundle) - != pre_submit_checker_policy.compiled_bundle_hash + if pre_submit_checker_policy.compiled_bundle.get("schema_version") == ( + "external_pre_submit_policy.v1" ): + from app.modules.checkers.api.external_policy import ( + LockedExternalPreSubmitPolicy, + ) + + compiled_pre = LockedExternalPreSubmitPolicy.model_validate( + pre_submit_checker_policy.compiled_bundle + ) + compiled_pre_hash = compiled_pre.policy_sha256 + else: + compiled_pre_hash = self._hash_canonical_json( + pre_submit_checker_policy.compiled_bundle + ) + if compiled_pre_hash != pre_submit_checker_policy.compiled_bundle_hash: raise GuideActivationBlocked("pre-submit checker compiled bundle hash mismatch") from .post_policy.custody import validate_activation_post_policy try: From 1989f6e002ea8ec7e3bb884224449ce499d090a6 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 22:16:02 +0100 Subject: [PATCH 117/283] [PILOT-04] bind selected policy hashes in TASK context --- .../app/modules/projects/api/locked_policy.py | 33 ++++++++++++++++--- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/backend/app/modules/projects/api/locked_policy.py b/backend/app/modules/projects/api/locked_policy.py index 3970867ae..c1a63a760 100644 --- a/backend/app/modules/projects/api/locked_policy.py +++ b/backend/app/modules/projects/api/locked_policy.py @@ -222,6 +222,34 @@ def __post_init__(self) -> None: ): raise ValueError("project display facts differ from locked context") target, upstream = receipt.command.target.proposal, receipt.command.target.upstream + external_body = json.loads(self.external_checker_policies.value) + if external_body.get("schema_version") == "external_checker_policies.v1": + from app.modules.checkers.api.external_policy import ( + LockedExternalCheckerPolicies, + ) + + external_policies = LockedExternalCheckerPolicies.model_validate(external_body) + pre_body = json.loads(self.compiled_pre_submit_bundle.value) + post_body = json.loads(self.compiled_post_submit_policy.value) + external_hashes_match = ( + external_policies.policies_sha256 + == receipt.command.target.upstream.effective_pre_submit_plan_hash + and external_policies.pre_submit.model_dump(mode="json") == pre_body + and external_policies.pre_submit.policy_sha256 + == self.pre_submit_policy_bundle_hash + and external_policies.post_submit.model_dump(mode="json") == post_body + and external_policies.post_submit.policy_sha256 + == receipt.command.target.policy_hash + ) + else: + external_hashes_match = ( + self.compiled_pre_submit_bundle.sha256 + == self.pre_submit_policy_bundle_hash + and self.compiled_post_submit_policy.sha256 + == receipt.command.target.policy_hash + and self.external_checker_policies.sha256 + == receipt.command.target.upstream.effective_pre_submit_plan_hash + ) if ( ( self.project_id, @@ -250,11 +278,8 @@ def __post_init__(self) -> None: upstream.pre_submit_bundle_hash, ) or self.effective_policy.sha256 != self.effective_policy_hash - or self.compiled_pre_submit_bundle.sha256 != self.pre_submit_policy_bundle_hash + or not external_hashes_match or self.artifact_policy.sha256 != target.artifact_policy_hash - or self.compiled_post_submit_policy.sha256 != receipt.command.target.policy_hash - or self.external_checker_policies.sha256 - != receipt.command.target.upstream.effective_pre_submit_plan_hash ): raise ValueError("project locked policy facts differ from activation") require_complete_policy( From 1153043319cb9467f28f3fd9825f236ef9ed4312 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 22:17:05 +0100 Subject: [PATCH 118/283] [PILOT-04] provision selected PRE fixture authority --- backend/tests/tasks/submission_lineage_support.py | 1 + 1 file changed, 1 insertion(+) diff --git a/backend/tests/tasks/submission_lineage_support.py b/backend/tests/tasks/submission_lineage_support.py index 1906a120a..f6f5b1224 100644 --- a/backend/tests/tasks/submission_lineage_support.py +++ b/backend/tests/tasks/submission_lineage_support.py @@ -28,6 +28,7 @@ async def _seed_services(factory): ServiceIdentity.ARTIFACT_PUT_RESOLVER, ServiceIdentity.ARTIFACT_VERIFIER, ServiceIdentity.ARTIFACT_BINDING, + ServiceIdentity.CHECKER_PRE_SUBMIT, ): actor_id, link_id = str(new_record_id()), str(new_record_id()) session.add( From 96c4781a94bf00f8690de5e78d1a529989bc85e0 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 22:19:09 +0100 Subject: [PATCH 119/283] [PILOT-04] bind selected POST request custody --- .../versions/0037_selected_checker_flow.py | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/backend/alembic/versions/0037_selected_checker_flow.py b/backend/alembic/versions/0037_selected_checker_flow.py index fe21411e4..fce79def1 100644 --- a/backend/alembic/versions/0037_selected_checker_flow.py +++ b/backend/alembic/versions/0037_selected_checker_flow.py @@ -630,6 +630,64 @@ def _replace_post_policy_custody() -> None: op.execute(definition.replace(old_policy, new_policy)) +def _replace_checker_run_custody() -> None: + definition = op.get_bind().execute(sa.text( + "select pg_get_functiondef('public.protect_checker_run_custody()'::regprocedure)" + )).scalar_one() + declaration = " DECLARE body jsonb; source submissions; mutable text[];" + if definition.count(declaration) != 1: + raise RuntimeError("checker run custody declaration shape changed") + definition = definition.replace( + declaration, + " DECLARE body jsonb; source submissions; mutable text[]; selected boolean;", + ) + body_anchor = " body := NEW.request_json::jsonb;" + if definition.count(body_anchor) != 1: + raise RuntimeError("checker run request body shape changed") + definition = definition.replace( + body_anchor, + body_anchor + "\n selected := body->>'schema_version'=" + "'workstream.selected_post_submit_request.v1';", + ) + old_policy = """ OR source.locked_post_submit_checker_policy_body::jsonb IS DISTINCT FROM body->'policy' + OR body->>'project_id' IS DISTINCT FROM NEW.project_id::text""" + new_policy = """ OR (NOT selected AND ( + source.locked_post_submit_checker_policy_body::jsonb IS DISTINCT FROM body->'policy' + OR NEW.selected_post_submit_policy_sha256 IS NOT NULL + OR NEW.selected_post_submit_policy_body IS NOT NULL)) + OR (selected AND ( + source.selected_post_submit_policy_body::jsonb IS DISTINCT FROM body->'policy' + OR source.selected_post_submit_policy_sha256 IS DISTINCT FROM + body#>>'{expected_context,selected_post_policy_hash}' + OR NEW.selected_post_submit_policy_body::jsonb IS DISTINCT FROM body->'policy' + OR NEW.selected_post_submit_policy_sha256 IS DISTINCT FROM + body#>>'{expected_context,selected_post_policy_hash}')) + OR body->>'project_id' IS DISTINCT FROM NEW.project_id::text""" + if definition.count(old_policy) != 1: + raise RuntimeError("checker run policy body shape changed") + definition = definition.replace(old_policy, new_policy) + old_context = """ OR body#>>'{expected_context,post_policy_id}' IS DISTINCT FROM NEW.locked_post_submit_checker_policy_id::text + OR body#>>'{expected_context,post_policy_version}' IS DISTINCT FROM NEW.locked_post_submit_checker_policy_version + OR body#>>'{expected_context,post_policy_hash}' IS DISTINCT FROM NEW.locked_post_submit_checker_policy_hash""" + new_context = """ OR (NOT selected AND ( + body#>>'{expected_context,post_policy_id}' IS DISTINCT FROM + NEW.locked_post_submit_checker_policy_id::text + OR body#>>'{expected_context,post_policy_version}' IS DISTINCT FROM + NEW.locked_post_submit_checker_policy_version + OR body#>>'{expected_context,post_policy_hash}' IS DISTINCT FROM + NEW.locked_post_submit_checker_policy_hash)) + OR (selected AND ( + body#>>'{expected_context,retained_catalogue_policy_id}' IS DISTINCT FROM + NEW.locked_post_submit_checker_policy_id::text + OR body#>>'{expected_context,retained_catalogue_policy_version}' IS DISTINCT FROM + NEW.locked_post_submit_checker_policy_version + OR body#>>'{expected_context,retained_catalogue_policy_hash}' IS DISTINCT FROM + NEW.locked_post_submit_checker_policy_hash))""" + if definition.count(old_context) != 1: + raise RuntimeError("checker run locked context shape changed") + op.execute(definition.replace(old_context, new_context)) + + def upgrade() -> None: op.execute("set local search_path=pg_catalog,public,pg_temp") op.execute("lock table public.actor_profiles, public.actor_identity_links, public.audit_events, public.submissions, public.checker_runs, public.submission_bundle_durable_intents, public.submission_bundle_admissions in access exclusive mode") @@ -640,6 +698,7 @@ def upgrade() -> None: _selected_run_guards() _replace_guide_approval_custody() _replace_post_policy_custody() + _replace_checker_run_custody() def downgrade() -> None: From 97f0b1b89aa8bca184eacd6e33e5bd41cda62339 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 22:19:42 +0100 Subject: [PATCH 120/283] [PILOT-04] record selected request custody schema --- backend/tests/conftest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/tests/conftest.py b/backend/tests/conftest.py index a41b3bff4..ae1dc8f3d 100644 --- a/backend/tests/conftest.py +++ b/backend/tests/conftest.py @@ -23,7 +23,7 @@ DDL_LOCK_DIRECTORY = Path("/tmp") # Match the PostgreSQL 16 engine used by Backend CI. Catalog identity rendering # differs across major versions; regenerate only after comparing actual objects. -EXPECTED_PUBLIC_SCHEMA_SHA256 = "d0b9ab67d8f1ec6358a8ee471609eee349616bc4bf10e5abcb7582bdfd761559" +EXPECTED_PUBLIC_SCHEMA_SHA256 = "85f860aa4cfede3055d2b28dd0613a62876e3f613fa3fc2ee716de124cd0a1e9" PROTECTED_TEST_TABLES = ( "actor_profile_migration_state", "alembic_version", From 419fee08aec7d09dd1b66b457dfac831e3fb36bf Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 22:20:36 +0100 Subject: [PATCH 121/283] [PILOT-04] bind selected dispatch packet custody --- .../versions/0037_selected_checker_flow.py | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/backend/alembic/versions/0037_selected_checker_flow.py b/backend/alembic/versions/0037_selected_checker_flow.py index fce79def1..2e0872035 100644 --- a/backend/alembic/versions/0037_selected_checker_flow.py +++ b/backend/alembic/versions/0037_selected_checker_flow.py @@ -688,6 +688,26 @@ def _replace_checker_run_custody() -> None: op.execute(definition.replace(old_context, new_context)) +def _replace_submission_dispatch_custody() -> None: + definition = op.get_bind().execute(sa.text( + "select pg_get_functiondef('public.submission_dispatch_valid(public.submission_dispatches)'::regprocedure)" + )).scalar_one() + old_packet = """ AND (r.request_json::jsonb->'structural_input'->>'summary')=s.summary + AND (r.request_json::jsonb->'structural_input'->>'worker_attestation')=s.worker_attestation""" + new_packet = """ AND ((r.request_json::jsonb->>'schema_version'= + 'workstream.selected_post_submit_request.v1' + AND r.selected_post_submit_policy_sha256=s.selected_post_submit_policy_sha256 + AND r.selected_post_submit_policy_body::jsonb=s.selected_post_submit_policy_body::jsonb + AND r.request_json::jsonb->'policy'=s.selected_post_submit_policy_body::jsonb) + OR (r.request_json::jsonb->>'schema_version'<> + 'workstream.selected_post_submit_request.v1' + AND (r.request_json::jsonb->'structural_input'->>'summary')=s.summary + AND (r.request_json::jsonb->'structural_input'->>'worker_attestation')=s.worker_attestation))""" + if definition.count(old_packet) != 1: + raise RuntimeError("submission dispatch packet custody shape changed") + op.execute(definition.replace(old_packet, new_packet)) + + def upgrade() -> None: op.execute("set local search_path=pg_catalog,public,pg_temp") op.execute("lock table public.actor_profiles, public.actor_identity_links, public.audit_events, public.submissions, public.checker_runs, public.submission_bundle_durable_intents, public.submission_bundle_admissions in access exclusive mode") @@ -699,6 +719,7 @@ def upgrade() -> None: _replace_guide_approval_custody() _replace_post_policy_custody() _replace_checker_run_custody() + _replace_submission_dispatch_custody() def downgrade() -> None: From 0e5a4db56d1e0315319a7da2e526d5bfc7fceb6d Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 22:21:07 +0100 Subject: [PATCH 122/283] [PILOT-04] record selected dispatch custody schema --- backend/tests/conftest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/tests/conftest.py b/backend/tests/conftest.py index ae1dc8f3d..2e8fc0730 100644 --- a/backend/tests/conftest.py +++ b/backend/tests/conftest.py @@ -23,7 +23,7 @@ DDL_LOCK_DIRECTORY = Path("/tmp") # Match the PostgreSQL 16 engine used by Backend CI. Catalog identity rendering # differs across major versions; regenerate only after comparing actual objects. -EXPECTED_PUBLIC_SCHEMA_SHA256 = "85f860aa4cfede3055d2b28dd0613a62876e3f613fa3fc2ee716de124cd0a1e9" +EXPECTED_PUBLIC_SCHEMA_SHA256 = "4e5aaf6139bc5bca8ff967e41320429a8a82c0f70ed5f56d984b9002ac1a55a7" PROTECTED_TEST_TABLES = ( "actor_profile_migration_state", "alembic_version", From 413a210cf01e502da9fa3361ba3790ea54305193 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 22:23:55 +0100 Subject: [PATCH 123/283] [PILOT-04] bind selected checked packet custody --- .../versions/0037_selected_checker_flow.py | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/backend/alembic/versions/0037_selected_checker_flow.py b/backend/alembic/versions/0037_selected_checker_flow.py index 2e0872035..db0d50cd3 100644 --- a/backend/alembic/versions/0037_selected_checker_flow.py +++ b/backend/alembic/versions/0037_selected_checker_flow.py @@ -708,6 +708,26 @@ def _replace_submission_dispatch_custody() -> None: op.execute(definition.replace(old_packet, new_packet)) +def _replace_submission_packet_custody() -> None: + definition = op.get_bind().execute(sa.text( + "select pg_get_functiondef('public.validate_submission_packet_custody()'::regprocedure)" + )).scalar_one() + old_lookup = """ SELECT evidence.packet_sha256 INTO expected_packet + FROM public.submission_bundle_admissions AS admission + JOIN public.pre_submit_evidence_sets AS evidence + ON evidence.id = admission.pre_submit_evidence_set_id + WHERE admission.id = stored.submission_bundle_admission_id;""" + new_lookup = """ SELECT coalesce(evidence.packet_sha256,admission.packet_sha256) + INTO expected_packet + FROM public.submission_bundle_admissions AS admission + LEFT JOIN public.pre_submit_evidence_sets AS evidence + ON evidence.id = admission.pre_submit_evidence_set_id + WHERE admission.id = stored.submission_bundle_admission_id;""" + if definition.count(old_lookup) != 1: + raise RuntimeError("submission packet custody lookup shape changed") + op.execute(definition.replace(old_lookup, new_lookup)) + + def upgrade() -> None: op.execute("set local search_path=pg_catalog,public,pg_temp") op.execute("lock table public.actor_profiles, public.actor_identity_links, public.audit_events, public.submissions, public.checker_runs, public.submission_bundle_durable_intents, public.submission_bundle_admissions in access exclusive mode") @@ -720,6 +740,7 @@ def upgrade() -> None: _replace_post_policy_custody() _replace_checker_run_custody() _replace_submission_dispatch_custody() + _replace_submission_packet_custody() def downgrade() -> None: From 5e95170bade4647552e2d2124285b7c9a3ac7f6a Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 22:24:26 +0100 Subject: [PATCH 124/283] [PILOT-04] record selected packet custody schema --- backend/tests/conftest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/tests/conftest.py b/backend/tests/conftest.py index 2e8fc0730..067a2eb8e 100644 --- a/backend/tests/conftest.py +++ b/backend/tests/conftest.py @@ -23,7 +23,7 @@ DDL_LOCK_DIRECTORY = Path("/tmp") # Match the PostgreSQL 16 engine used by Backend CI. Catalog identity rendering # differs across major versions; regenerate only after comparing actual objects. -EXPECTED_PUBLIC_SCHEMA_SHA256 = "4e5aaf6139bc5bca8ff967e41320429a8a82c0f70ed5f56d984b9002ac1a55a7" +EXPECTED_PUBLIC_SCHEMA_SHA256 = "ddc57fb0e94fc6f2ae41d7dcb29f2ea8fca7ef3ae7888b22a297a2b88775fd72" PROTECTED_TEST_TABLES = ( "actor_profile_migration_state", "alembic_version", From ee33ce0c172312b0ae8607b60f285c6a6134b8e5 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 22:32:59 +0100 Subject: [PATCH 125/283] [PILOT-04] seal selected dispatch and replay custody --- .../versions/0037_selected_checker_flow.py | 33 +++++++++++++++++++ backend/app/adapters/tasks/__init__.py | 19 +++++++++++ .../checkers/api/evaluation_contract.py | 6 ++++ .../modules/checkers/execution_repository.py | 6 ++-- .../modules/tasks/submission_composition.py | 27 +++++++++++++-- .../modules/tasks/submission_participants.py | 2 ++ backend/tests/conftest.py | 2 +- .../tests/tasks/test_submission_lineage.py | 8 ++--- 8 files changed, 93 insertions(+), 10 deletions(-) diff --git a/backend/alembic/versions/0037_selected_checker_flow.py b/backend/alembic/versions/0037_selected_checker_flow.py index db0d50cd3..4b823b2d9 100644 --- a/backend/alembic/versions/0037_selected_checker_flow.py +++ b/backend/alembic/versions/0037_selected_checker_flow.py @@ -708,6 +708,38 @@ def _replace_submission_dispatch_custody() -> None: op.execute(definition.replace(old_packet, new_packet)) +def _replace_submission_binding_resource() -> None: + op.execute(""" +CREATE OR REPLACE FUNCTION public.submission_binding_resource(admission_id uuid) RETURNS jsonb +LANGUAGE sql STABLE SET search_path = pg_catalog, public, pg_temp AS $$ + SELECT pg_catalog.jsonb_build_object( + 'resource_type','submission_binding','resource_id',a.id,'admission_id',a.id, + 'evidence_set_id',a.pre_submit_evidence_set_id, + 'selected_pre_submit_run_id',a.selected_pre_submit_run_id, + 'actor_profile_id',a.actor_profile_id,'identity_link_id',a.identity_link_id, + 'project_id',a.project_id,'task_id',a.task_id,'assignment_id',a.assignment_id, + 'predecessor_submission_id',a.predecessor_submission_id, + 'predecessor_submission_version',a.predecessor_submission_version, + 'submission_id',a.consumed_by_submission_id, + 'submission_version',a.consumed_by_submission_version, + 'guide_id',a.guide_id,'guide_version',a.guide_version, + 'source_snapshot_id',a.source_snapshot_id, + 'source_snapshot_sha256',a.source_snapshot_sha256, + 'effective_policy_id',a.effective_policy_id, + 'effective_policy_sha256',a.effective_policy_sha256, + 'pre_submit_policy_id',a.pre_submit_policy_id, + 'pre_submit_policy_sha256',a.pre_submit_policy_sha256, + 'locked_policy_context_hash',a.locked_policy_context_hash, + 'semantic_manifest_id',a.semantic_manifest_id, + 'semantic_manifest_sha256',a.semantic_manifest_sha256, + 'content_id',a.artifact_content_id,'sha256',a.archive_sha256, + 'byte_count',a.archive_byte_count,'logical_role','submission_bundle_original' + ) FROM public.submission_bundle_admissions a + WHERE a.id=$1 AND a.status='consumed' +$$; +""") + + def _replace_submission_packet_custody() -> None: definition = op.get_bind().execute(sa.text( "select pg_get_functiondef('public.validate_submission_packet_custody()'::regprocedure)" @@ -739,6 +771,7 @@ def upgrade() -> None: _replace_guide_approval_custody() _replace_post_policy_custody() _replace_checker_run_custody() + _replace_submission_binding_resource() _replace_submission_dispatch_custody() _replace_submission_packet_custody() diff --git a/backend/app/adapters/tasks/__init__.py b/backend/app/adapters/tasks/__init__.py index f4308876e..588bdfaa4 100644 --- a/backend/app/adapters/tasks/__init__.py +++ b/backend/app/adapters/tasks/__init__.py @@ -296,12 +296,31 @@ async def read_consumed( or result.status != "consumed" ): raise RuntimeError("retained admission custody unavailable") + from app.adapters.checkers import selected_submission_evaluation_content + from app.modules.checkers.api.external_policy import ( + LockedExternalPostSubmitPolicy, + ) + + selected_post_policy = ( + LockedExternalPostSubmitPolicy.model_validate( + result.selected_post_submit_policy_body + ) + if result.selected_post_submit_policy_body is not None + else None + ) return SubmissionArtifactBindingFacts( binding_id=result.binding_id, content_id=result.content_id, binding_decision_id=result.binding_decision_id, archive_sha256=result.material.archive_sha256, byte_count=result.material.archive_byte_count, + selected_evaluation_content=( + selected_submission_evaluation_content( + request.task_context, selected_post_policy + ) + if selected_post_policy is not None + else None + ), ) diff --git a/backend/app/modules/checkers/api/evaluation_contract.py b/backend/app/modules/checkers/api/evaluation_contract.py index 5dcf82d6f..5d617204b 100644 --- a/backend/app/modules/checkers/api/evaluation_contract.py +++ b/backend/app/modules/checkers/api/evaluation_contract.py @@ -34,6 +34,11 @@ def validate_execution_request(value: object) -> PostSubmissionExecutionRequest: return _REQUEST.validate_python(value) +def validate_stored_execution_request(value: str) -> PostSubmissionExecutionRequest: + """Decode retained canonical JSON using strict models' JSON boundary.""" + return _REQUEST.validate_json(value) + + def validate_execution_result(value: object) -> PostSubmissionExecutionResult: """Validate the selected writer or a retained legacy result by schema.""" return _RESULT.validate_python(value) @@ -43,5 +48,6 @@ def validate_execution_result(value: object) -> PostSubmissionExecutionResult: "PostSubmissionExecutionRequest", "PostSubmissionExecutionResult", "validate_execution_request", + "validate_stored_execution_request", "validate_execution_result", ) diff --git a/backend/app/modules/checkers/execution_repository.py b/backend/app/modules/checkers/execution_repository.py index 69c7b11ee..1369b75dc 100644 --- a/backend/app/modules/checkers/execution_repository.py +++ b/backend/app/modules/checkers/execution_repository.py @@ -16,8 +16,8 @@ from app.modules.checkers.api.evaluation_contract import ( PostSubmissionExecutionRequest, PostSubmissionExecutionResult, - validate_execution_request, validate_execution_result, + validate_stored_execution_request, ) from app.modules.checkers.api.selected_post_submit import ( SelectedPostSubmissionEvaluationResult, @@ -52,7 +52,9 @@ def stored_request(run: CheckerRun) -> PostSubmissionExecutionRequest: """Reconstitute and validate the stored request with its digest.""" body = json.loads(run.request_json) body["request_sha256"] = run.request_digest - return validate_execution_request(body) + return validate_stored_execution_request( + json.dumps(body, separators=(",", ":"), sort_keys=True) + ) def stored_result(run: CheckerRun) -> PostSubmissionExecutionResult: diff --git a/backend/app/modules/tasks/submission_composition.py b/backend/app/modules/tasks/submission_composition.py index b38c495c3..1ea3ea9c7 100644 --- a/backend/app/modules/tasks/submission_composition.py +++ b/backend/app/modules/tasks/submission_composition.py @@ -33,6 +33,7 @@ from app.modules.tasks.lifecycle import ensure_allowed_transition from app.modules.checkers.api.execution import EvaluationCoordinationPort from app.modules.checkers.api.selected_post_submit import ( + SelectedPostSubmissionEvaluationRequest, make_selected_post_submit_request, ) from app.modules.outbox.api import OutboxAppendPort @@ -222,8 +223,11 @@ async def create(self, request: SubmissionCreationRequest) -> SubmissionCreation content_sha256=consumed.archive_sha256, byte_count=consumed.byte_count, ) + selected = consumed.selected_evaluation_content evaluation = make_selected_post_submit_request( - **consumed.selected_evaluation_content.model_dump(), + project_id=selected.project_id, + expected_context=selected.expected_context, + policy=selected.policy, **request_fields, ) ensure_allowed_transition(task.status, "submitted") @@ -275,6 +279,7 @@ async def _replay(self, request, receipt, context) -> SubmissionCreationResult: contributor_id=request.contributor_id, submission_id=UUID(receipt.submission_id), submission_version=receipt.submission_version, packet_sha256=SubmissionPacketView(request.summary, request.contributor_attestation).sha256, + task_context=context, )) if (consumed.binding_id, consumed.content_id, consumed.binding_decision_id) != ( UUID(receipt.artifact_binding_id), UUID(receipt.artifact_content_id), UUID(receipt.binding_decision_id), @@ -296,8 +301,24 @@ async def _replay(self, request, receipt, context) -> SubmissionCreationResult: or evaluation.content_id != consumed.content_id or evaluation.content_sha256 != consumed.archive_sha256 or evaluation.byte_count != consumed.byte_count - or evaluation.structural_input.summary != request.summary - or evaluation.structural_input.worker_attestation != request.contributor_attestation + or ( + isinstance(evaluation, SelectedPostSubmissionEvaluationRequest) + and ( + consumed.selected_evaluation_content is None + or evaluation.project_id != consumed.selected_evaluation_content.project_id + or evaluation.expected_context + != consumed.selected_evaluation_content.expected_context + or evaluation.policy != consumed.selected_evaluation_content.policy + ) + ) + or ( + not isinstance(evaluation, SelectedPostSubmissionEvaluationRequest) + and ( + evaluation.structural_input.summary != request.summary + or evaluation.structural_input.worker_attestation + != request.contributor_attestation + ) + ) ): raise SubmissionCreationUnavailable("submission creation is unavailable") await self._events.require_existing(receipt.evaluation_event_id, evaluation_request_event(receipt)) diff --git a/backend/app/modules/tasks/submission_participants.py b/backend/app/modules/tasks/submission_participants.py index 6f880a462..7d881eb43 100644 --- a/backend/app/modules/tasks/submission_participants.py +++ b/backend/app/modules/tasks/submission_participants.py @@ -29,6 +29,7 @@ class SubmissionArtifactBindingFacts: binding_decision_id: UUID archive_sha256: str byte_count: int + selected_evaluation_content: SelectedPostSubmissionContent | None = None @dataclass(frozen=True, slots=True) @@ -65,6 +66,7 @@ class SubmissionArtifactReplayRequest: submission_id: UUID submission_version: int packet_sha256: str + task_context: TaskSubmissionContextFacts class SubmissionArtifactAdmissionPort(Protocol): diff --git a/backend/tests/conftest.py b/backend/tests/conftest.py index 067a2eb8e..9e0b23993 100644 --- a/backend/tests/conftest.py +++ b/backend/tests/conftest.py @@ -23,7 +23,7 @@ DDL_LOCK_DIRECTORY = Path("/tmp") # Match the PostgreSQL 16 engine used by Backend CI. Catalog identity rendering # differs across major versions; regenerate only after comparing actual objects. -EXPECTED_PUBLIC_SCHEMA_SHA256 = "ddc57fb0e94fc6f2ae41d7dcb29f2ea8fca7ef3ae7888b22a297a2b88775fd72" +EXPECTED_PUBLIC_SCHEMA_SHA256 = "77186384fdc0ef74c480a046205070c314cb309d78e1dece3a8f380278d2ce91" PROTECTED_TEST_TABLES = ( "actor_profile_migration_state", "alembic_version", diff --git a/backend/tests/tasks/test_submission_lineage.py b/backend/tests/tasks/test_submission_lineage.py index eaf371ab3..f29c6e55a 100644 --- a/backend/tests/tasks/test_submission_lineage.py +++ b/backend/tests/tasks/test_submission_lineage.py @@ -228,10 +228,10 @@ async def _assert_bound_packet_immutable(h, created): await session.execute(text(f"UPDATE public.submissions SET {update} WHERE id=:id"), {"id": created.submission_id, "foreign": new_record_id()}) for statement, message in ( - ("UPDATE public.pre_submit_evidence_sets SET packet_sha256='sha256:' || repeat('0',64) " - "WHERE id=(SELECT pre_submit_evidence_set_id FROM public.submission_bundle_admissions WHERE id=:id)", - "pre_submit_evidence_sets rows are immutable"), - ("UPDATE public.submission_bundle_admissions SET pre_submit_evidence_set_id=:foreign WHERE id=:id", + ("UPDATE public.selected_pre_submit_runs SET request_digest='sha256:' || repeat('0',64) " + "WHERE id=(SELECT selected_pre_submit_run_id FROM public.submission_bundle_admissions WHERE id=:id)", + "selected PRE request custody is immutable"), + ("UPDATE public.submission_bundle_admissions SET selected_pre_submit_run_id=:foreign WHERE id=:id", "submission bundle admission lineage is immutable"), ): with pytest.raises(DBAPIError, match=message): From 77b677f75be559e58e5a47ee4ac40a55e5f8a366 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 22:43:24 +0100 Subject: [PATCH 126/283] [PILOT-04] bind selected post custody and replay --- .../pilot04-workstream-default-checker.md | 1 + .../versions/0037_selected_checker_flow.py | 116 ++++++++++++++++++ .../artifacts/post_submit_selection.py | 95 +++++++++++--- .../checkers/api/evaluation_contract.py | 6 + .../modules/checkers/execution_repository.py | 6 +- backend/tests/checkers/execution/support.py | 3 +- .../external/test_selected_post_submit.py | 23 ++++ 7 files changed, 232 insertions(+), 18 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index d84f0dec4..fdcdb1a6a 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -224,6 +224,7 @@ intermediate-wait regression. | Selected POST callback | `pytest -q backend/tests/checkers/external/test_selected_post_submit.py`; Ruff and `git diff --check` on the affected files | 3 passed; actual Submission/ART identity reaches every locked POST image through its short-lived grant, work pass/fail remains evidence only, and infrastructure failure stays recoverable | Durable POST reservation/finalization, worker restart and routing composition remain pending | | Selected durable POST contract | `pytest -q backend/tests/checkers/external/test_selected_post_submit.py backend/tests/test_submission_bundle_admission.py`; Ruff and `git diff --check` on the affected files | 56 passed; the request digest binds the exact approved selected policy, separately named locked TASK context and native Submission/ART identity, while the result digest binds request/generation, ordered execution evidence or a closed recoverable infrastructure category without acceptance authority; a legacy catalogue hash cannot stand in for the selected image-policy digest | The existing scheduler/materializer still needs to select this contract and persist it through restart/replay | | Selected POST scheduler compatibility | `pytest -q backend/tests/checkers/external/test_selected_post_submit.py backend/tests/checkers/execution/test_results.py backend/tests/checkers/execution/test_completion_contract.py backend/tests/checkers/post_submit/test_request.py backend/tests/test_submission_bundle_admission.py`; focused Ruff | 84 passed; one discriminated owner accepts retained legacy and selected request/result envelopes, selected leases cover the ordered image budget and finalization margin, ART recomputes the selected manifest, and focused scheduler controls prove exact completed/infrastructure envelopes and generic replay parsing | Native selected columns/constraints and live Rust worker proof remain pending | +| Selected POST native custody | `python3 /tmp/p04_selected_runner.py /tmp/p04-selected-post-result-replay 420 tests/checkers/external/test_selected_post_submit.py::test_selected_post_materializes_actual_submission_and_replays`; focused selected-POST pure tests and Ruff | PostgreSQL 16 PASS 1 in 36.10s with database/role cleanup complete, plus 7 pure tests; actual immutable Submission and verified ART lineage materialize through the selected policy, finalize selected result/member custody and replay the stored strict envelope | The approved policy is empty in this discriminator; a locked nonempty image, live Rust service and worker restart remain pending | | Production delivery registration and owner boundaries | `pytest -q backend/tests/architecture/test_module_boundaries.py backend/tests/test_artifact_architecture.py backend/tests/outbox/test_contracts.py`; focused Ruff and a direct registry construction probe | 116 passed; the existing production outbox registry exposes assignment invalidation and evaluation request handlers, selected Rust configuration is lazy, and PRE coordination stays behind CHECKERS' public adapter root | Database-backed legacy/selected delivery and worker restart proofs remain pending | | New Submission selected-only boundary | `pytest -q backend/tests/test_submission_bundle_admission.py backend/tests/checkers/external/test_selected_post_submit.py backend/tests/test_artifact_architecture.py::test_checker_custody_ports_have_exact_owner_and_art_consumers`; focused Ruff | 59 passed; retained legacy and selected admission projections are mutually exclusive, and the TASK writer accepts only selected POST custody for a new immutable Submission | Native rollback proof for a retained unresolved legacy admission remains pending | | Retained admission migration shape | `pytest -q backend/tests/test_submission_bundle_admission.py backend/tests/checkers/external/test_selected_pre_submit_coordination.py backend/tests/checkers/external/test_selected_preparation_command.py backend/tests/test_artifact_architecture.py::test_checker_materialization_contract_has_one_canonical_consumer_owner`; focused Ruff | 62 passed; selected rows require complete new custody while every new column stays null on retained legacy rows, avoiding fabricated backfill or historical hash rewrites | Successor SQL and direct retained/selected row controls remain pending | diff --git a/backend/alembic/versions/0037_selected_checker_flow.py b/backend/alembic/versions/0037_selected_checker_flow.py index 4b823b2d9..2731e7728 100644 --- a/backend/alembic/versions/0037_selected_checker_flow.py +++ b/backend/alembic/versions/0037_selected_checker_flow.py @@ -740,6 +740,119 @@ def _replace_submission_binding_resource() -> None: """) +def _replace_checker_input_authority_digest() -> None: + definition = op.get_bind().execute(sa.text( + "select pg_get_functiondef(" + "'public.checker_input_authority_digest(public.checker_runs)'::regprocedure)" + )).scalar_one() + old_evidence = "'evidence_id', a.pre_submit_evidence_set_id::text" + if old_evidence not in definition: + old_evidence = "'evidence_id',a.pre_submit_evidence_set_id::text" + new_evidence = ( + "'evidence_id', coalesce(a.pre_submit_evidence_set_id, " + "a.selected_pre_submit_run_id)::text" + ) + if definition.count(old_evidence) != 1: + raise RuntimeError("checker input evidence identity shape changed") + op.execute(definition.replace(old_evidence, new_evidence)) + + +def _replace_checker_result_custody() -> None: + definition = op.get_bind().execute(sa.text( + "select pg_get_functiondef('public.protect_checker_result_custody()'::regprocedure)" + )).scalar_one() + anchor = ( + " entry := parent.request_json::jsonb #> " + "ARRAY['policy','entries',NEW.member_order::text];" + ) + selected = r""" + IF parent.request_json::jsonb->>'schema_version'= + 'workstream.selected_post_submit_request.v1' THEN + IF entry->>'requirement_id' IS DISTINCT FROM NEW.checker_name + OR entry#>>'{registry,entry_digest}' IS DISTINCT FROM NEW.implementation_version + OR NEW.definition_version IS DISTINCT FROM 'external_checker_result.v1' + OR NEW.status NOT IN ('passed','failed') + OR NEW.failure_category IS DISTINCT FROM + CASE WHEN NEW.status='passed' THEN 'none' ELSE 'submission_structure' END + OR NEW.severity IS DISTINCT FROM + CASE WHEN NEW.status='passed' THEN 'info' ELSE 'error' END + OR (NEW.status='passed' AND NEW.code IS DISTINCT FROM 'passed') + OR jsonb_typeof(NEW.counters::jsonb) IS DISTINCT FROM 'array' + OR jsonb_array_length(NEW.counters::jsonb)<>0 THEN + RAISE EXCEPTION 'checker member differs from selected definition' + USING ERRCODE='23514'; + END IF; + RETURN NEW; + END IF;""" + if definition.count(anchor) != 1: + raise RuntimeError("checker result selected definition anchor changed") + op.execute(definition.replace(anchor, anchor + selected)) + + +def _replace_checker_terminal_custody() -> None: + definition = op.get_bind().execute(sa.text( + "select pg_get_functiondef('public.validate_checker_terminal_custody()'::regprocedure)" + )).scalar_one() + declaration = ( + " passed integer; warning integer; failed integer; blocking integer; " + "setup integer; envelope jsonb;" + ) + if declaration not in definition: + declaration = ( + " passed integer; warning integer; failed integer; blocking integer; " + "setup integer; envelope jsonb;" + ) + if definition.count(declaration) != 1: + raise RuntimeError("checker terminal declaration shape changed") + definition = definition.replace( + declaration, + declaration.replace("envelope jsonb;", "envelope jsonb; expected_members jsonb;"), + ) + mismatch = """ IF result->'member_results' IS DISTINCT FROM members OR current_run.passed_count IS DISTINCT FROM passed + OR current_run.warning_count IS DISTINCT FROM warning OR current_run.failed_count IS DISTINCT FROM failed + OR current_run.blocking_count IS DISTINCT FROM blocking THEN""" + if mismatch not in definition: + mismatch = mismatch.replace(" IF", " IF").replace(" OR", " OR") + selected_check = r""" + IF result->>'schema_version'='workstream.selected_post_submit_result.v1' + AND result->>'outcome'='completed' THEN + SELECT coalesce(jsonb_agg(jsonb_build_object( + 'schema_version','post_submit_structural_result', + 'checker_id',item->>'requirement_id', + 'definition_version',item#>>'{result,schema_version}', + 'implementation_version',item->>'registry_entry_digest', + 'status',item#>>'{result,verdict}', + 'code',CASE WHEN item#>>'{result,verdict}'='passed' THEN 'passed' + ELSE coalesce(item#>>'{result,findings,0,code}','invalid_output') END, + 'failure_category',CASE WHEN item#>>'{result,verdict}'='passed' + THEN 'none' ELSE 'submission_structure' END, + 'severity',CASE WHEN item#>>'{result,verdict}'='passed' + THEN 'info' ELSE 'error' END, + 'counters','[]'::jsonb + ) ORDER BY (item->>'order')::integer),'[]'::jsonb) + INTO expected_members + FROM jsonb_array_elements(result#>'{execution,external_members}') item; + blocking := failed; + setup := 0; + IF members IS DISTINCT FROM expected_members + OR current_run.passed_count IS DISTINCT FROM passed + OR current_run.warning_count IS DISTINCT FROM warning + OR current_run.failed_count IS DISTINCT FROM failed + OR current_run.blocking_count IS DISTINCT FROM blocking THEN + RAISE EXCEPTION 'checker terminal members differ' USING ERRCODE='23514'; + END IF; + END IF; +""" + replacement = selected_check + mismatch.replace( + "IF result->'member_results'", + "IF result->>'schema_version'<>'workstream.selected_post_submit_result.v1'\n" + " AND result->'member_results'", + ) + if definition.count(mismatch) != 1: + raise RuntimeError("checker terminal member comparison shape changed") + op.execute(definition.replace(mismatch, replacement)) + + def _replace_submission_packet_custody() -> None: definition = op.get_bind().execute(sa.text( "select pg_get_functiondef('public.validate_submission_packet_custody()'::regprocedure)" @@ -774,6 +887,9 @@ def upgrade() -> None: _replace_submission_binding_resource() _replace_submission_dispatch_custody() _replace_submission_packet_custody() + _replace_checker_input_authority_digest() + _replace_checker_result_custody() + _replace_checker_terminal_custody() def downgrade() -> None: diff --git a/backend/app/modules/artifacts/post_submit_selection.py b/backend/app/modules/artifacts/post_submit_selection.py index 4e01cada7..da5728dcb 100644 --- a/backend/app/modules/artifacts/post_submit_selection.py +++ b/backend/app/modules/artifacts/post_submit_selection.py @@ -18,7 +18,12 @@ ) from app.modules.artifacts.sources import ArtifactCommitment from app.modules.artifacts.submission_bindings import SubmissionAdmissionConsumptionService -from app.modules.checkers.api import PostSubmissionEvaluationRequest +from app.modules.checkers.api.evaluation_contract import ( + PostSubmissionExecutionRequest, +) +from app.modules.checkers.api.selected_post_submit import ( + SelectedPostSubmissionEvaluationRequest, +) from app.modules.tasks.api.submitted_bundle import ( SubmittedBundleFacts, SubmittedBundlePort, SubmittedBundleRequest, ) @@ -47,21 +52,58 @@ class PostSubmissionMaterialSelection: async def select_post_submission_material( session: AsyncSession, *, tasks: SubmittedBundlePort, - request: PostSubmissionEvaluationRequest, namespace: ArtifactStorageNamespaceSpec, + request: PostSubmissionExecutionRequest, namespace: ArtifactStorageNamespaceSpec, store: ArtifactStore, ) -> PostSubmissionMaterialSelection: """Read fresh exact owner facts in one short caller-owned transaction.""" facts = await tasks.read(SubmittedBundleRequest( project_id=request.project_id, task_id=request.task_id, submission_id=request.submission_id, )) + selected_request = isinstance(request, SelectedPostSubmissionEvaluationRequest) + context = facts.context + context_matches = ( + ( + context.guide_version == request.expected_context.guide_version + and context.source_id == request.expected_context.source_id + and context.source_hash == request.expected_context.source_hash + and context.effective_policy_id + == request.expected_context.effective_policy_id + and context.effective_policy_hash + == request.expected_context.effective_policy_hash + and context.pre_policy_id == request.expected_context.pre_policy_id + and context.pre_policy_hash == request.expected_context.pre_policy_hash + and context.post_policy_id + == request.expected_context.retained_catalogue_policy_id + and context.post_policy_version + == request.expected_context.retained_catalogue_policy_version + and context.post_policy_hash + == request.expected_context.retained_catalogue_policy_hash + and context.selected_post_policy_hash + == request.expected_context.selected_post_policy_hash + and context.selected_post_policy_body == request.policy.model_dump(mode="json") + and context.review_policy_id == request.expected_context.review_policy_id + and context.review_generation == request.expected_context.review_generation + and context.review_hash == request.expected_context.review_hash + and context.revision_policy_id == request.expected_context.revision_policy_id + and context.revision_generation + == request.expected_context.revision_generation + and context.revision_hash == request.expected_context.revision_hash + ) + if selected_request + else asdict(context) == request.expected_context.model_dump() + ) if ( facts.status != "submitted" or (facts.project_id, facts.task_id, facts.assignment_id, facts.submission_id, facts.submission_version, facts.binding_id, facts.content_id) != ( request.project_id, request.task_id, request.assignment_id, request.submission_id, request.submission_version, request.binding_id, request.content_id) - or asdict(facts.context) != request.expected_context.model_dump() - or asdict(facts.context) != request.structural_input.observed_context.model_dump() + or not context_matches + or ( + not selected_request + and asdict(facts.context) + != request.structural_input.observed_context.model_dump() + ) ): raise PostSubmissionMaterializationUnavailable("post_submit_material_identity_mismatch") row = (await session.execute( @@ -69,7 +111,7 @@ async def select_post_submission_material( ArtifactContent, ArtifactReplica, ArtifactVerificationReceipt, ArtifactVerificationJob, ArtifactStorageNamespace) .select_from(SubmissionBundleAdmission) - .join(PreSubmitEvidenceSet, PreSubmitEvidenceSet.id == SubmissionBundleAdmission.pre_submit_evidence_set_id) + .outerjoin(PreSubmitEvidenceSet, PreSubmitEvidenceSet.id == SubmissionBundleAdmission.pre_submit_evidence_set_id) .join(ArtifactBinding, ArtifactBinding.id == str(facts.binding_id)) .join(ArtifactContent, ArtifactContent.id == SubmissionBundleAdmission.artifact_content_id) .join(ArtifactReplica, ArtifactReplica.id == SubmissionBundleAdmission.verified_replica_id) @@ -84,7 +126,15 @@ async def select_post_submission_material( if row is None: raise PostSubmissionMaterializationUnavailable("post_submit_material_unavailable") admission, evidence, binding, content, replica, receipt, job, persisted = row - context = facts.context + selected_lineage = ( + evidence is None + and admission.selected_pre_submit_run_id is not None + and admission.pre_submit_evidence_set_id is None + and admission.selected_post_submit_policy_sha256 + == request.policy.policy_sha256 + and admission.selected_post_submit_policy_body + == request.policy.model_dump(mode="json") + ) if selected_request else evidence is not None if not ( SubmissionAdmissionConsumptionService._art_lineage_is_intact(admission, evidence, content) and admission.status == "consumed" @@ -100,16 +150,27 @@ async def select_post_submission_material( and binding.logical_role == "submission_bundle_original" and binding.scope_version == 1 and binding.content_id == content.id == str(facts.content_id) + and selected_lineage and content.media_type == "application/zip" - and content.sha256 == request.content_sha256 == request.structural_input.package_hash + and content.sha256 == request.content_sha256 + and ( + selected_request + or content.sha256 == request.structural_input.package_hash + ) and content.byte_count == request.byte_count - and evidence.guide_version == context.guide_version - and evidence.source_snapshot_id == str(context.source_id) - and evidence.source_snapshot_sha256 == context.source_hash - and evidence.effective_policy_id == str(context.effective_policy_id) - and evidence.locked_artifact_policy_sha256 == context.effective_policy_hash - and evidence.pre_submit_policy_id == str(context.pre_policy_id) - and evidence.locked_checker_policy_sha256 == context.pre_policy_hash + and ( + selected_request + or ( + evidence.guide_version == context.guide_version + and evidence.source_snapshot_id == str(context.source_id) + and evidence.source_snapshot_sha256 == context.source_hash + and evidence.effective_policy_id == str(context.effective_policy_id) + and evidence.locked_artifact_policy_sha256 + == context.effective_policy_hash + and evidence.pre_submit_policy_id == str(context.pre_policy_id) + and evidence.locked_checker_policy_sha256 == context.pre_policy_hash + ) + ) and replica.content_id == content.id and (replica.verification_state, replica.availability_state, replica.integrity_state) == ("verified", "available", "valid") @@ -127,7 +188,11 @@ async def select_post_submission_material( if replica.provider_object_ref != artifact_provider_object_ref(commitment): raise PostSubmissionMaterializationUnavailable("post_submit_material_identity_mismatch") return PostSubmissionMaterialSelection( - submission=facts, evidence_id=UUID(evidence.id), replica_id=UUID(replica.id), + submission=facts, + evidence_id=UUID( + evidence.id if evidence is not None else admission.selected_pre_submit_run_id + ), + replica_id=UUID(replica.id), verification_receipt_id=UUID(receipt.id), verification_job_id=UUID(job.id), verification_generation=receipt.execution_generation, namespace_fingerprint=persisted.namespace_fingerprint, adapter=replica.adapter, diff --git a/backend/app/modules/checkers/api/evaluation_contract.py b/backend/app/modules/checkers/api/evaluation_contract.py index 5d617204b..b82e20385 100644 --- a/backend/app/modules/checkers/api/evaluation_contract.py +++ b/backend/app/modules/checkers/api/evaluation_contract.py @@ -44,10 +44,16 @@ def validate_execution_result(value: object) -> PostSubmissionExecutionResult: return _RESULT.validate_python(value) +def validate_stored_execution_result(value: str) -> PostSubmissionExecutionResult: + """Decode retained canonical result JSON through strict models' JSON boundary.""" + return _RESULT.validate_json(value) + + __all__ = ( "PostSubmissionExecutionRequest", "PostSubmissionExecutionResult", "validate_execution_request", "validate_stored_execution_request", + "validate_stored_execution_result", "validate_execution_result", ) diff --git a/backend/app/modules/checkers/execution_repository.py b/backend/app/modules/checkers/execution_repository.py index 1369b75dc..febed0ef5 100644 --- a/backend/app/modules/checkers/execution_repository.py +++ b/backend/app/modules/checkers/execution_repository.py @@ -16,8 +16,8 @@ from app.modules.checkers.api.evaluation_contract import ( PostSubmissionExecutionRequest, PostSubmissionExecutionResult, - validate_execution_result, validate_stored_execution_request, + validate_stored_execution_result, ) from app.modules.checkers.api.selected_post_submit import ( SelectedPostSubmissionEvaluationResult, @@ -63,7 +63,9 @@ def stored_result(run: CheckerRun) -> PostSubmissionExecutionResult: raise CheckerExecutionUnavailable("checker_result_unavailable") body = json.loads(run.result_json) body["result_digest"] = run.result_digest - result = validate_execution_result(body) + result = validate_stored_execution_result( + json.dumps(body, separators=(",", ":"), sort_keys=True) + ) result.validate_request(stored_request(run)) if (str(result.attempt_id), str(result.result_id)) != (run.id, run.result_id): raise CheckerExecutionUnavailable("checker_result_unavailable") diff --git a/backend/tests/checkers/execution/support.py b/backend/tests/checkers/execution/support.py index 8d19c5881..d58699a75 100644 --- a/backend/tests/checkers/execution/support.py +++ b/backend/tests/checkers/execution/support.py @@ -52,7 +52,7 @@ async def provision_post_submit_service(factory, identity=ServiceIdentity.CHECKE return actor_id -def live_executor(h, *, outbox=None): +def live_executor(h, *, outbox=None, selected_execution=None): from app.adapters.auth import post_submit_execution_authority from app.adapters.outbox import outbox_append from app.modules.checkers.execution import PostSubmissionExecutor @@ -62,6 +62,7 @@ def live_executor(h, *, outbox=None): materialization=h.service, execute_authority=post_submit_execution_authority, finalize_authority=post_submit_execution_authority, + selected_execution=selected_execution, outbox=outbox if outbox is not None else outbox_append, ) diff --git a/backend/tests/checkers/external/test_selected_post_submit.py b/backend/tests/checkers/external/test_selected_post_submit.py index 7123f59d0..b473d4c3d 100644 --- a/backend/tests/checkers/external/test_selected_post_submit.py +++ b/backend/tests/checkers/external/test_selected_post_submit.py @@ -3,6 +3,7 @@ from __future__ import annotations from contextlib import contextmanager +import json from types import SimpleNamespace import pytest @@ -28,6 +29,7 @@ from app.modules.checkers.api.evaluation_contract import ( validate_execution_request, validate_execution_result, + validate_stored_execution_result, ) from app.modules.checkers.api.execution import EvaluationReservation, ExecutionLease from app.modules.checkers.api.materialization import SubmissionMaterialEntry @@ -46,6 +48,8 @@ execution_material, registry_entry, ) +from tests.checkers.execution.support import live_executor, reserve +from tests.post_submit_materialization_helpers import material_fixture def _policy() -> LockedExternalPostSubmitPolicy: @@ -216,6 +220,23 @@ async def test_selected_post_separates_infrastructure_from_work_findings() -> No ).evaluate(object(), _MaterialView(execution_material(identity))) +@pytest.mark.postgres_schema_contract +async def test_selected_post_materializes_actual_submission_and_replays( + tmp_path, isolated_database_env, +) -> None: + """Exercise selected POST through native Submission, ART, AUTH and storage.""" + async with material_fixture(tmp_path, isolated_database_env) as h: + reservation = await reserve(h) + executor = live_executor(h, selected_execution=_Execution()) + result = await executor.evaluate_post_submission(h.request) + assert result.outcome == "completed" + assert result.attempt_id == reservation.attempt_id + assert result.execution is not None + assert result.execution.external_members == () + assert await executor.evaluate_post_submission(h.request) == result + assert len(h.store.opens) == 1 + + @pytest.mark.asyncio async def test_selected_post_request_and_result_bind_exact_locked_policy() -> None: identity = execution_identity("post_submit") @@ -294,6 +315,8 @@ async def test_selected_scheduler_consumer_derives_exact_envelope(outcome, expec result.validate_request(request) assert type(validate_execution_request(request.model_dump())) is type(request) assert type(validate_execution_result(result.model_dump())) is type(result) + stored = json.loads(result.model_dump_json()) + assert type(validate_stored_execution_result(json.dumps(stored))) is type(result) def test_selected_post_content_uses_selected_digest_not_catalogue_hash() -> None: From f3b844d7da41d2bfbd92e40a235237b248f1dfb7 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 22:57:25 +0100 Subject: [PATCH 127/283] [PILOT-04] prove nonempty selected post custody --- .../pilot04-workstream-default-checker.md | 1 + .../versions/0037_selected_checker_flow.py | 78 ++++++++++- backend/app/adapters/tasks/__init__.py | 8 +- .../modules/artifacts/submission_bindings.py | 4 +- .../modules/checkers/api/external_policy.py | 24 ++++ .../app/modules/projects/api/locked_policy.py | 4 +- .../projects/guide_activation/service.py | 6 +- .../guide_compilation/approval_custody.py | 8 +- .../modules/projects/post_policy/custody.py | 9 +- .../modules/projects/post_policy/service.py | 6 +- backend/app/modules/projects/service.py | 4 +- backend/app/modules/tasks/repository.py | 4 +- backend/app/modules/tasks/service.py | 3 +- .../external/test_selected_post_submit.py | 41 ++++++ backend/tests/conftest.py | 2 +- .../post_submit_materialization_helpers.py | 2 + .../guide_activation/source_fixtures.py | 121 +++++++++++++++++- .../finalization/pg_prerequisites.py | 10 +- .../test_hidden_orchestrator_postgresql.py | 4 +- .../tests/projects/unified_policy_fixtures.py | 7 +- backend/tests/selected_policy_fixtures.py | 3 +- 21 files changed, 311 insertions(+), 38 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index fdcdb1a6a..8ffdeb503 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -225,6 +225,7 @@ intermediate-wait regression. | Selected durable POST contract | `pytest -q backend/tests/checkers/external/test_selected_post_submit.py backend/tests/test_submission_bundle_admission.py`; Ruff and `git diff --check` on the affected files | 56 passed; the request digest binds the exact approved selected policy, separately named locked TASK context and native Submission/ART identity, while the result digest binds request/generation, ordered execution evidence or a closed recoverable infrastructure category without acceptance authority; a legacy catalogue hash cannot stand in for the selected image-policy digest | The existing scheduler/materializer still needs to select this contract and persist it through restart/replay | | Selected POST scheduler compatibility | `pytest -q backend/tests/checkers/external/test_selected_post_submit.py backend/tests/checkers/execution/test_results.py backend/tests/checkers/execution/test_completion_contract.py backend/tests/checkers/post_submit/test_request.py backend/tests/test_submission_bundle_admission.py`; focused Ruff | 84 passed; one discriminated owner accepts retained legacy and selected request/result envelopes, selected leases cover the ordered image budget and finalization margin, ART recomputes the selected manifest, and focused scheduler controls prove exact completed/infrastructure envelopes and generic replay parsing | Native selected columns/constraints and live Rust worker proof remain pending | | Selected POST native custody | `python3 /tmp/p04_selected_runner.py /tmp/p04-selected-post-result-replay 420 tests/checkers/external/test_selected_post_submit.py::test_selected_post_materializes_actual_submission_and_replays`; focused selected-POST pure tests and Ruff | PostgreSQL 16 PASS 1 in 36.10s with database/role cleanup complete, plus 7 pure tests; actual immutable Submission and verified ART lineage materialize through the selected policy, finalize selected result/member custody and replay the stored strict envelope | The approved policy is empty in this discriminator; a locked nonempty image, live Rust service and worker restart remain pending | +| Nonempty selected POST policy and result | `python3 /tmp/p04_selected_runner.py /tmp/p04-selected-post-nonempty5 600 tests/checkers/external/test_selected_post_submit.py::test_selected_post_persists_locked_external_member`; `pytest -q backend/tests/checkers/external/test_selected_post_submit.py -m 'not postgres_schema_contract'`; focused Ruff and `git diff --check` | PostgreSQL 16 PASS 1 with database/role cleanup complete, plus 7 pure tests; an actual immutable registry entry is registered through Operator authority, compiled into one supported POST requirement, approved, activated, materialized from the real Submission/ART lineage and persisted as the exact selected member. Persisted UUID-bearing policy JSON and SQL requirement custody are decoded and validated without relaxing strict in-memory contracts. | The adapter in this discriminator is bounded and deterministic; a live Rust service, restart/reclaim and external work/infra outcomes remain pending | | Production delivery registration and owner boundaries | `pytest -q backend/tests/architecture/test_module_boundaries.py backend/tests/test_artifact_architecture.py backend/tests/outbox/test_contracts.py`; focused Ruff and a direct registry construction probe | 116 passed; the existing production outbox registry exposes assignment invalidation and evaluation request handlers, selected Rust configuration is lazy, and PRE coordination stays behind CHECKERS' public adapter root | Database-backed legacy/selected delivery and worker restart proofs remain pending | | New Submission selected-only boundary | `pytest -q backend/tests/test_submission_bundle_admission.py backend/tests/checkers/external/test_selected_post_submit.py backend/tests/test_artifact_architecture.py::test_checker_custody_ports_have_exact_owner_and_art_consumers`; focused Ruff | 59 passed; retained legacy and selected admission projections are mutually exclusive, and the TASK writer accepts only selected POST custody for a new immutable Submission | Native rollback proof for a retained unresolved legacy admission remains pending | | Retained admission migration shape | `pytest -q backend/tests/test_submission_bundle_admission.py backend/tests/checkers/external/test_selected_pre_submit_coordination.py backend/tests/checkers/external/test_selected_preparation_command.py backend/tests/test_artifact_architecture.py::test_checker_materialization_contract_has_one_canonical_consumer_owner`; focused Ruff | 62 passed; selected rows require complete new custody while every new column stays null on retained legacy rows, avoiding fabricated backfill or historical hash rewrites | Successor SQL and direct retained/selected row controls remain pending | diff --git a/backend/alembic/versions/0037_selected_checker_flow.py b/backend/alembic/versions/0037_selected_checker_flow.py index 2731e7728..fa9322d28 100644 --- a/backend/alembic/versions/0037_selected_checker_flow.py +++ b/backend/alembic/versions/0037_selected_checker_flow.py @@ -627,7 +627,79 @@ def _replace_post_policy_custody() -> None: t->'proposal'->>'post_catalogue_manifest_hash'))""" if definition.count(old_policy) != 1: raise RuntimeError("post policy custody shape changed") - op.execute(definition.replace(old_policy, new_policy)) + definition = definition.replace(old_policy, new_policy) + old_required = """ IF EXISTS( + SELECT 1 FROM project_guide_compilations c, + jsonb_array_elements(c.canonical_result::jsonb->'post_submit_bindings') binding + WHERE c.id=NEW.compilation_id AND NOT EXISTS( + SELECT 1 FROM jsonb_array_elements(p.policy_body::jsonb->'entries') entry + WHERE entry->>'checker_id'=binding->>'capability_id' + AND entry->>'definition_version'=binding->>'capability_version' + AND entry->>'classification'='project_required' + AND entry->'configuration'=COALESCE((SELECT jsonb_object_agg(parameter->>'name',parameter->'value') + FROM jsonb_array_elements(binding->'parameters') parameter),'{}'::jsonb))) THEN + RAISE EXCEPTION 'post-policy compiled required binding missing' USING ERRCODE='23514'; + END IF;""" + new_required = """ IF EXISTS( + SELECT 1 FROM project_guide_compilations c, + jsonb_array_elements(c.canonical_result::jsonb->'post_submit_bindings') binding + WHERE c.id=NEW.compilation_id AND NOT EXISTS( + SELECT 1 FROM jsonb_array_elements(p.policy_body::jsonb->'entries') entry + WHERE CASE WHEN p.policy_body->>'schema_version'='external_post_submit_policy.v1' + THEN entry->>'requirement_id'=binding->>'requirement_id' + AND entry->>'stage'='post_submit' + AND entry->'registry'->>'capability_id'=binding->>'capability_id' + AND entry->'registry'->>'capability_version'=binding->>'capability_version' + AND entry->'configuration'=COALESCE((SELECT jsonb_object_agg(parameter->>'name',parameter->'value') + FROM jsonb_array_elements(binding->'parameters') parameter),'{}'::jsonb) + ELSE entry->>'checker_id'=binding->>'capability_id' + AND entry->>'definition_version'=binding->>'capability_version' + AND entry->>'classification'='project_required' + AND entry->'configuration'=COALESCE((SELECT jsonb_object_agg(parameter->>'name',parameter->'value') + FROM jsonb_array_elements(binding->'parameters') parameter),'{}'::jsonb) + END)) THEN + RAISE EXCEPTION 'post-policy compiled required binding missing' USING ERRCODE='23514'; + END IF;""" + old_extra = """ IF EXISTS( + SELECT 1 FROM jsonb_array_elements(p.policy_body::jsonb->'entries') entry + WHERE entry->>'classification' IS DISTINCT FROM 'platform_default' + AND NOT EXISTS( + SELECT 1 FROM project_guide_compilations c, + jsonb_array_elements(c.canonical_result::jsonb->'post_submit_bindings') binding + WHERE c.id=NEW.compilation_id + AND entry->>'checker_id'=binding->>'capability_id' + AND entry->>'definition_version'=binding->>'capability_version' + AND entry->>'classification'='project_required' + AND entry->'configuration'=COALESCE((SELECT jsonb_object_agg(parameter->>'name',parameter->'value') + FROM jsonb_array_elements(binding->'parameters') parameter),'{}'::jsonb))) THEN + RAISE EXCEPTION 'post-policy compiled selection not requested' USING ERRCODE='23514'; + END IF;""" + new_extra = """ IF EXISTS( + SELECT 1 FROM jsonb_array_elements(p.policy_body::jsonb->'entries') entry + WHERE (p.policy_body->>'schema_version'='external_post_submit_policy.v1' + OR entry->>'classification' IS DISTINCT FROM 'platform_default') + AND NOT EXISTS( + SELECT 1 FROM project_guide_compilations c, + jsonb_array_elements(c.canonical_result::jsonb->'post_submit_bindings') binding + WHERE c.id=NEW.compilation_id AND CASE + WHEN p.policy_body->>'schema_version'='external_post_submit_policy.v1' + THEN entry->>'requirement_id'=binding->>'requirement_id' + AND entry->>'stage'='post_submit' + AND entry->'registry'->>'capability_id'=binding->>'capability_id' + AND entry->'registry'->>'capability_version'=binding->>'capability_version' + AND entry->'configuration'=COALESCE((SELECT jsonb_object_agg(parameter->>'name',parameter->'value') + FROM jsonb_array_elements(binding->'parameters') parameter),'{}'::jsonb) + ELSE entry->>'checker_id'=binding->>'capability_id' + AND entry->>'definition_version'=binding->>'capability_version' + AND entry->>'classification'='project_required' + AND entry->'configuration'=COALESCE((SELECT jsonb_object_agg(parameter->>'name',parameter->'value') + FROM jsonb_array_elements(binding->'parameters') parameter),'{}'::jsonb) + END)) THEN + RAISE EXCEPTION 'post-policy compiled selection not requested' USING ERRCODE='23514'; + END IF;""" + if definition.count(old_required) != 1 or definition.count(old_extra) != 1: + raise RuntimeError("post policy binding custody shape changed") + op.execute(definition.replace(old_required, new_required).replace(old_extra, new_extra)) def _replace_checker_run_custody() -> None: @@ -773,9 +845,9 @@ def _replace_checker_result_custody() -> None: OR NEW.definition_version IS DISTINCT FROM 'external_checker_result.v1' OR NEW.status NOT IN ('passed','failed') OR NEW.failure_category IS DISTINCT FROM - CASE WHEN NEW.status='passed' THEN 'none' ELSE 'submission_structure' END + (CASE WHEN NEW.status='passed' THEN 'none' ELSE 'submission_structure' END) OR NEW.severity IS DISTINCT FROM - CASE WHEN NEW.status='passed' THEN 'info' ELSE 'error' END + (CASE WHEN NEW.status='passed' THEN 'info' ELSE 'error' END) OR (NEW.status='passed' AND NEW.code IS DISTINCT FROM 'passed') OR jsonb_typeof(NEW.counters::jsonb) IS DISTINCT FROM 'array' OR jsonb_array_length(NEW.counters::jsonb)<>0 THEN diff --git a/backend/app/adapters/tasks/__init__.py b/backend/app/adapters/tasks/__init__.py index 588bdfaa4..492a1542f 100644 --- a/backend/app/adapters/tasks/__init__.py +++ b/backend/app/adapters/tasks/__init__.py @@ -249,11 +249,11 @@ async def consume( raise RuntimeError("admission did not produce a binding") from app.adapters.checkers import selected_submission_evaluation_content from app.modules.checkers.api.external_policy import ( - LockedExternalPostSubmitPolicy, + validate_stored_external_post_policy, ) selected_post_policy = ( - LockedExternalPostSubmitPolicy.model_validate(result.selected_post_submit_policy_body) + validate_stored_external_post_policy(result.selected_post_submit_policy_body) if result.selected_post_submit_policy_body is not None else None ) @@ -298,11 +298,11 @@ async def read_consumed( raise RuntimeError("retained admission custody unavailable") from app.adapters.checkers import selected_submission_evaluation_content from app.modules.checkers.api.external_policy import ( - LockedExternalPostSubmitPolicy, + validate_stored_external_post_policy, ) selected_post_policy = ( - LockedExternalPostSubmitPolicy.model_validate( + validate_stored_external_post_policy( result.selected_post_submit_policy_body ) if result.selected_post_submit_policy_body is not None diff --git a/backend/app/modules/artifacts/submission_bindings.py b/backend/app/modules/artifacts/submission_bindings.py index c426e5d5e..e53807c82 100644 --- a/backend/app/modules/artifacts/submission_bindings.py +++ b/backend/app/modules/artifacts/submission_bindings.py @@ -19,7 +19,7 @@ ) from app.modules.artifacts.api.submission_admission import ConsumedSubmissionAdmissionRequest from app.modules.artifacts.submission_manifest import SubmissionManifest -from app.modules.checkers.api.external_policy import LockedExternalPostSubmitPolicy +from app.modules.checkers.api.external_policy import validate_stored_external_post_policy from app.modules.artifacts.models import ( ArtifactBinding, ArtifactContent, @@ -323,7 +323,7 @@ def _art_lineage_is_intact( selected_policy_intact = admission.selected_pre_submit_run_id is None if admission.selected_pre_submit_run_id is not None: try: - selected_policy = LockedExternalPostSubmitPolicy.model_validate( + selected_policy = validate_stored_external_post_policy( admission.selected_post_submit_policy_body ) selected_policy_intact = ( diff --git a/backend/app/modules/checkers/api/external_policy.py b/backend/app/modules/checkers/api/external_policy.py index fd64c268c..a8d7e2aff 100644 --- a/backend/app/modules/checkers/api/external_policy.py +++ b/backend/app/modules/checkers/api/external_policy.py @@ -2,6 +2,7 @@ from __future__ import annotations +import json from typing import Literal, Self from pydantic import BaseModel, ConfigDict, Field, JsonValue, model_validator @@ -127,6 +128,29 @@ def validate_policies(self) -> Self: return self +def validate_stored_external_checker_policies( + value: object, +) -> LockedExternalCheckerPolicies: + """Decode retained JSON through strict UUID and timestamp model boundaries.""" + return LockedExternalCheckerPolicies.model_validate_json( + json.dumps(value, ensure_ascii=False, allow_nan=False) + ) + + +def validate_stored_external_pre_policy(value: object) -> LockedExternalPreSubmitPolicy: + """Decode one retained selected PRE policy without Python-string coercion.""" + return LockedExternalPreSubmitPolicy.model_validate_json( + json.dumps(value, ensure_ascii=False, allow_nan=False) + ) + + +def validate_stored_external_post_policy(value: object) -> LockedExternalPostSubmitPolicy: + """Decode one retained selected POST policy without Python-string coercion.""" + return LockedExternalPostSubmitPolicy.model_validate_json( + json.dumps(value, ensure_ascii=False, allow_nan=False) + ) + + def _validate_entries( entries: tuple[LockedExternalCheckerBinding, ...], phase: ExternalCheckerPhase ) -> None: diff --git a/backend/app/modules/projects/api/locked_policy.py b/backend/app/modules/projects/api/locked_policy.py index c1a63a760..263262d8d 100644 --- a/backend/app/modules/projects/api/locked_policy.py +++ b/backend/app/modules/projects/api/locked_policy.py @@ -225,10 +225,10 @@ def __post_init__(self) -> None: external_body = json.loads(self.external_checker_policies.value) if external_body.get("schema_version") == "external_checker_policies.v1": from app.modules.checkers.api.external_policy import ( - LockedExternalCheckerPolicies, + validate_stored_external_checker_policies, ) - external_policies = LockedExternalCheckerPolicies.model_validate(external_body) + external_policies = validate_stored_external_checker_policies(external_body) pre_body = json.loads(self.compiled_pre_submit_bundle.value) post_body = json.loads(self.compiled_post_submit_policy.value) external_hashes_match = ( diff --git a/backend/app/modules/projects/guide_activation/service.py b/backend/app/modules/projects/guide_activation/service.py index f631aba4d..5a0a3548d 100644 --- a/backend/app/modules/projects/guide_activation/service.py +++ b/backend/app/modules/projects/guide_activation/service.py @@ -6,7 +6,9 @@ from app.core.identifiers import new_record_id from app.modules.authorization.api import ActorKind -from app.modules.checkers.api.external_policy import LockedExternalCheckerPolicies +from app.modules.checkers.api.external_policy import ( + validate_stored_external_checker_policies, +) from app.modules.checkers.api.external import ExternalCheckerRegistryPort from app.modules.projects.api.guide_activation import ( GuideActivationCommand, @@ -227,7 +229,7 @@ async def _readiness(self, command, locked, policy, post, review, revision): ) if not external or self.registry is None: raise GuideProposalError("approval_blocked") - policies = LockedExternalCheckerPolicies.model_validate( + policies = validate_stored_external_checker_policies( approval.operation.effective_pre_submit_plan ) if policies.pre_submit.model_dump(mode="json") != approval.pre.compiled_bundle: diff --git a/backend/app/modules/projects/guide_compilation/approval_custody.py b/backend/app/modules/projects/guide_compilation/approval_custody.py index 99bf93d9e..78eeeaf3f 100644 --- a/backend/app/modules/projects/guide_compilation/approval_custody.py +++ b/backend/app/modules/projects/guide_compilation/approval_custody.py @@ -17,7 +17,9 @@ SubmissionPolicyMutationIdempotencyRecord, SubmissionArtifactPolicy, ) -from app.modules.checkers.api.external_policy import LockedExternalCheckerPolicies +from app.modules.checkers.api.external_policy import ( + validate_stored_external_checker_policies, +) from .custody_payloads import policy_digest from .models import ProjectGuideProposalApproval @@ -103,7 +105,7 @@ def approved_projection_digest(view) -> str: if operation.effective_pre_submit_plan.get("schema_version") == ( "external_checker_policies.v1" ): - external_policies = LockedExternalCheckerPolicies.model_validate( + external_policies = validate_stored_external_checker_policies( operation.effective_pre_submit_plan ) external_plan_hash = external_policies.policies_sha256 @@ -221,7 +223,7 @@ def _require_plan_and_provenance(view, custody, target) -> None: "manifest_sha256": target.pre_catalogue_manifest_hash, } if operation.effective_pre_submit_plan.get("schema_version") == "external_checker_policies.v1": - policies = LockedExternalCheckerPolicies.model_validate( + policies = validate_stored_external_checker_policies( operation.effective_pre_submit_plan ) if policies.pre_submit.model_dump(mode="json") != pre.compiled_bundle: diff --git a/backend/app/modules/projects/post_policy/custody.py b/backend/app/modules/projects/post_policy/custody.py index 4fe567492..3b5e9d84f 100644 --- a/backend/app/modules/projects/post_policy/custody.py +++ b/backend/app/modules/projects/post_policy/custody.py @@ -10,7 +10,10 @@ CompiledPostSubmitPolicy, parse_locked_post_submit_policy, ) -from app.modules.checkers.api.external_policy import LockedExternalPostSubmitPolicy +from app.modules.checkers.api.external_policy import ( + LockedExternalPostSubmitPolicy, + validate_stored_external_post_policy, +) from app.modules.authorization.api import ActorKind from app.modules.authorization.api.post_policy import PostPolicyAuthorityReceipt from app.modules.projects.api.guide_proposals import GuideProposalError @@ -128,7 +131,7 @@ async def load_post_policy_custody(session, policy) -> PostPolicyCustody: raise GuideProposalError("proposal_unavailable") target = operation_receipt(projection).target if policy.policy_body.get("schema_version") == "external_post_submit_policy.v1": - compiled = LockedExternalPostSubmitPolicy.model_validate(policy.policy_body) + compiled = validate_stored_external_post_policy(policy.policy_body) if ( compiled.policy_sha256 != policy.policy_hash or policy.required_checkers @@ -294,7 +297,7 @@ def validate_activation_post_policy( post_submit_checker_policy.policy_body.get("schema_version") == "external_post_submit_policy.v1" ): - parsed = LockedExternalPostSubmitPolicy.model_validate( + parsed = validate_stored_external_post_policy( post_submit_checker_policy.policy_body ) if ( diff --git a/backend/app/modules/projects/post_policy/service.py b/backend/app/modules/projects/post_policy/service.py index 4e9efaa63..6d0478ff4 100644 --- a/backend/app/modules/projects/post_policy/service.py +++ b/backend/app/modules/projects/post_policy/service.py @@ -11,8 +11,8 @@ from app.modules.authorization.api import ActorIdentityFacts from app.modules.authorization.api.guide_proposal_review import GuideProposalAuthorizationPort from app.modules.checkers.api.external_policy import ( - LockedExternalCheckerPolicies, LockedExternalPostSubmitPolicy, + validate_stored_external_checker_policies, ) from app.modules.authorization.api.post_policy import ( PostPolicyAuthorizationFacts, @@ -99,7 +99,7 @@ async def derive( raise GuideProposalError("proposal_stale") compiled = compile_saved_post_policy( result=locked.result, - policies=LockedExternalCheckerPolicies.model_validate( + policies=validate_stored_external_checker_policies( upstream.effective_pre_submit_plan ), ) @@ -156,7 +156,7 @@ async def approve( raise GuideProposalError("proposal_stale") compiled = compile_saved_post_policy( result=locked.result, - policies=LockedExternalCheckerPolicies.model_validate( + policies=validate_stored_external_checker_policies( locked.view.approval_custody.operation.effective_pre_submit_plan ), ) diff --git a/backend/app/modules/projects/service.py b/backend/app/modules/projects/service.py index 7b5c0bbc9..e2cd6a936 100644 --- a/backend/app/modules/projects/service.py +++ b/backend/app/modules/projects/service.py @@ -1191,10 +1191,10 @@ def validate_activation_ready( "external_pre_submit_policy.v1" ): from app.modules.checkers.api.external_policy import ( - LockedExternalPreSubmitPolicy, + validate_stored_external_pre_policy, ) - compiled_pre = LockedExternalPreSubmitPolicy.model_validate( + compiled_pre = validate_stored_external_pre_policy( pre_submit_checker_policy.compiled_bundle ) compiled_pre_hash = compiled_pre.policy_sha256 diff --git a/backend/app/modules/tasks/repository.py b/backend/app/modules/tasks/repository.py index 246db5ed5..f8db292b2 100644 --- a/backend/app/modules/tasks/repository.py +++ b/backend/app/modules/tasks/repository.py @@ -6,7 +6,7 @@ from collections.abc import Sequence from app.modules.tasks.api.transition_audit import TaskPolicyLineage -from app.modules.checkers.api.external_policy import LockedExternalPostSubmitPolicy +from app.modules.checkers.api.external_policy import validate_stored_external_post_policy from app.modules.checkers.api.historical_post_submit import CompiledPostSubmitPolicy from uuid import UUID @@ -736,7 +736,7 @@ async def lock_submission_context( ) post_body = task.locked_post_submit_checker_policy_body if post_body.get("schema_version") == "external_post_submit_policy.v1": - selected_post = LockedExternalPostSubmitPolicy.model_validate(post_body) + selected_post = validate_stored_external_post_policy(post_body) if ( selected_post.policy_sha256 != locked_policy.locked_post_submit_checker_policy_hash diff --git a/backend/app/modules/tasks/service.py b/backend/app/modules/tasks/service.py index 559c91cf1..7d9222954 100644 --- a/backend/app/modules/tasks/service.py +++ b/backend/app/modules/tasks/service.py @@ -14,6 +14,7 @@ from app.modules.checkers.api.external_policy import ( LockedExternalCheckerPolicies, LockedExternalPostSubmitPolicy, + validate_stored_external_post_policy, ) from app.modules.checkers.api.historical_post_submit import CompiledPostSubmitPolicy from app.modules.projects.api.locked_policy import ( @@ -262,7 +263,7 @@ def _parse_post_submit_policy_summary( """Decode selected policy bodies while retaining historical read custody.""" body = json.loads(facts.compiled_post_submit_policy.value) if body.get("schema_version") == "external_post_submit_policy.v1": - selected = LockedExternalPostSubmitPolicy.model_validate(body) + selected = validate_stored_external_post_policy(body) policies = LockedExternalCheckerPolicies.model_validate_json( facts.external_checker_policies.value ) diff --git a/backend/tests/checkers/external/test_selected_post_submit.py b/backend/tests/checkers/external/test_selected_post_submit.py index b473d4c3d..dd52aa434 100644 --- a/backend/tests/checkers/external/test_selected_post_submit.py +++ b/backend/tests/checkers/external/test_selected_post_submit.py @@ -18,6 +18,7 @@ from app.modules.checkers.api.external import ( POST_SUBMIT_INPUT_SCHEMA_ID, ExternalCheckerRegistryEntry, + ExternalCheckerRegistrySpec, ExternalCheckerSchema, external_checker_json_hash, make_external_checker_execution_result, @@ -47,6 +48,7 @@ execution_identity, execution_material, registry_entry, + registry_spec, ) from tests.checkers.execution.support import live_executor, reserve from tests.post_submit_materialization_helpers import material_fixture @@ -93,6 +95,19 @@ def _policy() -> LockedExternalPostSubmitPolicy: ) +def _post_spec() -> ExternalCheckerRegistrySpec: + """Use the exact selected POST schema with the shared immutable registry facts.""" + values = registry_spec("post_submit").model_dump(mode="json") + document = {"type": "object"} + values["input_schema"] = ExternalCheckerSchema( + schema_id=POST_SUBMIT_INPUT_SCHEMA_ID, + schema_version="v1", + document=document, + schema_sha256=external_checker_json_hash(document), + ).model_dump(mode="json") + return ExternalCheckerRegistrySpec.model_validate(values) + + def _request(identity, policy): context = SelectedPostSubmitLockedContext( guide_version="guide-v1", @@ -237,6 +252,32 @@ async def test_selected_post_materializes_actual_submission_and_replays( assert len(h.store.opens) == 1 +@pytest.mark.postgres_schema_contract +async def test_selected_post_persists_locked_external_member( + tmp_path, isolated_database_env, +) -> None: + """Compile, approve and execute one real registered POST requirement.""" + async with material_fixture( + tmp_path, + isolated_database_env, + post_submit_registry_spec=_post_spec(), + ) as h: + assert len(h.request.policy.entries) == 1 + execution = _Execution() + result = await live_executor( + h, + selected_execution=execution, + ).evaluate_post_submission(h.request) + assert result.outcome == "completed" + assert result.execution is not None + assert len(result.execution.external_members) == 1 + member = result.execution.external_members[0] + assert member.requirement_id == "project.post_evidence" + assert member.registry_entry_id == h.request.policy.entries[0].registry.registry_entry_id + assert member.result.verdict == "passed" + assert len(execution.requests) == 1 + + @pytest.mark.asyncio async def test_selected_post_request_and_result_bind_exact_locked_policy() -> None: identity = execution_identity("post_submit") diff --git a/backend/tests/conftest.py b/backend/tests/conftest.py index 9e0b23993..d35f3f15b 100644 --- a/backend/tests/conftest.py +++ b/backend/tests/conftest.py @@ -23,7 +23,7 @@ DDL_LOCK_DIRECTORY = Path("/tmp") # Match the PostgreSQL 16 engine used by Backend CI. Catalog identity rendering # differs across major versions; regenerate only after comparing actual objects. -EXPECTED_PUBLIC_SCHEMA_SHA256 = "77186384fdc0ef74c480a046205070c314cb309d78e1dece3a8f380278d2ce91" +EXPECTED_PUBLIC_SCHEMA_SHA256 = "5125dcbb74b9502dbbca216fa1dc46c37e4a417ffd413d85a602f1fffadd7a3e" PROTECTED_TEST_TABLES = ( "actor_profile_migration_state", "alembic_version", diff --git a/backend/tests/post_submit_materialization_helpers.py b/backend/tests/post_submit_materialization_helpers.py index 8efd65956..abd1aae29 100644 --- a/backend/tests/post_submit_materialization_helpers.py +++ b/backend/tests/post_submit_materialization_helpers.py @@ -118,6 +118,7 @@ async def _material_fixture( provision_checker=True, contribution_awards=(), human_review_required=True, + post_submit_registry_spec=None, ): engine = create_async_engine(database_url) factory = async_sessionmaker(engine, expire_on_commit=False) @@ -149,6 +150,7 @@ async def _material_fixture( guide_version="v1", contribution_awards=contribution_awards, human_review_required=human_review_required, + post_submit_registry_spec=post_submit_registry_spec, ) context = _context() await provision_material_services(factory, artifacts=provision_services, checker=provision_checker) diff --git a/backend/tests/projects/guide_activation/source_fixtures.py b/backend/tests/projects/guide_activation/source_fixtures.py index 69285c725..84f1497eb 100644 --- a/backend/tests/projects/guide_activation/source_fixtures.py +++ b/backend/tests/projects/guide_activation/source_fixtures.py @@ -8,6 +8,7 @@ from app.modules.actors.models import ActorIdentityLink, ActorProfile from app.modules.actors.service import ResolvedActor +from app.core.identifiers import new_record_id from app.modules.authorization.kernel import AuthorizationService from app.modules.authorization.prepared import PreparedAuthorizationService from app.modules.authorization.repository import AdminAuthorizationRepository @@ -35,7 +36,15 @@ from tests.projects.guide_compilation.proposals.pg_support import seed_review_actor -async def create_compiled_guide(factory, values, actor, *, version="v1", artifact_proposal=None): +async def create_compiled_guide( + factory, + values, + actor, + *, + version="v1", + artifact_proposal=None, + post_submit_registry_entry=None, +): """Create declarations with real AUTH, then execute/project/finalize scripted findings.""" async with factory() as session, session.begin(): resolved = ResolvedActor( @@ -85,7 +94,16 @@ async def create_compiled_guide(factory, values, actor, *, version="v1", artifac "snapshot": manifest.source_snapshot_id, "setup_1": manifest.setup_run_id, } - compilation_context = context(values, guide_version=version).model_copy( + checker_capabilities = None + if post_submit_registry_entry is not None: + from tests.checkers.external.support import capability_projection + + checker_capabilities = capability_projection(post_submit_registry_entry) + compilation_context = context( + values, + guide_version=version, + checker_capabilities=checker_capabilities, + ).model_copy( update={"material": manifest} ) outcome = result() @@ -102,6 +120,33 @@ async def create_compiled_guide(factory, values, actor, *, version="v1", artifac outcome = outcome.model_copy( update={"findings": (outcome.findings[0].model_copy(update={"evidence_refs": refs}),)} ) + if post_submit_registry_entry is not None: + from app.interfaces.project_agents import ( + AtomicGuideRequirement, + PostSubmissionBindingProposal, + ) + + outcome = outcome.model_copy( + update={ + "requirements": ( + AtomicGuideRequirement( + requirement_id="project.post_evidence", + statement="Evaluate the submitted evidence package.", + disposition="supported_post_submit", + evidence_refs=refs, + ), + ), + "post_submit_bindings": ( + PostSubmissionBindingProposal( + requirement_id="project.post_evidence", + capability_id=post_submit_registry_entry.capability_id, + capability_version=post_submit_registry_entry.capability_version, + stage="post_submit", + parameters=(), + ), + ), + } + ) url = factory.kw["bind"].url.render_as_string(hide_password=False) finalization = await compilation_and_projections( url, @@ -115,7 +160,14 @@ async def create_compiled_guide(factory, values, actor, *, version="v1", artifac @asynccontextmanager -async def source_case(url, *, namespace=None, guide_version="v1", artifact_proposal=None): +async def source_case( + url, + *, + namespace=None, + guide_version="v1", + artifact_proposal=None, + post_submit_registry_spec=None, +): """An authorized draft Project plus a genuinely created complete guide source.""" engine = create_async_engine(url) factory = async_sessionmaker(engine, expire_on_commit=False) @@ -152,9 +204,68 @@ async def source_case(url, *, namespace=None, guide_version="v1", artifact_propo ).one() values.update(actor=UUID(service_id), link=UUID(link_id)) actor, grant = await seed_review_actor(factory, values["project"]) + registry_entry = ( + await _register_external_checker_fixture(factory, post_submit_registry_spec) + if post_submit_registry_spec is not None + else None + ) async with current_art_attempt_seed_schema(url): - values, finalization = await create_compiled_guide(factory, values, actor, version=guide_version, - artifact_proposal=artifact_proposal) + values, finalization = await create_compiled_guide( + factory, + values, + actor, + version=guide_version, + artifact_proposal=artifact_proposal, + post_submit_registry_entry=registry_entry, + ) yield values, factory, finalization, actor, grant finally: await engine.dispose() + + +async def _register_external_checker_fixture(factory, spec): + """Publish one real Operator-authorized immutable entry before compilation.""" + from app.modules.authorization.checker_registry_authorization import ( + ExternalCheckerRegistryAuthorizationAdapter, + ) + from app.modules.checkers.api.external import make_external_checker_registration_request + from app.modules.checkers.external_registry import ExternalCheckerRegistryService + from tests.project_create_fixtures import ( + grant_fixture_admin_role, + seed_fixture_actor, + ) + + async with factory() as session, session.begin(): + profile, link = await seed_fixture_actor( + session, + issuer="https://external-checker-fixture.test", + subject_prefix="external-checker-operator", + ) + await grant_fixture_admin_role( + session, + profile.id, + role="operator", + scope="system", + ) + operation_id = new_record_id() + request = make_external_checker_registration_request( + actor_profile_id=UUID(profile.id), + operation_id=operation_id, + registry_entry_id=new_record_id(), + spec=spec, + ) + authority_context = HumanAuthorizationContext( + actor_profile_id=UUID(profile.id), + actor_kind=ActorKind.HUMAN, + actor_status=ActorStatus.ACTIVE, + identity_link_id=UUID(link.id), + identity_link_status=IdentityLinkStatus.ACTIVE, + request_id=uuid4(), + correlation_id=operation_id, + ) + return await ExternalCheckerRegistryService( + session, + ExternalCheckerRegistryAuthorizationAdapter( + AuthorizationService(session, authority_context) + ), + ).register(request) diff --git a/backend/tests/projects/guide_compilation/finalization/pg_prerequisites.py b/backend/tests/projects/guide_compilation/finalization/pg_prerequisites.py index 92d3c0eda..aca7243bc 100644 --- a/backend/tests/projects/guide_compilation/finalization/pg_prerequisites.py +++ b/backend/tests/projects/guide_compilation/finalization/pg_prerequisites.py @@ -153,7 +153,15 @@ async def compilation_and_projections( ProjectGuideCompilationExecutionCommand, ProjectGuideCompilationExecutionClassification, ) runtime = _Runtime(outcome) - receipt = await _port(factory, runtime).execute( + receipt = await _port( + factory, + runtime, + checker_capabilities=( + compilation_context.checker_capabilities + if compilation_context.checker_capabilities.definitions + else None + ), + ).execute( ProjectGuideCompilationExecutionCommand(attempt_id=requested.attempt_id) ) assert receipt.classification is ProjectGuideCompilationExecutionClassification.PERSISTED diff --git a/backend/tests/projects/guide_compilation/test_hidden_orchestrator_postgresql.py b/backend/tests/projects/guide_compilation/test_hidden_orchestrator_postgresql.py index 9c1e472cb..56b4f4bdd 100644 --- a/backend/tests/projects/guide_compilation/test_hidden_orchestrator_postgresql.py +++ b/backend/tests/projects/guide_compilation/test_hidden_orchestrator_postgresql.py @@ -112,12 +112,12 @@ def _backend(factory): ) -def _port(factory, runtime): +def _port(factory, runtime, *, checker_capabilities=None): return project_guide_compilation_execution_port( factory, material_factory=guide_document_manifest_port, document_access_factory=document_access, - checker_capabilities=capability_projection(), + checker_capabilities=checker_capabilities or capability_projection(), authorization_context=_fixed_service_authorization, runtime_factory=lambda configuration: runtime, ) diff --git a/backend/tests/projects/unified_policy_fixtures.py b/backend/tests/projects/unified_policy_fixtures.py index cc4289318..7be070b86 100644 --- a/backend/tests/projects/unified_policy_fixtures.py +++ b/backend/tests/projects/unified_policy_fixtures.py @@ -166,6 +166,7 @@ async def create_standalone_unified_policy( artifact_proposal=None, contribution_awards=(), human_review_required=True, + post_submit_registry_spec=None, ): """Arrange complete activated context before a downstream artifact transaction.""" from app.modules.projects.models import PreSubmitCheckerPolicy @@ -179,7 +180,11 @@ async def create_standalone_unified_policy( url = sessions.kw["bind"].url.render_as_string(hide_password=False) async with source_case( - url, namespace=namespace, guide_version=guide_version, artifact_proposal=artifact_proposal + url, + namespace=namespace, + guide_version=guide_version, + artifact_proposal=artifact_proposal, + post_submit_registry_spec=post_submit_registry_spec, ) as (values, _, command, actor, grant): await seed_selected_review_revision_inputs( sessions, command, actor, human_review_required=human_review_required diff --git a/backend/tests/selected_policy_fixtures.py b/backend/tests/selected_policy_fixtures.py index 63b5fad3b..e62222de3 100644 --- a/backend/tests/selected_policy_fixtures.py +++ b/backend/tests/selected_policy_fixtures.py @@ -13,6 +13,7 @@ async def approved_selected_policy_fixture( guide_version, contribution_awards=(), human_review_required=True, + post_submit_registry_spec=None, ): """Build an activated guide backed only by immutable external policy custody.""" from app.interfaces.project_agents import SubmissionArtifactPolicyProposal @@ -32,6 +33,7 @@ async def approved_selected_policy_fixture( required_evidence=("results",), attestation_terms=("rights_confirmed",), ), + post_submit_registry_spec=post_submit_registry_spec, ) async with factory() as session: guide = await session.get(ProjectGuide, str(values["guide"])) @@ -58,4 +60,3 @@ async def approved_selected_policy_fixture( "evidence_path": "evidence/" + effective["effective_policy"]["required_evidence"][0]["key"], } - From d9a9aa10cad4e33e33441a44427c3621ad510d99 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 23:19:15 +0100 Subject: [PATCH 128/283] [PILOT-04] prove actual selected post service --- .../pilot04-workstream-default-checker.md | 1 + .../artifacts/post_submit_materialization.py | 11 +- .../external/test_selected_post_submit.py | 1 + .../README.md | 9 ++ .../checker.py | 15 +- .../run_selected_post_probe.py | 130 ++++++++++++++++++ .../workstream-checker-service/src/main.rs | 7 +- 7 files changed, 169 insertions(+), 5 deletions(-) create mode 100644 experiments/pilot04_external_checker_runtime/run_selected_post_probe.py diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 8ffdeb503..3abb51292 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -226,6 +226,7 @@ intermediate-wait regression. | Selected POST scheduler compatibility | `pytest -q backend/tests/checkers/external/test_selected_post_submit.py backend/tests/checkers/execution/test_results.py backend/tests/checkers/execution/test_completion_contract.py backend/tests/checkers/post_submit/test_request.py backend/tests/test_submission_bundle_admission.py`; focused Ruff | 84 passed; one discriminated owner accepts retained legacy and selected request/result envelopes, selected leases cover the ordered image budget and finalization margin, ART recomputes the selected manifest, and focused scheduler controls prove exact completed/infrastructure envelopes and generic replay parsing | Native selected columns/constraints and live Rust worker proof remain pending | | Selected POST native custody | `python3 /tmp/p04_selected_runner.py /tmp/p04-selected-post-result-replay 420 tests/checkers/external/test_selected_post_submit.py::test_selected_post_materializes_actual_submission_and_replays`; focused selected-POST pure tests and Ruff | PostgreSQL 16 PASS 1 in 36.10s with database/role cleanup complete, plus 7 pure tests; actual immutable Submission and verified ART lineage materialize through the selected policy, finalize selected result/member custody and replay the stored strict envelope | The approved policy is empty in this discriminator; a locked nonempty image, live Rust service and worker restart remain pending | | Nonempty selected POST policy and result | `python3 /tmp/p04_selected_runner.py /tmp/p04-selected-post-nonempty5 600 tests/checkers/external/test_selected_post_submit.py::test_selected_post_persists_locked_external_member`; `pytest -q backend/tests/checkers/external/test_selected_post_submit.py -m 'not postgres_schema_contract'`; focused Ruff and `git diff --check` | PostgreSQL 16 PASS 1 with database/role cleanup complete, plus 7 pure tests; an actual immutable registry entry is registered through Operator authority, compiled into one supported POST requirement, approved, activated, materialized from the real Submission/ART lineage and persisted as the exact selected member. Persisted UUID-bearing policy JSON and SQL requirement custody are decoded and validated without relaxing strict in-memory contracts. | The adapter in this discriminator is bounded and deterministic; a live Rust service, restart/reclaim and external work/infra outcomes remain pending | +| Actual selected POST Rust service | `run_selected_post_probe.py` through the isolated PostgreSQL runner at `/tmp/p04-selected-post-probe-final2`, using local registry platform manifest `sha256:c664d8d85d6dfcded31710223c8d91441548e5445f0aa9b59d246fc464a129ef`; focused Rust POST-grant round-trip test, Ruff and `git diff --check` | PASS 1 in 45.06s on PostgreSQL 16/schema 0037 with database/role and callback workspace cleanup complete. The real Rust service validates the full POST grant, launches the digest-pinned container in explicit local `runc`/`docker-dev` mode, reads every verified manifest file, returns an exact isolation receipt, and the normal owner persists its selected member. | This local proof does not claim hosted `runsc`; restart/reclaim, live PRE orchestration and final end-to-end MinIO evidence remain pending | | Production delivery registration and owner boundaries | `pytest -q backend/tests/architecture/test_module_boundaries.py backend/tests/test_artifact_architecture.py backend/tests/outbox/test_contracts.py`; focused Ruff and a direct registry construction probe | 116 passed; the existing production outbox registry exposes assignment invalidation and evaluation request handlers, selected Rust configuration is lazy, and PRE coordination stays behind CHECKERS' public adapter root | Database-backed legacy/selected delivery and worker restart proofs remain pending | | New Submission selected-only boundary | `pytest -q backend/tests/test_submission_bundle_admission.py backend/tests/checkers/external/test_selected_post_submit.py backend/tests/test_artifact_architecture.py::test_checker_custody_ports_have_exact_owner_and_art_consumers`; focused Ruff | 59 passed; retained legacy and selected admission projections are mutually exclusive, and the TASK writer accepts only selected POST custody for a new immutable Submission | Native rollback proof for a retained unresolved legacy admission remains pending | | Retained admission migration shape | `pytest -q backend/tests/test_submission_bundle_admission.py backend/tests/checkers/external/test_selected_pre_submit_coordination.py backend/tests/checkers/external/test_selected_preparation_command.py backend/tests/test_artifact_architecture.py::test_checker_materialization_contract_has_one_canonical_consumer_owner`; focused Ruff | 62 passed; selected rows require complete new custody while every new column stays null on retained legacy rows, avoiding fabricated backfill or historical hash rewrites | Successor SQL and direct retained/selected row controls remain pending | diff --git a/backend/app/modules/artifacts/post_submit_materialization.py b/backend/app/modules/artifacts/post_submit_materialization.py index 5d65317a9..79f9e7722 100644 --- a/backend/app/modules/artifacts/post_submit_materialization.py +++ b/backend/app/modules/artifacts/post_submit_materialization.py @@ -2,6 +2,7 @@ import asyncio from collections.abc import Callable +from contextlib import contextmanager from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker @@ -10,6 +11,7 @@ ArtifactStore, ArtifactObjectMissingError, ArtifactInputMismatchError, ArtifactIntegrityError, ArtifactLimitExceededError, ArtifactStoreUnavailableError, ) +from app.interfaces.external_checker_execution import ExternalCheckerMaterialGrant from app.modules.checkers.api.materialization import ( PostSubmissionMaterialConsumer, PostSubmissionMaterializationResult, PostSubmissionMaterializationUnavailable, PostSubmissionMaterializationFailure, @@ -82,6 +84,7 @@ def read_file(self, normalized_path: str, *, maximum_bytes: int) -> bytes: self._require_open() return self._tree.read_file(normalized_path, maximum_bytes=maximum_bytes) + @contextmanager def external_checker_grant(self, request: ExternalCheckerExecutionRequest): """Bind a POST service grant to actual current execution and ART ancestry.""" self._require_open() @@ -156,9 +159,13 @@ def external_checker_grant(self, request: ExternalCheckerExecutionRequest): semantic_manifest_sha256=material.semantic_manifest_sha256, directories=directories, files=files, ) - return self._preparation.external_material_grant( + with self._preparation.external_material_grant( self._prepared, self._workspace, grant_request - ) + ) as grant: + yield ExternalCheckerMaterialGrant( + grant_id=grant.grant_id, + binding_digest=grant.binding_digest, + ) @property def external_checker_material(self) -> PostSubmitExternalCheckerMaterial: diff --git a/backend/tests/checkers/external/test_selected_post_submit.py b/backend/tests/checkers/external/test_selected_post_submit.py index dd52aa434..2374417de 100644 --- a/backend/tests/checkers/external/test_selected_post_submit.py +++ b/backend/tests/checkers/external/test_selected_post_submit.py @@ -168,6 +168,7 @@ def __init__(self, *, outcome="completed", verdict="passed") -> None: self.requests = [] async def execute(self, request, _grant): + assert type(_grant) is ExternalCheckerMaterialGrant self.requests.append(request) infrastructure = self.outcome == "infrastructure_failed" findings = () if self.verdict == "passed" or infrastructure else ({ diff --git a/experiments/pilot04_external_checker_runtime/README.md b/experiments/pilot04_external_checker_runtime/README.md index 9639c8f5b..0f5ed85b9 100644 --- a/experiments/pilot04_external_checker_runtime/README.md +++ b/experiments/pilot04_external_checker_runtime/README.md @@ -12,3 +12,12 @@ fails its own result if the expected verified file differs, effective capabilities are nonzero, a Docker socket exists, the root is writable, or a network connection succeeds. This small Linux fixture does not establish hosted gVisor readiness, representative checker sizing, or product routing. + +`run_selected_post_probe.py` composes the same service with the selected POST +owner against an already migrated isolated PostgreSQL database. It registers +the supplied platform-manifest digest, builds a real locked policy, creates an +immutable Submission through the existing TASK/ART path, mounts the verified +archive through the callback-scoped POST grant, and requires the normalized +result, isolation receipt, database finalization, and workspace cleanup. The +database must be disposable and independently cleaned by the caller; the probe +does not create or drop it. diff --git a/experiments/pilot04_external_checker_runtime/checker.py b/experiments/pilot04_external_checker_runtime/checker.py index 86d7ba21b..5f62735d5 100644 --- a/experiments/pilot04_external_checker_runtime/checker.py +++ b/experiments/pilot04_external_checker_runtime/checker.py @@ -30,8 +30,19 @@ def main() -> int: sys.stdout.write("x" * (request["registry"]["resources"]["maximum_output_bytes"] + 1)) return 0 failures: list[str] = [] - if Path("/work/input/src/main.txt").read_bytes() != b"verified bytes": - failures.append("material") + manifest = request["input"].get("manifest") + if manifest is None: + if Path("/work/input/src/main.txt").read_bytes() != b"verified bytes": + failures.append("material") + else: + for entry in manifest: + if entry["entry_type"] != "file": + continue + value = Path("/work/input", entry["normalized_path"]).read_bytes() + digest = "sha256:" + hashlib.sha256(value).hexdigest() + if len(value) != entry["byte_count"] or digest != entry["sha256"]: + failures.append("material") + break status = Path("/proc/self/status").read_text() if "CapEff:\t0000000000000000" not in status: failures.append("capabilities") diff --git a/experiments/pilot04_external_checker_runtime/run_selected_post_probe.py b/experiments/pilot04_external_checker_runtime/run_selected_post_probe.py new file mode 100644 index 000000000..1e074f957 --- /dev/null +++ b/experiments/pilot04_external_checker_runtime/run_selected_post_probe.py @@ -0,0 +1,130 @@ +"""Run the selected POST owner through real PostgreSQL, ART and Rust service custody.""" + +from __future__ import annotations + +import argparse +import asyncio +import json +import os +from pathlib import Path +import subprocess +import tempfile + +from app.adapters.checkers import external_checker_execution_factory +from app.modules.checkers.api.external import ExternalCheckerRegistrySpec +from tests.checkers.execution.support import live_executor, reserve +from tests.checkers.external.test_selected_post_submit import _post_spec +from tests.post_submit_materialization_helpers import material_fixture + +from experiments.pilot04_external_checker_runtime.run_probe import _image_identity + + +async def run( + *, database_url: str, image_reference: str, service_binary: Path, root: Path +) -> dict[str, object]: + """Execute one registered POST image against actual Submission and ART facts.""" + image = _image_identity(image_reference) + values = _post_spec().model_dump(mode="json") + values["image_digest"] = image["platform_manifest_digest"] + values["resources"] |= {"deadline_ms": 8_000, "maximum_output_bytes": 8_192} + spec = ExternalCheckerRegistrySpec.model_validate(values) + async with material_fixture( + root, database_url, post_submit_registry_spec=spec + ) as fixture: + socket_root = root / "service" + socket_root.mkdir(mode=0o700) + socket_path = socket_root / "checker.sock" + config = { + "socket_path": str(socket_path), + "material_root": str(fixture.scratch), + "docker_binary": "/usr/bin/docker", + "runtime": "runc", + "isolation_mode": "docker-dev", + "operating_system": image["operating_system"], + "architecture": image["architecture"], + "sandbox_uid": os.getuid(), + "sandbox_gid": os.getgid(), + "cache": [image], + } + config_path = socket_root / "service.json" + config_path.write_text(json.dumps(config, separators=(",", ":"))) + service = subprocess.Popen( + [str(service_binary), str(config_path)], + stdout=subprocess.DEVNULL, + stderr=subprocess.PIPE, + text=True, + ) + try: + for _ in range(500): + if socket_path.exists(): + break + if service.poll() is not None: + raise RuntimeError("checker service exited before readiness") + await asyncio.sleep(0.02) + else: + raise RuntimeError("checker service socket did not become ready") + adapter = external_checker_execution_factory( + socket_path=socket_path, timeout_seconds=90.0 + ).create("unix_socket") + health = await adapter.health() + reservation = await reserve(fixture) + result = await live_executor( + fixture, selected_execution=adapter + ).evaluate_post_submission(fixture.request) + if result.outcome != "completed" or result.execution is None: + raise RuntimeError("selected POST execution did not complete") + if len(result.execution.external_members) != 1: + raise RuntimeError("selected POST member count differs") + member = result.execution.external_members[0] + if ( + member.result.verdict != "passed" + or member.isolation.platform_manifest_digest + != image["platform_manifest_digest"] + or result.attempt_id != reservation.attempt_id + ): + raise RuntimeError("selected POST result or isolation differs") + workspace_cleanup = list((fixture.scratch / "workspaces").iterdir()) == [] + if not workspace_cleanup: + raise RuntimeError("selected POST workspace cleanup is incomplete") + return { + "image": image, + "health": { + "runtime": health.runtime, + "isolation_mode": health.isolation_mode, + }, + "attempt_id": str(result.attempt_id), + "result_digest": result.result_digest, + "member_result_digest": member.result.result_digest, + "workspace_cleanup": workspace_cleanup, + "store_open_count": len(fixture.store.opens), + } + finally: + service.terminate() + try: + service.wait(timeout=5) + except subprocess.TimeoutExpired: + service.kill() + service.wait(timeout=5) + + +def main() -> int: + parser = argparse.ArgumentParser() + parser.add_argument("--database-url", required=True) + parser.add_argument("--image-reference", required=True) + parser.add_argument("--service-binary", required=True, type=Path) + args = parser.parse_args() + with tempfile.TemporaryDirectory(prefix="ws-pilot04-selected-post-") as directory: + result = asyncio.run( + run( + database_url=args.database_url, + image_reference=args.image_reference, + service_binary=args.service_binary, + root=Path(directory), + ) + ) + print(json.dumps(result, sort_keys=True, separators=(",", ":"))) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/external_checkers/workstream-checker-service/src/main.rs b/external_checkers/workstream-checker-service/src/main.rs index 5367645e0..5f342fa40 100644 --- a/external_checkers/workstream-checker-service/src/main.rs +++ b/external_checkers/workstream-checker-service/src/main.rs @@ -77,7 +77,6 @@ struct GrantReference { } #[derive(Debug, Clone, Deserialize, Serialize)] -#[serde(deny_unknown_fields)] struct GrantManifest { protocol_version: String, grant_id: String, @@ -1869,6 +1868,12 @@ mod tests { unreachable!() }; *semantic_manifest_sha256 = semantic.clone(); + let encoded = serde_json::to_vec(&manifest).unwrap(); + let decoded: GrantManifest = serde_json::from_slice(&encoded).unwrap(); + assert!(matches!(decoded.identity, GrantIdentity::PostSubmit { .. })); + let mut substituted = serde_json::to_value(&manifest).unwrap(); + substituted["unexpected"] = Value::Bool(true); + assert!(serde_json::from_value::(substituted).is_err()); let mut material = material; material["semantic_manifest_sha256"] = Value::String(semantic); let request = ValidatedRequest { From 4fb2152cb33997dd3bcb1c7ccebf42209aeb63eb Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 23:23:04 +0100 Subject: [PATCH 129/283] [PILOT-04] prove actual selected pre service --- .../pilot04-workstream-default-checker.md | 3 +- .../run_selected_pre_probe.py | 268 ++++++++++++++++++ 2 files changed, 270 insertions(+), 1 deletion(-) create mode 100644 experiments/pilot04_external_checker_runtime/run_selected_pre_probe.py diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 3abb51292..de230b14e 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -227,10 +227,11 @@ intermediate-wait regression. | Selected POST native custody | `python3 /tmp/p04_selected_runner.py /tmp/p04-selected-post-result-replay 420 tests/checkers/external/test_selected_post_submit.py::test_selected_post_materializes_actual_submission_and_replays`; focused selected-POST pure tests and Ruff | PostgreSQL 16 PASS 1 in 36.10s with database/role cleanup complete, plus 7 pure tests; actual immutable Submission and verified ART lineage materialize through the selected policy, finalize selected result/member custody and replay the stored strict envelope | The approved policy is empty in this discriminator; a locked nonempty image, live Rust service and worker restart remain pending | | Nonempty selected POST policy and result | `python3 /tmp/p04_selected_runner.py /tmp/p04-selected-post-nonempty5 600 tests/checkers/external/test_selected_post_submit.py::test_selected_post_persists_locked_external_member`; `pytest -q backend/tests/checkers/external/test_selected_post_submit.py -m 'not postgres_schema_contract'`; focused Ruff and `git diff --check` | PostgreSQL 16 PASS 1 with database/role cleanup complete, plus 7 pure tests; an actual immutable registry entry is registered through Operator authority, compiled into one supported POST requirement, approved, activated, materialized from the real Submission/ART lineage and persisted as the exact selected member. Persisted UUID-bearing policy JSON and SQL requirement custody are decoded and validated without relaxing strict in-memory contracts. | The adapter in this discriminator is bounded and deterministic; a live Rust service, restart/reclaim and external work/infra outcomes remain pending | | Actual selected POST Rust service | `run_selected_post_probe.py` through the isolated PostgreSQL runner at `/tmp/p04-selected-post-probe-final2`, using local registry platform manifest `sha256:c664d8d85d6dfcded31710223c8d91441548e5445f0aa9b59d246fc464a129ef`; focused Rust POST-grant round-trip test, Ruff and `git diff --check` | PASS 1 in 45.06s on PostgreSQL 16/schema 0037 with database/role and callback workspace cleanup complete. The real Rust service validates the full POST grant, launches the digest-pinned container in explicit local `runc`/`docker-dev` mode, reads every verified manifest file, returns an exact isolation receipt, and the normal owner persists its selected member. | This local proof does not claim hosted `runsc`; restart/reclaim, live PRE orchestration and final end-to-end MinIO evidence remain pending | +| Actual selected PRE Rust service | `PYTHONPATH=.:backend /tmp/workstream-pilot-review-locked-env/bin/python experiments/pilot04_external_checker_runtime/run_selected_pre_probe.py --image-reference localhost:35104/ws-pilot04-checker@sha256:c664d8d85d6dfcded31710223c8d91441548e5445f0aa9b59d246fc464a129ef --service-binary external_checkers/target/debug/workstream-checker-service`; Ruff and `py_compile` | PASS. Genuine prepared ART bytes and the server-computed manifest enter the selected default-plus-project-image processor before any Submission exists. The callback-scoped grant launches the exact digest-pinned image through the Rust service in explicit local `runc`/`docker-dev` mode, returns matching result/isolation custody, and confirms the workspace is empty after the callback. | This is the actual selected PRE execution boundary, not the final PostgreSQL/MinIO admission-to-dispatch journey or a hosted `runsc` claim. | | Production delivery registration and owner boundaries | `pytest -q backend/tests/architecture/test_module_boundaries.py backend/tests/test_artifact_architecture.py backend/tests/outbox/test_contracts.py`; focused Ruff and a direct registry construction probe | 116 passed; the existing production outbox registry exposes assignment invalidation and evaluation request handlers, selected Rust configuration is lazy, and PRE coordination stays behind CHECKERS' public adapter root | Database-backed legacy/selected delivery and worker restart proofs remain pending | | New Submission selected-only boundary | `pytest -q backend/tests/test_submission_bundle_admission.py backend/tests/checkers/external/test_selected_post_submit.py backend/tests/test_artifact_architecture.py::test_checker_custody_ports_have_exact_owner_and_art_consumers`; focused Ruff | 59 passed; retained legacy and selected admission projections are mutually exclusive, and the TASK writer accepts only selected POST custody for a new immutable Submission | Native rollback proof for a retained unresolved legacy admission remains pending | | Retained admission migration shape | `pytest -q backend/tests/test_submission_bundle_admission.py backend/tests/checkers/external/test_selected_pre_submit_coordination.py backend/tests/checkers/external/test_selected_preparation_command.py backend/tests/test_artifact_architecture.py::test_checker_materialization_contract_has_one_canonical_consumer_owner`; focused Ruff | 62 passed; selected rows require complete new custody while every new column stays null on retained legacy rows, avoiding fabricated backfill or historical hash rewrites | Successor SQL and direct retained/selected row controls remain pending | -| Owner/caller trace | PROJECT approval/activation, ART preparation/admission, TASK composition and CHECKERS dispatch | In progress | Persistence delta and migration ordinal await actual linear predecessor | +| Owner/caller trace | PROJECT approval/activation, ART preparation/admission, TASK composition and CHECKERS dispatch | Selected PRE uses durable reserve/lease/finalize roots around the genuine ART callback; a pass is consumed only by TASK's existing atomic Submission/evaluation reservation/outbox composition, while POST uses immutable Submission/ART custody | Final F-020 recovery, retained-history transition, catalogue deletion and combined native journey remain pending | | End-to-end replacement | Real PostgreSQL/MinIO/Rust public and worker journey | Not run | Implementation incomplete | ## Reconciliation diff --git a/experiments/pilot04_external_checker_runtime/run_selected_pre_probe.py b/experiments/pilot04_external_checker_runtime/run_selected_pre_probe.py new file mode 100644 index 000000000..ea6aacf7d --- /dev/null +++ b/experiments/pilot04_external_checker_runtime/run_selected_pre_probe.py @@ -0,0 +1,268 @@ +"""Run selected PRE over genuine prepared ART bytes and the Rust service.""" + +from __future__ import annotations + +import argparse +import asyncio +from dataclasses import replace +from datetime import UTC, datetime, timedelta +import json +import os +from pathlib import Path +import subprocess +from types import SimpleNamespace + +from app.adapters.checkers import ( + SelectedPreSubmitCheckerExecutionAdapter, + external_checker_execution_factory, +) +from app.core.hashing import canonical_json_hash +from app.core.identifiers import new_record_id +from app.modules.artifacts.submission_materialization import ( + PreparedBundleMaterializationService, +) +from app.modules.checkers.api.default_checker import ( + WORKSTREAM_DEFAULT_BEHAVIOR_SHA256, + WorkstreamDefaultCheckerInput, + workstream_default_input_sha256, +) +from app.modules.checkers.api.external import ( + ExternalCheckerRegistryEntry, + ExternalCheckerRegistrySpec, +) +from app.modules.checkers.api.external_policy import ( + LockedExternalCheckerBinding, + LockedExternalPreSubmitPolicy, +) +from app.modules.checkers.api.materialization import SubmissionMaterialEntry +from app.modules.checkers.api.pre_submit import SubmissionPacketView +from app.modules.checkers.api.selected_pre_submit import ( + SelectedPreSubmitLeaseFacts, + SelectedPreSubmitReservationFacts, +) +from experiments.pilot04_external_checker_runtime.run_probe import ( + _image_identity, +) +from tests.checkers.external.test_selected_pre_submit import _policy, _request + + +def _locked_policy(image: dict[str, str]) -> LockedExternalPreSubmitPolicy: + """Replace only the fixture image and resource limits, then rebind hashes.""" + fixture = _policy() + source = fixture.entries[0] + body = source.registry.model_dump( + mode="json", + exclude={ + "registry_entry_id", + "entry_digest", + "registration_operation_id", + "registered_by_actor_profile_id", + "authorization_decision_event_id", + "created_at", + }, + ) + body["image_digest"] = image["platform_manifest_digest"] + body["resources"] |= {"deadline_ms": 8_000, "maximum_output_bytes": 8_192} + spec = ExternalCheckerRegistrySpec.model_validate(body) + registry = ExternalCheckerRegistryEntry( + **spec.model_dump(), + registry_entry_id=source.registry.registry_entry_id, + entry_digest=spec.spec_digest, + registration_operation_id=source.registry.registration_operation_id, + registered_by_actor_profile_id=source.registry.registered_by_actor_profile_id, + authorization_decision_event_id=( + source.registry.authorization_decision_event_id + ), + created_at=source.registry.created_at, + ) + binding = LockedExternalCheckerBinding( + requirement_id=source.requirement_id, + stage="pre_submit", + registry=registry, + configuration=source.configuration, + configuration_sha256=source.configuration_sha256, + ) + policy_body = { + "schema_version": "external_pre_submit_policy.v1", + "workstream_default": fixture.workstream_default.model_dump(mode="json"), + "entries": [binding.model_dump(mode="json")], + } + return LockedExternalPreSubmitPolicy( + workstream_default=fixture.workstream_default, + entries=(binding,), + policy_sha256=canonical_json_hash(policy_body), + ) + + +async def run( + *, image_reference: str, service_binary: Path, root: Path +) -> dict[str, object]: + """Execute one selected PRE image with no Submission or durable ART binding.""" + image = _image_identity(image_reference) + request, inspector, manager, preparation, _ = await _request(root) + socket_root = root / "service" + socket_root.mkdir(mode=0o700) + socket_path = socket_root / "checker.sock" + config = { + "socket_path": str(socket_path), + "material_root": str(root / "scratch"), + "docker_binary": "/usr/bin/docker", + "runtime": "runc", + "isolation_mode": "docker-dev", + "operating_system": image["operating_system"], + "architecture": image["architecture"], + "sandbox_uid": os.getuid(), + "sandbox_gid": os.getgid(), + "cache": [image], + } + config_path = socket_root / "service.json" + config_path.write_text(json.dumps(config, separators=(",", ":"))) + service = subprocess.Popen( + [str(service_binary), str(config_path)], + stdout=subprocess.DEVNULL, + stderr=subprocess.PIPE, + text=True, + ) + try: + for _ in range(500): + if socket_path.exists(): + break + if service.poll() is not None: + raise RuntimeError("checker service exited before readiness") + await asyncio.sleep(0.02) + else: + raise RuntimeError("checker service socket did not become ready") + policy = _locked_policy(image) + entries = tuple( + SubmissionMaterialEntry( + item.normalized_path, + item.entry_type.value, + item.byte_count, + item.sha256, + item.executable, + ) + for item in request.manifest.entries + ) + default_input = WorkstreamDefaultCheckerInput( + archive_sha256=request.prepared_artifact.commitment.sha256, + archive_byte_count=request.prepared_artifact.commitment.byte_count, + archive_media_type="application/zip", + semantic_manifest_sha256=request.manifest.sha256, + entries=entries, + predecessor=None, + predecessor_exists=False, + current_predecessor=None, + current_rules_sha256=policy.policy_sha256, + predecessor_rules_sha256=None, + packet=SubmissionPacketView("", ""), + ) + attempt_id = new_record_id() + reservation = SelectedPreSubmitReservationFacts( + actor_profile_id=new_record_id(), + identity_link_id=new_record_id(), + project_id=request.effective_plan.lineage.project_id, + task_id=request.task_id, + assignment_id=request.assignment_id, + attempt_id=attempt_id, + idempotency_key=new_record_id(), + attempt_request_digest="sha256:" + "2" * 64, + prepared_generation_id=request.prepared_artifact.generation_id, + policy_sha256=policy.policy_sha256, + default_behavior_sha256=WORKSTREAM_DEFAULT_BEHAVIOR_SHA256, + default_input_sha256=workstream_default_input_sha256(default_input), + archive_sha256=request.prepared_artifact.commitment.sha256, + archive_byte_count=request.prepared_artifact.commitment.byte_count, + semantic_manifest_sha256=request.manifest.sha256, + execution_budget_ms=120_000, + ) + request = replace( + request, + external_policy=policy, + default_checker_input=default_input, + selected_reservation=reservation, + ) + lease = SelectedPreSubmitLeaseFacts( + reservation=reservation, + lease_id=new_record_id(), + lease_generation=1, + lease_expires_at=datetime.now(UTC) + timedelta(minutes=2), + ) + adapter = external_checker_execution_factory( + socket_path=socket_path, timeout_seconds=90.0 + ).create("unix_socket") + health = await adapter.health() + materialization = PreparedBundleMaterializationService( + session=SimpleNamespace(in_transaction=lambda: False), + authorization=object(), + preparation=preparation, + checker_execution=SelectedPreSubmitCheckerExecutionAdapter( + archive_inspector=inspector, + external_execution=adapter, + ), + storage_scheme="s3", + ) + result = await materialization.materialize_selected_pre_submit( + request, + run_id=attempt_id, + lease=lease, + execution_authority=SimpleNamespace( + consume=lambda *, run_id, lease: lease + ), + ) + member = result.external_members[0] + workspaces = root / "scratch" / "workspaces" + workspace_cleanup = not workspaces.exists() or list(workspaces.iterdir()) == [] + if ( + not result.eligible + or len(result.external_members) != 1 + or member.result.verdict != "passed" + or member.isolation.platform_manifest_digest + != image["platform_manifest_digest"] + or not workspace_cleanup + ): + raise RuntimeError("selected PRE result or cleanup differs") + return { + "health": { + "runtime": health.runtime, + "isolation_mode": health.isolation_mode, + }, + "image": image, + "attempt_id": str(attempt_id), + "request_digest": reservation.request_digest, + "result_digest": result.result_digest, + "member_result_digest": member.result.result_digest, + "workspace_cleanup": workspace_cleanup, + "submission_created": False, + } + finally: + await request.prepared_artifact.close() + manager.close() + service.terminate() + try: + service.wait(timeout=5) + except subprocess.TimeoutExpired: + service.kill() + service.wait(timeout=5) + + +def main() -> int: + parser = argparse.ArgumentParser() + parser.add_argument("--image-reference", required=True) + parser.add_argument("--service-binary", required=True, type=Path) + args = parser.parse_args() + import tempfile + + with tempfile.TemporaryDirectory(prefix="ws-pilot04-selected-pre-") as directory: + result = asyncio.run( + run( + image_reference=args.image_reference, + service_binary=args.service_binary, + root=Path(directory), + ) + ) + print(json.dumps(result, sort_keys=True, separators=(",", ":"))) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) From 1450d90f3dbf1f1fb5a2892915fc9d62a5b8e722 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 23:26:58 +0100 Subject: [PATCH 130/283] [PILOT-04] provision selected pre policy fixtures --- .../guide_activation/source_fixtures.py | 84 +++++++++++++------ .../tests/projects/unified_policy_fixtures.py | 2 + backend/tests/selected_policy_fixtures.py | 2 + 3 files changed, 64 insertions(+), 24 deletions(-) diff --git a/backend/tests/projects/guide_activation/source_fixtures.py b/backend/tests/projects/guide_activation/source_fixtures.py index 84f1497eb..cb09d9ce8 100644 --- a/backend/tests/projects/guide_activation/source_fixtures.py +++ b/backend/tests/projects/guide_activation/source_fixtures.py @@ -43,6 +43,7 @@ async def create_compiled_guide( *, version="v1", artifact_proposal=None, + pre_submit_registry_entry=None, post_submit_registry_entry=None, ): """Create declarations with real AUTH, then execute/project/finalize scripted findings.""" @@ -95,10 +96,15 @@ async def create_compiled_guide( "setup_1": manifest.setup_run_id, } checker_capabilities = None - if post_submit_registry_entry is not None: + registry_entries = tuple( + entry + for entry in (pre_submit_registry_entry, post_submit_registry_entry) + if entry is not None + ) + if registry_entries: from tests.checkers.external.support import capability_projection - checker_capabilities = capability_projection(post_submit_registry_entry) + checker_capabilities = capability_projection(*registry_entries) compilation_context = context( values, guide_version=version, @@ -120,31 +126,56 @@ async def create_compiled_guide( outcome = outcome.model_copy( update={"findings": (outcome.findings[0].model_copy(update={"evidence_refs": refs}),)} ) - if post_submit_registry_entry is not None: + if registry_entries: from app.interfaces.project_agents import ( AtomicGuideRequirement, + PreSubmissionBindingProposal, PostSubmissionBindingProposal, ) + requirements = [] + pre_bindings = [] + post_bindings = [] + if pre_submit_registry_entry is not None: + requirements.append( + AtomicGuideRequirement( + requirement_id="project.archive_rules", + statement="Validate the submitted project archive rules.", + disposition="supported_pre_submit", + evidence_refs=refs, + ) + ) + pre_bindings.append( + PreSubmissionBindingProposal( + requirement_id="project.archive_rules", + capability_id=pre_submit_registry_entry.capability_id, + capability_version=pre_submit_registry_entry.capability_version, + stage="pre_submit", + ) + ) + if post_submit_registry_entry is not None: + requirements.append( + AtomicGuideRequirement( + requirement_id="project.post_evidence", + statement="Evaluate the submitted evidence package.", + disposition="supported_post_submit", + evidence_refs=refs, + ) + ) + post_bindings.append( + PostSubmissionBindingProposal( + requirement_id="project.post_evidence", + capability_id=post_submit_registry_entry.capability_id, + capability_version=post_submit_registry_entry.capability_version, + stage="post_submit", + parameters=(), + ) + ) outcome = outcome.model_copy( update={ - "requirements": ( - AtomicGuideRequirement( - requirement_id="project.post_evidence", - statement="Evaluate the submitted evidence package.", - disposition="supported_post_submit", - evidence_refs=refs, - ), - ), - "post_submit_bindings": ( - PostSubmissionBindingProposal( - requirement_id="project.post_evidence", - capability_id=post_submit_registry_entry.capability_id, - capability_version=post_submit_registry_entry.capability_version, - stage="post_submit", - parameters=(), - ), - ), + "requirements": tuple(requirements), + "pre_submit_bindings": tuple(pre_bindings), + "post_submit_bindings": tuple(post_bindings), } ) url = factory.kw["bind"].url.render_as_string(hide_password=False) @@ -166,6 +197,7 @@ async def source_case( namespace=None, guide_version="v1", artifact_proposal=None, + pre_submit_registry_spec=None, post_submit_registry_spec=None, ): """An authorized draft Project plus a genuinely created complete guide source.""" @@ -204,10 +236,13 @@ async def source_case( ).one() values.update(actor=UUID(service_id), link=UUID(link_id)) actor, grant = await seed_review_actor(factory, values["project"]) - registry_entry = ( + pre_registry_entry = ( + await _register_external_checker_fixture(factory, pre_submit_registry_spec) + if pre_submit_registry_spec is not None else None + ) + post_registry_entry = ( await _register_external_checker_fixture(factory, post_submit_registry_spec) - if post_submit_registry_spec is not None - else None + if post_submit_registry_spec is not None else None ) async with current_art_attempt_seed_schema(url): values, finalization = await create_compiled_guide( @@ -216,7 +251,8 @@ async def source_case( actor, version=guide_version, artifact_proposal=artifact_proposal, - post_submit_registry_entry=registry_entry, + pre_submit_registry_entry=pre_registry_entry, + post_submit_registry_entry=post_registry_entry, ) yield values, factory, finalization, actor, grant finally: diff --git a/backend/tests/projects/unified_policy_fixtures.py b/backend/tests/projects/unified_policy_fixtures.py index 7be070b86..b942cb944 100644 --- a/backend/tests/projects/unified_policy_fixtures.py +++ b/backend/tests/projects/unified_policy_fixtures.py @@ -166,6 +166,7 @@ async def create_standalone_unified_policy( artifact_proposal=None, contribution_awards=(), human_review_required=True, + pre_submit_registry_spec=None, post_submit_registry_spec=None, ): """Arrange complete activated context before a downstream artifact transaction.""" @@ -184,6 +185,7 @@ async def create_standalone_unified_policy( namespace=namespace, guide_version=guide_version, artifact_proposal=artifact_proposal, + pre_submit_registry_spec=pre_submit_registry_spec, post_submit_registry_spec=post_submit_registry_spec, ) as (values, _, command, actor, grant): await seed_selected_review_revision_inputs( diff --git a/backend/tests/selected_policy_fixtures.py b/backend/tests/selected_policy_fixtures.py index e62222de3..3fa3983a1 100644 --- a/backend/tests/selected_policy_fixtures.py +++ b/backend/tests/selected_policy_fixtures.py @@ -13,6 +13,7 @@ async def approved_selected_policy_fixture( guide_version, contribution_awards=(), human_review_required=True, + pre_submit_registry_spec=None, post_submit_registry_spec=None, ): """Build an activated guide backed only by immutable external policy custody.""" @@ -33,6 +34,7 @@ async def approved_selected_policy_fixture( required_evidence=("results",), attestation_terms=("rights_confirmed",), ), + pre_submit_registry_spec=pre_submit_registry_spec, post_submit_registry_spec=post_submit_registry_spec, ) async with factory() as session: From 34d6965b5913678068a6046fb58a167c6f7a933d Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 23:31:17 +0100 Subject: [PATCH 131/283] [PILOT-04] migrate retained submission fixture to selected PRE --- backend/tests/committed_guide_fixtures.py | 2 +- backend/tests/retained_material_fixtures.py | 97 ++++++++++++++++----- 2 files changed, 76 insertions(+), 23 deletions(-) diff --git a/backend/tests/committed_guide_fixtures.py b/backend/tests/committed_guide_fixtures.py index 321b02ae1..42592eac1 100644 --- a/backend/tests/committed_guide_fixtures.py +++ b/backend/tests/committed_guide_fixtures.py @@ -117,7 +117,7 @@ async def create_compiled_report_fixture( status, findings = diagnostic.status, diagnostic.findings manifest = await create_committed_document_fixture(source_snapshot_id) configuration = runtime_configuration() - async with sessions() as session: + async with sessions() as session, session.begin(): capabilities = await external_checker_capability_projection(session) async with sessions() as session: setup = await session.get(ProjectSetupRun, str(manifest.setup_run_id)) diff --git a/backend/tests/retained_material_fixtures.py b/backend/tests/retained_material_fixtures.py index 434d3d78d..e8f8ec432 100644 --- a/backend/tests/retained_material_fixtures.py +++ b/backend/tests/retained_material_fixtures.py @@ -4,8 +4,6 @@ conformance. Local/MinIO execution has its own focused integration proof. """ -from app.adapters.checkers import submission_evaluation_content - from contextlib import asynccontextmanager from io import BytesIO from pathlib import Path @@ -15,14 +13,21 @@ from sqlalchemy import select -from app.adapters.artifacts import CheckerPhaseService +from app.adapters.auth import selected_pre_submit_authority +from app.adapters.checkers import ( + SelectedPreSubmitCheckerExecutionAdapter, + selected_pre_submit_coordinator, +) from app.core.identifiers import new_record_id from app.interfaces.artifacts import ( ArtifactObjectHead, ArtifactPutObservation, ArtifactPutResult, artifact_provider_object_ref, ) from app.interfaces.external_services import ExternalServiceAdapterIdentity from app.modules.artifacts.api import SubmissionBundlePreparationRequest -from app.modules.artifacts.authorization import PreparedSubmissionBundlePreparationAuthorization +from app.modules.artifacts.authorization import ( + PreparedPreSubmitMaterializationAuthorization, + PreparedSubmissionBundlePreparationAuthorization, +) from app.modules.artifacts.models import ArtifactStorageNamespace, ArtifactVerificationJob, SubmissionBundleAdmission from app.modules.artifacts.preparation import ArtifactPreparationService, ArtifactScratchManager from app.modules.artifacts.service import ArtifactAdmissionService, ArtifactStorageNamespaceSpec, ArtifactStorageOrchestrator @@ -30,17 +35,26 @@ PreparedSubmissionBundlePreparationCommand, SubmissionBundleDurablePutService, SubmissionBundlePreparationRuntime, ) +from app.modules.artifacts.selected_pre_submit_execution import SelectedPreSubmitExecutionService from app.modules.artifacts.submission_archive import SubmissionArchiveInspector, SubmissionArchiveLimits +from app.modules.artifacts.submission_materialization import PreparedBundleMaterializationService from app.modules.authorization.api import ActorIdentityFacts, ActorKind -from app.modules.checkers.catalogue import build_pre_submission_checker_catalogue +from app.modules.actors.api import ServiceIdentity from app.modules.projects.locked_policy_repository import ProjectLockedPolicyRepository from app.modules.projects.models import EffectiveProjectSubmissionArtifactPolicy from app.modules.tasks.repository import TaskRepository -from tests.checkers.execution.support import forbidden_post_submission -from tests.pre_submit_test_helpers import evidence_workflow from tests.test_artifact_admission import _AllowArtifactAuthority, _context, _settings from tests.test_checker_materialization import _limits -from tests.test_default_pre_submit_execution import _AllowAuthority, _bytes +from tests.checkers.execution.support import provision_post_submit_service + + +async def _bytes(value: bytes): + yield value + + +class _ForbiddenExternalExecution: + async def execute(self, *_args, **_kwargs): + raise AssertionError("empty selected policy invoked an external image") class MemoryStore: @@ -75,8 +89,19 @@ async def head(self, ref): return ArtifactObjectHead(ref, data is not None, len(data) if data is not None else None) -async def retained_admission(factory, task, assignment, link, packet, predecessor_id): +async def retained_admission( + factory, + task, + assignment, + link, + packet, + predecessor_id, + *, + external_execution=None, +): """Prepare/check/publish/verify actual ZIP bytes for this existing assignment.""" + await provision_post_submit_service(factory, ServiceIdentity.ARTIFACT_MATERIALIZER) + await provision_post_submit_service(factory, ServiceIdentity.CHECKER_PRE_SUBMIT) async with factory() as session: persisted = await session.get(ArtifactStorageNamespace, "primary") namespace = ArtifactStorageNamespaceSpec( @@ -116,27 +141,55 @@ async def retained_admission(factory, task, assignment, link, packet, predecesso try: async with factory() as session: authority = PreparedSubmissionBundlePreparationAuthorization(session, context) + materialization_authority = PreparedPreSubmitMaterializationAuthorization( + session, + request_id=request.request_id, + correlation_id=request.correlation_id, + ) tasks, projects = TaskRepository(session), ProjectLockedPolicyRepository(session) preparation = ArtifactPreparationService(manager) inspector = SubmissionArchiveInspector(SubmissionArchiveLimits()) - catalogue = build_pre_submission_checker_catalogue() - evidence = evidence_workflow( - session=session, preparation=preparation, inspector=inspector, catalogue=catalogue, - materialization_authorization=_AllowAuthority(), preparation_authorization=authority, + materialization = PreparedBundleMaterializationService( + session=session, + authorization=materialization_authority, + preparation=preparation, + checker_execution=SelectedPreSubmitCheckerExecutionAdapter( + archive_inspector=inspector, + external_execution=external_execution + or _ForbiddenExternalExecution(), + ), + storage_scheme="s3", ) storage = ArtifactStorageOrchestrator(session, store, namespace, settings, _AllowArtifactAuthority()) + coordinator = selected_pre_submit_coordinator(session) @asynccontextmanager async def runtime(): - yield SubmissionBundlePreparationRuntime( - preparation, inspector, catalogue, evidence._materialization, evidence, - CheckerPhaseService(pre_submission=evidence, post_submission=forbidden_post_submission()), - SubmissionBundleDurablePutService( - session=session, admission=ArtifactAdmissionService(session, settings, namespace), - storage=storage, authorization=authority, task_contexts=tasks, project_contexts=projects, - ), - submission_evaluation_content, - ) + try: + yield SubmissionBundlePreparationRuntime( + preparation=preparation, + inspector=inspector, + materialization=materialization, + durable_put=SubmissionBundleDurablePutService( + session=session, + admission=ArtifactAdmissionService(session, settings, namespace), + storage=storage, + authorization=authority, + task_contexts=tasks, + project_contexts=projects, + ), + selected_coordinator=coordinator, + selected_execution=SelectedPreSubmitExecutionService( + session=session, + coordinator=coordinator, + authority=selected_pre_submit_authority(session), + materialization=materialization, + ), + storage_scheme="s3", + artifact_deadline_ms=180_000, + ) + finally: + materialization_authority.close() result = await PreparedSubmissionBundlePreparationCommand( session=session, authority=authority, task_contexts=tasks, From 6dd0cf6a6f9a743d9c6000a086408f3b8f56328e Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 23:35:55 +0100 Subject: [PATCH 132/283] [PILOT-04] migrate routing completion fixtures to selected POST --- .../checkers/execution/completion_fixture.py | 79 +++++-------------- backend/tests/checkers/execution/support.py | 57 ++++++++++++- .../execution/test_completion_evidence.py | 23 ++---- backend/tests/checkers/external/support.py | 13 +++ .../external/test_selected_post_submit.py | 12 +-- .../test_failure_completion.py | 40 ---------- 6 files changed, 96 insertions(+), 128 deletions(-) delete mode 100644 backend/tests/tasks/post_submit_routing/test_failure_completion.py diff --git a/backend/tests/checkers/execution/completion_fixture.py b/backend/tests/checkers/execution/completion_fixture.py index 0f9b4b197..3d6d227d7 100644 --- a/backend/tests/checkers/execution/completion_fixture.py +++ b/backend/tests/checkers/execution/completion_fixture.py @@ -1,4 +1,4 @@ -"""Stored completion fixtures; controlled handlers prove classification, not input quality.""" +"""Stored selected completion fixtures with no routing or acceptance shortcut.""" import json from contextlib import asynccontextmanager @@ -7,71 +7,32 @@ from sqlalchemy import select, text from app.modules.checkers.api.execution import EvaluationCompletion -from app.modules.checkers.api.post_submit import PostSubmitCounter, PostSubmitMemberResult from app.modules.checkers.models import CheckerRun -from app.modules.checkers.post_submit_contracts import make_post_submit_result -from app.modules.checkers.runner import CheckerOutcome, CheckerRegistry, FunctionChecker, default_checker_registry from app.modules.outbox.models import OutboxEvent +from tests.checkers.external.support import post_registry_spec from tests.post_submit_materialization_helpers import material_fixture -from .support import live_executor, reserve -from .test_concurrency import final_facts - - -FAILURE_CHECKERS = { - "needs_revision": "check_submission_packet", - "task_setup_blocked": "check_policy_context_present", -} - - -def controlled_registry(recommendation): - """Keep canonical definitions; change only one selected handler's declared outcome.""" - canonical = default_checker_registry() - if recommendation == "allow_review": - return canonical - definition = canonical.resolve(FAILURE_CHECKERS[recommendation]).definition - - async def declared_failure(context): - return CheckerOutcome( - checker_name=definition.capability_id, status=definition.failure_status, - severity=definition.failure_severity, message="Controlled declared failure.", - ) - - registry = CheckerRegistry() - for item in canonical.definitions(): - checker = ( - FunctionChecker(item.capability_id, declared_failure) - if item.capability_id == definition.capability_id - else canonical.resolve(item.capability_id).checker - ) - registry.register(checker, definition=item) - return registry +from .support import ControlledSelectedExecution, live_executor, reserve @asynccontextmanager -async def completed_evidence(tmp_path, database_url, recommendation="needs_revision", *, counters=False, **options): - """Use real material, AUTH, finalization and publication; never insert a terminal row.""" - async with material_fixture(tmp_path, database_url, **options) as h: +async def completed_evidence(tmp_path, database_url, recommendation="needs_revision", **options): + """Use real selected material, AUTH, finalization and event publication.""" + if recommendation not in {"allow_review", "needs_revision"}: + raise ValueError("selected completion recommendation is unsupported") + failed = recommendation == "needs_revision" + async with material_fixture( + tmp_path, + database_url, + post_submit_registry_spec=post_registry_spec() if failed else None, + **options, + ) as h: await reserve(h) - executor = live_executor(h, registry=controlled_registry(recommendation)) - if counters: - lease, replay = await executor._claim(h.request) - assert replay is None - facts = await final_facts(h, lease) - definition = h.request.catalogue.definition(FAILURE_CHECKERS[recommendation], "v0.1") - member = PostSubmitMemberResult( - checker_id=definition.capability_id, implementation_version=definition.implementation_version, - status=definition.failure_status, code=definition.failure_code, - failure_category=definition.failure_category, severity=definition.failure_severity, - counters=(PostSubmitCounter(key="missing_count", value=2),), - ) - fields = facts.result.model_dump(exclude={"result_digest"}) - fields["member_results"] = tuple( - member if m.checker_id == member.checker_id else m for m in facts.result.member_results - ) - controlled = make_post_submit_result(**fields) - h.result = await executor.finalize(facts.model_copy(update={"result": controlled})) - else: - h.result = await executor.evaluate_post_submission(h.request) + h.result = await live_executor( + h, + selected_execution=ControlledSelectedExecution( + verdict="failed" if failed else "passed" + ), + ).evaluate_post_submission(h.request) async with h.factory() as session: h.run = await session.get(CheckerRun, str(h.result.attempt_id)) assert h.run.routing_recommendation == recommendation diff --git a/backend/tests/checkers/execution/support.py b/backend/tests/checkers/execution/support.py index d58699a75..6d485926a 100644 --- a/backend/tests/checkers/execution/support.py +++ b/backend/tests/checkers/execution/support.py @@ -8,6 +8,61 @@ from app.modules.actors.models import ActorProfile, ActorIdentityLink +class ControlledSelectedExecution: + """Return one request-bound selected result without replacing owner logic.""" + + def __init__(self, *, verdict="passed"): + self.verdict = verdict + self.requests = [] + + async def execute(self, request, grant): + from app.interfaces.external_checker_execution import ( + ExternalCheckerExecutionResponse, + ExternalCheckerIsolationReceipt, + ExternalCheckerMaterialGrant, + ) + from app.modules.checkers.api.external import ( + make_external_checker_execution_result, + ) + + assert type(grant) is ExternalCheckerMaterialGrant + self.requests.append(request) + findings = () if self.verdict == "passed" else ({ + "code": "post_evidence_failed", + "level": "error", + "message": "Post evidence failed.", + },) + result = make_external_checker_execution_result( + request_digest=request.request_digest, + registry_entry_id=request.registry.registry_entry_id, + registry_entry_digest=request.registry.entry_digest, + phase="post_submit", + outcome="completed", + verdict=self.verdict, + findings=findings, + infrastructure_failure_code=None, + ) + sha = "sha256:" + "a" * 64 + return ExternalCheckerExecutionResponse( + result=result, + isolation=ExternalCheckerIsolationReceipt( + repository="registry.example/workstream/checker", + platform_manifest_digest=request.registry.image_digest, + platform_manifest_media_type=( + "application/vnd.oci.image.manifest.v1+json" + ), + platform_manifest_byte_count=1024, + operating_system="linux", + architecture="amd64", + config_image_id=sha, + runtime="runsc", + isolation_mode="gvisor", + sandbox_uid=65532, + sandbox_gid=65532, + ), + ) + + class ForbiddenPostSubmission: async def evaluate_post_submission(self, request): pytest.fail("pre-submit-only test entered post-submit execution") @@ -62,7 +117,7 @@ def live_executor(h, *, outbox=None, selected_execution=None): materialization=h.service, execute_authority=post_submit_execution_authority, finalize_authority=post_submit_execution_authority, - selected_execution=selected_execution, + selected_execution=selected_execution or ControlledSelectedExecution(), outbox=outbox if outbox is not None else outbox_append, ) diff --git a/backend/tests/checkers/execution/test_completion_evidence.py b/backend/tests/checkers/execution/test_completion_evidence.py index 2d30ae4ab..1c754de3c 100644 --- a/backend/tests/checkers/execution/test_completion_evidence.py +++ b/backend/tests/checkers/execution/test_completion_evidence.py @@ -8,7 +8,7 @@ from app.adapters.checkers import evaluation_coordinator from app.core.identifiers import new_record_id from app.modules.checkers.api.execution import CheckerExecutionUnavailable, VerifiedMaterialFacts -from app.modules.checkers.api.post_submit import PostSubmissionEvaluationResult +from app.modules.checkers.api.evaluation_contract import validate_stored_execution_result from app.modules.checkers.models import CheckerSubmissionFence from tests.checkers.post_submit.support import change_request from .completion_fixture import completed_evidence, evidence_snapshot @@ -21,14 +21,14 @@ async def verify(session, h, *, completion=None, event_id=None): ) -@pytest.mark.parametrize("recommendation", ["allow_review", "needs_revision", "task_setup_blocked"]) +@pytest.mark.parametrize("recommendation", ["allow_review", "needs_revision"]) async def test_current_completion_returns_exact_stored_result(tmp_path, isolated_database_env, recommendation): async with completed_evidence(tmp_path, isolated_database_env, recommendation) as h: async with h.factory() as session: await session.begin() before = await evidence_snapshot(session) actual = await verify(session, h) - assert actual.result == h.result == PostSubmissionEvaluationResult.model_validate_json( + assert actual.result == h.result == validate_stored_execution_result( json.dumps(json.loads(h.run.result_json) | {"result_digest": h.run.result_digest}) ) assert actual.completion == h.completion @@ -44,26 +44,13 @@ async def test_current_completion_returns_exact_stored_result(tmp_path, isolated assert await evidence_snapshot(session) == before -async def test_current_completion_preserves_nonempty_stored_counters(tmp_path, isolated_database_env): - async with completed_evidence(tmp_path, isolated_database_env, counters=True) as h: - async with h.factory() as session, session.begin(): - actual = await verify(session, h) - stored = PostSubmissionEvaluationResult.model_validate_json( - json.dumps(json.loads(h.run.result_json) | {"result_digest": h.run.result_digest}) - ) - assert any(m.counters for m in stored.member_results), "fixture must discriminate dropped counters" - assert actual.result == stored == h.result - failed = next(m for m in actual.result.member_results if m.status == "failed") - assert [(c.key, c.value) for c in failed.counters] == [("missing_count", 2)] - - -@pytest.mark.parametrize("recommendation", ["allow_review", "needs_revision", "task_setup_blocked"]) +@pytest.mark.parametrize("recommendation", ["allow_review", "needs_revision"]) async def test_current_completion_rejects_wrong_derived_recommendation(tmp_path, isolated_database_env, recommendation): async with completed_evidence(tmp_path, isolated_database_env, recommendation) as h: async with h.factory() as session, session.begin(): await verify(session, h) before = await evidence_snapshot(session) - for wrong in {"allow_review", "needs_revision", "task_setup_blocked"} - {recommendation}: + for wrong in {"allow_review", "needs_revision"} - {recommendation}: altered = h.completion.model_copy(update={"routing_recommendation": wrong}) with pytest.raises(CheckerExecutionUnavailable, match="checker_current_completion_unavailable"): await verify(session, h, completion=altered) diff --git a/backend/tests/checkers/external/support.py b/backend/tests/checkers/external/support.py index cade082db..2897e3cba 100644 --- a/backend/tests/checkers/external/support.py +++ b/backend/tests/checkers/external/support.py @@ -70,6 +70,19 @@ def registry_spec( ) +def post_registry_spec() -> ExternalCheckerRegistrySpec: + """Return the exact selected POST schema used by native execution fixtures.""" + values = registry_spec("post_submit").model_dump(mode="json") + document = {"type": "object"} + values["input_schema"] = ExternalCheckerSchema( + schema_id=POST_SUBMIT_INPUT_SCHEMA_ID, + schema_version="v1", + document=document, + schema_sha256=external_checker_json_hash(document), + ).model_dump(mode="json") + return ExternalCheckerRegistrySpec.model_validate(values) + + def registry_entry( phase: str = "pre_submit", *, maximum_output_bytes: int = 32_768 ) -> ExternalCheckerRegistryEntry: diff --git a/backend/tests/checkers/external/test_selected_post_submit.py b/backend/tests/checkers/external/test_selected_post_submit.py index 2374417de..fc6e56644 100644 --- a/backend/tests/checkers/external/test_selected_post_submit.py +++ b/backend/tests/checkers/external/test_selected_post_submit.py @@ -47,8 +47,8 @@ SHA, execution_identity, execution_material, + post_registry_spec, registry_entry, - registry_spec, ) from tests.checkers.execution.support import live_executor, reserve from tests.post_submit_materialization_helpers import material_fixture @@ -97,15 +97,7 @@ def _policy() -> LockedExternalPostSubmitPolicy: def _post_spec() -> ExternalCheckerRegistrySpec: """Use the exact selected POST schema with the shared immutable registry facts.""" - values = registry_spec("post_submit").model_dump(mode="json") - document = {"type": "object"} - values["input_schema"] = ExternalCheckerSchema( - schema_id=POST_SUBMIT_INPUT_SCHEMA_ID, - schema_version="v1", - document=document, - schema_sha256=external_checker_json_hash(document), - ).model_dump(mode="json") - return ExternalCheckerRegistrySpec.model_validate(values) + return post_registry_spec() def _request(identity, policy): diff --git a/backend/tests/tasks/post_submit_routing/test_failure_completion.py b/backend/tests/tasks/post_submit_routing/test_failure_completion.py deleted file mode 100644 index 24c262d64..000000000 --- a/backend/tests/tasks/post_submit_routing/test_failure_completion.py +++ /dev/null @@ -1,40 +0,0 @@ -"""A verified checker failure still grants no success routing or acceptance authority.""" - -import pytest -from sqlalchemy import func, select, text - -from app.adapters.checkers import evaluation_coordinator -from app.adapters.tasks import evaluation_completion_handler, routing_source_preparer, task_post_submit_outcome -from app.modules.outbox.api import HandlerOutcome -from app.modules.tasks.post_submit_routing.models import TaskRoutingRequest, TaskPostSubmitRoutingManifest -from app.modules.tasks.post_submit_routing.requests import TaskRoutingRequests, TaskRoutingRequestUnavailable -from tests.checkers.execution.completion_fixture import completed_evidence, evidence_snapshot -from tests.checkers.execution.test_completion_evidence import verify -from .outcome_support import invoked_completion - - -@pytest.mark.parametrize("recommendation", ["task_setup_blocked"]) -async def test_stored_failure_cannot_enter_task_routing_or_completion_delivery(tmp_path, isolated_database_env, recommendation): - async with completed_evidence(tmp_path, isolated_database_env, recommendation) as h: - async with h.factory() as session, session.begin(): - await session.execute(text("UPDATE public.task_assignments SET accepted_at=clock_timestamp() WHERE id=:id"), - {"id": h.request.assignment_id}) - envelope = await invoked_completion(h) - async with h.factory() as session, session.begin(): - # The same actual stored failure is valid for CHECKERS observation. - assert (await verify(session, h)).completion.routing_recommendation == recommendation - before = await evidence_snapshot(session) - with pytest.raises(TaskRoutingRequestUnavailable, match="routing_request_unavailable"): - await TaskRoutingRequests(session, evaluation_coordinator(session)).stage( - h.source["completion_event_id"], h.completion, - ) - with pytest.raises(TaskRoutingRequestUnavailable, match="routing_request_unavailable"): - await routing_source_preparer(session).prepare(h.source["completion_event_id"], h.completion) - with pytest.raises(TaskRoutingRequestUnavailable, match="routing invocation unavailable"): - await task_post_submit_outcome(session, h.factory).apply(envelope, current_generation=None) - assert await evidence_snapshot(session) == before - assert await session.scalar(select(func.count()).select_from(TaskRoutingRequest)) == 0 - assert await session.scalar(select(func.count()).select_from(TaskPostSubmitRoutingManifest)) == 0 - assert await evaluation_completion_handler(sessions=h.factory)(envelope) is HandlerOutcome.REJECT - async with h.factory() as session: - assert await evidence_snapshot(session) == before From 0f0e706bb81724f58efcb933ac674147a9a424a6 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Sun, 11 Oct 2026 23:45:22 +0100 Subject: [PATCH 133/283] [PILOT-04] remove obsolete checker catalogues --- .ci/auth-boundaries/TEST_STRUCTURE_DEBT.json | 24 - .ci/behavior-ownership/partition.v1.json | 48 +- .../private-edge-debt.v1.json | 24 - .../pilot04-workstream-default-checker.md | 14 +- .../checkers/api/pre_submit_catalogue.py | 55 - backend/app/modules/checkers/catalogue.py | 730 -------- backend/app/modules/checkers/compiler.py | 649 ------- .../app/modules/checkers/effective_plan.py | 184 -- .../modules/checkers/post_submit_catalogue.py | 23 - .../checkers/post_submit_implementations.py | 155 -- .../modules/checkers/pre_submit_execution.py | 644 ------- backend/app/modules/checkers/runner.py | 844 --------- .../modules/projects/post_submit_policy.py | 216 --- backend/scripts/behavior_ownership.py | 37 +- backend/scripts/test_lane_catalogue.py | 25 - .../architecture/test_module_boundaries.py | 129 +- .../test_cross_owner_lock_order.py | 131 +- .../tests/checkers/execution/test_results.py | 99 -- .../checkers/post_submit/test_catalogue.py | 131 -- .../post_submit/test_compiled_policy.py | 171 -- .../checkers/post_submit/test_conformance.py | 255 --- .../checkers/test_effective_intake_rules.py | 74 - backend/tests/pre_submit_test_helpers.py | 322 ---- backend/tests/project_role_issue_fixtures.py | 78 + .../projects/post_policy/test_compiler.py | 93 - .../projects/post_policy/test_direct_sql.py | 176 -- .../projects/review_policy/test_activation.py | 52 - .../projects/test_activation_readiness.py | 281 --- .../submission_dispatch/test_concurrency.py | 8 +- .../tasks/test_contribution_claim_races.py | 8 +- backend/tests/test_approved_guide_intake.py | 277 --- backend/tests/test_behavior_ownership.py | 16 + ..._blocked_pre_submit_feedback_postgresql.py | 232 --- backend/tests/test_checker_catalogue.py | 686 -------- backend/tests/test_checkers.py | 1186 ------------- backend/tests/test_ci_lane_catalogue.py | 24 - .../test_default_pre_submit_execution.py | 1558 ----------------- .../test_effective_pre_submit_execution.py | 500 ------ ...re_submit_attempt_authority_integration.py | 154 -- .../test_pre_submit_attempt_contracts.py | 330 ---- .../test_pre_submit_attempt_lock_order.py | 334 ---- .../tests/test_pre_submit_attempt_recovery.py | 613 ------- .../tests/test_pre_submit_attempt_schema.py | 408 ----- .../test_pre_submit_related_lock_order.py | 369 ---- .../test_pre_submit_role_issue_lock_order.py | 330 ---- .../test_submission_evaluation_capacity.py | 157 -- .../test_submission_predecessor_custody.py | 2 - backend/tests/test_tasks.py | 77 - 48 files changed, 161 insertions(+), 12772 deletions(-) delete mode 100644 backend/app/modules/checkers/api/pre_submit_catalogue.py delete mode 100644 backend/app/modules/checkers/catalogue.py delete mode 100644 backend/app/modules/checkers/compiler.py delete mode 100644 backend/app/modules/checkers/effective_plan.py delete mode 100644 backend/app/modules/checkers/post_submit_catalogue.py delete mode 100644 backend/app/modules/checkers/post_submit_implementations.py delete mode 100644 backend/app/modules/checkers/pre_submit_execution.py delete mode 100644 backend/app/modules/checkers/runner.py delete mode 100644 backend/app/modules/projects/post_submit_policy.py delete mode 100644 backend/tests/checkers/execution/test_results.py delete mode 100644 backend/tests/checkers/post_submit/test_catalogue.py delete mode 100644 backend/tests/checkers/post_submit/test_compiled_policy.py delete mode 100644 backend/tests/checkers/post_submit/test_conformance.py delete mode 100644 backend/tests/checkers/test_effective_intake_rules.py delete mode 100644 backend/tests/pre_submit_test_helpers.py create mode 100644 backend/tests/project_role_issue_fixtures.py delete mode 100644 backend/tests/projects/post_policy/test_compiler.py delete mode 100644 backend/tests/projects/post_policy/test_direct_sql.py delete mode 100644 backend/tests/projects/review_policy/test_activation.py delete mode 100644 backend/tests/projects/test_activation_readiness.py delete mode 100644 backend/tests/test_approved_guide_intake.py delete mode 100644 backend/tests/test_blocked_pre_submit_feedback_postgresql.py delete mode 100644 backend/tests/test_checker_catalogue.py delete mode 100644 backend/tests/test_checkers.py delete mode 100644 backend/tests/test_default_pre_submit_execution.py delete mode 100644 backend/tests/test_effective_pre_submit_execution.py delete mode 100644 backend/tests/test_pre_submit_attempt_authority_integration.py delete mode 100644 backend/tests/test_pre_submit_attempt_contracts.py delete mode 100644 backend/tests/test_pre_submit_attempt_lock_order.py delete mode 100644 backend/tests/test_pre_submit_attempt_recovery.py delete mode 100644 backend/tests/test_pre_submit_attempt_schema.py delete mode 100644 backend/tests/test_pre_submit_related_lock_order.py delete mode 100644 backend/tests/test_pre_submit_role_issue_lock_order.py delete mode 100644 backend/tests/test_submission_evaluation_capacity.py diff --git a/.ci/auth-boundaries/TEST_STRUCTURE_DEBT.json b/.ci/auth-boundaries/TEST_STRUCTURE_DEBT.json index 5f944e184..d5c3da7cc 100644 --- a/.ci/auth-boundaries/TEST_STRUCTURE_DEBT.json +++ b/.ci/auth-boundaries/TEST_STRUCTURE_DEBT.json @@ -120,18 +120,6 @@ "removal_chunk": "WS-AUTH-003-CLOSE", "start_line": 1 }, - { - "capability": "oversized_authorization_structure", - "content_sha256": "5be930834a7b5694625231f2f3412f1dd0930f9ae754e7907c0063e4b13bc052", - "end_line": 1558, - "hard_limit": 1200, - "kind": "test_file", - "observed_lines": 1558, - "path": "backend/tests/test_default_pre_submit_execution.py", - "qualified_symbol": null, - "removal_chunk": "WS-AUTH-003-CLOSE", - "start_line": 1 - }, { "capability": "oversized_authorization_structure", "content_sha256": "f3098d904831d566b1fef38c6d8bda4d17765958ed899f8c6b219afa12cc6c0c", @@ -396,18 +384,6 @@ "removal_chunk": "WS-AUTH-003-CLOSE", "start_line": 10047 }, - { - "capability": "oversized_authorization_structure", - "content_sha256": "c8f454738457615f8e183744c677e8384ef01c27f5dac2b352caf84f4c77b2d1", - "end_line": 928, - "hard_limit": 120, - "kind": "test_function", - "observed_lines": 487, - "path": "backend/tests/test_default_pre_submit_execution.py", - "qualified_symbol": "test_effective_evidence_workflow_persists_once_and_replays_exactly", - "removal_chunk": "WS-AUTH-003-CLOSE", - "start_line": 442 - }, { "capability": "oversized_authorization_structure", "content_sha256": "26170dfbd986d2930d7f89357d59cdd17ae50b2ac1b936a3966e24225312e895", diff --git a/.ci/behavior-ownership/partition.v1.json b/.ci/behavior-ownership/partition.v1.json index 0e84afed7..f851ad5bf 100644 --- a/.ci/behavior-ownership/partition.v1.json +++ b/.ci/behavior-ownership/partition.v1.json @@ -924,6 +924,10 @@ "group": "artifacts", "target": "backend/app/modules/checkers/api/external_policy.py" }, + { + "group": "artifacts", + "target": "backend/app/modules/checkers/api/historical_post_submit.py" + }, { "group": "artifacts", "target": "backend/app/modules/checkers/api/history.py" @@ -946,20 +950,16 @@ }, { "group": "artifacts", - "target": "backend/app/modules/checkers/api/post_submit.py" + "target": "backend/app/modules/checkers/api/policy_custody.py" }, { "group": "artifacts", - "target": "backend/app/modules/checkers/api/post_submit_catalogue.py" + "target": "backend/app/modules/checkers/api/post_submit.py" }, { "group": "artifacts", "target": "backend/app/modules/checkers/api/pre_submit.py" }, - { - "group": "artifacts", - "target": "backend/app/modules/checkers/api/pre_submit_catalogue.py" - }, { "group": "artifacts", "target": "backend/app/modules/checkers/api/selected_post_submit.py" @@ -968,14 +968,6 @@ "group": "artifacts", "target": "backend/app/modules/checkers/api/selected_pre_submit.py" }, - { - "group": "artifacts", - "target": "backend/app/modules/checkers/catalogue.py" - }, - { - "group": "artifacts", - "target": "backend/app/modules/checkers/compiler.py" - }, { "group": "artifacts", "target": "backend/app/modules/checkers/default_checker.py" @@ -984,10 +976,6 @@ "group": "artifacts", "target": "backend/app/modules/checkers/delivery_authority.py" }, - { - "group": "artifacts", - "target": "backend/app/modules/checkers/effective_plan.py" - }, { "group": "artifacts", "target": "backend/app/modules/checkers/execution.py" @@ -1016,34 +1004,18 @@ "group": "artifacts", "target": "backend/app/modules/checkers/models.py" }, - { - "group": "artifacts", - "target": "backend/app/modules/checkers/post_submit_catalogue.py" - }, { "group": "artifacts", "target": "backend/app/modules/checkers/post_submit_contracts.py" }, - { - "group": "artifacts", - "target": "backend/app/modules/checkers/post_submit_implementations.py" - }, { "group": "artifacts", "target": "backend/app/modules/checkers/pre_submit_defaults.py" }, - { - "group": "artifacts", - "target": "backend/app/modules/checkers/pre_submit_execution.py" - }, { "group": "artifacts", "target": "backend/app/modules/checkers/router.py" }, - { - "group": "artifacts", - "target": "backend/app/modules/checkers/runner.py" - }, { "group": "artifacts", "target": "backend/app/modules/checkers/selected_post_submit_execution.py" @@ -1520,10 +1492,6 @@ "group": "lifecycle", "target": "backend/app/modules/projects/post_policy/service.py" }, - { - "group": "lifecycle", - "target": "backend/app/modules/projects/post_submit_policy.py" - }, { "group": "lifecycle", "target": "backend/app/modules/projects/repository.py" @@ -1981,7 +1949,7 @@ "target": "backend/scripts/validate_test_lane_evidence.py" } ], - "authority_digest": "54f17769f0826105e68a14fbd9d142336749d95685b8f523a23ce7086806b34d", - "protected_base_commit": "e31e1777c47b794b1d4d8240192608e4fff4f536", + "authority_digest": "680cffbc4aab0f6abde3520ac34fe36f4d581cba475e5b6316f6b90ccf7731de", + "protected_base_commit": "7676ce4347db0c9694962a9b587a20765e16eac6", "schema": "workstream.behavior-ownership-partition.v1" } diff --git a/.ci/module-boundaries/private-edge-debt.v1.json b/.ci/module-boundaries/private-edge-debt.v1.json index 9a47e2df4..b91f8e28b 100644 --- a/.ci/module-boundaries/private-edge-debt.v1.json +++ b/.ci/module-boundaries/private-edge-debt.v1.json @@ -163,12 +163,6 @@ "imported_private_path": "app.modules.artifacts.service", "repair_owner": "WS-ARCH-001-04" }, - { - "source_file": "backend/app/main.py", - "target_module": "checkers", - "imported_private_path": "app.modules.checkers.catalogue", - "repair_owner": "WS-ARCH-001-04" - }, { "source_file": "backend/app/modules/actors/service.py", "target_module": "audit", @@ -241,24 +235,6 @@ "imported_private_path": "app.modules.tasks.models", "repair_owner": "WS-ARCH-001-03" }, - { - "source_file": "backend/app/modules/checkers/pre_submit_execution.py", - "target_module": "artifacts", - "imported_private_path": "app.modules.artifacts.sources", - "repair_owner": "WS-ARCH-001-04" - }, - { - "source_file": "backend/app/modules/checkers/pre_submit_execution.py", - "target_module": "artifacts", - "imported_private_path": "app.modules.artifacts.submission_archive", - "repair_owner": "WS-ARCH-001-04" - }, - { - "source_file": "backend/app/modules/checkers/pre_submit_execution.py", - "target_module": "artifacts", - "imported_private_path": "app.modules.artifacts.submission_manifest", - "repair_owner": "WS-ARCH-001-04" - }, { "source_file": "backend/app/modules/projects/create_router.py", "target_module": "actors", diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index de230b14e..d28613ea8 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -59,9 +59,12 @@ request handler alongside assignment invalidation, leases worker-owned ART material only during execution, and creates the configured Rust adapter only for a selected request. New TASK submission composition now requires selected POST custody and refuses an unresolved legacy admission instead of executing -it; retained legacy envelopes remain read-only decoding inputs. Native SQL -custody and the live worker journey remain unfinished. -Production still uses the older pre/post catalogues. +it; retained legacy envelopes remain read-only decoding inputs. Admission, +routing completion and remediation fixtures now exercise the selected PRE/POST +owners. Both obsolete executable catalogues and their isolated callers and +tests have been removed; retained immutable evidence has only its bounded +historical decoder. F-020 recovery and the combined public/native journey remain +unfinished. ## Bounded change @@ -190,7 +193,7 @@ intermediate-wait regression. - [ ] Retained old evidence remains readable without rewriting hashes; unresolved old execution cannot cross into the new runtime and requires authorized policy transition. -- [ ] Both obsolete catalogues, implementations, callers and obsolete tests are +- [x] Both obsolete catalogues, implementations, callers and obsolete tests are removed without a fallback or parallel runtime. - [ ] A real PostgreSQL 16, MinIO and Rust-service journey proves pass, work failure, infrastructure/retry and post-dispatch paths with cleanup. @@ -230,8 +233,9 @@ intermediate-wait regression. | Actual selected PRE Rust service | `PYTHONPATH=.:backend /tmp/workstream-pilot-review-locked-env/bin/python experiments/pilot04_external_checker_runtime/run_selected_pre_probe.py --image-reference localhost:35104/ws-pilot04-checker@sha256:c664d8d85d6dfcded31710223c8d91441548e5445f0aa9b59d246fc464a129ef --service-binary external_checkers/target/debug/workstream-checker-service`; Ruff and `py_compile` | PASS. Genuine prepared ART bytes and the server-computed manifest enter the selected default-plus-project-image processor before any Submission exists. The callback-scoped grant launches the exact digest-pinned image through the Rust service in explicit local `runc`/`docker-dev` mode, returns matching result/isolation custody, and confirms the workspace is empty after the callback. | This is the actual selected PRE execution boundary, not the final PostgreSQL/MinIO admission-to-dispatch journey or a hosted `runsc` claim. | | Production delivery registration and owner boundaries | `pytest -q backend/tests/architecture/test_module_boundaries.py backend/tests/test_artifact_architecture.py backend/tests/outbox/test_contracts.py`; focused Ruff and a direct registry construction probe | 116 passed; the existing production outbox registry exposes assignment invalidation and evaluation request handlers, selected Rust configuration is lazy, and PRE coordination stays behind CHECKERS' public adapter root | Database-backed legacy/selected delivery and worker restart proofs remain pending | | New Submission selected-only boundary | `pytest -q backend/tests/test_submission_bundle_admission.py backend/tests/checkers/external/test_selected_post_submit.py backend/tests/test_artifact_architecture.py::test_checker_custody_ports_have_exact_owner_and_art_consumers`; focused Ruff | 59 passed; retained legacy and selected admission projections are mutually exclusive, and the TASK writer accepts only selected POST custody for a new immutable Submission | Native rollback proof for a retained unresolved legacy admission remains pending | +| Obsolete catalogue removal | Focused lane/architecture/ownership suite; recursive collection of every modified surviving test module; Ruff, module-boundary inventory and stale-import scan | 84 focused tests passed and 94 surviving tests collected. Ten obsolete executable catalogue/runner targets, their private-edge debt and tests are absent; exact ownership metadata admits only the selected owners and those retirements. | The stacked branch still has separately tracked structural-debt growth from earlier P02/P10/P04 source, so the repository-wide structural-debt gate is not claimed by this deletion checkpoint. | | Retained admission migration shape | `pytest -q backend/tests/test_submission_bundle_admission.py backend/tests/checkers/external/test_selected_pre_submit_coordination.py backend/tests/checkers/external/test_selected_preparation_command.py backend/tests/test_artifact_architecture.py::test_checker_materialization_contract_has_one_canonical_consumer_owner`; focused Ruff | 62 passed; selected rows require complete new custody while every new column stays null on retained legacy rows, avoiding fabricated backfill or historical hash rewrites | Successor SQL and direct retained/selected row controls remain pending | -| Owner/caller trace | PROJECT approval/activation, ART preparation/admission, TASK composition and CHECKERS dispatch | Selected PRE uses durable reserve/lease/finalize roots around the genuine ART callback; a pass is consumed only by TASK's existing atomic Submission/evaluation reservation/outbox composition, while POST uses immutable Submission/ART custody | Final F-020 recovery, retained-history transition, catalogue deletion and combined native journey remain pending | +| Owner/caller trace | PROJECT approval/activation, ART preparation/admission, TASK composition and CHECKERS dispatch | Selected PRE uses durable reserve/lease/finalize roots around the genuine ART callback; a pass is consumed only by TASK's existing atomic Submission/evaluation reservation/outbox composition, while POST uses immutable Submission/ART custody | Final F-020 recovery, retained-history transition and combined native journey remain pending | | End-to-end replacement | Real PostgreSQL/MinIO/Rust public and worker journey | Not run | Implementation incomplete | ## Reconciliation diff --git a/backend/app/modules/checkers/api/pre_submit_catalogue.py b/backend/app/modules/checkers/api/pre_submit_catalogue.py deleted file mode 100644 index 00a7a4324..000000000 --- a/backend/app/modules/checkers/api/pre_submit_catalogue.py +++ /dev/null @@ -1,55 +0,0 @@ -"""Public immutable pre-submission capability projection owned by CHECKERS.""" - -from __future__ import annotations - -from typing import Literal - -from pydantic import BaseModel, ConfigDict, Field, StrictInt - - -class ResourceBudget(BaseModel): - """Frozen canonical ART resource budget.""" - - model_config = ConfigDict(extra="forbid", frozen=True) - - maximum_results: StrictInt = Field(ge=1) - - -class PreSubmissionCapabilityDefinition(BaseModel): - """Exact read-only projection of one ART catalogue definition.""" - - model_config = ConfigDict(extra="forbid", frozen=True) - - stable_id: str - version: str - public_name: str - owner: str - phase: str - order: int = Field(ge=0) - dependencies: tuple[str, ...] - classification: str - typed_inputs: tuple[str, ...] - result_schema: str - failure_code: str - resource_budget: ResourceBudget - state: Literal["enabled", "disabled"] - disabled_behavior: str - policy_trace_source: str - dispatch_kind: Literal["platform_capability", "policy_primitive"] - dispatch_capability: str - primitive: str | None = None - policy_fields: tuple[str, ...] = () - selectable: bool - - -class PreSubmissionCapabilityProjection(BaseModel): - """Complete immutable ART catalogue plus model-facing selectability.""" - - model_config = ConfigDict(extra="forbid", frozen=True) - - catalogue_id: Literal["workstream.pre_submission_checkers"] - version: Literal["v0.1"] - schema_version: Literal["pre_submission_checker_catalogue.v1"] - manifest_sha256: str = Field(pattern=r"^sha256:[0-9a-f]{64}$") - available: bool - definitions: tuple[PreSubmissionCapabilityDefinition, ...] diff --git a/backend/app/modules/checkers/catalogue.py b/backend/app/modules/checkers/catalogue.py deleted file mode 100644 index fac8b96dd..000000000 --- a/backend/app/modules/checkers/catalogue.py +++ /dev/null @@ -1,730 +0,0 @@ -"""Single immutable catalogue for pre-submission checker planning.""" - -from __future__ import annotations - -from dataclasses import dataclass, replace -from enum import StrEnum -from types import MappingProxyType -from typing import Any, Mapping - -from app.modules.checkers.api.pre_submit_catalogue import ( - PreSubmissionCapabilityDefinition, PreSubmissionCapabilityProjection, -) -from app.core.hashing import canonical_json_hash -from app.modules.checkers.api.policy_compilation import CompiledPreSubmitCheckerPolicy -from app.modules.checkers.api import ( - EffectivePreSubmissionExecutionPlan, - EffectivePreSubmissionPlanLineage, -) - - -PRE_SUBMISSION_CATALOGUE_ID = "workstream.pre_submission_checkers" -PRE_SUBMISSION_CATALOGUE_VERSION = "v0.1" -PRE_SUBMISSION_CATALOGUE_SCHEMA_VERSION = "pre_submission_checker_catalogue.v1" -PRE_SUBMISSION_RESULT_SCHEMA_VERSION = "pre_submission_checker_result.v1" - - -class PreSubmissionCatalogueError(ValueError): - """Reject an invalid or ambiguous catalogue configuration.""" - - -class PreSubmissionCheckerClassification(StrEnum): - """Closed operational classification for one catalogue definition.""" - - MANDATORY_SECURITY = "mandatory_security" - MANDATORY_INTEGRITY = "mandatory_integrity" - MANDATORY_ACCOUNTABILITY = "mandatory_accountability" - ADVISORY = "advisory" - - @property - def mandatory(self) -> bool: - """Return whether disabling this definition makes intake unavailable.""" - return self is not PreSubmissionCheckerClassification.ADVISORY - - -class PreSubmissionCheckerPhase(StrEnum): - """Canonical execution-plan phases.""" - - CUSTODY = "custody" - IDENTITY = "identity" - MATERIALIZATION = "materialization" - DEFAULT_POLICY = "default_policy" - PROJECT_POLICY = "project_policy" - - -_PHASE_ORDER = {phase: index for index, phase in enumerate(PreSubmissionCheckerPhase)} - - -def pre_submission_phase_order(phase: PreSubmissionCheckerPhase) -> int: - """Return the canonical ordinal for one pre-submission phase.""" - return _PHASE_ORDER[phase] - - -class PreSubmissionCheckerState(StrEnum): - ENABLED = "enabled" - DISABLED = "disabled" - - -class PreSubmissionDisabledBehavior(StrEnum): - INFRASTRUCTURE_UNAVAILABLE = "infrastructure_unavailable" - RECORD_DISABLED_AND_CONTINUE = "record_disabled_and_continue" - - -class PreSubmissionDispatchKind(StrEnum): - PLATFORM_CAPABILITY = "platform_capability" - POLICY_PRIMITIVE = "policy_primitive" - - -class PreSubmissionPlatformCapability(StrEnum): - OUTER_ZIP_VALID = "submission_archive.outer_zip_valid" - PATHS_SAFE = "submission_archive.paths_safe" - ENTRIES_SAFE = "submission_archive.entries_safe" - RESOURCES_BOUNDED = "submission_archive.resources_bounded" - INTEGRITY_VERIFIED = "submission_archive.integrity_verified" - ARCHIVE_IDENTITY = "artifact_commitment.identity" - MANIFEST_IDENTITY = "submission_manifest.semantic_identity" - EXECUTABLE_NORMALIZED = "submission_manifest.executable_normalized" - CONTENT_CHANGED = "submission_change.changed" - SEALED_TREE_VERIFIED = "submission_materialization.sealed_tree_verified" - SUBMISSION_PACKET = "validate_submission_packet" - ATTESTATION = "require_attestation" - SENSITIVE_PATH = "forbid_high_confidence_sensitive_path" - QUALITY_WARNING = "warn_low_quality_generated_artifact" - - -class PreSubmissionPolicyPrimitive(StrEnum): - FORBID_ARTIFACT = "forbid_artifact" - LIMIT_FILE_SIZE = "limit_file_size" - LIMIT_PACKAGE_SIZE = "limit_package_size" - LIMIT_ARCHIVE_ENTRIES = "limit_archive_entries" - LIMIT_ARCHIVE_SIZE = "limit_archive_size" - ENFORCE_STORAGE_SCHEME = "enforce_storage_scheme" - VERIFY_HASH = "verify_hash" - REQUIRE_ATTESTATION = "require_attestation" - REQUIRE_PACKAGING = "require_packaging" - REQUIRE_FILE = "require_file" - REQUIRE_MINIMUM_EVIDENCE = "require_minimum_evidence" - REQUIRE_MANIFEST_FIELD = "require_manifest_field" - VALIDATE_SUBMISSION_PACKET = "validate_submission_packet" - WARN_LOW_QUALITY_GENERATED_ARTIFACT = "warn_low_quality_generated_artifact" - - -@dataclass(frozen=True, slots=True) -class PreSubmissionCheckerDefinition: - """One closed typed definition in the process-wide catalogue.""" - - stable_id: str - version: str - public_name: str - owner: str - phase: PreSubmissionCheckerPhase - order: int - dependencies: tuple[str, ...] - classification: PreSubmissionCheckerClassification - typed_inputs: tuple[str, ...] - result_schema: str - failure_code: str - resource_budget: tuple[tuple[str, int], ...] - state: PreSubmissionCheckerState - disabled_behavior: PreSubmissionDisabledBehavior - policy_trace_source: str - dispatch_kind: PreSubmissionDispatchKind - dispatch_capability: str - primitive: str | None = None - policy_fields: tuple[str, ...] = () - - def __post_init__(self) -> None: - values = ( - self.stable_id, - self.version, - self.public_name, - self.owner, - self.result_schema, - self.failure_code, - self.policy_trace_source, - self.dispatch_capability, - ) - if any(type(value) is not str or not value for value in values): - raise PreSubmissionCatalogueError("catalogue definition identity is invalid") - if type(self.order) is not int or self.order < 0: - raise PreSubmissionCatalogueError("catalogue definition order is invalid") - if len(self.dependencies) != len(set(self.dependencies)): - raise PreSubmissionCatalogueError("catalogue definition has duplicate dependencies") - if len(self.typed_inputs) != len(set(self.typed_inputs)) or not self.typed_inputs: - raise PreSubmissionCatalogueError("catalogue definition typed inputs are invalid") - if tuple(sorted(self.resource_budget)) != self.resource_budget or any( - type(key) is not str or not key or type(value) is not int or value < 0 - for key, value in self.resource_budget - ): - raise PreSubmissionCatalogueError("catalogue definition resource budget is invalid") - if self.classification.mandatory: - if ( - self.disabled_behavior - is not PreSubmissionDisabledBehavior.INFRASTRUCTURE_UNAVAILABLE - ): - raise PreSubmissionCatalogueError("mandatory catalogue definition may not skip") - elif ( - self.disabled_behavior is not PreSubmissionDisabledBehavior.RECORD_DISABLED_AND_CONTINUE - ): - raise PreSubmissionCatalogueError("advisory catalogue definition may not block startup") - if self.dispatch_kind is PreSubmissionDispatchKind.POLICY_PRIMITIVE: - if not self.primitive or not self.policy_fields: - raise PreSubmissionCatalogueError("policy catalogue definition is incomplete") - if ( - self.primitive not in set(PreSubmissionPolicyPrimitive) - or self.dispatch_capability != self.primitive - ): - raise PreSubmissionCatalogueError("policy catalogue primitive is unknown") - elif self.primitive is not None or self.policy_fields: - raise PreSubmissionCatalogueError( - "platform capability may not masquerade as a primitive" - ) - elif self.dispatch_capability not in set(PreSubmissionPlatformCapability): - raise PreSubmissionCatalogueError("platform catalogue capability is unknown") - - def manifest_entry(self) -> dict[str, Any]: - """Return the canonical immutable catalogue projection.""" - return { - "stable_id": self.stable_id, - "version": self.version, - "public_name": self.public_name, - "owner": self.owner, - "phase": self.phase.value, - "order": self.order, - "dependencies": list(self.dependencies), - "classification": self.classification.value, - "typed_inputs": list(self.typed_inputs), - "result_schema": self.result_schema, - "failure_code": self.failure_code, - "resource_budget": dict(self.resource_budget), - "state": self.state.value, - "disabled_behavior": self.disabled_behavior.value, - "policy_trace_source": self.policy_trace_source, - "dispatch_kind": self.dispatch_kind.value, - "dispatch_capability": self.dispatch_capability, - "primitive": self.primitive, - "policy_fields": list(self.policy_fields), - } - - -@dataclass(frozen=True, slots=True) -class PreSubmissionCheckerCatalogue: - """Validated process-wide catalogue and its canonical identity.""" - - catalogue_id: str - version: str - schema_version: str - entries: tuple[PreSubmissionCheckerDefinition, ...] - - def __post_init__(self) -> None: - if ( - self.catalogue_id != PRE_SUBMISSION_CATALOGUE_ID - or self.version != PRE_SUBMISSION_CATALOGUE_VERSION - or self.schema_version != PRE_SUBMISSION_CATALOGUE_SCHEMA_VERSION - ): - raise PreSubmissionCatalogueError("catalogue envelope is invalid") - if not self.entries: - raise PreSubmissionCatalogueError("catalogue requires definitions") - stable_ids = [entry.stable_id for entry in self.entries] - if len(stable_ids) != len(set(stable_ids)): - raise PreSubmissionCatalogueError("catalogue contains duplicate stable IDs") - primitives = [entry.primitive for entry in self.entries if entry.primitive is not None] - if len(primitives) != len(set(primitives)): - raise PreSubmissionCatalogueError("catalogue contains duplicate primitives") - expected_order = tuple(sorted(self.entries, key=_definition_sort_key)) - if self.entries != expected_order: - raise PreSubmissionCatalogueError("catalogue definitions are not canonical") - self._validate_dependencies() - - def _validate_dependencies(self) -> None: - by_id = {entry.stable_id: entry for entry in self.entries} - for entry in self.entries: - for dependency_id in entry.dependencies: - dependency = by_id.get(dependency_id) - if dependency is None: - raise PreSubmissionCatalogueError("catalogue dependency is missing") - if _PHASE_ORDER[dependency.phase] > _PHASE_ORDER[entry.phase]: - raise PreSubmissionCatalogueError("catalogue dependency phase is invalid") - if dependency.phase is entry.phase and dependency.order >= entry.order: - raise PreSubmissionCatalogueError("catalogue dependency order is invalid") - visiting: set[str] = set() - visited: set[str] = set() - - def visit(stable_id: str) -> None: - if stable_id in visiting: - raise PreSubmissionCatalogueError("catalogue dependency cycle detected") - if stable_id in visited: - return - visiting.add(stable_id) - for dependency_id in by_id[stable_id].dependencies: - visit(dependency_id) - visiting.remove(stable_id) - visited.add(stable_id) - - for entry in self.entries: - visit(entry.stable_id) - - @property - def manifest(self) -> Mapping[str, Any]: - """Return an immutable top-level manifest projection.""" - return MappingProxyType( - { - "catalogue_id": self.catalogue_id, - "version": self.version, - "schema_version": self.schema_version, - "entries": [entry.manifest_entry() for entry in self.entries], - } - ) - - @property - def manifest_sha256(self) -> str: - return canonical_json_hash(dict(self.manifest)) - - @property - def available(self) -> bool: - return not any( - entry.classification.mandatory and entry.state is PreSubmissionCheckerState.DISABLED - for entry in self.entries - ) - - def definition(self, stable_id: str) -> PreSubmissionCheckerDefinition: - for entry in self.entries: - if entry.stable_id == stable_id: - return entry - raise PreSubmissionCatalogueError("catalogue definition is unknown") - - def primitive_definition(self, primitive: str) -> PreSubmissionCheckerDefinition: - for entry in self.entries: - if entry.primitive == primitive: - return entry - raise PreSubmissionCatalogueError("catalogue primitive is unknown") - - def compile_policy_bundle( - self, *, effective_policy: Mapping[str, object], effective_policy_hash: str, - ) -> CompiledPreSubmitCheckerPolicy: - """Implement the public policy compiler capability through its sole owner.""" - from app.modules.checkers.compiler import compile_effective_project_submission_artifact_policy - - return compile_effective_project_submission_artifact_policy( - dict(effective_policy), effective_policy_hash, - ) - - def compile_effective_plan( - self, - *, - lineage: EffectivePreSubmissionPlanLineage, - effective_policy: Mapping[str, object], - compiled_bundle: Mapping[str, object], - ) -> EffectivePreSubmissionExecutionPlan: - """Implement the public deterministic CHECKER planning capability.""" - from app.modules.checkers.effective_plan import ( - compile_effective_pre_submission_execution_plan, - ) - - return compile_effective_pre_submission_execution_plan( - lineage=lineage, - effective_policy=dict(effective_policy), - compiled_bundle=dict(compiled_bundle), - catalogue=self, - ) - - -def build_pre_submission_checker_catalogue( - *, disabled_entry_ids: frozenset[str] = frozenset() -) -> PreSubmissionCheckerCatalogue: - """Build the sole catalogue with startup-fixed availability state.""" - definitions = _default_definitions() - known = {definition.stable_id for definition in definitions} - if not disabled_entry_ids.issubset(known): - raise PreSubmissionCatalogueError("disabled catalogue definition is unknown") - entries = tuple( - replace(definition, state=PreSubmissionCheckerState.DISABLED) - if definition.stable_id in disabled_entry_ids - else definition - for definition in definitions - ) - return PreSubmissionCheckerCatalogue( - PRE_SUBMISSION_CATALOGUE_ID, - PRE_SUBMISSION_CATALOGUE_VERSION, - PRE_SUBMISSION_CATALOGUE_SCHEMA_VERSION, - tuple(sorted(entries, key=_definition_sort_key)), - ) - - -def parse_disabled_pre_submission_checker_ids(raw: str) -> frozenset[str]: - """Parse one startup-owned comma-separated disabled-definition set.""" - if type(raw) is not str: - raise PreSubmissionCatalogueError("disabled catalogue configuration is invalid") - parts = [part.strip() for part in raw.split(",") if part.strip()] - if len(parts) != len(set(parts)): - raise PreSubmissionCatalogueError("disabled catalogue configuration has duplicates") - return frozenset(parts) - - -def _definition_sort_key(entry: PreSubmissionCheckerDefinition) -> tuple[int, int, str]: - return (_PHASE_ORDER[entry.phase], entry.order, entry.stable_id) - - -def _platform( - stable_id: str, - *, - phase: PreSubmissionCheckerPhase, - order: int, - classification: PreSubmissionCheckerClassification, - input_name: str, - capability: str, - failure_code: str, - dependencies: tuple[str, ...] = (), - public_name: str | None = None, -) -> PreSubmissionCheckerDefinition: - return PreSubmissionCheckerDefinition( - stable_id=stable_id, - version="v1", - public_name=public_name or stable_id, - owner="workstream.artifact", - phase=phase, - order=order, - dependencies=dependencies, - classification=classification, - typed_inputs=(input_name,), - result_schema=PRE_SUBMISSION_RESULT_SCHEMA_VERSION, - failure_code=failure_code, - resource_budget=(("maximum_results", 1),), - state=PreSubmissionCheckerState.ENABLED, - disabled_behavior=( - PreSubmissionDisabledBehavior.RECORD_DISABLED_AND_CONTINUE - if classification is PreSubmissionCheckerClassification.ADVISORY - else PreSubmissionDisabledBehavior.INFRASTRUCTURE_UNAVAILABLE - ), - policy_trace_source="workstream_default_policy", - dispatch_kind=PreSubmissionDispatchKind.PLATFORM_CAPABILITY, - dispatch_capability=capability, - ) - - -def _policy( - stable_id: str, - primitive: str, - public_name: str, - policy_fields: tuple[str, ...], - *, - order: int, - classification: PreSubmissionCheckerClassification = PreSubmissionCheckerClassification.MANDATORY_ACCOUNTABILITY, - typed_inputs: tuple[str, ...] = ("LockedProjectCheckerRule", "SubmissionManifestView"), -) -> PreSubmissionCheckerDefinition: - return PreSubmissionCheckerDefinition( - stable_id=stable_id, - version="v1", - public_name=public_name, - owner="workstream.checker_policy", - phase=PreSubmissionCheckerPhase.PROJECT_POLICY, - order=order, - dependencies=("artifact.scratch.sealed_tree_verified",), - classification=classification, - typed_inputs=typed_inputs, - result_schema=PRE_SUBMISSION_RESULT_SCHEMA_VERSION, - failure_code="pre_submission_checker_failed", - resource_budget=(("maximum_results", 1),), - state=PreSubmissionCheckerState.ENABLED, - disabled_behavior=( - PreSubmissionDisabledBehavior.RECORD_DISABLED_AND_CONTINUE - if classification is PreSubmissionCheckerClassification.ADVISORY - else PreSubmissionDisabledBehavior.INFRASTRUCTURE_UNAVAILABLE - ), - policy_trace_source="locked_effective_project_submission_artifact_policy", - dispatch_kind=PreSubmissionDispatchKind.POLICY_PRIMITIVE, - dispatch_capability=primitive, - primitive=primitive, - policy_fields=tuple(sorted(policy_fields)), - ) - - -def _default_definitions() -> tuple[PreSubmissionCheckerDefinition, ...]: - security = PreSubmissionCheckerClassification.MANDATORY_SECURITY - integrity = PreSubmissionCheckerClassification.MANDATORY_INTEGRITY - accountability = PreSubmissionCheckerClassification.MANDATORY_ACCOUNTABILITY - advisory = PreSubmissionCheckerClassification.ADVISORY - custody = PreSubmissionCheckerPhase.CUSTODY - identity = PreSubmissionCheckerPhase.IDENTITY - materialization = PreSubmissionCheckerPhase.MATERIALIZATION - defaults = PreSubmissionCheckerPhase.DEFAULT_POLICY - definitions = ( - _platform( - "artifact.outer_zip.valid", - phase=custody, - order=10, - classification=security, - input_name="SubmissionArchiveInspectionResult", - capability="submission_archive.outer_zip_valid", - failure_code="submission_archive_malformed", - ), - _platform( - "artifact.archive.paths_safe", - phase=custody, - order=20, - classification=security, - input_name="SubmissionArchiveInspectionResult", - capability="submission_archive.paths_safe", - failure_code="submission_archive_unsafe_entry", - dependencies=("artifact.outer_zip.valid",), - ), - _platform( - "artifact.archive.entries_safe", - public_name="Reject encrypted ZIP entries, symbolic links and special files", - phase=custody, - order=30, - classification=security, - input_name="SubmissionArchiveInspectionResult", - capability="submission_archive.entries_safe", - failure_code="submission_archive_unsafe_entry", - dependencies=("artifact.archive.paths_safe",), - ), - _platform( - "artifact.archive.resources_bounded", - phase=custody, - order=40, - classification=security, - input_name="SubmissionArchiveInspectionResult", - capability="submission_archive.resources_bounded", - failure_code="submission_archive_limit_exceeded", - dependencies=("artifact.archive.entries_safe",), - ), - _platform( - "artifact.archive.integrity_verified", - phase=custody, - order=50, - classification=integrity, - input_name="SubmissionArchiveInspectionResult", - capability="submission_archive.integrity_verified", - failure_code="submission_archive_integrity_failure", - dependencies=("artifact.archive.resources_bounded",), - ), - _platform( - "artifact.archive.identity_computed", - phase=identity, - order=10, - classification=integrity, - input_name="ArtifactCommitment", - capability="artifact_commitment.identity", - failure_code="submission_archive_identity_unavailable", - dependencies=("artifact.archive.integrity_verified",), - ), - _platform( - "artifact.manifest.semantic_identity_computed", - phase=identity, - order=20, - classification=integrity, - input_name="SubmissionManifest", - capability="submission_manifest.semantic_identity", - failure_code="submission_manifest_identity_unavailable", - dependencies=("artifact.archive.identity_computed",), - ), - _platform( - "artifact.manifest.executable_normalized", - phase=identity, - order=30, - classification=integrity, - input_name="SubmissionManifest", - capability="submission_manifest.executable_normalized", - failure_code="submission_manifest_executable_invalid", - dependencies=("artifact.manifest.semantic_identity_computed",), - ), - _platform( - "artifact.revision.content_changed", - phase=identity, - order=40, - classification=integrity, - input_name="SubmissionChangeGateResult", - capability="submission_change.changed", - failure_code="submission_manifest_unchanged", - dependencies=("artifact.manifest.executable_normalized",), - ), - _platform( - "artifact.scratch.sealed_tree_verified", - phase=materialization, - order=10, - classification=integrity, - input_name="SealedSubmissionTree", - capability="submission_materialization.sealed_tree_verified", - failure_code="pre_submission_materialization_unavailable", - dependencies=("artifact.revision.content_changed",), - ), - _platform( - "submission.packet.required_fields", - phase=defaults, - order=10, - classification=accountability, - input_name="SubmissionPacket", - capability="validate_submission_packet", - failure_code="pre_submission_packet_invalid", - dependencies=("artifact.scratch.sealed_tree_verified",), - public_name="check_submission_packet", - ), - _platform( - "submission.attestation.required_topics", - phase=defaults, - order=20, - classification=accountability, - input_name="SubmissionPacket", - capability="require_attestation", - failure_code="pre_submission_attestation_missing", - dependencies=("submission.packet.required_fields",), - public_name="check_confidentiality_attestation", - ), - _platform( - "artifact.sensitive_paths.high_confidence", - phase=defaults, - order=30, - classification=security, - input_name="SubmissionManifest", - capability="forbid_high_confidence_sensitive_path", - failure_code="pre_submission_sensitive_path_forbidden", - dependencies=("submission.attestation.required_topics",), - public_name="check_forbidden_files", - ), - _platform( - "artifact.quality.placeholder_signal", - phase=defaults, - order=40, - classification=advisory, - input_name="SubmissionPacket", - capability="warn_low_quality_generated_artifact", - failure_code="pre_submission_quality_warning", - dependencies=("artifact.sensitive_paths.high_confidence",), - public_name="check_low_quality_generated_artifacts", - ), - _policy( - "policy.submission_packet.validate", - "validate_submission_packet", - "check_submission_packet", - ("required_packet_fields",), - order=10, - ), - _policy( - "policy.storage_scheme.enforce", - "enforce_storage_scheme", - "check_evidence_integrity", - ("allowed_storage_schemes",), - order=20, - classification=integrity, - ), - _policy( - "policy.manifest_field.require", - "require_manifest_field", - "check_evidence_integrity", - ("manifest_required",), - order=30, - classification=integrity, - ), - _policy( - "policy.hash.verify", - "verify_hash", - "check_evidence_integrity", - ("artifact_hash_algorithm", "artifact_hash_required"), - order=40, - classification=integrity, - ), - _policy( - "policy.file.require", - "require_file", - "check_required_files", - ("required_artifacts",), - order=50, - ), - _policy( - "policy.evidence.minimum", - "require_minimum_evidence", - "check_evidence_present", - ("required_evidence",), - order=60, - ), - _policy( - "policy.artifact.forbid", - "forbid_artifact", - "check_forbidden_files", - ("forbidden_artifacts",), - order=70, - classification=security, - ), - _policy( - "policy.attestation.require", - "require_attestation", - "check_confidentiality_attestation", - ("attestation_terms",), - order=80, - ), - _policy( - "policy.file_size.limit", - "limit_file_size", - "check_evidence_integrity", - ("maximum_file_size_bytes",), - order=90, - classification=integrity, - ), - _policy( - "policy.package_size.limit", - "limit_package_size", - "check_evidence_integrity", - ("maximum_package_size_bytes",), - order=100, - classification=integrity, - ), - _policy( - "policy.archive_size.limit", - "limit_archive_size", - "check_evidence_integrity", - ("maximum_archive_size_bytes",), - order=102, - classification=integrity, - typed_inputs=("LockedProjectCheckerRule", "ArtifactCommitment"), - ), - _policy( - "policy.archive_entries.limit", - "limit_archive_entries", - "check_evidence_integrity", - ("maximum_archive_entries",), - order=105, - classification=integrity, - ), - _policy( - "policy.packaging.require", - "require_packaging", - "check_submission_packet", - ("packaging",), - order=110, - ), - _policy( - "policy.generated_quality.warn", - "warn_low_quality_generated_artifact", - "check_low_quality_generated_artifacts", - ("workstream_default_policy",), - order=120, - classification=advisory, - ), - ) - return tuple(sorted(definitions, key=_definition_sort_key)) - - -def project_guide_pre_submission_capabilities( - catalogue: PreSubmissionCheckerCatalogue, -) -> PreSubmissionCapabilityProjection: - """Project the exact deployment catalogue without creating policy authority.""" - definitions = tuple( - PreSubmissionCapabilityDefinition( - **entry.manifest_entry(), - selectable=( - entry.state is PreSubmissionCheckerState.ENABLED - and entry.dispatch_kind is PreSubmissionDispatchKind.POLICY_PRIMITIVE - and entry.phase is PreSubmissionCheckerPhase.PROJECT_POLICY - ), - ) - for entry in catalogue.entries - ) - return PreSubmissionCapabilityProjection( - catalogue_id=catalogue.catalogue_id, - version=catalogue.version, - schema_version=catalogue.schema_version, - manifest_sha256=catalogue.manifest_sha256, - available=catalogue.available, - definitions=definitions, - ) diff --git a/backend/app/modules/checkers/compiler.py b/backend/app/modules/checkers/compiler.py deleted file mode 100644 index a82b127ae..000000000 --- a/backend/app/modules/checkers/compiler.py +++ /dev/null @@ -1,649 +0,0 @@ -"""Trusted compiler for project pre-submit checker bundles.""" - -from __future__ import annotations - -from functools import lru_cache -from collections.abc import Callable -from typing import Any - -from app.core.hashing import canonical_json_hash -from app.modules.checkers.api.policy_compilation import CompiledPreSubmitCheckerPolicy -from app.modules.checkers.catalogue import ( - PreSubmissionCatalogueError, - PreSubmissionCheckerCatalogue, - build_pre_submission_checker_catalogue, -) -from app.modules.checkers.api.artifact_paths import is_canonical_relative_path, required_evidence_path - -PRE_SUBMIT_COMPILER_VERSION = "workstream-pre-submit-compiler-v0.1" -PRE_SUBMIT_BUNDLE_SCHEMA_VERSION = "pre_submit_checker_bundle.v1" -PRE_SUBMIT_SPEC_SCHEMA_VERSION = "pre_submit_checker_spec.v1" -PRIMITIVES_VERSION = "workstream-pre-submit-primitives.v1" - -BLOCKING_SEVERITY = "blocking" -WARNING_SEVERITY = "warning" - - -class PreSubmitCheckerCompilerError(ValueError): - """Raised when checker specification compilation fails closed.""" - - - - -@lru_cache(maxsize=1) -def _compiler_catalogue() -> PreSubmissionCheckerCatalogue: - """Return the immutable base catalogue used for policy compilation.""" - return build_pre_submission_checker_catalogue() - - -def build_project_pre_submit_checker_spec( - effective_policy: dict[str, Any], - effective_policy_hash: str, -) -> dict[str, Any]: - """Build the default checker specification from an effective project policy.""" - rules = [ - _rule( - "validate_submission_packet", - ["required_packet_fields"], - {"fields": effective_policy.get("required_packet_fields", [])}, - ), - _rule( - "enforce_storage_scheme", - ["allowed_storage_schemes"], - {"schemes": effective_policy.get("allowed_storage_schemes", [])}, - ), - ] - if effective_policy.get("manifest_required"): - rules.append(_rule("require_manifest_field", ["manifest_required"], {})) - if effective_policy.get("artifact_hash_required"): - rules.append( - _rule( - "verify_hash", - ["artifact_hash_required", "artifact_hash_algorithm"], - {"algorithm": effective_policy.get("artifact_hash_algorithm")}, - ) - ) - required_artifacts = [ - artifact - for artifact in effective_policy.get("required_artifacts", []) - if artifact.get("required", True) - ] - if required_artifacts: - artifact_paths = _project_unique_paths( - required_artifacts, - projector=_required_artifact_path, - field="required_artifacts", - ) - rules.append( - _rule( - "require_file", - ["required_artifacts"], - { - "artifact_paths": artifact_paths - }, - ) - ) - required_evidence = [ - evidence - for evidence in effective_policy.get("required_evidence", []) - if evidence.get("required", True) - ] - if required_evidence: - evidence_paths = _project_unique_paths( - required_evidence, - projector=lambda item: required_evidence_path(item.get("key")), - field="required_evidence", - ) - rules.append( - _rule( - "require_minimum_evidence", - ["required_evidence"], - { - "evidence_paths": evidence_paths - }, - ) - ) - forbidden_artifacts = effective_policy.get("forbidden_artifacts", []) - if forbidden_artifacts: - rules.append( - _rule( - "forbid_artifact", - ["forbidden_artifacts"], - {"patterns": [artifact["pattern"] for artifact in forbidden_artifacts]}, - ) - ) - attestation_terms = effective_policy.get("attestation_terms", []) - if attestation_terms: - rules.append( - _rule( - "require_attestation", - ["attestation_terms"], - {"terms": attestation_terms}, - ) - ) - if effective_policy.get("maximum_file_size_bytes") is not None: - rules.append( - _rule( - "limit_file_size", - ["maximum_file_size_bytes"], - {"maximum_file_size_bytes": effective_policy["maximum_file_size_bytes"]}, - ) - ) - if effective_policy.get("maximum_package_size_bytes") is not None: - rules.append( - _rule( - "limit_package_size", - ["maximum_package_size_bytes"], - {"maximum_package_size_bytes": effective_policy["maximum_package_size_bytes"]}, - ) - ) - if effective_policy.get("maximum_archive_size_bytes") is not None: - rules.append(_rule( - "limit_archive_size", ["maximum_archive_size_bytes"], - {"maximum_archive_size_bytes": effective_policy["maximum_archive_size_bytes"]}, - )) - if effective_policy.get("maximum_archive_entries") is not None: - rules.append(_rule( - "limit_archive_entries", ["maximum_archive_entries"], - {"maximum_archive_entries": effective_policy["maximum_archive_entries"]}, - )) - packaging = effective_policy.get("packaging", {}) - if packaging.get("package_required") or packaging.get("allowed_package_formats"): - rules.append(_rule("require_packaging", ["packaging"], packaging)) - rules.append( - _rule( - "warn_low_quality_generated_artifact", - ["workstream_default_policy"], - {}, - severity=WARNING_SEVERITY, - ) - ) - return { - "schema_version": PRE_SUBMIT_SPEC_SCHEMA_VERSION, - "effective_policy_hash": effective_policy_hash, - "rules": sorted(rules, key=lambda rule: rule["primitive"]), - } - - -def compile_effective_project_submission_artifact_policy( - effective_policy: dict[str, Any], - effective_policy_hash: str, - *, - compiler_version: str = PRE_SUBMIT_COMPILER_VERSION, -) -> CompiledPreSubmitCheckerPolicy: - """Compile the default project pre-submit checker bundle.""" - spec = build_project_pre_submit_checker_spec(effective_policy, effective_policy_hash) - return compile_project_pre_submit_checker_spec( - effective_policy, - effective_policy_hash, - spec, - compiler_version=compiler_version, - ) - - -def compile_project_pre_submit_checker_spec( - effective_policy: dict[str, Any], - effective_policy_hash: str, - spec: dict[str, Any], - *, - compiler_version: str = PRE_SUBMIT_COMPILER_VERSION, -) -> CompiledPreSubmitCheckerPolicy: - """Validate and compile a project pre-submit checker specification.""" - _validate_spec_shape(spec, effective_policy_hash) - rules = [_canonical_rule(rule) for rule in spec["rules"]] - _validate_rule_coverage(effective_policy, rules) - bundle = { - "schema_version": PRE_SUBMIT_BUNDLE_SCHEMA_VERSION, - "compiler_version": compiler_version, - "primitives_version": PRIMITIVES_VERSION, - "effective_policy_hash": effective_policy_hash, - "rules": rules, - } - checker_names = _checker_names_for_rules(rules) - return CompiledPreSubmitCheckerPolicy( - compiler_version=compiler_version, - compiled_bundle=bundle, - compiled_bundle_hash=canonical_json_hash(bundle), - checker_names=checker_names, - checker_configs={ - rule["primitive"]: rule["config"] - for rule in rules - }, - ) - - -def validate_compiled_pre_submit_checker_bundle( - effective_policy: dict[str, Any], - effective_policy_hash: str, - compiled_bundle: dict[str, Any], - *, - compiler_version: str | None = None, -) -> list[str]: - """Validate a persisted compiled bundle against its effective policy. - - Args: - effective_policy: Effective project submission artifact policy body. - effective_policy_hash: Canonical hash locked by the task/submission. - compiled_bundle: Persisted compiled checker bundle to validate. - compiler_version: Optional compiler version expected by the row. - - Returns: - Stable checker-name projection derived from the compiled rules. - - Raises: - PreSubmitCheckerCompilerError: If the compiled bundle cannot fully - enforce the effective policy. - """ - if compiled_bundle.get("schema_version") != PRE_SUBMIT_BUNDLE_SCHEMA_VERSION: - raise PreSubmitCheckerCompilerError("compiled checker bundle schema version is invalid") - if compiler_version is not None and compiled_bundle.get("compiler_version") != compiler_version: - raise PreSubmitCheckerCompilerError("compiled checker bundle compiler version mismatch") - if compiled_bundle.get("primitives_version") != PRIMITIVES_VERSION: - raise PreSubmitCheckerCompilerError("compiled checker bundle primitives version is invalid") - if compiled_bundle.get("effective_policy_hash") != effective_policy_hash: - raise PreSubmitCheckerCompilerError( - "compiled checker bundle effective project submission artifact policy hash mismatch" - ) - rules = compiled_bundle.get("rules") - if not isinstance(rules, list) or not rules: - raise PreSubmitCheckerCompilerError("compiled checker bundle requires rules") - canonical_rules = [_canonical_rule(rule) for rule in rules] - if canonical_rules != rules: - raise PreSubmitCheckerCompilerError("compiled checker bundle rules are not canonical") - _validate_rule_coverage(effective_policy, canonical_rules) - checker_names = _checker_names_for_rules(canonical_rules) - return checker_names - - -def _rule( - primitive: str, - policy_fields: list[str], - config: dict[str, Any], - *, - severity: str = BLOCKING_SEVERITY, -) -> dict[str, Any]: - """Build one canonical checker-spec rule.""" - return { - "primitive": primitive, - "severity": severity, - "policy_fields": sorted(policy_fields), - "config": _canonical_value(config), - } - - -def _validate_spec_shape(spec: dict[str, Any], effective_policy_hash: str) -> None: - """Validate the top-level checker-spec envelope.""" - if spec.get("schema_version") != PRE_SUBMIT_SPEC_SCHEMA_VERSION: - raise PreSubmitCheckerCompilerError("checker spec schema version is invalid") - if spec.get("effective_policy_hash") != effective_policy_hash: - raise PreSubmitCheckerCompilerError( - "checker spec effective project submission artifact policy hash mismatch" - ) - rules = spec.get("rules") - if not isinstance(rules, list) or not rules: - raise PreSubmitCheckerCompilerError("checker spec requires rules") - - -def _canonical_rule(rule: dict[str, Any]) -> dict[str, Any]: - """Validate and normalize one checker-spec rule.""" - primitive = rule.get("primitive") - if not isinstance(primitive, str): - raise PreSubmitCheckerCompilerError("checker spec contains unknown primitive") - try: - definition = _compiler_catalogue().primitive_definition(primitive) - except PreSubmissionCatalogueError as exc: - raise PreSubmitCheckerCompilerError("checker spec contains unknown primitive") from exc - severity = rule.get("severity") - if severity not in {BLOCKING_SEVERITY, WARNING_SEVERITY}: - raise PreSubmitCheckerCompilerError("checker spec contains invalid severity") - expected_severity = ( - BLOCKING_SEVERITY if definition.classification.mandatory else WARNING_SEVERITY - ) - if severity != expected_severity: - message = ( - "checker spec weakens severity" - if definition.classification.mandatory - else "checker spec escalates warning-only rule" - ) - raise PreSubmitCheckerCompilerError(message) - policy_fields = rule.get("policy_fields") - if not isinstance(policy_fields, list) or not policy_fields: - raise PreSubmitCheckerCompilerError("checker spec rule lacks policy trace fields") - if not all(isinstance(field, str) and field for field in policy_fields): - raise PreSubmitCheckerCompilerError("checker spec rule contains invalid policy trace field") - actual_policy_fields = set(policy_fields) - expected_policy_fields = set(definition.policy_fields) - if actual_policy_fields != expected_policy_fields: - raise PreSubmitCheckerCompilerError( - f"checker spec rule has untraceable policy fields for {primitive}" - ) - config = rule.get("config", {}) - if not isinstance(config, dict): - raise PreSubmitCheckerCompilerError("checker spec rule config must be an object") - return { - "primitive": primitive, - "severity": severity, - "policy_fields": sorted(set(policy_fields)), - "config": _canonical_value(config), - } - - -def _validate_rule_coverage(effective_policy: dict[str, Any], rules: list[dict[str, Any]]) -> None: - """Reject checker specs that do not fully enforce the effective policy.""" - primitives = [rule["primitive"] for rule in rules] - if len(primitives) != len(set(primitives)): - raise PreSubmitCheckerCompilerError("checker spec contains duplicate primitive rules") - expected_primitives = _expected_primitives(effective_policy) - extra_primitives = sorted(set(primitives).difference(expected_primitives)) - if extra_primitives: - raise PreSubmitCheckerCompilerError( - f"checker spec contains untraceable primitive rules: {', '.join(extra_primitives)}" - ) - omitted_primitives = sorted(expected_primitives.difference(primitives)) - if omitted_primitives: - raise PreSubmitCheckerCompilerError( - f"checker spec omits required primitive rules: {', '.join(omitted_primitives)}" - ) - by_primitive = {rule["primitive"]: rule for rule in rules} - for field, primitive in ( - ("maximum_archive_entries", "limit_archive_entries"), - ("maximum_archive_size_bytes", "limit_archive_size"), - ): - maximum = effective_policy.get(field) - if maximum is not None: - _require_blocking_rule(by_primitive, primitive) - config = by_primitive[primitive]["config"] - if ( - type(maximum) is not int or maximum <= 0 - or type(config.get(field)) is not int - or config != {field: maximum} - ): - raise PreSubmitCheckerCompilerError(f"checker spec weakens {field}") - _require_warning_rule(by_primitive, "warn_low_quality_generated_artifact") - _require_blocking_rule(by_primitive, "validate_submission_packet") - _require_config_values( - by_primitive["validate_submission_packet"], - "fields", - effective_policy.get("required_packet_fields", []), - "required packet fields", - ) - if effective_policy.get("manifest_required"): - _require_blocking_rule(by_primitive, "require_manifest_field") - if effective_policy.get("artifact_hash_required"): - _require_blocking_rule(by_primitive, "verify_hash") - if by_primitive["verify_hash"]["config"].get("algorithm") != "sha256": - raise PreSubmitCheckerCompilerError("checker spec weakens artifact hash algorithm") - _require_blocking_rule(by_primitive, "enforce_storage_scheme") - _require_config_values( - by_primitive["enforce_storage_scheme"], - "schemes", - effective_policy.get("allowed_storage_schemes", []), - "allowed storage schemes", - ) - - required_artifact_paths = _project_unique_paths( - [ - artifact - for artifact in effective_policy.get("required_artifacts", []) - if artifact.get("required", True) - ], - projector=_required_artifact_path, - field="required_artifacts", - ) - if required_artifact_paths: - _require_blocking_rule(by_primitive, "require_file") - _require_config_values( - by_primitive["require_file"], - "artifact_paths", - required_artifact_paths, - "required artifacts", - ) - required_evidence_paths = _project_unique_paths( - [ - evidence - for evidence in effective_policy.get("required_evidence", []) - if evidence.get("required", True) - ], - projector=lambda item: required_evidence_path(item.get("key")), - field="required_evidence", - ) - if required_evidence_paths: - _require_blocking_rule(by_primitive, "require_minimum_evidence") - _require_config_values( - by_primitive["require_minimum_evidence"], - "evidence_paths", - required_evidence_paths, - "required evidence", - ) - forbidden_patterns = [ - artifact["pattern"] - for artifact in effective_policy.get("forbidden_artifacts", []) - ] - if forbidden_patterns: - _require_blocking_rule(by_primitive, "forbid_artifact") - _require_config_values( - by_primitive["forbid_artifact"], - "patterns", - forbidden_patterns, - "forbidden artifacts", - ) - attestation_terms = effective_policy.get("attestation_terms", []) - if attestation_terms: - _require_blocking_rule(by_primitive, "require_attestation") - _require_config_values( - by_primitive["require_attestation"], - "terms", - attestation_terms, - "attestation terms", - ) - if effective_policy.get("maximum_file_size_bytes") is not None: - _require_blocking_rule(by_primitive, "limit_file_size") - if ( - by_primitive["limit_file_size"]["config"].get("maximum_file_size_bytes") - != effective_policy["maximum_file_size_bytes"] - ): - raise PreSubmitCheckerCompilerError("checker spec weakens file size limit") - if effective_policy.get("maximum_package_size_bytes") is not None: - _require_blocking_rule(by_primitive, "limit_package_size") - if ( - by_primitive["limit_package_size"]["config"].get("maximum_package_size_bytes") - != effective_policy["maximum_package_size_bytes"] - ): - raise PreSubmitCheckerCompilerError("checker spec weakens package size limit") - packaging = effective_policy.get("packaging", {}) - if packaging.get("package_required") or packaging.get("allowed_package_formats"): - _require_blocking_rule(by_primitive, "require_packaging") - if by_primitive["require_packaging"]["config"] != _canonical_value(packaging): - raise PreSubmitCheckerCompilerError("checker spec weakens packaging requirements") - - default_policy = effective_policy.get("workstream_default_policy") - if not isinstance(default_policy, dict): - raise PreSubmitCheckerCompilerError("effective policy lacks Workstream defaults") - _require_config_contains( - by_primitive["validate_submission_packet"], - "fields", - default_policy.get("required_packet_fields", []), - "Workstream default packet fields", - ) - _require_config_contains( - by_primitive["forbid_artifact"], - "patterns", - [artifact["pattern"] for artifact in default_policy.get("forbidden_artifacts", [])], - "Workstream default forbidden artifacts", - ) - _require_config_contains( - by_primitive["require_attestation"], - "terms", - default_policy.get("attestation_terms", []), - "Workstream default attestation terms", - ) - - -def _require_blocking_rule(by_primitive: dict[str, dict[str, Any]], primitive: str) -> None: - """Require one blocking primitive rule.""" - rule = by_primitive.get(primitive) - if rule is None: - raise PreSubmitCheckerCompilerError(f"checker spec omits {primitive}") - if rule["severity"] != BLOCKING_SEVERITY: - raise PreSubmitCheckerCompilerError(f"checker spec weakens severity for {primitive}") - - -def _require_warning_rule(by_primitive: dict[str, dict[str, Any]], primitive: str) -> None: - """Require one warning-only primitive rule.""" - rule = by_primitive.get(primitive) - if rule is None: - raise PreSubmitCheckerCompilerError(f"checker spec omits {primitive}") - if rule["severity"] != WARNING_SEVERITY: - raise PreSubmitCheckerCompilerError(f"checker spec escalates warning-only rule for {primitive}") - if rule["config"] != {}: - raise PreSubmitCheckerCompilerError(f"checker spec adds config for warning-only rule {primitive}") - - -def _require_config_values( - rule: dict[str, Any], - config_key: str, - expected_values: list[Any], - label: str, -) -> None: - """Require a rule config list to exactly match expected values.""" - actual_values = set(rule["config"].get(config_key, [])) - expected_value_set = set(expected_values) - missing_values = sorted(expected_value_set.difference(actual_values)) - if missing_values: - raise PreSubmitCheckerCompilerError( - f"checker spec omits {label}: {', '.join(str(value) for value in missing_values)}" - ) - extra_values = sorted(actual_values.difference(expected_value_set)) - if extra_values: - raise PreSubmitCheckerCompilerError( - f"checker spec adds untraceable {label}: {', '.join(str(value) for value in extra_values)}" - ) - - -def _require_config_contains( - rule: dict[str, Any], - config_key: str, - expected_values: list[Any], - label: str, -) -> None: - """Require a rule config list to include platform-default values.""" - actual_values = set(rule["config"].get(config_key, [])) - missing_values = sorted(set(expected_values).difference(actual_values)) - if missing_values: - raise PreSubmitCheckerCompilerError( - f"checker spec omits {label}: {', '.join(str(value) for value in missing_values)}" - ) - - -def _expected_primitives(effective_policy: dict[str, Any]) -> set[str]: - """Return primitive rules required to enforce one effective policy.""" - expected = { - "enforce_storage_scheme", - "validate_submission_packet", - "warn_low_quality_generated_artifact", - } - if effective_policy.get("manifest_required"): - expected.add("require_manifest_field") - if effective_policy.get("artifact_hash_required"): - expected.add("verify_hash") - required_artifacts = _policy_object_list(effective_policy, "required_artifacts") - if [artifact["key"] for artifact in required_artifacts if artifact.get("required", True)]: - expected.add("require_file") - required_evidence = _policy_object_list(effective_policy, "required_evidence") - if [evidence["key"] for evidence in required_evidence if evidence.get("required", True)]: - expected.add("require_minimum_evidence") - if effective_policy.get("forbidden_artifacts", []): - expected.add("forbid_artifact") - if effective_policy.get("attestation_terms", []): - expected.add("require_attestation") - if effective_policy.get("maximum_file_size_bytes") is not None: - expected.add("limit_file_size") - if effective_policy.get("maximum_package_size_bytes") is not None: - expected.add("limit_package_size") - if effective_policy.get("maximum_archive_entries") is not None: - expected.add("limit_archive_entries") - if effective_policy.get("maximum_archive_size_bytes") is not None: - expected.add("limit_archive_size") - packaging = effective_policy.get("packaging", {}) - if not isinstance(packaging, dict): - raise PreSubmitCheckerCompilerError( - "effective project submission artifact policy packaging must be an object" - ) - if packaging.get("package_required") or packaging.get("allowed_package_formats"): - expected.add("require_packaging") - return expected - - -def _policy_object_list(effective_policy: dict[str, Any], field: str) -> list[dict[str, Any]]: - """Return a policy list that must contain object entries with keys.""" - values = effective_policy.get(field, []) - if not isinstance(values, list): - raise PreSubmitCheckerCompilerError( - f"effective project submission artifact policy {field} must be a list" - ) - keys: set[str] = set() - for value in values: - if not isinstance(value, dict) or not isinstance(value.get("key"), str): - raise PreSubmitCheckerCompilerError( - f"effective project submission artifact policy {field} entries are invalid" - ) - key = value["key"] - if not key or key in keys: - raise PreSubmitCheckerCompilerError( - f"effective project submission artifact policy {field} keys are invalid" - ) - keys.add(key) - return values - - -def _required_artifact_path(item: dict[str, Any]) -> str: - """Require the explicit server-approved path attached to an artifact key.""" - value = item.get("path") - if not isinstance(value, str) or not is_canonical_relative_path(value): - raise PreSubmitCheckerCompilerError( - "effective project submission artifact policy path is invalid" - ) - return value - - -def _project_unique_paths( - items: list[dict[str, Any]], - *, - projector: Callable[[dict[str, Any]], str], - field: str, -) -> list[str]: - """Project policy identities into unique canonical server-owned paths.""" - try: - paths = [projector(item) for item in items] - except ValueError as exc: - raise PreSubmitCheckerCompilerError(str(exc)) from exc - if len(paths) != len(set(paths)): - raise PreSubmitCheckerCompilerError( - f"effective project submission artifact policy {field} paths are ambiguous" - ) - return paths - - -def _checker_names_for_rules(rules: list[dict[str, Any]]) -> list[str]: - """Build stable checker-name projections from compiled primitive rules.""" - catalogue = _compiler_catalogue() - names: list[str] = [] - for rule in rules: - try: - name = catalogue.primitive_definition(rule["primitive"]).public_name - except PreSubmissionCatalogueError as exc: - raise PreSubmitCheckerCompilerError( - "compiled checker bundle references unknown catalogue definitions" - ) from exc - if name not in names: - names.append(name) - return names - - -def _canonical_value(value: Any) -> Any: - """Recursively canonicalize JSON-like values.""" - if isinstance(value, dict): - return {key: _canonical_value(value[key]) for key in sorted(value)} - if isinstance(value, list): - return [_canonical_value(item) for item in value] - return value diff --git a/backend/app/modules/checkers/effective_plan.py b/backend/app/modules/checkers/effective_plan.py deleted file mode 100644 index 15864d1df..000000000 --- a/backend/app/modules/checkers/effective_plan.py +++ /dev/null @@ -1,184 +0,0 @@ -"""Pure compiler for one locked effective pre-submission execution plan.""" - -from __future__ import annotations - -from typing import Any - -from app.core.hashing import canonical_json_hash -from app.modules.checkers.api import ( - EffectivePreSubmissionExecutionPlan, - EffectivePreSubmissionPlanEntry, - EffectivePreSubmissionPlanError, - EffectivePreSubmissionPlanLineage, - FrozenJsonObject, - PreSubmissionInfrastructureUnavailableError, -) -from app.modules.checkers.api.pre_submit import effective_plan_body, freeze_json -from app.modules.checkers.catalogue import ( - PreSubmissionCheckerCatalogue, - PreSubmissionCheckerDefinition, - PreSubmissionCheckerPhase, - PreSubmissionCheckerState, - pre_submission_phase_order, -) -from app.modules.checkers.compiler import ( - PRE_SUBMIT_BUNDLE_SCHEMA_VERSION, - PRE_SUBMIT_COMPILER_VERSION, - PRIMITIVES_VERSION, - PreSubmitCheckerCompilerError, - validate_compiled_pre_submit_checker_bundle, -) - - -def compile_effective_pre_submission_execution_plan( - *, - lineage: EffectivePreSubmissionPlanLineage, - effective_policy: dict[str, Any], - compiled_bundle: dict[str, Any], - catalogue: PreSubmissionCheckerCatalogue, -) -> EffectivePreSubmissionExecutionPlan: - """Compose platform definitions and locked project rules without execution.""" - if not catalogue.available: - raise PreSubmissionInfrastructureUnavailableError( - "pre_submission_infrastructure_unavailable" - ) - if canonical_json_hash(compiled_bundle) != lineage.pre_submit_policy_bundle_hash: - raise EffectivePreSubmissionPlanError("compiled checker bundle hash mismatch") - if ( - compiled_bundle.get("schema_version") != PRE_SUBMIT_BUNDLE_SCHEMA_VERSION - or compiled_bundle.get("compiler_version") != PRE_SUBMIT_COMPILER_VERSION - or compiled_bundle.get("primitives_version") != PRIMITIVES_VERSION - ): - raise EffectivePreSubmissionPlanError("compiled checker bundle envelope is invalid") - if compiled_bundle.get("effective_policy_hash") != lineage.effective_policy_hash: - raise EffectivePreSubmissionPlanError("compiled checker effective policy mismatch") - if canonical_json_hash(effective_policy) != lineage.effective_policy_hash: - raise EffectivePreSubmissionPlanError( - "locked effective project submission artifact policy hash mismatch" - ) - try: - validate_compiled_pre_submit_checker_bundle( - effective_policy, - lineage.effective_policy_hash, - compiled_bundle, - compiler_version=PRE_SUBMIT_COMPILER_VERSION, - ) - except PreSubmitCheckerCompilerError as exc: - raise EffectivePreSubmissionPlanError( - f"compiled checker bundle does not enforce the locked effective policy: {exc}" - ) from exc - rules = compiled_bundle.get("rules") - if not isinstance(rules, list) or not rules: - raise EffectivePreSubmissionPlanError("compiled checker bundle rules are invalid") - - entries = [ - _entry_from_definition(definition, configuration={}, rule_instance_id=None) - for definition in catalogue.entries - if definition.primitive is None - ] - seen_primitives: set[str] = set() - catalogue_manifest_sha256 = catalogue.manifest_sha256 - for rule in rules: - if not isinstance(rule, dict): - raise EffectivePreSubmissionPlanError("compiled checker rule is invalid") - primitive = rule.get("primitive") - if not isinstance(primitive, str) or primitive in seen_primitives: - raise EffectivePreSubmissionPlanError("compiled checker primitive is invalid") - seen_primitives.add(primitive) - try: - definition = catalogue.primitive_definition(primitive) - except ValueError as exc: - raise EffectivePreSubmissionPlanError("compiled checker primitive is unknown") from exc - if definition.state is PreSubmissionCheckerState.DISABLED: - if definition.classification.mandatory: - raise PreSubmissionInfrastructureUnavailableError( - "pre_submission_infrastructure_unavailable" - ) - configuration = rule.get("config") - if not isinstance(configuration, dict): - raise EffectivePreSubmissionPlanError("compiled checker configuration is invalid") - if rule.get("policy_fields") != list(definition.policy_fields): - raise EffectivePreSubmissionPlanError("compiled checker policy trace is invalid") - expected_severity = "warning" if not definition.classification.mandatory else "blocking" - if rule.get("severity") != expected_severity: - raise EffectivePreSubmissionPlanError("compiled checker severity is invalid") - rule_instance_id = canonical_json_hash( - { - "domain": "workstream.pre_submission_rule_instance.v1", - "catalogue_id": catalogue.catalogue_id, - "catalogue_version": catalogue.version, - "catalogue_manifest_sha256": catalogue_manifest_sha256, - "definition_id": definition.stable_id, - "definition_version": definition.version, - "effective_policy_id": str(lineage.effective_policy_id), - "effective_policy_hash": lineage.effective_policy_hash, - "pre_submit_policy_id": str(lineage.pre_submit_policy_id), - "configuration": configuration, - } - ) - entries.append( - _entry_from_definition( - definition, - configuration=configuration, - rule_instance_id=rule_instance_id, - ) - ) - ordered_entries = tuple( - sorted( - entries, key=lambda entry: (_phase_order(entry.phase), entry.order, entry.definition_id) - ) - ) - body = effective_plan_body( - lineage, - catalogue.catalogue_id, - catalogue.version, - catalogue.schema_version, - catalogue_manifest_sha256, - ordered_entries, - ) - return EffectivePreSubmissionExecutionPlan( - lineage=lineage, - catalogue_id=catalogue.catalogue_id, - catalogue_version=catalogue.version, - catalogue_schema_version=catalogue.schema_version, - catalogue_manifest_sha256=catalogue_manifest_sha256, - entries=ordered_entries, - plan_sha256=canonical_json_hash(body), - ) - - -def _entry_from_definition( - definition: PreSubmissionCheckerDefinition, - *, - configuration: dict[str, Any], - rule_instance_id: str | None, -) -> EffectivePreSubmissionPlanEntry: - configuration_sha256 = canonical_json_hash(configuration) - frozen_configuration = FrozenJsonObject( - tuple((key, freeze_json(value)) for key, value in sorted(configuration.items())) - ) - return EffectivePreSubmissionPlanEntry( - definition_id=definition.stable_id, - definition_version=definition.version, - public_name=definition.public_name, - phase=definition.phase.value, - order=definition.order, - dependencies=definition.dependencies, - classification=definition.classification.value, - checker_definition_state=definition.state.value, - disabled_behavior=definition.disabled_behavior.value, - dispatch_kind=definition.dispatch_kind.value, - dispatch_capability=definition.dispatch_capability, - typed_inputs=definition.typed_inputs, - result_schema=definition.result_schema, - failure_code=definition.failure_code, - resource_budget=definition.resource_budget, - policy_trace_source=definition.policy_trace_source, - rule_instance_id=rule_instance_id, - configuration=frozen_configuration, - configuration_sha256=configuration_sha256, - ) - - -def _phase_order(phase: str) -> int: - return pre_submission_phase_order(PreSubmissionCheckerPhase(phase)) diff --git a/backend/app/modules/checkers/post_submit_catalogue.py b/backend/app/modules/checkers/post_submit_catalogue.py deleted file mode 100644 index cf52802bc..000000000 --- a/backend/app/modules/checkers/post_submit_catalogue.py +++ /dev/null @@ -1,23 +0,0 @@ -"""Validate installed handlers against the one current public catalogue.""" - -from __future__ import annotations -from typing import TYPE_CHECKING -from app.modules.checkers.api.historical_post_submit import ( - PostSubmitCatalogue, - current_post_submit_catalogue, -) - -if TYPE_CHECKING: - from app.modules.checkers.runner import CheckerRegistry - - -def build_post_submit_catalogue(registry: CheckerRegistry) -> PostSubmitCatalogue: - """Require exact metadata and callable installation parity.""" - catalogue = current_post_submit_catalogue() - if registry.names() != {item.capability_id for item in catalogue.definitions}: - raise ValueError("post-submit registered catalogue is incomplete") - for definition in catalogue.definitions: - entry = registry.resolve(definition.capability_id) - if entry.definition != definition or entry.checker.name != definition.capability_id: - raise ValueError("post-submit registered implementation mismatch") - return catalogue diff --git a/backend/app/modules/checkers/post_submit_implementations.py b/backend/app/modules/checkers/post_submit_implementations.py deleted file mode 100644 index 90ab9cfb2..000000000 --- a/backend/app/modules/checkers/post_submit_implementations.py +++ /dev/null @@ -1,155 +0,0 @@ -"""Private detached-input adaptation over the existing registered structural rules.""" - -from __future__ import annotations - -from dataclasses import dataclass -import re - -from app.modules.checkers.api.post_submit import ( - PostSubmissionEvaluationRequest, - PostSubmitEvidenceEntry, - PostSubmitMemberResult, -) -from app.modules.checkers.api.historical_post_submit import PostSubmitDefinition -from app.modules.checkers.runner import ( - CheckerContext, - CheckerOutcome, - CheckerRegistry, - _normalize_artifact_path, -) - - -def _copied_artifact_path(value: str) -> str: - """Normalize valid private paths; let the actual handler classify invalid ones.""" - try: - return _normalize_artifact_path(value) - except ValueError: - return value - - -@dataclass(frozen=True) -class _TaskView: - """Detached criteria consumed by the existing presence handler.""" - - acceptance_criteria: str - - -@dataclass(frozen=True) -class _EvidenceView: - """Private copied evidence values for the existing structural helpers.""" - - label: str - uri: str | None - hash: str | None - type: str - metadata_json: dict[str, str] - - @classmethod - def from_facts(cls, facts: PostSubmitEvidenceEntry) -> _EvidenceView: - """Copy only closed evidence keys for the existing pure presence rule.""" - keys = ("key", "policy_key", "evidence_key", "required_evidence_key") - metadata = {key: value for key in keys if (value := getattr(facts, key)) is not None} - return cls( - facts.label, - _copied_artifact_path(facts.uri) - if facts.uri and not re.match(r"^[A-Za-z][A-Za-z0-9+.-]*:", facts.uri) - else facts.uri, - facts.hash, facts.type, metadata, - ) - - -@dataclass(frozen=True) -class _SubmissionView: - """Private copies shield immutable source facts from handler mutation.""" - - summary: str - package_hash: str - worker_attestation: str - artifact_hash_manifest: list[dict] - evidence_items: tuple[_EvidenceView, ...] - - -def detached_checker_context(request: PostSubmissionEvaluationRequest) -> CheckerContext: - """Use copies for structural helpers; no original immutable fact can be mutated.""" - request = PostSubmissionEvaluationRequest.model_validate(request) - data = request.structural_input - policy = data.policy_inputs - return CheckerContext( - task=_TaskView(data.criteria), - submission=_SubmissionView( - data.summary, - data.package_hash, - data.worker_attestation, - [ - {**item.model_dump(mode="json"), "artifact": _copied_artifact_path(item.artifact)} - for item in data.manifest - ], - tuple(_EvidenceView.from_facts(item) for item in data.evidence), - ), - required_checker_names=frozenset( - entry.checker_id - for entry in request.policy.entries - if entry.classification == "project_required" - ), - warning_checker_names=frozenset( - entry.checker_id - for entry in request.policy.entries - if entry.classification == "project_warning" - ), - blocking_severities=frozenset(request.policy.blocking_severities), - effective_policy={ - "required_artifacts": [ - {"path": value, "required": True} for value in policy.required_artifact_paths - ], - "required_evidence": [ - {"key": value, "required": True} for value in policy.required_evidence_keys - ], - "forbidden_artifacts": [ - {"pattern": value} for value in policy.forbidden_artifact_patterns - ], - "attestation_terms": list(policy.required_attestation_terms), - }, - observed_context=data.observed_context, - expected_context=request.expected_context, - ) - - -def bounded_structural_result( - definition: PostSubmitDefinition, outcome: CheckerOutcome -) -> PostSubmitMemberResult: - """Discard free-form text/metadata and require the registered claim's closed outcome.""" - if outcome.checker_name != definition.capability_id: - raise ValueError("post-submit handler returned another checker identity") - passed = outcome.status == "passed" - result = PostSubmitMemberResult( - checker_id=definition.capability_id, - implementation_version=definition.implementation_version, - status=outcome.status, - code="passed" if passed else definition.failure_code, - failure_category="none" if passed else definition.failure_category, - severity=outcome.severity, - ) - if not passed and (result.status, result.severity) != ( - definition.failure_status, - definition.failure_severity, - ): - raise ValueError("post-submit handler returned an unsupported outcome") - return result - - -async def evaluate_registered_structural_member( - registry: CheckerRegistry, - definition: PostSubmitDefinition, - request: PostSubmissionEvaluationRequest, -) -> PostSubmitMemberResult: - """Private conformance seam; no product route or complete live phase executor.""" - selected = request.catalogue.definition(definition.capability_id, definition.capability_version) - if selected != definition: - raise ValueError("post-submit conformance definition mismatch") - definition.validate_configuration({}) - registration = registry.resolve(definition.capability_id) - if registration.definition != definition: - raise ValueError("post-submit installed definition mismatch") - context = detached_checker_context(request) - outcome = await registration.checker.run(context) - return bounded_structural_result(definition, outcome) diff --git a/backend/app/modules/checkers/pre_submit_execution.py b/backend/app/modules/checkers/pre_submit_execution.py deleted file mode 100644 index a9d5239d7..000000000 --- a/backend/app/modules/checkers/pre_submit_execution.py +++ /dev/null @@ -1,644 +0,0 @@ -"""Hidden plan-bound execution of Workstream-default pre-submission checks.""" - -from __future__ import annotations - -from dataclasses import dataclass -from enum import StrEnum -from pathlib import Path -from pathlib import PurePosixPath -import threading -from typing import BinaryIO -from fnmatch import fnmatchcase -from uuid import UUID - -from app.core.hashing import canonical_json_hash -from app.modules.checkers.api import ( - ALLOWED_PRE_SUBMIT_STORAGE_SCHEMES, - EffectivePreSubmissionExecutionPlan, - EffectivePreSubmissionPlanEntry, - PreSubmissionExecutionEntryFacts, - PreSubmissionExecutionFacts, - PreSubmissionInfrastructureUnavailableError, - PRE_SUBMISSION_RESULT_METADATA_KEYS, - SubmissionPacketView, - validate_pre_submission_execution_facts, -) -from app.modules.artifacts.sources import ArtifactCommitment -from app.modules.artifacts.submission_archive import ( - SealedSubmissionTree, - SubmissionArchiveInspectionResult, - SubmissionArchiveInspector, -) -from app.modules.artifacts.submission_manifest import ( - SubmissionChangeGateResult, - SubmissionManifest, - build_submission_manifest, -) -from app.modules.checkers.catalogue import ( - PreSubmissionCheckerCatalogue, - PreSubmissionCheckerPhase, - PreSubmissionCheckerState, - PreSubmissionPlatformCapability, - PreSubmissionPolicyPrimitive, -) -from app.modules.checkers.api.artifact_paths import is_canonical_relative_path -from app.modules.checkers.pre_submit_defaults import ( - attestation_validation_facts, - matched_low_quality_patterns, -) - - -_EXECUTED_PHASES = frozenset( - { - PreSubmissionCheckerPhase.CUSTODY.value, - PreSubmissionCheckerPhase.IDENTITY.value, - PreSubmissionCheckerPhase.MATERIALIZATION.value, - PreSubmissionCheckerPhase.DEFAULT_POLICY.value, - } -) -_FORBIDDEN_EXACT_NAMES = frozenset({".env", "id_rsa", "id_ed25519"}) -_FORBIDDEN_DIRECTORY_NAMES = frozenset({".git"}) -_FORBIDDEN_SUFFIXES = (".pem", ".key") -class DefaultPreSubmissionExecutionError(RuntimeError): - """Fail hidden execution without creating a durable checker effect.""" - - -class PreSubmissionInfrastructureUnavailable(DefaultPreSubmissionExecutionError): - """Fail closed for an impossible or disabled mandatory execution state.""" - - -class PreSubmissionResultStatus(StrEnum): - """Closed non-review status vocabulary for every pre-submit result.""" - - PASSED = "passed" - WARNING = "warning" - ADVISORY_DISABLED = "advisory_disabled" - DEPENDENCY_NOT_RUN = "dependency_not_run" - FAILED = "failed" - - -@dataclass(frozen=True, slots=True) -class PreSubmissionResultDefinition: - """Authority-neutral identity for one catalogue-owned definition.""" - - dispatch_authority: str - definition_id: str - definition_version: str - public_name: str - source: str - - -@dataclass(frozen=True, slots=True) -class PreSubmissionResultPolicyTrace: - """Exact locked policy trace for one result.""" - - effective_plan_sha256: str - rule_instance_id: str | None - locked_policy_sha256: str - - -@dataclass(frozen=True, slots=True) -class PreSubmissionEntryResult: - """One canonical bounded and path-redacted pre-submit result.""" - - schema_version: str - definition: PreSubmissionResultDefinition - policy_trace: PreSubmissionResultPolicyTrace - phase: str - order: int - classification: str - severity: str - status: PreSubmissionResultStatus - failure_code: str | None - message_code: str - metadata: tuple[tuple[str, int], ...] = () - - -@dataclass(frozen=True, slots=True) -class PreSubmissionExecutionCustody: - """Exact server-owned artifact facts observed by the sealed-tree execution.""" - - prepared_generation_id: UUID - archive_sha256: str - archive_byte_count: int - semantic_manifest_sha256: str - storage_scheme: str - - -@dataclass(frozen=True, slots=True) -class PreSubmissionExecutionResult: - """Complete canonical platform-plus-project result after scratch cleanup.""" - - plan_sha256: str - custody: PreSubmissionExecutionCustody - eligible: bool - entries: tuple[PreSubmissionEntryResult, ...] - - def bounded_facts(self) -> PreSubmissionExecutionFacts: - """Project CHECKER outcomes without leaking ART-owned custody.""" - return PreSubmissionExecutionFacts( - plan_sha256=self.plan_sha256, - eligible=self.eligible, - entries=tuple( - PreSubmissionExecutionEntryFacts( - dispatch_authority=entry.definition.dispatch_authority, - definition_id=entry.definition.definition_id, - definition_version=entry.definition.definition_version, - public_name=entry.definition.public_name, - policy_source=entry.definition.source, - effective_plan_sha256=entry.policy_trace.effective_plan_sha256, - rule_instance_id=entry.policy_trace.rule_instance_id, - locked_policy_sha256=entry.policy_trace.locked_policy_sha256, - phase=entry.phase, - order=entry.order, - classification=entry.classification, - severity=entry.severity, - checker_execution_status=entry.status.value, - failure_code=entry.failure_code, - message_code=entry.message_code, - metadata=tuple( - (key, value) - for key, value in entry.metadata - if key in PRE_SUBMISSION_RESULT_METADATA_KEYS - and type(value) is int - and value >= 0 - ), - ) - for entry in self.entries - ), - ) - - -@dataclass(frozen=True, slots=True) -class DefaultPreSubmissionExecutionInput: - """Exact 04A/04B1 facts required by the default executor.""" - - plan: EffectivePreSubmissionExecutionPlan - commitment: ArtifactCommitment - inspection: SubmissionArchiveInspectionResult - manifest: SubmissionManifest - change_gate: SubmissionChangeGateResult - packet: SubmissionPacketView - prepared_generation_id: UUID - storage_scheme: str - - -class EffectivePreSubmissionProcessor: - """Prepared-artifact processor owning the sole effective-plan dispatch.""" - - def __init__( - self, - *, - archive_inspector: SubmissionArchiveInspector, - catalogue: PreSubmissionCheckerCatalogue, - execution_input: DefaultPreSubmissionExecutionInput, - ) -> None: - """Bind one exact inspector, catalogue, and immutable execution input.""" - self._archive_inspector = archive_inspector - self._catalogue = catalogue - self._input = execution_input - self._aborted = threading.Event() - - def abort(self) -> None: - """Prevent checker callback access after caller cancellation or timeout.""" - self._aborted.set() - - def process_blocking(self, reader: BinaryIO, workspace: Path) -> PreSubmissionExecutionResult: - """Project and execute inside preparation's bounded blocking adapter.""" - self._validate_input() - return self._archive_inspector.project_and_run( - reader, - workspace, - expected=self._input.inspection, - callback=self._execute_unless_aborted, - ) - - def _execute_unless_aborted( - self, - tree: SealedSubmissionTree, - ) -> PreSubmissionExecutionResult: - """Deny checker access after caller cancellation or deadline expiry.""" - if self._aborted.is_set(): - raise DefaultPreSubmissionExecutionError("pre_submission_execution_aborted") - return self._execute(tree) - - def _validate_input(self) -> None: - """Fail closed unless every plan, archive, and manifest fact agrees.""" - plan = self._input.plan - if canonical_json_hash(plan.as_dict()) != plan.plan_sha256: - raise PreSubmissionInfrastructureUnavailable("pre_submission_plan_identity_invalid") - if plan.catalogue_manifest_sha256 != self._catalogue.manifest_sha256: - raise PreSubmissionInfrastructureUnavailable("pre_submission_catalogue_stale") - if build_submission_manifest(self._input.inspection) != self._input.manifest: - raise PreSubmissionInfrastructureUnavailable("submission_manifest_identity_unavailable") - if ( - self._input.change_gate.archive_sha256 != self._input.commitment.sha256 - or self._input.change_gate.archive_byte_count != self._input.commitment.byte_count - or self._input.change_gate.manifest != self._input.manifest - ): - raise PreSubmissionInfrastructureUnavailable("submission_change_identity_invalid") - - def _execute(self, tree: SealedSubmissionTree) -> PreSubmissionExecutionResult: - """Run the complete ordered platform-plus-project plan exactly once.""" - results: list[PreSubmissionEntryResult] = [] - statuses: dict[str, PreSubmissionResultStatus] = {} - blocked = False - executed_ids = { - entry.definition_id - for entry in self._input.plan.entries - if entry.phase in _EXECUTED_PHASES | {PreSubmissionCheckerPhase.PROJECT_POLICY.value} - } - for entry in self._input.plan.entries: - definition = self._catalogue.definition(entry.definition_id) - if entry.definition_id in statuses: - raise PreSubmissionInfrastructureUnavailable("pre_submission_duplicate_result") - if ( - entry.checker_definition_state - == PreSubmissionCheckerState.DISABLED.value - and definition.classification.mandatory - ): - raise PreSubmissionInfrastructureUnavailable( - "pre_submission_infrastructure_unavailable" - ) - if ( - entry.definition_version != definition.version - or entry.dispatch_capability != definition.dispatch_capability - or entry.classification != definition.classification.value - or entry.checker_definition_state != definition.state.value - ): - raise PreSubmissionInfrastructureUnavailable("pre_submission_plan_entry_stale") - if any(dependency not in executed_ids for dependency in entry.dependencies): - raise PreSubmissionInfrastructureUnavailable("pre_submission_dependency_invalid") - unmet = any( - statuses.get(dependency) - not in { - PreSubmissionResultStatus.PASSED, - PreSubmissionResultStatus.WARNING, - PreSubmissionResultStatus.ADVISORY_DISABLED, - } - for dependency in entry.dependencies - ) - if blocked or unmet: - result = self._result( - entry, - PreSubmissionResultStatus.DEPENDENCY_NOT_RUN, - message_code="dependency_not_run", - ) - elif ( - entry.checker_definition_state - == PreSubmissionCheckerState.DISABLED.value - ): - result = self._result( - entry, - PreSubmissionResultStatus.ADVISORY_DISABLED, - message_code="advisory_disabled", - ) - else: - result = self._dispatch(entry, tree) - if result.status is PreSubmissionResultStatus.FAILED: - blocked = True - statuses[entry.definition_id] = result.status - results.append(result) - if set(statuses) != executed_ids: - raise PreSubmissionInfrastructureUnavailable("pre_submission_result_incomplete") - execution = PreSubmissionExecutionResult( - plan_sha256=self._input.plan.plan_sha256, - custody=PreSubmissionExecutionCustody( - prepared_generation_id=self._input.prepared_generation_id, - archive_sha256=self._input.commitment.sha256, - archive_byte_count=self._input.commitment.byte_count, - semantic_manifest_sha256=self._input.manifest.sha256, - storage_scheme=self._input.storage_scheme, - ), - eligible=not blocked, - entries=tuple(results), - ) - validate_pre_submission_execution_result(self._input.plan, execution) - return execution - - def _dispatch( - self, - entry: EffectivePreSubmissionPlanEntry, - tree: SealedSubmissionTree, - ) -> PreSubmissionEntryResult: - """Dispatch one catalogue-validated platform capability or policy primitive.""" - if entry.dispatch_kind == "policy_primitive": - return self._dispatch_policy(entry, tree) - if entry.dispatch_kind != "platform_capability": - raise PreSubmissionInfrastructureUnavailable("pre_submission_dispatch_kind_invalid") - try: - capability = PreSubmissionPlatformCapability(entry.dispatch_capability) - except ValueError as exc: - raise PreSubmissionInfrastructureUnavailable( - "pre_submission_dispatch_capability_unknown" - ) from exc - if entry.phase in { - PreSubmissionCheckerPhase.CUSTODY.value, - PreSubmissionCheckerPhase.IDENTITY.value, - }: - return self._result(entry, PreSubmissionResultStatus.PASSED) - if entry.phase == PreSubmissionCheckerPhase.MATERIALIZATION.value: - if tree.entries != self._input.manifest.entries: - raise PreSubmissionInfrastructureUnavailable( - "pre_submission_materialization_unavailable" - ) - return self._result( - entry, - PreSubmissionResultStatus.PASSED, - metadata=(("entry_count", len(tree.entries)),), - ) - if capability is PreSubmissionPlatformCapability.SUBMISSION_PACKET: - missing = int(not self._input.packet.summary.strip()) + int( - not self._input.packet.contributor_attestation.strip() - ) - return self._blocking_or_pass(entry, missing, "submission_packet_invalid") - if capability is PreSubmissionPlatformCapability.ATTESTATION: - facts = attestation_validation_facts(self._input.packet.contributor_attestation) - missing = sum( - not getattr(facts, key) - for key in ( - "has_required_length", - "has_non_generic_text", - "has_confidentiality_term", - "has_credential_term", - "has_source_or_platform_term", - ) - ) - return self._blocking_or_pass(entry, missing, "attestation_missing") - if capability is PreSubmissionPlatformCapability.SENSITIVE_PATH: - matches = sum( - _is_high_confidence_sensitive(item.normalized_path) for item in tree.entries - ) - return self._blocking_or_pass(entry, matches, "sensitive_path_forbidden") - if capability is not PreSubmissionPlatformCapability.QUALITY_WARNING: - raise PreSubmissionInfrastructureUnavailable( - "pre_submission_dispatch_capability_unknown" - ) - matches = matched_low_quality_patterns( - ( - self._input.packet.summary, - self._input.packet.contributor_attestation, - *(item.normalized_path for item in tree.entries), - ) - ) - if matches: - return self._result( - entry, - PreSubmissionResultStatus.WARNING, - message_code="quality_signal_warning", - metadata=(("matched_category_count", len(matches)),), - ) - return self._result(entry, PreSubmissionResultStatus.PASSED) - - def _dispatch_policy( - self, entry: EffectivePreSubmissionPlanEntry, tree: SealedSubmissionTree - ) -> PreSubmissionEntryResult: - """Evaluate one closed project-policy primitive using server-owned facts only.""" - try: - primitive = PreSubmissionPolicyPrimitive(entry.dispatch_capability) - except ValueError as exc: - raise PreSubmissionInfrastructureUnavailable( - "pre_submission_policy_primitive_unknown" - ) from exc - config = entry.configuration.as_dict() - file_entries = tuple(item for item in tree.entries if item.sha256 is not None) - paths = {item.normalized_path for item in file_entries} - failure_count = 0 - message_code = "passed" - if primitive is PreSubmissionPolicyPrimitive.REQUIRE_FILE: - required = self._canonical_policy_paths(config.get("artifact_paths")) - failure_count = sum(path not in paths for path in required) - message_code = "required_file_missing" - elif primitive is PreSubmissionPolicyPrimitive.REQUIRE_MINIMUM_EVIDENCE: - required = self._canonical_policy_paths(config.get("evidence_paths")) - failure_count = sum(path not in paths for path in required) - message_code = "required_evidence_missing" - elif primitive is PreSubmissionPolicyPrimitive.FORBID_ARTIFACT: - patterns = self._string_list(config.get("patterns")) - failure_count = sum( - any(fnmatchcase(path, pattern) for pattern in patterns) for path in paths - ) - message_code = "forbidden_artifact_present" - elif primitive is PreSubmissionPolicyPrimitive.LIMIT_FILE_SIZE: - maximum = self._positive_limit(config, "maximum_file_size_bytes") - failure_count = sum(item.byte_count > maximum for item in file_entries) - message_code = "file_size_limit_exceeded" - elif primitive is PreSubmissionPolicyPrimitive.LIMIT_PACKAGE_SIZE: - maximum = self._positive_limit(config, "maximum_package_size_bytes") - failure_count = int(self._input.manifest.total_expanded_bytes > maximum) - message_code = "package_size_limit_exceeded" - elif primitive is PreSubmissionPolicyPrimitive.LIMIT_ARCHIVE_SIZE: - maximum = self._positive_limit(config, "maximum_archive_size_bytes") - if maximum == 0: - raise PreSubmissionInfrastructureUnavailable( - "pre_submission_policy_configuration_invalid" - ) - failure_count = int(self._input.commitment.byte_count > maximum) - message_code = "archive_size_limit_exceeded" - elif primitive is PreSubmissionPolicyPrimitive.LIMIT_ARCHIVE_ENTRIES: - maximum = self._positive_limit(config, "maximum_archive_entries") - if maximum == 0: - raise PreSubmissionInfrastructureUnavailable( - "pre_submission_policy_configuration_invalid" - ) - failure_count = int(self._input.manifest.entry_count > maximum) - message_code = "archive_entry_limit_exceeded" - elif primitive is PreSubmissionPolicyPrimitive.REQUIRE_ATTESTATION: - terms = self._string_list(config.get("terms")) - attestation = self._input.packet.contributor_attestation.casefold() - failure_count = sum(term.casefold() not in attestation for term in terms) - message_code = "policy_attestation_missing" - elif primitive is PreSubmissionPolicyPrimitive.VALIDATE_SUBMISSION_PACKET: - fields = set(self._string_list(config.get("fields"))) - # The artifact hash manifest is derived and verified before dispatch. - known = {"summary", "worker_attestation", "contributor_attestation", "artifact_hash_manifest"} - if not fields.issubset(known): - raise PreSubmissionInfrastructureUnavailable( - "pre_submission_policy_field_unmappable" - ) - failure_count = int("summary" in fields and not self._input.packet.summary.strip()) - failure_count += int( - bool(fields & {"worker_attestation", "contributor_attestation"}) - and not self._input.packet.contributor_attestation.strip() - ) - message_code = "submission_packet_invalid" - elif primitive is PreSubmissionPolicyPrimitive.REQUIRE_MANIFEST_FIELD: - failure_count = 0 - elif primitive is PreSubmissionPolicyPrimitive.VERIFY_HASH: - if config.get("algorithm") != "sha256": - raise PreSubmissionInfrastructureUnavailable( - "pre_submission_policy_hash_algorithm_invalid" - ) - elif primitive is PreSubmissionPolicyPrimitive.REQUIRE_PACKAGING: - allowed = config.get("allowed_package_formats", []) - if not isinstance(allowed, list) or any(not isinstance(item, str) for item in allowed): - raise PreSubmissionInfrastructureUnavailable( - "pre_submission_policy_configuration_invalid" - ) - failure_count = int(bool(allowed) and "zip" not in allowed) - message_code = "packaging_requirement_failed" - elif primitive is PreSubmissionPolicyPrimitive.ENFORCE_STORAGE_SCHEME: - schemes = self._string_list(config.get("schemes")) - failure_count = int(self._input.storage_scheme not in schemes) - message_code = "storage_scheme_not_allowed" - elif primitive is PreSubmissionPolicyPrimitive.WARN_LOW_QUALITY_GENERATED_ARTIFACT: - matches = matched_low_quality_patterns( - (self._input.packet.summary, self._input.packet.contributor_attestation, *paths) - ) - return self._result( - entry, - PreSubmissionResultStatus.WARNING if matches else PreSubmissionResultStatus.PASSED, - message_code="quality_signal_warning" if matches else "passed", - metadata=(("matched_category_count", len(matches)),) if matches else (), - ) - else: - raise PreSubmissionInfrastructureUnavailable( - "pre_submission_policy_primitive_unknown" - ) - return self._blocking_or_pass(entry, failure_count, message_code) - - @staticmethod - def _string_list(value: object) -> tuple[str, ...]: - if not isinstance(value, list) or any( - not isinstance(item, str) or not item for item in value - ): - raise PreSubmissionInfrastructureUnavailable( - "pre_submission_policy_configuration_invalid" - ) - return tuple(value) - - @classmethod - def _canonical_policy_paths(cls, value: object) -> tuple[str, ...]: - paths = cls._string_list(value) - if len(paths) != len(set(paths)) or any( - not is_canonical_relative_path(path) for path in paths - ): - raise PreSubmissionInfrastructureUnavailable("pre_submission_policy_path_unmappable") - return paths - - @staticmethod - def _positive_limit(config: dict[str, object], key: str) -> int: - value = config.get(key) - if type(value) is not int or value < 0: - raise PreSubmissionInfrastructureUnavailable( - "pre_submission_policy_configuration_invalid" - ) - return value - - def _blocking_or_pass( - self, - entry: EffectivePreSubmissionPlanEntry, - finding_count: int, - message_code: str, - ) -> PreSubmissionEntryResult: - """Build one blocking failure or successful bounded result.""" - return self._result( - entry, - ( - PreSubmissionResultStatus.FAILED - if finding_count - else PreSubmissionResultStatus.PASSED - ), - failure_code=entry.failure_code if finding_count else None, - message_code=message_code if finding_count else "passed", - metadata=(("finding_count", finding_count),) if finding_count else (), - ) - - def _result( - self, - entry: EffectivePreSubmissionPlanEntry, - status: PreSubmissionResultStatus, - *, - failure_code: str | None = None, - message_code: str = "passed", - metadata: tuple[tuple[str, int], ...] = (), - ) -> PreSubmissionEntryResult: - """Build one result bound to the exact plan and definition version.""" - return PreSubmissionEntryResult( - schema_version=entry.result_schema, - definition=PreSubmissionResultDefinition( - dispatch_authority="workstream.pre_submission_checker_catalogue", - definition_id=entry.definition_id, - definition_version=entry.definition_version, - public_name=entry.public_name, - source=entry.policy_trace_source, - ), - policy_trace=PreSubmissionResultPolicyTrace( - effective_plan_sha256=self._input.plan.plan_sha256, - rule_instance_id=entry.rule_instance_id, - locked_policy_sha256=self._input.plan.lineage.effective_policy_hash, - ), - phase=entry.phase, - order=entry.order, - classification=entry.classification, - severity="warning" if entry.classification == "advisory" else "blocking", - status=status, - failure_code=failure_code, - message_code=message_code, - metadata=metadata, - ) - - -def validate_pre_submission_execution_result( - plan: EffectivePreSubmissionExecutionPlan, - execution: PreSubmissionExecutionResult, -) -> None: - """Reject any result envelope not produced by the exact immutable plan.""" - custody = execution.custody - try: - ArtifactCommitment.validate_sha256(custody.archive_sha256) - ArtifactCommitment.validate_sha256(custody.semantic_manifest_sha256) - except ValueError as exc: - raise PreSubmissionInfrastructureUnavailable( - "pre_submission_result_context_invalid" - ) from exc - if ( - type(custody.prepared_generation_id) is not UUID - or type(custody.archive_byte_count) is not int - or type(execution.eligible) is not bool - or custody.archive_byte_count < 0 - or custody.storage_scheme not in ALLOWED_PRE_SUBMIT_STORAGE_SCHEMES - or execution.plan_sha256 != plan.plan_sha256 - or len(execution.entries) != len(plan.entries) - ): - raise PreSubmissionInfrastructureUnavailable("pre_submission_result_context_invalid") - for plan_entry, result in zip(plan.entries, execution.entries, strict=True): - metadata = result.metadata - if type(metadata) is not tuple or any( - type(item) is not tuple - or len(item) != 2 - or type(item[0]) is not str - or type(item[1]) is not int - for item in metadata - ): - raise PreSubmissionInfrastructureUnavailable( - "pre_submission_result_context_invalid" - ) - metadata_keys = tuple(item[0] for item in metadata) - if ( - type(result.status) is not PreSubmissionResultStatus - or result.schema_version != plan_entry.result_schema - or len(metadata_keys) != len(set(metadata_keys)) - or any( - key not in PRE_SUBMISSION_RESULT_METADATA_KEYS - or value < 0 - for key, value in metadata - ) - ): - raise PreSubmissionInfrastructureUnavailable("pre_submission_result_context_invalid") - try: - validate_pre_submission_execution_facts(plan, execution.bounded_facts()) - except PreSubmissionInfrastructureUnavailableError as exc: - raise PreSubmissionInfrastructureUnavailable(str(exc)) from exc - - -def _is_high_confidence_sensitive(normalized_path: str) -> bool: - """Match only the narrow Workstream-default sensitive-path set.""" - parts = tuple(part.casefold() for part in PurePosixPath(normalized_path).parts) - if not parts: - return False - return ( - parts[-1] in _FORBIDDEN_EXACT_NAMES - or parts[-1].endswith(_FORBIDDEN_SUFFIXES) - or any(part in _FORBIDDEN_DIRECTORY_NAMES for part in parts) - ) diff --git a/backend/app/modules/checkers/runner.py b/backend/app/modules/checkers/runner.py deleted file mode 100644 index 0b7a1db1a..000000000 --- a/backend/app/modules/checkers/runner.py +++ /dev/null @@ -1,844 +0,0 @@ -"""Checker registry, structural checkers, and manifest hashing.""" - -from __future__ import annotations - -import asyncio - -import hashlib -import json -import re -from fnmatch import fnmatchcase -from collections.abc import Callable, Sequence -from dataclasses import dataclass, field -from typing import Awaitable -from typing import Protocol - -from app.modules.checkers.api.historical_post_submit import ( - PostSubmitDefinition, PostSubmitPolicyEntry, structural_definition, -) -from app.modules.checkers.api.post_submit import ( - ExpectedPostSubmitContext, ObservedPostSubmitContext, -) -from app.modules.checkers.pre_submit_defaults import ( - LOW_QUALITY_GENERATED_PATTERNS, - attestation_validation_facts, - matched_low_quality_patterns, - normalize_policy_token as _normalize_policy_token, -) - -CHECKER_STATUS_PASSED = "passed" -CHECKER_STATUS_WARNING = "warning" -CHECKER_STATUS_FAILED = "failed" - -CHECKER_SEVERITY_INFO = "info" -CHECKER_SEVERITY_LOW = "low" -CHECKER_SEVERITY_MEDIUM = "medium" -CHECKER_SEVERITY_HIGH = "high" -CHECKER_SEVERITY_CRITICAL = "critical" - -BLOCKING_SEVERITIES = {CHECKER_SEVERITY_HIGH, CHECKER_SEVERITY_CRITICAL} -ROUTING_TASK_SETUP_BLOCKED = "task_setup_blocked" - -HASH_TOKEN_PATTERN = re.compile(r"^sha256:\S+$") -FORBIDDEN_EXACT_SEGMENTS = { - ".env", - ".git", - "credential", - "id_rsa", - "node_modules", - "private_key", - "secret", - "token", -} -FORBIDDEN_SUFFIXES = (".pem", ".key") - - -class CheckerNameConflict(ValueError): - """Raised when duplicate checker names are registered.""" - - -class UnknownChecker(ValueError): - """Raised when a policy references an unregistered checker.""" - - -class ArtifactManifestError(ValueError): - """Raised when an artifact manifest cannot be canonicalized.""" - - -@dataclass(frozen=True) -class CheckerOutcome: - """In-memory checker result before persistence.""" - - checker_name: str - status: str - severity: str - message: str - blocks_review: bool = False - worker_message: str | None = None - worker_suggested_fix: str | None = None - worker_evidence_refs: list[str] = field(default_factory=list) - worker_visible: bool = True - metadata: dict = field(default_factory=dict) - routing_recommendation: str | None = None - - -class _StructuralTask(Protocol): - """Criteria consumed by the shared structural handlers.""" - - @property - def acceptance_criteria(self) -> str | None: - """Read acceptance criteria.""" - - -class _StructuralEvidence(Protocol): - """Read-only evidence attributes used by registered structural handlers.""" - - @property - def label(self) -> str: - """Read label.""" - - @property - def uri(self) -> str | None: - """Read uri.""" - - @property - def hash(self) -> str | None: - """Read hash.""" - - @property - def type(self) -> str: - """Read type.""" - - @property - def metadata_json(self) -> dict: - """Read metadata json.""" - - -class _StructuralSubmission(Protocol): - """Packet attributes consumed by the structural handlers.""" - - @property - def summary(self) -> str: - """Read summary.""" - - @property - def package_hash(self) -> str | None: - """Read package hash.""" - - @property - def worker_attestation(self) -> str: - """Read worker attestation.""" - - @property - def artifact_hash_manifest(self) -> list[dict]: - """Read artifact hash manifest.""" - - @property - def evidence_items(self) -> Sequence[_StructuralEvidence]: - """Read evidence items.""" - - -@dataclass(frozen=True) -class CheckerContext: - """Data available to structural checkers.""" - - task: _StructuralTask - submission: _StructuralSubmission - required_checker_names: frozenset[str] - warning_checker_names: frozenset[str] - blocking_severities: frozenset[str] - effective_policy: dict | None = None - observed_context: ObservedPostSubmitContext | None = None - expected_context: ExpectedPostSubmitContext | None = None - - -class Checker(Protocol): - """Protocol implemented by registered checkers.""" - - name: str - - async def run(self, context: CheckerContext) -> CheckerOutcome: - """Run the checker against a finalized submission context.""" - - -CheckerHandler = Callable[[CheckerContext], Awaitable[CheckerOutcome]] - - -class FunctionChecker: - """Checker adapter around a plain callable.""" - - def __init__(self, name: str, handler: "CheckerHandler") -> None: - """Create a named checker. - - Args: - name: Canonical checker name referenced by checker policies. - handler: Function that evaluates a checker context. - """ - self.name = name - self._handler = handler - - async def run(self, context: CheckerContext) -> CheckerOutcome: - """Run the wrapped checker handler.""" - return await self._handler(context) - - -@dataclass(frozen=True) -class CheckerRegistration: - """Keep canonical metadata and the actual implementation in one entry.""" - - checker: Checker - definition: PostSubmitDefinition - - -class CheckerRegistry: - """Install exactly one handler and immutable definition per checker ID.""" - - def __init__(self) -> None: - """Start an empty explicit installation.""" - self._checkers: dict[str, CheckerRegistration] = {} - - def register(self, checker: Checker, *, definition: PostSubmitDefinition) -> None: - """Reject duplicate IDs and metadata belonging to another handler.""" - if checker.name in self._checkers: - raise CheckerNameConflict(f"checker already registered: {checker.name}") - definition = PostSubmitDefinition.model_validate(definition) - if definition.capability_id != checker.name: - raise ValueError("checker registration definition mismatch") - self._checkers[checker.name] = CheckerRegistration(checker, definition) - - def resolve(self, checker_name: str) -> CheckerRegistration: - """Resolve the sole installed handler for an exact checker ID.""" - try: - return self._checkers[checker_name] - except KeyError as exc: - raise UnknownChecker(f"unregistered checker: {checker_name}") from exc - - def definitions(self) -> tuple[PostSubmitDefinition, ...]: - """Return metadata attached to installed handlers.""" - return tuple(entry.definition for entry in self._checkers.values()) - - def require_registered(self, checker_names: set[str]) -> None: - """Reject selections absent from this installation.""" - missing = sorted(checker_names.difference(self.names())) - if missing: - raise UnknownChecker(f"unregistered checker policy names: {', '.join(missing)}") - - async def run( - self, context: CheckerContext, entries: tuple[PostSubmitPolicyEntry, ...] - ) -> list[CheckerOutcome]: - """Validate all compiled member identities before executing any handler.""" - registrations = [] - seen: set[str] = set() - for entry in entries: - entry = PostSubmitPolicyEntry.model_validate(entry) - registration = self.resolve(entry.checker_id) - definition = registration.definition - if entry.checker_id in seen or ( - entry.definition_version != definition.capability_version - or entry.implementation_version != definition.implementation_version - ): - raise ValueError("post-submit installed implementation mismatch") - definition.validate_configuration(entry.configuration) - seen.add(entry.checker_id) - registrations.append(registration) - outcomes = [] - for registration in registrations: - async with asyncio.timeout(registration.definition.resources.deadline_ms / 1000): - outcomes.append(await registration.checker.run(context)) - return outcomes - - def names(self) -> set[str]: - """Return installed checker IDs.""" - return set(self._checkers) - - -def canonical_artifact_manifest_hash(manifest: list[dict]) -> str: - """Hash a submission artifact manifest using Workstream canonical JSON. - - Args: - manifest: Artifact hash entries persisted on a submission. - - Returns: - SHA-256 digest prefixed with ``sha256:``. - - Raises: - ArtifactManifestError: If duplicate artifacts or invalid entries are present. - """ - seen_artifacts: set[str] = set() - canonical_entries: list[dict] = [] - for entry in manifest: - artifact = str(entry.get("artifact", "")).strip() - artifact_hash = str(entry.get("hash", "")).strip() - if not artifact or not artifact_hash: - raise ArtifactManifestError("artifact manifest entries require artifact and hash") - if artifact in seen_artifacts: - raise ArtifactManifestError(f"duplicate artifact in manifest: {artifact}") - seen_artifacts.add(artifact) - canonical_entries.append( - { - "artifact": artifact, - "hash": artifact_hash, - "notes": entry.get("notes"), - "size_bytes": entry.get("size_bytes"), - } - ) - encoded = json.dumps( - sorted(canonical_entries, key=lambda item: (item["artifact"], item["hash"])), - sort_keys=True, - separators=(",", ":"), - ensure_ascii=True, - ).encode("utf-8") - return f"sha256:{hashlib.sha256(encoded).hexdigest()}" - - -def _pass(name: str, message: str, *, metadata: dict | None = None) -> CheckerOutcome: - """Build a passing checker outcome.""" - return CheckerOutcome( - checker_name=name, - status=CHECKER_STATUS_PASSED, - severity=CHECKER_SEVERITY_INFO, - message=message, - worker_message=message, - metadata=metadata or {}, - ) - - -def _fail( - name: str, - message: str, - suggested_fix: str, - *, - metadata: dict | None = None, - worker_visible: bool = True, - routing_recommendation: str | None = None, -) -> CheckerOutcome: - """Build a worker-fixable failing checker outcome.""" - return CheckerOutcome( - checker_name=name, - status=CHECKER_STATUS_FAILED, - severity=CHECKER_SEVERITY_HIGH, - message=message, - blocks_review=True, - worker_message=message if worker_visible else None, - worker_suggested_fix=suggested_fix if worker_visible else None, - worker_visible=worker_visible, - metadata=metadata or {}, - routing_recommendation=routing_recommendation, - ) - - -def _warning(name: str, message: str, *, metadata: dict | None = None) -> CheckerOutcome: - """Build a non-blocking warning checker outcome.""" - return CheckerOutcome( - checker_name=name, - status=CHECKER_STATUS_WARNING, - severity=CHECKER_SEVERITY_MEDIUM, - message=message, - blocks_review=False, - worker_message=message, - worker_visible=True, - metadata=metadata or {}, - ) - - -def _packet_shape_outcome(summary: str, package_hash: str, manifest: list[dict]) -> CheckerOutcome: - """Validate required packet fields for persisted post-submit checks.""" - missing: list[str] = [] - if not summary.strip(): - missing.append("summary") - if not package_hash.strip(): - missing.append("package_hash") - if not manifest: - missing.append("artifact_hash_manifest") - if missing: - return _fail( - "check_submission_packet", - f"Submission packet is missing required fields: {', '.join(missing)}.", - "Add the missing packet fields before submitting.", - metadata={"missing_fields": missing}, - ) - return _pass("check_submission_packet", "Submission packet contains required fields.") - - -def _hash_token_is_valid(value: str | None) -> bool: - """Return whether a hash value has the Chunk 8 structural token shape.""" - if value is None: - return False - return bool(HASH_TOKEN_PATTERN.match(value.strip())) - - -def _normalize_artifact_path(value: str) -> str: - """Normalize an artifact path for checker comparison. - - Raises: - ValueError: If the path is empty, absolute, or contains traversal segments. - """ - normalized = re.sub(r"/+", "/", value.strip().replace("\\", "/")) - if normalized.startswith("./"): - normalized = normalized[2:] - if not normalized or normalized.startswith("/"): - raise ValueError("artifact path must be relative and non-empty") - segments = normalized.split("/") - if any(segment in {"", ".", ".."} for segment in segments): - raise ValueError("artifact path must not contain empty or traversal segments") - return normalized - - -def _evidence_integrity_outcome(manifest: list[dict], evidence_items: list[dict]) -> CheckerOutcome: - """Validate manifest and evidence reference structural integrity.""" - try: - artifact_names = [] - invalid_artifacts = [] - for entry in manifest: - artifact = str(entry.get("artifact", "")) - artifact_names.append(_normalize_artifact_path(artifact)) - if not _hash_token_is_valid(str(entry.get("hash", ""))): - invalid_artifacts.append(artifact) - manifest_hash = canonical_artifact_manifest_hash(manifest) - except (ArtifactManifestError, ValueError) as exc: - return _fail( - "check_evidence_integrity", - "Artifact manifest contains invalid or duplicate entries.", - "Use relative artifact paths, one unique artifact entry per artifact, and a sha256 hash token.", - metadata={"integrity_error": str(exc)}, - ) - if invalid_artifacts: - return _fail( - "check_evidence_integrity", - "Artifact manifest contains malformed hash references.", - "Use hash values shaped like sha256: for each artifact.", - metadata={"invalid_artifact_count": len(invalid_artifacts)}, - ) - - missing_evidence_hash_labels = [ - str(item.get("label", "")).strip() or str(index) - for index, item in enumerate(evidence_items, start=1) - if item.get("uri") and not _hash_token_is_valid(item.get("hash")) - ] - if missing_evidence_hash_labels: - return _fail( - "check_evidence_integrity", - "Evidence object references are missing structural hash tokens.", - "Add sha256: hash values for evidence objects stored in local, R2, or S3 storage.", - metadata={"missing_evidence_hash_count": len(missing_evidence_hash_labels)}, - ) - return _pass( - "check_evidence_integrity", - "Artifact manifest and evidence references are structurally valid.", - metadata={"artifact_manifest_hash": manifest_hash, "artifact_count": len(artifact_names)}, - ) - - -def _evidence_candidate_tokens(evidence_item: dict) -> set[str]: - """Return policy tokens exposed by one submitted evidence item.""" - candidates = { - str(evidence_item.get("type", "")), - str(evidence_item.get("label", "")), - } - metadata = evidence_item.get("metadata") or evidence_item.get("metadata_json") or {} - if isinstance(metadata, dict): - for key in ("key", "policy_key", "evidence_key", "required_evidence_key"): - value = metadata.get(key) - if value is not None: - candidates.add(str(value)) - return { - normalized for candidate in candidates if (normalized := _normalize_policy_token(candidate)) - } - - -def _evidence_presence_outcome( - evidence_items: list[dict], - required_evidence: list[str], -) -> CheckerOutcome: - """Validate that required evidence keys are represented by evidence rows.""" - required_tokens = { - _normalize_policy_token(required_key): required_key - for required_key in required_evidence - if _normalize_policy_token(required_key) - } - provided_tokens: set[str] = set() - for item in evidence_items: - provided_tokens.update(_evidence_candidate_tokens(item)) - - missing = [ - original_key - for token, original_key in sorted(required_tokens.items()) - if token not in provided_tokens - ] - if missing: - return _fail( - "check_evidence_present", - "Submission is missing required evidence references.", - "Attach evidence items required by the task before submitting.", - metadata={"missing_required_evidence": missing}, - ) - return _pass("check_evidence_present", "Submission includes required evidence references.") - - -def _required_files_outcome(required_files: list[str], manifest: list[dict]) -> CheckerOutcome: - """Validate that required files are represented in the artifact manifest.""" - if not required_files: - return _pass("check_required_files", "Task does not require specific files.") - try: - required = {_normalize_artifact_path(path) for path in required_files} - provided = { - _normalize_artifact_path(str(entry.get("artifact", ""))) - for entry in manifest - if str(entry.get("artifact", "")).strip() - } - except ValueError as exc: - return _fail( - "check_required_files", - str(exc), - "Use relative artifact paths without traversal segments.", - ) - missing = sorted(required.difference(provided)) - if missing: - return _fail( - "check_required_files", - "Submission is missing required artifact files.", - "Add every file required by the task to the artifact hash manifest.", - metadata={"missing_required_files": missing}, - ) - return _pass("check_required_files", "Submission includes required artifact files.") - - -def _forbidden_files_outcome( - manifest: list[dict], - evidence_items: list[dict], - forbidden_patterns: list[str] | None = None, -) -> CheckerOutcome: - """Validate artifact and evidence paths against default forbidden path patterns.""" - paths = [str(entry.get("artifact", "")) for entry in manifest] - paths.extend(str(item.get("uri", "")) for item in evidence_items if item.get("uri")) - forbidden_categories: set[str] = set() - patterns = forbidden_patterns or [] - for path in paths: - try: - normalized = _normalize_artifact_path(path) - except ValueError: - continue - lowered_segments = [segment.lower() for segment in normalized.split("/")] - filename = lowered_segments[-1] - if any(segment in FORBIDDEN_EXACT_SEGMENTS for segment in lowered_segments): - forbidden_categories.add("forbidden_path_segment") - if filename.endswith(FORBIDDEN_SUFFIXES): - forbidden_categories.add("forbidden_file_suffix") - if any(_path_matches_forbidden_pattern(normalized, pattern) for pattern in patterns): - forbidden_categories.add("forbidden_policy_pattern") - if forbidden_categories: - return _fail( - "check_forbidden_files", - "Submission includes forbidden artifact or evidence path patterns.", - "Remove forbidden files or evidence references before review.", - metadata={"forbidden_categories": sorted(forbidden_categories)}, - ) - return _pass("check_forbidden_files", "Submission does not include default forbidden paths.") - - -def _required_artifact_paths(effective_policy: dict | None) -> list[str]: - """Return required artifact paths from the locked effective project policy.""" - if effective_policy is None: - return [] - return [ - str(artifact["path"]) - for artifact in effective_policy.get("required_artifacts", []) - if artifact.get("required", True) - ] - - -def _required_evidence_keys(effective_policy: dict | None) -> list[str]: - """Return required evidence keys from the locked effective project policy.""" - if effective_policy is None: - return [] - return [ - str(evidence["key"]) - for evidence in effective_policy.get("required_evidence", []) - if evidence.get("required", True) - ] - - -def _forbidden_artifact_patterns(effective_policy: dict | None) -> list[str]: - """Return forbidden artifact patterns from the locked effective project policy.""" - if effective_policy is None: - return [] - return [ - str(rule["pattern"]) - for rule in effective_policy.get("forbidden_artifacts", []) - if rule.get("pattern") - ] - - -def _required_attestation_terms(effective_policy: dict | None) -> list[str]: - """Return required attestation terms from the locked effective project policy.""" - if effective_policy is None: - return [] - return [str(term) for term in effective_policy.get("attestation_terms", []) if term] - - -def _path_matches_forbidden_pattern(path: str, pattern: str) -> bool: - """Return whether a normalized path matches a forbidden policy pattern.""" - normalized = path.lower() - normalized_pattern = pattern.strip().lower() - if not normalized_pattern: - return False - filename = normalized.rsplit("/", 1)[-1] - segments = normalized.split("/") - return ( - fnmatchcase(normalized, normalized_pattern) - or fnmatchcase(filename, normalized_pattern) - or any(fnmatchcase(segment, normalized_pattern) for segment in segments) - ) - - -def _missing_effective_policy_outcome(checker_name: str) -> CheckerOutcome: - """Build a setup-blocked outcome when locked effective policy is missing.""" - return _fail( - checker_name, - "Task is missing locked effective project submission artifact policy context.", - "A project manager must re-screen the task before review can continue.", - worker_visible=False, - routing_recommendation=ROUTING_TASK_SETUP_BLOCKED, - ) - - -def _confidentiality_attestation_outcome( - worker_attestation: str, - required_terms: list[str] | None = None, -) -> CheckerOutcome: - """Validate confidentiality and project-required attestation terms.""" - facts = attestation_validation_facts( - worker_attestation, - required_terms=required_terms or (), - ) - missing_terms = facts.missing_attestation_terms - if not all( - [ - facts.has_required_length, - facts.has_non_generic_text, - facts.has_confidentiality_term, - facts.has_credential_term, - facts.has_source_or_platform_term, - not missing_terms, - ] - ): - return _fail( - "check_confidentiality_attestation", - "Submission is missing the required confidentiality attestation.", - ( - "Attest that the submission excludes confidential data, credentials, " - "and copied source or platform artifacts." - ), - metadata={ - "has_required_length": facts.has_required_length, - "has_confidentiality_term": facts.has_confidentiality_term, - "has_credential_term": facts.has_credential_term, - "has_source_or_platform_term": facts.has_source_or_platform_term, - "missing_attestation_terms": missing_terms, - }, - ) - return _pass( - "check_confidentiality_attestation", - "Submission includes the required confidentiality attestation.", - ) - - -def _low_quality_generated_artifacts_outcome( - summary: str, - worker_attestation: str, - manifest: list[dict], - evidence_items: list[dict], -) -> CheckerOutcome | None: - """Warn on obvious placeholder or generated-output signals.""" - haystack_parts = [summary, worker_attestation] - haystack_parts.extend(str(entry.get("artifact", "")) for entry in manifest) - haystack_parts.extend(str(entry.get("notes", "")) for entry in manifest) - haystack_parts.extend(str(item.get("label", "")) for item in evidence_items) - matched = matched_low_quality_patterns(haystack_parts) - if not matched: - return None - return _warning( - "check_low_quality_generated_artifacts", - "Submission contains placeholder or generic generated-output signals.", - metadata={ - "matched_pattern_count": len(matched), - "matched_categories": [ - pattern for pattern in LOW_QUALITY_GENERATED_PATTERNS if pattern in matched - ], - }, - ) - - -async def check_submission_packet(context: CheckerContext) -> CheckerOutcome: - """Validate required submission packet fields after the packet is locked.""" - return _packet_shape_outcome( - context.submission.summary, - context.submission.package_hash or "", - context.submission.artifact_hash_manifest, - ) - - -def policy_context_mismatches( - expected: ExpectedPostSubmitContext, observed: ObservedPostSubmitContext, -) -> list[str]: - """Compare the one closed current fact shape for owner guards and checking.""" - expected = ExpectedPostSubmitContext.model_validate(expected) - observed = ObservedPostSubmitContext.model_validate(observed) - return [key for key, value in expected.model_dump().items() if getattr(observed, key) != value] - - -async def check_policy_context_present(context: CheckerContext) -> CheckerOutcome: - """Compare current locked facts without asserting ownership or authorization.""" - if context.observed_context is None or context.expected_context is None: - raise ValueError("checker requires expected and observed policy context") - mismatches = policy_context_mismatches(context.expected_context, context.observed_context) - if mismatches: - return _fail( - "check_policy_context_present", - "Submission policy context is incomplete or inconsistent.", - "A project manager must correct the locked policy context.", - metadata={"invalid_context": mismatches}, - worker_visible=False, - routing_recommendation=ROUTING_TASK_SETUP_BLOCKED, - ) - return _pass("check_policy_context_present", "Submission has consistent policy context.") - - -async def check_evidence_integrity(context: CheckerContext) -> CheckerOutcome: - """Validate artifact manifest and evidence reference structural integrity.""" - evidence_items = [ - { - "label": item.label, - "uri": item.uri, - "hash": item.hash, - "type": item.type, - } - for item in context.submission.evidence_items - ] - return _evidence_integrity_outcome(context.submission.artifact_hash_manifest, evidence_items) - - -async def check_evidence_present(context: CheckerContext) -> CheckerOutcome: - """Validate that evidence references exist when the task requires evidence.""" - if context.effective_policy is None: - return _missing_effective_policy_outcome("check_evidence_present") - required_evidence = _required_evidence_keys(context.effective_policy) - evidence_items = [ - { - "label": item.label, - "uri": item.uri, - "hash": item.hash, - "type": item.type, - "metadata_json": item.metadata_json, - } - for item in context.submission.evidence_items - ] - return _evidence_presence_outcome( - evidence_items, - required_evidence, - ) - - -async def check_acceptance_criteria_present(context: CheckerContext) -> CheckerOutcome: - """Validate that task setup includes reviewable acceptance criteria.""" - if not (context.task.acceptance_criteria or "").strip(): - return _fail( - "check_acceptance_criteria_present", - "Task is not review-ready because acceptance criteria are missing.", - "A project manager must add reviewable acceptance criteria before review can continue.", - worker_visible=False, - routing_recommendation=ROUTING_TASK_SETUP_BLOCKED, - ) - return _pass( - "check_acceptance_criteria_present", - "Task includes reviewable acceptance criteria.", - ) - - -async def check_required_files(context: CheckerContext) -> CheckerOutcome: - """Validate required task files against the artifact manifest.""" - if context.effective_policy is None: - return _missing_effective_policy_outcome("check_required_files") - required_files = _required_artifact_paths(context.effective_policy) - return _required_files_outcome( - required_files, - context.submission.artifact_hash_manifest, - ) - - -async def check_forbidden_files(context: CheckerContext) -> CheckerOutcome: - """Validate artifact and evidence paths against forbidden path patterns.""" - evidence_items = [ - { - "label": item.label, - "uri": item.uri, - "hash": item.hash, - "type": item.type, - } - for item in context.submission.evidence_items - ] - if context.effective_policy is None: - return _missing_effective_policy_outcome("check_forbidden_files") - forbidden_patterns = _forbidden_artifact_patterns(context.effective_policy) - return _forbidden_files_outcome( - context.submission.artifact_hash_manifest, - evidence_items, - forbidden_patterns, - ) - - -async def check_confidentiality_attestation(context: CheckerContext) -> CheckerOutcome: - """Validate the worker confidentiality attestation.""" - if context.effective_policy is None: - return _missing_effective_policy_outcome("check_confidentiality_attestation") - return _confidentiality_attestation_outcome( - context.submission.worker_attestation, - _required_attestation_terms(context.effective_policy), - ) - - -async def check_low_quality_generated_artifacts(context: CheckerContext) -> CheckerOutcome: - """Warn on obvious placeholder or generated-output signals.""" - evidence_items = [ - { - "label": item.label, - "uri": item.uri, - "hash": item.hash, - "type": item.type, - } - for item in context.submission.evidence_items - ] - outcome = _low_quality_generated_artifacts_outcome( - context.submission.summary, - context.submission.worker_attestation, - context.submission.artifact_hash_manifest, - evidence_items, - ) - return outcome or _pass( - "check_low_quality_generated_artifacts", - "Submission does not contain obvious generated-output placeholder signals.", - ) - - -def default_checker_registry() -> CheckerRegistry: - """Install one structural implementation per canonical definition.""" - from app.modules.checkers.post_submit_catalogue import build_post_submit_catalogue - - registry = CheckerRegistry() - for handler in ( - check_submission_packet, - check_policy_context_present, - check_evidence_present, - check_evidence_integrity, - check_required_files, - check_forbidden_files, - check_confidentiality_attestation, - check_low_quality_generated_artifacts, - check_acceptance_criteria_present, - ): - registry.register( - FunctionChecker(handler.__name__, handler), - definition=structural_definition(handler.__name__), - ) - build_post_submit_catalogue(registry) - return registry diff --git a/backend/app/modules/projects/post_submit_policy.py b/backend/app/modules/projects/post_submit_policy.py deleted file mode 100644 index a7f43007b..000000000 --- a/backend/app/modules/projects/post_submit_policy.py +++ /dev/null @@ -1,216 +0,0 @@ -"""Compile and validate the single current post-submit policy contract.""" - -from __future__ import annotations -import json -from typing import Any -from uuid import UUID -from app.modules.checkers.api.historical_post_submit import ( - CompiledPostSubmitPolicy, - EmptyPostSubmitConfiguration, - PostSubmitPolicyEntry, - current_post_submit_catalogue, -) - -POST_SUBMIT_CHECKER_POLICY_SPEC_SCHEMA_VERSION = "post_submit_checker_policy_spec" -POST_SUBMIT_CHECKER_POLICY_SPEC_KEYS = { - "schema_version", - "project_id", - "guide_version", - "required_checkers", - "warning_checkers", - "blocking_severities", -} -DEFAULT_DURABLE_CHECKERS = [ - item.capability_id - for item in current_post_submit_catalogue().definitions - if item.platform_default -] -POST_SUBMIT_SEVERITY_ORDER = ("critical", "high", "medium", "low", "info") -PLATFORM_BLOCKING_SEVERITIES = ("critical", "high") -PLATFORM_BLOCKING_SEVERITY_SET = frozenset(PLATFORM_BLOCKING_SEVERITIES) - - -class PostSubmitCheckerCompilerError(ValueError): - """The supplied policy cannot compile into the current contract.""" - - -def build_project_post_submit_checker_spec( - *, - project_id: str, - guide_version: str, - required_checkers: list[str] | None = None, - warning_checkers: list[str] | None = None, - blocking_severities: list[str] | None = None, -) -> dict[str, Any]: - """Build constrained project additions without reclassifying platform defaults.""" - required = _canonical_checker_names(required_checkers if required_checkers is not None else []) - warning = _canonical_checker_names(warning_checkers if warning_checkers is not None else []) - _validate_checker_classifications( - required, warning, platform_default_checkers=DEFAULT_DURABLE_CHECKERS - ) - return { - "schema_version": POST_SUBMIT_CHECKER_POLICY_SPEC_SCHEMA_VERSION, - "project_id": project_id, - "guide_version": guide_version, - "required_checkers": required, - "warning_checkers": warning, - "blocking_severities": _canonical_blocking_severities( - list(PLATFORM_BLOCKING_SEVERITIES) - if blocking_severities is None - else blocking_severities - ), - } - - -def compile_project_post_submit_checker_spec( - *, - project_id: str, - guide_version: str, - spec: dict[str, Any], -) -> CompiledPostSubmitPolicy: - """Compile project selections into the one canonical ordered policy body.""" - _validate_spec_shape(spec, project_id, guide_version) - required = _canonical_checker_names(spec["required_checkers"]) - warning = _canonical_checker_names(spec["warning_checkers"]) - severities = _canonical_blocking_severities(spec["blocking_severities"]) - _validate_checker_classifications( - required, warning, platform_default_checkers=DEFAULT_DURABLE_CHECKERS - ) - catalogue = current_post_submit_catalogue() - requested = set(required + warning) - selectable = {item.capability_id for item in catalogue.definitions if item.selectable} - if not requested.issubset(selectable): - raise PostSubmitCheckerCompilerError("post-submit project selection is unavailable") - entries = tuple( - PostSubmitPolicyEntry( - checker_id=item.capability_id, - definition_version=item.capability_version, - implementation_version=item.implementation_version, - classification=( - "platform_default" - if item.platform_default - else "project_required" - if item.capability_id in required - else "project_warning" - ), - configuration=item.validate_configuration(EmptyPostSubmitConfiguration()), - ) - for item in catalogue.definitions - if item.platform_default or item.capability_id in requested - ) - try: - policy = CompiledPostSubmitPolicy( - project_id=UUID(project_id), - guide_version=guide_version, - catalogue_manifest_sha256=catalogue.manifest_sha256, - entries=entries, - blocking_severities=tuple(severities), - ) - policy.validate_catalogue(catalogue) - except ValueError as exc: - raise PostSubmitCheckerCompilerError(str(exc)) from exc - return policy - - -def parse_locked_post_submit_checker_policy_body( - body: Any, - *, - project_id: str, - guide_version: str, - policy_hash: str, -) -> CompiledPostSubmitPolicy: - """Validate the saved schema, guide identity and body hash independently of live eligibility.""" - if not isinstance(body, dict): - raise ValueError("locked post-submit checker policy body is missing") - policy = CompiledPostSubmitPolicy.model_validate_json(json.dumps(body)) - if str(policy.project_id) != project_id or policy.guide_version != guide_version: - raise ValueError("locked post-submit checker policy guide context mismatch") - if policy.policy_hash != policy_hash: - raise ValueError("locked post-submit checker policy hash is invalid") - return policy - - -def _validate_spec_shape( - spec: dict[str, Any], - project_id: str, - guide_version: str, -) -> None: - """Validate the constrained post-submit spec envelope.""" - if not isinstance(spec, dict): - raise PostSubmitCheckerCompilerError("post-submit checker spec shape is invalid") - if set(spec) != POST_SUBMIT_CHECKER_POLICY_SPEC_KEYS: - raise PostSubmitCheckerCompilerError("post-submit checker spec shape is invalid") - if spec.get("schema_version") != POST_SUBMIT_CHECKER_POLICY_SPEC_SCHEMA_VERSION: - raise PostSubmitCheckerCompilerError("post-submit checker spec schema version is invalid") - if spec.get("project_id") != project_id or spec.get("guide_version") != guide_version: - raise PostSubmitCheckerCompilerError("post-submit checker spec guide context mismatch") - for field_name in ("required_checkers", "warning_checkers", "blocking_severities"): - if not _string_list(spec.get(field_name)): - raise PostSubmitCheckerCompilerError( - f"post-submit checker spec {field_name} is invalid" - ) - - -def _validate_checker_classifications( - required_checkers: list[str], - warning_checkers: list[str], - *, - platform_default_checkers: list[str], -) -> None: - """Reject duplicate, contradictory, or weakening checker classifications.""" - duplicate_required = _duplicates(required_checkers) - duplicate_warning = _duplicates(warning_checkers) - if duplicate_required or duplicate_warning: - raise PostSubmitCheckerCompilerError( - "post-submit checker spec contains duplicate checker names" - ) - conflicting = set(required_checkers).intersection(warning_checkers) - if conflicting: - raise PostSubmitCheckerCompilerError( - "post-submit checker spec contains conflicting checker classifications" - ) - weakened_defaults = sorted(set(warning_checkers).intersection(platform_default_checkers)) - if weakened_defaults: - raise PostSubmitCheckerCompilerError( - "post-submit checker spec cannot mark default checkers as warning-only" - ) - - -def _canonical_checker_names(checker_names: list[str]) -> list[str]: - """Return stable checker names while rejecting malformed values.""" - if not _string_list(checker_names): - raise PostSubmitCheckerCompilerError("post-submit checker names must be strings") - for checker_name in checker_names: - if checker_name.strip() != checker_name or not checker_name: - raise PostSubmitCheckerCompilerError("post-submit checker names must be canonical") - return sorted(checker_names) - - -def _canonical_blocking_severities(severities: list[str]) -> list[str]: - """Return canonical blocking severities without weakening platform defaults.""" - if not _string_list(severities): - raise PostSubmitCheckerCompilerError("post-submit blocking severities must be strings") - unknown = sorted(set(severities).difference(POST_SUBMIT_SEVERITY_ORDER)) - if unknown: - raise PostSubmitCheckerCompilerError("post-submit checker spec contains unknown severities") - if not PLATFORM_BLOCKING_SEVERITY_SET.issubset(severities): - raise PostSubmitCheckerCompilerError( - "post-submit checker spec weakens platform blocking severities" - ) - return [severity for severity in POST_SUBMIT_SEVERITY_ORDER if severity in set(severities)] - - -def _string_list(value: Any) -> bool: - """Return whether a value is a JSON-list-shaped string list.""" - return isinstance(value, list) and all(isinstance(item, str) for item in value) - - -def _duplicates(values: list[str]) -> set[str]: - """Return duplicate values from a sequence.""" - seen: set[str] = set() - duplicates: set[str] = set() - for value in values: - if value in seen: - duplicates.add(value) - seen.add(value) - return duplicates diff --git a/backend/scripts/behavior_ownership.py b/backend/scripts/behavior_ownership.py index 3d72a3257..2649b1e51 100644 --- a/backend/scripts/behavior_ownership.py +++ b/backend/scripts/behavior_ownership.py @@ -173,6 +173,38 @@ "backend/app/modules/checkers/default_checker.py", } ) +PILOT_04_RETIRED_CATALOGUE_TARGETS = frozenset( + { + "backend/app/modules/checkers/api/pre_submit_catalogue.py", + "backend/app/modules/checkers/api/post_submit_catalogue.py", + "backend/app/modules/checkers/catalogue.py", + "backend/app/modules/checkers/compiler.py", + "backend/app/modules/checkers/effective_plan.py", + "backend/app/modules/checkers/post_submit_catalogue.py", + "backend/app/modules/checkers/post_submit_implementations.py", + "backend/app/modules/checkers/pre_submit_execution.py", + "backend/app/modules/checkers/runner.py", + "backend/app/modules/projects/post_submit_policy.py", + } +) +PILOT_04_SELECTED_FLOW_TARGETS = frozenset( + { + "backend/app/modules/artifacts/selected_pre_submit_admission.py", + "backend/app/modules/artifacts/selected_pre_submit_execution.py", + "backend/app/modules/authorization/domain/pre_submit.py", + "backend/app/modules/authorization/pre_submit_authorization.py", + "backend/app/modules/checkers/api/evaluation_contract.py", + "backend/app/modules/checkers/api/external_policy.py", + "backend/app/modules/checkers/api/historical_post_submit.py", + "backend/app/modules/checkers/api/material.py", + "backend/app/modules/checkers/api/policy_custody.py", + "backend/app/modules/checkers/api/selected_post_submit.py", + "backend/app/modules/checkers/api/selected_pre_submit.py", + "backend/app/modules/checkers/selected_post_submit_execution.py", + "backend/app/modules/checkers/selected_pre_submit_coordination.py", + "backend/app/modules/checkers/selected_pre_submit_execution.py", + } +) LOCAL_PILOT_HELPER_TARGETS = frozenset( { "backend/scripts/ensure_local_minio_bucket.py", @@ -308,9 +340,7 @@ { "backend/app/modules/checkers/api/post_submit.py", "backend/app/modules/checkers/api/post_submit_catalogue.py", - "backend/app/modules/checkers/post_submit_catalogue.py", "backend/app/modules/checkers/post_submit_contracts.py", - "backend/app/modules/checkers/post_submit_implementations.py", } ) ARCH_02F_SUBMISSION_COMPOSITION_TARGETS = frozenset( @@ -844,7 +874,7 @@ def _validate_additive_partition_transition( ] if ( trusted_targets != sorted(trusted_targets) - or removed - (REV_04C_REMOVED_TARGETS | ARCH_04D2_REMOVED_TARGETS | ARCH_03D_REMOVED_TARGETS | TASK_CHECKER_CLEANUP_REMOVED_TARGETS | ARCH_03C2_REMOVED_TARGETS | OUTBOX_IDENTITY_REMOVED_TARGETS | V01_BASELINE_REMOVED_TARGETS | POL_03B_REMOVED_TARGETS | POL_04B_REMOVED_TARGETS | POL_05A_REMOVED_TARGETS | ARCH_03A_GUIDE_CONTEXT_REMOVED_TARGETS | ARCH_04B_SEAM_REMOVED_TARGETS) + or removed - (REV_04C_REMOVED_TARGETS | ARCH_04D2_REMOVED_TARGETS | ARCH_03D_REMOVED_TARGETS | TASK_CHECKER_CLEANUP_REMOVED_TARGETS | ARCH_03C2_REMOVED_TARGETS | OUTBOX_IDENTITY_REMOVED_TARGETS | V01_BASELINE_REMOVED_TARGETS | POL_03B_REMOVED_TARGETS | POL_04B_REMOVED_TARGETS | POL_05A_REMOVED_TARGETS | ARCH_03A_GUIDE_CONTEXT_REMOVED_TARGETS | ARCH_04B_SEAM_REMOVED_TARGETS | PILOT_04_RETIRED_CATALOGUE_TARGETS) or [current_by_target[item["target"]] for item in retained_trusted] != retained_trusted ): @@ -863,6 +893,7 @@ def _validate_additive_partition_transition( | PILOT_10_EXPORT_TARGETS | PILOT_04_RUNTIME_TARGETS | PILOT_04_DEFAULT_CHECKER_TARGETS + | PILOT_04_SELECTED_FLOW_TARGETS | LOCAL_PILOT_HELPER_TARGETS | MODULE_BOUNDARY_FOUNDATION_TARGETS | MODULE_PUBLIC_API_FOUNDATION_TARGETS diff --git a/backend/scripts/test_lane_catalogue.py b/backend/scripts/test_lane_catalogue.py index c6a2ba7c7..b3467ce10 100644 --- a/backend/scripts/test_lane_catalogue.py +++ b/backend/scripts/test_lane_catalogue.py @@ -251,7 +251,6 @@ class TestLane: "tests/test_project_policy_mutations.py", "tests/projects/review_policy/test_semantics.py", "tests/projects/review_policy/test_mutation.py", - "tests/projects/review_policy/test_activation.py", "tests/projects/review_policy/test_postgresql.py", "tests/projects/review_policy/test_schema.py", "tests/projects/review_policy/test_migration.py", @@ -329,7 +328,6 @@ class TestLane: "tests/projects/guide_compilation/finalization/test_replay.py", "tests/projects/guide_compilation/finalization/test_service.py", "tests/projects/guide_compilation/finalization/test_structure.py", - "tests/projects/post_policy/test_compiler.py", "tests/projects/post_policy/test_public_api.py", "tests/projects/post_policy/test_public_recovery.py", "tests/projects/post_policy/test_delivery_worker.py", @@ -338,7 +336,6 @@ class TestLane: "tests/projects/public_activation/test_failures.py", "tests/projects/public_activation/test_workflow.py", "tests/projects/post_policy/test_authority.py", - "tests/projects/post_policy/test_direct_sql.py", "tests/projects/post_policy/test_concurrency.py", "tests/projects/post_policy/test_replacement.py", "tests/projects/post_policy/test_inventory.py", @@ -348,7 +345,6 @@ class TestLane: "tests/projects/post_policy/test_postgresql.py", "tests/projects/guide_compilation/proposals/test_approved_tip.py", "tests/projects/guide_compilation/proposals/test_artifact_paths.py", - "tests/projects/guide_compilation/proposals/test_selected_checks.py", "tests/projects/guide_compilation/proposals/test_authority_contract.py", "tests/projects/guide_compilation/proposals/test_contracts.py", "tests/projects/guide_compilation/proposals/test_audit_schema.py", @@ -401,7 +397,6 @@ class TestLane: "tests/projects/test_locked_policy_contract.py", "tests/projects/test_locked_policy_custody.py", "tests/projects/test_locked_policy_concurrency.py", - "tests/projects/test_activation_readiness.py", "tests/projects/test_policy_read_composition.py", "tests/projects/test_active_guide_read_composition.py", "tests/projects/test_diagnostic_read_composition.py", @@ -442,7 +437,6 @@ class TestLane: "tests/checkers/external/test_selected_pre_submit_coordination.py", "tests/checkers/external/test_selected_pre_submit_service.py", "tests/checkers/external/test_selected_preparation_command.py", - "tests/checkers/execution/test_results.py", "tests/checkers/execution/test_execution.py", "tests/checkers/execution/test_coordination.py", "tests/checkers/execution/test_concurrency.py", @@ -452,7 +446,6 @@ class TestLane: "tests/checkers/execution/test_material_migration.py", "tests/test_post_submit_materialization.py", "tests/test_post_submit_selection.py", - "tests/test_submission_evaluation_capacity.py", "tests/test_checker_output_custody.py", "tests/test_checker_output_storage.py", ) @@ -467,7 +460,6 @@ class TestLane: "tests/tasks/test_task_import_batches.py", "tests/checkers/execution/test_completion_evidence.py", "tests/checkers/execution/test_completion_contract.py", - "tests/tasks/post_submit_routing/test_failure_completion.py", "tests/tasks/post_submit_routing/test_remediation.py", "tests/tasks/post_submit_routing/test_remediation_storage.py", "tests/tasks/post_submit_routing/test_remediation_currentness.py", @@ -525,29 +517,12 @@ class TestLane: "tests/tasks/test_assignment_invalidation_races.py", "tests/tasks/test_contribution_claim_races.py", "tests/tasks/test_submission_lineage.py", - "tests/checkers/post_submit/test_catalogue.py", - "tests/checkers/post_submit/test_compiled_policy.py", "tests/checkers/post_submit/test_configuration.py", - "tests/checkers/post_submit/test_conformance.py", "tests/checkers/post_submit/test_input_bounds.py", "tests/checkers/post_submit/test_public_boundary.py", "tests/checkers/post_submit/test_request.py", "tests/checkers/post_submit/test_requirement_dispositions.py", "tests/checkers/post_submit/test_result_contract.py", - "tests/test_checker_catalogue.py", - "tests/test_checkers.py", - "tests/checkers/test_effective_intake_rules.py", - "tests/test_blocked_pre_submit_feedback_postgresql.py", - "tests/test_default_pre_submit_execution.py", - "tests/test_approved_guide_intake.py", - "tests/test_pre_submit_attempt_recovery.py", - "tests/test_pre_submit_attempt_contracts.py", - "tests/test_pre_submit_attempt_authority_integration.py", - "tests/test_pre_submit_attempt_lock_order.py", - "tests/test_pre_submit_role_issue_lock_order.py", - "tests/test_pre_submit_related_lock_order.py", - "tests/test_pre_submit_attempt_schema.py", - "tests/test_effective_pre_submit_execution.py", "tests/test_project_guide_compilation_contracts.py", "tests/test_review_queue_persistence.py", "tests/test_review_lease_persistence.py", diff --git a/backend/tests/architecture/test_module_boundaries.py b/backend/tests/architecture/test_module_boundaries.py index b260e7b90..bdb059ac5 100644 --- a/backend/tests/architecture/test_module_boundaries.py +++ b/backend/tests/architecture/test_module_boundaries.py @@ -4,26 +4,9 @@ import json from pathlib import Path -from app.core.identifiers import new_record_id import pytest -from app.core.hashing import canonical_json_hash -from app.modules.checkers.api import ( - EffectivePreSubmissionExecutionPlan, - EffectivePreSubmissionPlanLineage, - EffectivePreSubmissionPlanningPort, -) -from app.modules.checkers.catalogue import build_pre_submission_checker_catalogue -from app.modules.checkers.compiler import compile_effective_project_submission_artifact_policy -from app.modules.checkers.pre_submit_execution import ( - PreSubmissionEntryResult, - PreSubmissionExecutionCustody, - PreSubmissionExecutionResult, - PreSubmissionResultDefinition, - PreSubmissionResultPolicyTrace, - PreSubmissionResultStatus, -) from scripts import module_boundaries as boundary from scripts.authorization_boundary import AuthorizationBoundaryError @@ -287,6 +270,7 @@ def test_projects_public_api_has_no_private_or_mutable_dependency() -> None: assert all( not target.startswith("app.modules.") or target.startswith("app.modules.projects.api") + or target == "app.modules.checkers.api.external_policy" for target in imports ) @@ -310,100 +294,6 @@ def test_checkers_public_api_has_no_private_or_mutable_dependency() -> None: ) -def test_checkers_public_planning_port_uses_the_canonical_compiler() -> None: - """The public port delegates to the sole deterministic compiler.""" - defaults = { - "required_packet_fields": ["summary", "worker_attestation"], - "forbidden_artifacts": [{"pattern": ".env"}], - "attestation_terms": ["rights_confirmed"], - } - policy = { - "workstream_default_policy": defaults, - "project_policy": {}, - **defaults, - "required_artifacts": [{"key": "task.toml", "path": "task.toml", "required": True}], - "required_evidence": [{"key": "results", "required": True}], - "manifest_required": True, - "artifact_hash_required": True, - "artifact_hash_algorithm": "sha256", - "allowed_storage_schemes": ["s3"], - "maximum_file_size_bytes": 1_000_000, - "maximum_package_size_bytes": 5_000_000, - "packaging": {"package_required": True, "allowed_package_formats": ["zip"]}, - } - policy_hash = canonical_json_hash(policy) - compiled = compile_effective_project_submission_artifact_policy(policy, policy_hash) - lineage = EffectivePreSubmissionPlanLineage( - project_id=new_record_id(), guide_id=new_record_id(), guide_version="1", - source_snapshot_id=new_record_id(), source_snapshot_hash="sha256:" + "1" * 64, - effective_policy_id=new_record_id(), effective_policy_hash=policy_hash, - pre_submit_policy_id=new_record_id(), - pre_submit_policy_bundle_hash=compiled.compiled_bundle_hash, - ) - port: EffectivePreSubmissionPlanningPort = build_pre_submission_checker_catalogue() - plan = port.compile_effective_plan( - lineage=lineage, effective_policy=policy, compiled_bundle=compiled.compiled_bundle - ) - repeated = port.compile_effective_plan( - lineage=lineage, effective_policy=policy, compiled_bundle=compiled.compiled_bundle - ) - assert type(plan) is EffectivePreSubmissionExecutionPlan - assert plan.lineage is lineage - assert plan.plan_sha256 == canonical_json_hash(plan.as_dict()) - assert repeated.as_dict() == plan.as_dict() - assert repeated.plan_sha256 == plan.plan_sha256 - - -def test_checkers_public_execution_facts_exclude_artifact_custody() -> None: - """The public result projection cannot leak ART-owned custody fields.""" - execution = PreSubmissionExecutionResult( - plan_sha256="sha256:" + "1" * 64, - custody=PreSubmissionExecutionCustody( - prepared_generation_id=new_record_id(), archive_sha256="sha256:" + "2" * 64, - archive_byte_count=7, semantic_manifest_sha256="sha256:" + "3" * 64, - storage_scheme="s3", - ), - eligible=True, - entries=(PreSubmissionEntryResult( - schema_version="pre_submission_checker_result.v1", - definition=PreSubmissionResultDefinition( - dispatch_authority="workstream.pre_submission_checker_catalogue", - definition_id="submission_archive.outer_zip_valid", - definition_version="v0.1", public_name="Outer ZIP validation", - source="platform_default", - ), - policy_trace=PreSubmissionResultPolicyTrace( - effective_plan_sha256="sha256:" + "1" * 64, - rule_instance_id=None, locked_policy_sha256="sha256:" + "4" * 64, - ), - phase="custody", order=10, classification="mandatory_security", - severity="blocking", status=PreSubmissionResultStatus.PASSED, - failure_code=None, message_code="passed", - metadata=( - ("entry_count", 2), - ("finding_count", -1), - ("matched_category_count", True), - ("custody_id", 3), - ("archive_sha256", 5), - ("scratch_path", 4), - ("provider_key", 9), - ("evidence_id", 6), - ), - ),), - ) - facts = execution.bounded_facts() - assert ( - facts.plan_sha256, - facts.eligible, - facts.entries[0].checker_execution_status, - ) == ( - execution.plan_sha256, True, "passed" - ) - assert facts.entries[0].metadata == (("entry_count", 2),) - assert not hasattr(facts, "custody") - assert not hasattr(facts, "storage_scheme") - - def test_cyclic_public_dependencies_fail_closed() -> None: """Typed public facades cannot form an architectural dependency cycle.""" graph = {name: set() for name in boundary.load_registry(REGISTRY).names} @@ -414,7 +304,7 @@ def test_cyclic_public_dependencies_fail_closed() -> None: def test_art_implements_checker_consumer_ports_without_a_public_cycle() -> None: - """The delivered seam is ART implementation to CHECKERS-owned public ports.""" + """Selected checker execution has no private CHECKERS-to-ART dependency.""" registry = boundary.load_registry(REGISTRY) private, graph, _ = boundary.scan(ROOT, registry) assert "checkers" in graph["artifacts"] @@ -424,20 +314,7 @@ def test_art_implements_checker_consumer_ports_without_a_public_cycle() -> None: for edge in private if edge.source_file.startswith("backend/app/modules/checkers/") and edge.target_module == "artifacts" - } == { - ( - "backend/app/modules/checkers/pre_submit_execution.py", - "app.modules.artifacts.sources", - ), - ( - "backend/app/modules/checkers/pre_submit_execution.py", - "app.modules.artifacts.submission_archive", - ), - ( - "backend/app/modules/checkers/pre_submit_execution.py", - "app.modules.artifacts.submission_manifest", - ), - } + } == set() boundary._validate_acyclic(graph) # noqa: SLF001 - architecture proof diff --git a/backend/tests/authorization/contribution_policies/test_cross_owner_lock_order.py b/backend/tests/authorization/contribution_policies/test_cross_owner_lock_order.py index 5d2bc8562..5505a55cc 100644 --- a/backend/tests/authorization/contribution_policies/test_cross_owner_lock_order.py +++ b/backend/tests/authorization/contribution_policies/test_cross_owner_lock_order.py @@ -3,29 +3,22 @@ from __future__ import annotations import asyncio -from dataclasses import replace -from pathlib import Path from uuid import UUID, uuid4 import pytest -from sqlalchemy import select, text +from sqlalchemy import text from sqlalchemy.exc import DBAPIError -from sqlalchemy.ext.asyncio import async_sessionmaker, create_async_engine from app.adapters.auth import ( - compensation_adapter_binding_authorization, contribution_policy_authorization, + compensation_adapter_binding_authorization, ) -from app.adapters.contributions import contribution_policy_service, contribution_policy_validation_port +from app.adapters.contributions import contribution_policy_validation_port from app.db import session as db_session -from app.modules.artifacts.models import PreSubmitEvidenceSet from app.modules.authorization.repository import AdminAuthorizationRepository -from app.modules.authorization.runtime import ( - ActorKind, ActorStatus, HumanAuthorizationContext, IdentityLinkStatus, -) from app.modules.compensation.api import AdapterBindingSuspendRequest from app.modules.compensation.service import AdapterBindingService from app.modules.contributions.api import ( - ContributionPolicyCreateDraftRequest, ContributionPolicyValidationPurpose, + ContributionPolicyValidationPurpose, ContributionPolicyValidationRequest, ) from app.modules.projects.contribution_policy import ProjectContributionPolicyEligibility @@ -34,13 +27,6 @@ from tests.authorization.contribution_policies.test_selected_validation_postgresql import ( published_world, ) -from tests.authorization.test_pre_submit_attempt_authority import _seed_materializer -from tests.test_pre_submit_attempt_authority_integration import _reserve_with_real_materializer -from tests.test_pre_submit_attempt_recovery import _harness -from tests.test_pre_submit_related_lock_order import ( - _PauseBeforeProject, _assert_row_locked, _ready_workflow, -) -from project_create_fixtures import grant_fixture_admin_role def _role_body(target_id: UUID) -> dict: @@ -253,112 +239,3 @@ async def suspend_binding(): finally: release.set() await asyncio.gather(*tasks, return_exceptions=True) - - -class _ObservedBeforeProject(_PauseBeforeProject): - def __init__(self, repository, session, entered, release): - super().__init__(repository, entered, release) - self.session = session - self.backend_pid: int | None = None - - async def lock_locked_policy_context(self, request): - self.backend_pid = int(await self.session.scalar(text("select pg_backend_pid()"))) - return await super().lock_locked_policy_context(request) - - -@pytest.mark.asyncio -async def test_dual_finance_submitter_profile_precedes_policy_project_lock( - tmp_path: Path, isolated_database_env: str, monkeypatch, -) -> None: - import tests.archive_fixtures as default_tests - - original_limits = default_tests._limits - monkeypatch.setattr(default_tests, "_limits", lambda: replace( - original_limits(), total_deadline_seconds=90, reservation_ttl_seconds=120, - aggregate_reserved_bytes=4 * default_tests.HARD_MAXIMUM_ARTIFACT_BYTES, - )) - harness = await _harness(tmp_path, isolated_database_env) - con_engine = None - art_task = con_task = None - release_art = asyncio.Event() - try: - await _seed_materializer(harness.factory) - project_id = harness.request.effective_plan.lineage.project_id - async with harness.factory.begin() as setup: - await grant_fixture_admin_role( - setup, harness.actor_id, role="finance_authority", - scope="project", project_id=project_id, - ) - con_name = f"cp07a-dual-finance-{uuid4().hex[:10]}" - con_engine = create_async_engine( - isolated_database_env, - connect_args={"server_settings": {"application_name": con_name}}, - ) - con_factory = async_sessionmaker(con_engine, expire_on_commit=False) - draft = ContributionPolicyCreateDraftRequest( - actor_profile_id=harness.actor_id, project_id=project_id, - operation_id=uuid4(), name="Dual role lock order", - ) - async with harness.factory() as art_session, con_factory() as con_session: - calls: list[int] = [] - workflow, materializer = await _ready_workflow(harness, art_session, calls) - reservation = await _reserve_with_real_materializer( - workflow, harness.request, harness.preparation_request, - ) - art_before_project = asyncio.Event() - paused = _ObservedBeforeProject( - workflow._project_contexts, art_session, - art_before_project, release_art, - ) - workflow._project_contexts = paused - context = HumanAuthorizationContext( - actor_profile_id=harness.actor_id, actor_kind=ActorKind.HUMAN, - actor_status=ActorStatus.ACTIVE, identity_link_id=harness.identity_link_id, - identity_link_status=IdentityLinkStatus.ACTIVE, - request_id=uuid4(), correlation_id=uuid4(), - ) - - async def create_draft(): - async with con_session.begin(): - authority = contribution_policy_authorization(con_session, context) - return await contribution_policy_service( - con_session, read_authorization=authority, - mutation_authorization=authority, - ).create_draft(draft) - - try: - art_task = asyncio.create_task(workflow.execute_reserved( - harness.request, reservation, - preparation_request=harness.preparation_request, - )) - await asyncio.wait_for(art_before_project.wait(), timeout=30) - assert paused.backend_pid is not None - await _assert_row_locked(harness.engine, "actor_profiles", harness.actor_id) - await _assert_row_locked( - harness.engine, "actor_identity_links", harness.identity_link_id, - ) - con_task = asyncio.create_task(create_draft()) - await _wait_edge( - isolated_database_env, con_name, None, paused.backend_pid, - ) - release_art.set() - art_result, policy_result = await asyncio.wait_for( - asyncio.gather(art_task, con_task), timeout=60, - ) - assert art_result.pass_capability is not None - assert policy_result.operation_id == draft.operation_id - assert calls == [1] - finally: - release_art.set() - await asyncio.gather( - *(task for task in (art_task, con_task) if task is not None), - return_exceptions=True, - ) - materializer.close() - async with harness.factory() as check: - assert await check.scalar(select(PreSubmitEvidenceSet.id).limit(1)) is not None - finally: - release_art.set() - if con_engine is not None: - await con_engine.dispose() - await harness.close() diff --git a/backend/tests/checkers/execution/test_results.py b/backend/tests/checkers/execution/test_results.py deleted file mode 100644 index 268cad87f..000000000 --- a/backend/tests/checkers/execution/test_results.py +++ /dev/null @@ -1,99 +0,0 @@ -"""Complete locked-policy classification; one bad member cannot hide in a pass.""" - -import pytest - -from app.modules.checkers.api.post_submit import PostSubmitMemberResult -from app.modules.checkers.execution_results import classify_result -from tests.checkers.post_submit.support import request -from tests.checkers.post_submit.test_result_contract import result - - -@pytest.mark.parametrize( - "failed_ids,expected", - [ - ((), "allow_review"), - (("check_submission_packet",), "needs_revision"), - (("check_policy_context_present",), "task_setup_blocked"), - (("check_submission_packet", "check_policy_context_present"), "task_setup_blocked"), - (("check_low_quality_generated_artifacts",), "allow_review"), - ], -) -def test_routing_uses_complete_locked_policy(failed_ids, expected): - source = request() - members = [] - matched = set() - for entry, passed in zip(source.policy.entries, result(source).member_results, strict=True): - definition = source.catalogue.definition(entry.checker_id, entry.definition_version) - if entry.checker_id in failed_ids: - matched.add(entry.checker_id) - members.append( - PostSubmitMemberResult( - checker_id=entry.checker_id, - definition_version=entry.definition_version, - implementation_version=entry.implementation_version, - status=definition.failure_status, - code=definition.failure_code, - failure_category=definition.failure_category, - severity=definition.failure_severity, - ) - ) - else: - members.append(passed) - assert matched == set(failed_ids), "case must exercise a registered member" - actual = classify_result(source, result(source, member_results=tuple(members))) - assert actual.routing == expected - assert actual.passed + actual.warning + actual.failed == len(source.policy.entries) - assert actual.blocking == sum(m.status == "failed" for m in members) - - -def test_incomplete_members_cannot_classify(): - source = request() - with pytest.raises(ValueError, match="members mismatch"): - classify_result(source, result(source, member_results=result(source).member_results[:-1])) - - -@pytest.mark.parametrize("strict", [False, True]) -def test_locked_medium_severity_can_block_placeholder_warning(strict): - from app.modules.projects.post_submit_policy import ( - build_project_post_submit_checker_spec, - compile_project_post_submit_checker_spec, - ) - from tests.checkers.post_submit.support import change_request - - source = request() - policy = compile_project_post_submit_checker_spec( - project_id=str(source.project_id), - guide_version="v1", - spec=build_project_post_submit_checker_spec( - project_id=str(source.project_id), - guide_version="v1", - blocking_severities=["critical", "high", "medium"] if strict else ["critical", "high"], - ), - ) - source = change_request( - source, - policy=policy, - expected_context=source.expected_context.model_copy( - update={"post_policy_hash": policy.policy_hash} - ), - ) - members = list(result(source).member_results) - idx = next( - index - for index, item in enumerate(members) - if item.checker_id == "check_low_quality_generated_artifacts" - ) - definition = source.catalogue.definition( - members[idx].checker_id, members[idx].definition_version - ) - members[idx] = PostSubmitMemberResult( - checker_id=definition.capability_id, - implementation_version=definition.implementation_version, - status="warning", - severity="medium", - code=definition.failure_code, - failure_category=definition.failure_category, - ) - classified = classify_result(source, result(source, member_results=tuple(members))) - assert classified.routing == ("needs_revision" if strict else "allow_review") - assert classified.warning == 1 and classified.failed == 0 and classified.blocking == int(strict) diff --git a/backend/tests/checkers/post_submit/test_catalogue.py b/backend/tests/checkers/post_submit/test_catalogue.py deleted file mode 100644 index de8c29cc2..000000000 --- a/backend/tests/checkers/post_submit/test_catalogue.py +++ /dev/null @@ -1,131 +0,0 @@ -"""Registry installation, identity, and single-handler installation proof.""" - -from dataclasses import replace - -import pytest -from pydantic import ValidationError - -from app.core.hashing import canonical_json_hash -from app.modules.checkers.api.historical_post_submit import ( - structural_definition, - PostSubmitCatalogue, - PostSubmitDefinition, -) -from app.modules.checkers.post_submit_catalogue import ( - build_post_submit_catalogue, -) -from app.modules.checkers.runner import ( - CheckerNameConflict, - CheckerRegistry, - FunctionChecker, - UnknownChecker, - check_policy_context_present, - default_checker_registry, -) -from tests.checkers.post_submit.support import altered_catalogue, catalogue - - -def test_catalogue_matches_exactly_one_registered_handler_per_id(): - registry = default_checker_registry() - snapshot = build_post_submit_catalogue(registry) - assert len(snapshot.definitions) == 9 - assert len(registry._checkers) == 9 - for definition in snapshot.definitions: - entry = registry.resolve(definition.capability_id) - assert entry.definition == definition - assert entry.checker.name == definition.capability_id - entry = registry.resolve("check_policy_context_present") - assert entry.checker._handler is check_policy_context_present - assert entry.definition in snapshot.definitions - assert registry.names() == {item.capability_id for item in snapshot.definitions} - - -@pytest.mark.parametrize("damage", ("missing", "version", "identity")) -def test_catalogue_rejects_uninstalled_or_mismatched_handler(damage): - registry = default_checker_registry() - key = "check_submission_packet" - entry = registry._checkers.pop(key) - if damage == "version": - registry._checkers[key] = replace( - entry, - definition=entry.definition.model_copy(update={"implementation_version": "wrong"}), - ) - elif damage == "identity": - registry._checkers[key] = replace( - entry, checker=FunctionChecker("other", entry.checker._handler) - ) - with pytest.raises((ValueError, UnknownChecker), match="incomplete|unregistered|mismatch"): - build_post_submit_catalogue(registry) - - -def test_registry_rejects_duplicates_and_metadata_substitution(): - registry = default_checker_registry() - checker = registry.resolve("check_submission_packet").checker - with pytest.raises(CheckerNameConflict, match="already registered"): - registry.register(checker, definition=structural_definition(checker.name)) - with pytest.raises(ValueError, match="definition mismatch"): - CheckerRegistry().register( - checker, definition=structural_definition("check_required_files") - ) - with pytest.raises(UnknownChecker, match="unregistered checker policy names"): - registry.require_registered({"missing"}) - with pytest.raises(ValueError, match="unknown structural"): - structural_definition("missing") - - -@pytest.mark.parametrize( - "change", - [ - {"state": "disabled"}, - {"implementation_version": "another-implementation"}, - {"supported_claim": "packet_presence"}, - {"dependencies": ["check_submission_packet"]}, - ], -) -def test_catalogue_hash_binds_semantics(change): - original = catalogue() - changed = altered_catalogue(original, **change) - assert changed.manifest_sha256 != original.manifest_sha256 - assert catalogue().manifest_sha256 == original.manifest_sha256 - exported = original.model_dump(mode="json") - exported["definitions"][0]["state"] = "disabled" - assert original.definitions[0].resources.deadline_ms == 5000 - with pytest.raises(ValidationError, match="hash mismatch"): - PostSubmitCatalogue.model_validate(exported) - - -@pytest.mark.parametrize( - "kind", ("duplicate", "order", "dependency", "hash", "classification", "severity") -) -def test_invalid_catalogue_shape(kind): - body = catalogue().model_dump(mode="json", exclude={"manifest_sha256"}) - if kind == "duplicate": - body["definitions"][1]["capability_id"] = body["definitions"][0]["capability_id"] - elif kind == "order": - body["definitions"][0]["order"] = 9 - elif kind == "dependency": - body["definitions"][0]["dependencies"] = ["missing"] - elif kind == "classification": - body["definitions"][0]["selectable"] = True - elif kind == "severity": - body["definitions"][0]["failure_severity"] = "medium" - digest = "sha256:" + "0" * 64 if kind == "hash" else canonical_json_hash(body) - with pytest.raises(ValidationError): - PostSubmitCatalogue(**body, manifest_sha256=digest) - - -def test_definition_validates_boolean_resource_limits_and_unknown_fields(): - definition = catalogue().definitions[0].model_dump() - definition["resources"] = {"maximum_results": True} - with pytest.raises(ValidationError, match="require integers"): - PostSubmitDefinition(**definition) - with pytest.raises(ValidationError, match="Extra inputs"): - PostSubmitDefinition(**catalogue().definitions[0].model_dump(), arbitrary="secret") - - -def test_hash_valid_catalogue_rejects_duplicate_dependencies(): - body = catalogue().model_dump(mode="json", exclude={"manifest_sha256"}) - dependency = body["definitions"][0]["capability_id"] - body["definitions"][1]["dependencies"] = [dependency, dependency] - with pytest.raises(ValidationError, match="definition has duplicate dependencies"): - PostSubmitCatalogue(**body, manifest_sha256=canonical_json_hash(body)) diff --git a/backend/tests/checkers/post_submit/test_compiled_policy.py b/backend/tests/checkers/post_submit/test_compiled_policy.py deleted file mode 100644 index 15624f60d..000000000 --- a/backend/tests/checkers/post_submit/test_compiled_policy.py +++ /dev/null @@ -1,171 +0,0 @@ -"""Canonical compiler custody, closed-body rejection and policy classification proof.""" - -import json - -import pytest -from pydantic import ValidationError - -from app.core.hashing import canonical_json_hash -from app.modules.checkers.api import CompiledPostSubmitPolicy -from app.modules.checkers.api.historical_post_submit import current_post_submit_catalogue -from app.modules.projects.post_submit_policy import build_project_post_submit_checker_spec, compile_project_post_submit_checker_spec, parse_locked_post_submit_checker_policy_body -from tests.checkers.post_submit.support import PROJECT, altered_catalogue, catalogue, request - - -def compile_selection(*, required=(), warning=()): - return compile_project_post_submit_checker_spec( - project_id=str(PROJECT), - guide_version="v1", - spec=build_project_post_submit_checker_spec( - project_id=str(PROJECT), - guide_version="v1", - required_checkers=list(required), - warning_checkers=list(warning), - ), - ) - - -def parse(body, *, digest=None): - parsed = parse_locked_post_submit_checker_policy_body( - body, - project_id=str(PROJECT), - guide_version="v1", - policy_hash=canonical_json_hash(body) if digest is None else digest, - ) - - parsed.validate_catalogue(current_post_submit_catalogue()) - return parsed - - -def test_canonical_compile_parse_and_derived_lists(): - policy = request().policy - assert parse(policy.policy_body) == policy - assert policy.entries[1].implementation_version == "workstream-structural" - assert len(policy.entries) == 9 - assert len(compile_selection().entries) == 8 - warning = compile_selection(warning=("check_acceptance_criteria_present",)) - assert warning.entries[-1].classification == "project_warning" - assert warning.warning_checkers == ["check_acceptance_criteria_present"] - assert warning.required_checkers == [] - assert policy.required_checkers == ["check_acceptance_criteria_present"] - assert policy.execution_checkers == policy.default_checkers + policy.required_checkers - - -@pytest.mark.parametrize( - "required,warning", - [ - (("unknown",), ()), - (("check_submission_packet",), ()), - ((), ("check_submission_packet",)), - (("check_acceptance_criteria_present",), ("check_acceptance_criteria_present",)), - (("check_acceptance_criteria_present", "check_acceptance_criteria_present"), ()), - ], -) -def test_compiler_rejects_unavailable_or_conflicting_project_selection(required, warning): - with pytest.raises( - ValueError, match="selection is unavailable|conflicting|duplicate|warning-only" - ): - compile_selection(required=required, warning=warning) - - -@pytest.mark.parametrize("index", (0, 8)) -def test_disabled_default_or_selected_definition_rejects(index): - policy = request().policy - snapshot = altered_catalogue(index=index, state="disabled") - body = policy.policy_body - body["catalogue_manifest_sha256"] = snapshot.manifest_sha256 - with pytest.raises(ValueError, match="definition is unavailable"): - CompiledPostSubmitPolicy.model_validate_json(json.dumps(body)).validate_catalogue(snapshot) - # Self-consistent metadata still cannot replace the installed compiler catalogue. - with pytest.raises(ValueError, match="catalogue hash mismatch"): - parse(body) - - -@pytest.mark.parametrize( - "change,match", - [ - ("hash", "policy hash is invalid"), - ("catalogue", "catalogue hash mismatch"), - ("implementation", "implementation version mismatch"), - ("omit", "omits mandatory"), - ("default", "classification mismatch"), - ("order", "order or dependency"), - ("repeat", "duplicate entries"), - ("severity", "blocking severities"), - ("configuration", "Extra inputs"), - ("checker", "capability or version is unavailable"), - ("schema_version", "Input should be"), - ("compiler_version", "Input should be"), - ("catalogue_id", "Input should be"), - ("catalogue_source_version", "Input should be"), - ("catalogue_schema_version", "Input should be"), - ], -) -def test_recomputed_hash_cannot_hide_invalid_current_body(change, match): - body = request().policy.policy_body - if change == "hash": - with pytest.raises(ValueError, match=match): - parse(body, digest="sha256:" + "0" * 64) - return - if change == "catalogue": - body["catalogue_manifest_sha256"] = "sha256:" + "0" * 64 - elif change == "implementation": - body["entries"][1]["implementation_version"] = "unsupported" - elif change == "omit": - del body["entries"][0] - elif change == "default": - body["entries"][0]["classification"] = "project_required" - elif change == "order": - body["entries"][0], body["entries"][1] = body["entries"][1], body["entries"][0] - elif change == "repeat": - body["entries"][1] = body["entries"][0] - elif change == "severity": - body["blocking_severities"] = ["low", "medium"] - elif change == "configuration": - body["entries"][0]["configuration"] = {"skip": True} - elif change == "checker": - body["entries"][0]["checker_id"] = "unknown" - else: - body[change] = "unsupported" - with pytest.raises(ValueError, match=match): - parse(body) - - -def test_agent_projection_is_exact_current_catalogue(): - projection = current_post_submit_catalogue() - assert projection.model_dump(mode="json") == catalogue().model_dump(mode="json") - corrupted = projection.model_dump() - corrupted["definitions"][0]["state"] = "disabled" - with pytest.raises(ValidationError, match="hash mismatch"): - type(projection).model_validate(corrupted) - - -def test_sparse_policy_with_recomputed_hash_has_no_reader(): - policy = request().policy - body = { - "schema_version": "post_submit_checker_policy", - "compiler_version": "workstream-post-submit-compiler", - "project_id": str(PROJECT), - "guide_version": "v1", - "default_checkers": policy.default_checkers, - "required_checkers": policy.required_checkers, - "warning_checkers": [], - "execution_checkers": policy.execution_checkers, - "blocking_severities": ["critical", "high"], - } - with pytest.raises(ValidationError, match="Extra inputs"): - parse(body) - - -@pytest.mark.parametrize("field", ("required_checkers", "warning_checkers", "blocking_severities")) -def test_each_persisted_sidecar_must_equal_canonical_body(field): - policy = request().policy - values = dict( - required_checkers=policy.required_checkers, - warning_checkers=policy.warning_checkers, - blocking_severities=list(policy.blocking_severities), - ) - policy.validate_sidecars(**values) - values[field] = [*values[field], "crossed"] - with pytest.raises(ValueError, match="summaries disagree"): - policy.validate_sidecars(**values) diff --git a/backend/tests/checkers/post_submit/test_conformance.py b/backend/tests/checkers/post_submit/test_conformance.py deleted file mode 100644 index 22f4b10b0..000000000 --- a/backend/tests/checkers/post_submit/test_conformance.py +++ /dev/null @@ -1,255 +0,0 @@ -"""Real registered handlers and reachable counterexamples.""" - -from dataclasses import replace -from app.core.identifiers import new_record_id - -import pytest - -from app.modules.checkers.api import ExpectedPostSubmitContext -from app.modules.checkers.post_submit_implementations import ( - bounded_structural_result, - detached_checker_context, - evaluate_registered_structural_member, -) -from app.modules.checkers.runner import ( - check_policy_context_present, - CheckerOutcome, - default_checker_registry, -) -from tests.checkers.post_submit.support import change_request, request - -CASES = ( - ("check_submission_packet", "packet_fields_missing", "failed"), - ("check_policy_context_present", "policy_context_invalid", "failed"), - ("check_evidence_present", "evidence_missing", "failed"), - ("check_evidence_integrity", "evidence_structure_invalid", "failed"), - ("check_required_files", "required_files_missing", "failed"), - ("check_forbidden_files", "forbidden_path_present", "failed"), - ("check_confidentiality_attestation", "attestation_missing", "failed"), - ("check_low_quality_generated_artifacts", "placeholder_signal", "warning"), - ("check_acceptance_criteria_present", "acceptance_criteria_missing", "failed"), -) - - -def damaged_input(source, name): - data = source.structural_input.model_dump() - if name == "check_submission_packet": - data["summary"] = "" - elif name == "check_policy_context_present": - data["observed_context"]["post_policy_id"] = None - elif name == "check_evidence_present": - data["evidence"] = () - elif name == "check_evidence_integrity": - data["manifest"][0]["hash"] = "invalid" - elif name == "check_required_files": - data["manifest"][0]["artifact"] = "another.txt" - elif name == "check_forbidden_files": - data["manifest"][0]["artifact"] = "forbidden/data.txt" - elif name == "check_confidentiality_attestation": - data["worker_attestation"] = data["worker_attestation"].replace("Rights confirmed.", "") - elif name == "check_low_quality_generated_artifacts": - data["summary"] = "TODO: add actual content" - elif name == "check_acceptance_criteria_present": - data["criteria"] = " " - return change_request(source, structural_input=data) - - -@pytest.mark.parametrize("name,code,status", CASES) -async def test_structural_conformance(name, code, status): - registry = default_checker_registry() - source = request() - definition = source.catalogue.definition(name, "v0.1") - control = await evaluate_registered_structural_member(registry, definition, source) - assert (control.status, control.code, control.severity, control.failure_category) == ( - "passed", - "passed", - "info", - "none", - ) - result = await evaluate_registered_structural_member( - registry, definition, damaged_input(source, name) - ) - assert (result.status, result.code) == (status, code) - assert result.severity == ("medium" if status == "warning" else "high") - assert result.failure_category == ( - "task_configuration" - if name in {"check_policy_context_present", "check_acceptance_criteria_present"} - else "submission_structure" - ) - assert "message" not in result.model_dump() - - -@pytest.mark.parametrize("field", tuple(ExpectedPostSubmitContext.model_fields)) -@pytest.mark.parametrize("kind", ("missing", "crossed")) -async def test_current_policy_context_without_payment(field, kind): - source = request() - data = source.structural_input.model_dump() - old = data["observed_context"][field] - replacement = None - if kind == "crossed": - replacement = ( - new_record_id() - if field.endswith("_id") - else 2 - if type(old) is int - else ("sha256:" + "b" * 64 if str(old).startswith("sha256:") else "other") - ) - data["observed_context"][field] = replacement - changed = change_request(source, structural_input=data) - definition = source.catalogue.definition("check_policy_context_present", "v0.1") - registry = default_checker_registry() - assert ( - await evaluate_registered_structural_member(registry, definition, source) - ).status == "passed" - result = await evaluate_registered_structural_member(registry, definition, changed) - assert result.code == "policy_context_invalid" - assert result.status == "failed" - - -async def test_registry_executes_canonical_entries_with_current_context(): - source = request() - outcomes = await default_checker_registry().run( - detached_checker_context(source), source.policy.entries - ) - assert [item.checker_name for item in outcomes] == source.policy.execution_checkers - assert all(item.status == "passed" for item in outcomes) - - -async def test_presence_check_does_not_claim_substantive_quality(): - source = request() - changed = change_request( - source, - structural_input={ - **source.structural_input.model_dump(), - "summary": "An incorrect analysis with unsupported conclusions.", - }, - ) - definition = source.catalogue.definition("check_acceptance_criteria_present", "v0.1") - result = await evaluate_registered_structural_member( - default_checker_registry(), definition, changed - ) - assert result.status == "passed" - assert definition.supported_claim == "criteria_presence" - - -@pytest.mark.parametrize("mutation", ("identity", "severity", "status")) -def test_bounded_result_rejects_malformed_handler_output(mutation): - definition = request().catalogue.definitions[0] - values = dict( - checker_name=definition.capability_id, status="failed", severity="high", message="secret" - ) - values[{"identity": "checker_name", "severity": "severity", "status": "status"}[mutation]] = { - "identity": "other", - "severity": "low", - "status": "accept", - }[mutation] - with pytest.raises(ValueError): - bounded_structural_result(definition, CheckerOutcome(**values)) - - -async def test_context_handler_requires_observed_input_and_definitions_are_exact(): - source = request() - context = detached_checker_context(source) - context = replace(context, observed_context=None) - with pytest.raises(ValueError, match="requires expected and observed"): - await check_policy_context_present(context) - definition = source.catalogue.definitions[0].model_copy(update={"state": "disabled"}) - with pytest.raises(ValueError, match="definition mismatch"): - await evaluate_registered_structural_member(default_checker_registry(), definition, source) - registry = default_checker_registry() - key = source.catalogue.definitions[0].capability_id - registry._checkers[key] = registry._checkers["check_required_files"] - with pytest.raises(ValueError, match="installed definition mismatch"): - await evaluate_registered_structural_member( - registry, source.catalogue.definitions[0], source - ) - - -@pytest.mark.parametrize( - "damage", ("duplicate", "empty_package", "empty_manifest", "missing_evidence_hash") -) -async def test_additional_claim_specific_failures_reach_handlers(damage): - source = request() - data = source.structural_input.model_dump() - name, code = "check_evidence_integrity", "evidence_structure_invalid" - if damage == "duplicate": - data["manifest"] = data["manifest"] * 2 - elif damage == "missing_evidence_hash": - data["evidence"][0]["hash"] = None - else: - name, code = "check_submission_packet", "packet_fields_missing" - if damage == "empty_package": - data["package_hash"] = "" - else: - data["manifest"] = () - changed = change_request(source, structural_input=data) - result = await evaluate_registered_structural_member( - default_checker_registry(), source.catalogue.definition(name, "v0.1"), changed - ) - assert result.code == code - - -@pytest.mark.parametrize("alias", ("./report.txt", ".\\report.txt", " report.txt ")) -async def test_normalized_duplicates_preserve_immutable_source(alias): - source = request() - data = source.structural_input.model_dump() - entry = data["manifest"][0] - data["manifest"] = (entry, {**entry, "artifact": alias}) - changed = change_request(source, structural_input=data) - original = changed.model_dump_json() - registry = default_checker_registry() - definition = changed.catalogue.definition("check_evidence_integrity", "v0.1") - outcome = await evaluate_registered_structural_member(registry, definition, changed) - assert (outcome.status, outcome.code) == ("failed", "evidence_structure_invalid") - assert changed.model_dump_json() == original - - -@pytest.mark.parametrize("path", ("../report.txt", "/report.txt", "./")) -async def test_invalid_copied_paths_reach_registered_failure(path): - source = request() - data = source.structural_input.model_dump() - data["manifest"][0]["artifact"] = path - changed = change_request(source, structural_input=data) - original = changed.model_dump_json() - outcome = await evaluate_registered_structural_member( - default_checker_registry(), - changed.catalogue.definition("check_evidence_integrity", "v0.1"), - changed, - ) - assert (outcome.status, outcome.code) == ("failed", "evidence_structure_invalid") - assert changed.model_dump_json() == original - - -@pytest.mark.parametrize( - "uri,expected", - ( - ("./report.txt", "report.txt"), - ("https://example.com/proof", "https://example.com/proof"), - ), -) -def test_copied_evidence_paths_preserve_external_uri_identity(uri, expected): - source = request() - data = source.structural_input.model_dump() - data["evidence"][0]["uri"] = uri - changed = change_request(source, structural_input=data) - assert detached_checker_context(changed).submission.evidence_items[0].uri == expected - assert changed.structural_input.evidence[0].uri == uri - - -@pytest.mark.parametrize( - "field", - ( - "payment_policy_version", - "compilation_id", - "compilation_result_hash", - "contribution_policy_version_id", - "guide_id", - "project_id", - ), -) -def test_context_rejects_unsupported_or_fabricated_observations(field): - from app.modules.checkers.api import ObservedPostSubmitContext - - values = request().structural_input.observed_context.model_dump() - with pytest.raises(ValueError, match="Extra inputs"): - ObservedPostSubmitContext.model_validate({**values, field: new_record_id()}) diff --git a/backend/tests/checkers/test_effective_intake_rules.py b/backend/tests/checkers/test_effective_intake_rules.py deleted file mode 100644 index 7af6dfcf1..000000000 --- a/backend/tests/checkers/test_effective_intake_rules.py +++ /dev/null @@ -1,74 +0,0 @@ -"""Project intake rules over actual prepared ZIP bytes, not caller packet manifests. - -AUTH is an explicit port double here; canonical authority has separate tests. -This module proves materialization outcomes, not durable admission or Submission creation. -""" - -from dataclasses import replace -from types import SimpleNamespace -from tests.pre_submit_test_helpers import materialize_member_fixture - - -import pytest - -from app.core.hashing import canonical_json_hash -from app.modules.artifacts.submission_materialization import PreparedBundleMaterializationService -from app.modules.checkers.compiler import compile_effective_project_submission_artifact_policy -from app.modules.checkers.effective_plan import compile_effective_pre_submission_execution_plan -from app.modules.checkers.pre_submit_execution import PreSubmissionResultStatus -from tests.test_default_pre_submit_execution import ( - _AllowAuthority, _CheckerExecution, _effective_policy, _request, -) - - -@pytest.mark.parametrize(("case", "failed_definition"), [ - ("complete", None), - ("missing_file", "policy.file.require"), - ("project_evidence", "policy.evidence.minimum"), - ("project_attestation", "policy.attestation.require"), - ("project_forbidden_file", "policy.artifact.forbid"), -]) -async def test_effective_project_rules_control_exact_prepared_contents( - tmp_path, case, failed_definition, -): - request, inspector, manager, preparation, catalogue = await _request( - tmp_path, - path="unexpected.txt" if case == "missing_file" else "task.toml", - extra_path="project-private.data" if case == "project_forbidden_file" else None, - ) - try: - policy = _effective_policy() - if case == "project_evidence": - addition = {"key": "build_log", "required": True} - policy["project_policy"] = {"required_evidence": [addition]} - policy["required_evidence"] = [*policy["required_evidence"], addition] - elif case == "project_attestation": - policy["project_policy"] = {"attestation_terms": ["project_confidentiality_confirmed"]} - policy["attestation_terms"] = [*policy["attestation_terms"], "project_confidentiality_confirmed"] - elif case == "project_forbidden_file": - addition = {"pattern": "project-private.data"} - policy["project_policy"] = {"forbidden_artifacts": [addition]} - policy["forbidden_artifacts"] = [*policy["forbidden_artifacts"], addition] - policy_hash = canonical_json_hash(policy) - compiled = compile_effective_project_submission_artifact_policy(policy, policy_hash) - plan = compile_effective_pre_submission_execution_plan( - lineage=replace( - request.effective_plan.lineage, effective_policy_hash=policy_hash, - pre_submit_policy_bundle_hash=compiled.compiled_bundle_hash, - ), - effective_policy=policy, compiled_bundle=compiled.compiled_bundle, catalogue=catalogue, - ) - service = PreparedBundleMaterializationService( - session=SimpleNamespace(), - authorization=_AllowAuthority(), preparation=preparation, - checker_execution=_CheckerExecution(inspector, catalogue), storage_scheme="s3", - ) - result = await materialize_member_fixture(service, replace(request, effective_plan=plan)) - assert result.eligible is (failed_definition is None) - failed = [entry.definition_id for entry in result.entries - if entry.checker_execution_status == PreSubmissionResultStatus.FAILED.value] - assert failed == ([] if failed_definition is None else [failed_definition]) - assert list((tmp_path / "scratch" / "workspaces").iterdir()) == [] - finally: - await request.prepared_artifact.close() - manager.close() diff --git a/backend/tests/pre_submit_test_helpers.py b/backend/tests/pre_submit_test_helpers.py deleted file mode 100644 index b4645d01a..000000000 --- a/backend/tests/pre_submit_test_helpers.py +++ /dev/null @@ -1,322 +0,0 @@ -"""Shared dependency-safe construction for focused pre-submit tests.""" - -import json -import asyncio -from dataclasses import replace -from pathlib import Path -from types import SimpleNamespace -from typing import Any, BinaryIO -from unittest.mock import AsyncMock - -import pytest -from sqlalchemy import select, text -from sqlalchemy.exc import DBAPIError -from uuid import UUID, uuid4 -from app.core.identifiers import new_record_id - -from app.modules.checkers.api import ( - PreSubmissionExecutionFacts, - PreSubmissionInfrastructureUnavailableError, -) -from app.modules.checkers.pre_submit_execution import ( - DefaultPreSubmissionExecutionError, - DefaultPreSubmissionExecutionInput, - EffectivePreSubmissionProcessor, -) -from app.modules.artifacts.api import SubmissionBundlePreparationRequest -from app.modules.artifacts.submission_materialization import ( - PreparedBundleMaterializationService, - PreparedBundlePreSubmitEvidenceService, -) -from app.modules.authorization.api import ActorIdentityFacts, ActorKind -from app.modules.projects.locked_policy_repository import ProjectLockedPolicyRepository -from app.modules.tasks.repository import TaskRepository -from app.modules.artifacts.pre_submit_attempts import PreSubmitAttemptClaim -from app.modules.artifacts.pre_submit_evidence import PreSubmitEvidencePersistenceResult - - -async def materialize_member_fixture(service, request): - """Isolate existing member/scratch tests from SQL; this is not attempt-custody proof.""" - claim = object.__new__(PreSubmitAttemptClaim) - claim.attempt_id, claim._nonce = new_record_id(), uuid4() - claim.request_digest = "sha256:" + "1" * 64 - claim._request = replace(request, prepared_authorization=None) - claim._started, claim._execution = False, None - claim._session = service._session - in_transaction = True - service._session.in_transaction = lambda: in_transaction - service._session.in_nested_transaction = lambda: False - service._session.scalar = AsyncMock(return_value=SimpleNamespace( - status="reserved", evidence_set_id=None, claim_nonce=str(claim._nonce), - request_digest=claim.request_digest, - prepared_generation_id=str(request.prepared_artifact.generation_id), - )) - await service.authorize_prepared_bundle(request, claim=claim) - in_transaction = False - return await service.materialize_prepared_bundle( - replace(request, prepared_authorization=None), claim=claim - ) - - -async def execute_evidence_workflow(workflow, request, *, preparation_request): - """Exercise real reservation/commit/execution/evidence owners in PostgreSQL fixtures.""" - async with workflow._session.begin(): - selected = await workflow.reserve(request, preparation_request=preparation_request) - if isinstance(selected, PreSubmitEvidencePersistenceResult): - return selected - return await workflow.execute_reserved(request, selected, preparation_request=preparation_request) - - -class _HistoricalFactsProcessor: - """Execute only pre-cutover test evidence while its SQL fixtures are retained.""" - - def __init__(self, processor: EffectivePreSubmissionProcessor) -> None: - self._processor = processor - - def abort(self) -> None: - self._processor.abort() - - async def process( - self, reader: BinaryIO, workspace: Path - ) -> PreSubmissionExecutionFacts: - try: - result = await asyncio.to_thread( - self._processor.process_blocking, reader, workspace - ) - return result.bounded_facts() - except DefaultPreSubmissionExecutionError as exc: - raise PreSubmissionInfrastructureUnavailableError(str(exc)) from exc - - -class _HistoricalCheckerExecution: - """Test-only adapter for predecessor evidence; never a product composition root.""" - - def __init__(self, *, catalogue: Any, archive_inspector: Any) -> None: - self._catalogue = catalogue - self._archive_inspector = archive_inspector - - @property - def catalogue_manifest_sha256(self) -> str: - return self._catalogue.manifest_sha256 - - def build(self, request) -> _HistoricalFactsProcessor: - if request.plan is None: - raise PreSubmissionInfrastructureUnavailableError( - "pre_submission_plan_identity_invalid" - ) - return _HistoricalFactsProcessor( - EffectivePreSubmissionProcessor( - archive_inspector=self._archive_inspector, - catalogue=self._catalogue, - execution_input=DefaultPreSubmissionExecutionInput( - plan=request.plan, - commitment=request.commitment, - inspection=request.inspection, - manifest=request.manifest, - change_gate=request.change_gate, - packet=request.packet, - prepared_generation_id=request.prepared_generation_id, - storage_scheme=request.storage_scheme, - ), - ) - ) - - -def checker_execution(inspector, catalogue) -> _HistoricalCheckerExecution: - """Build the test-only predecessor evidence adapter.""" - return _HistoricalCheckerExecution( - archive_inspector=inspector, - catalogue=catalogue, - ) - - -def submission_preparation_request( - request, - *, - actor_profile_id: UUID, - identity_link_id: UUID, -) -> SubmissionBundlePreparationRequest: - """Project one private materialization fixture into the public ART request.""" - return SubmissionBundlePreparationRequest( - actor=ActorIdentityFacts( - actor_profile_id=actor_profile_id, - identity_link_id=identity_link_id, - actor_kind=ActorKind.HUMAN, - ), - request_id=uuid4(), - correlation_id=uuid4(), - task_id=request.task_id, - assignment_id=request.assignment_id, - predecessor_submission_id=None, - idempotency_key=uuid4(), - summary=request.packet.summary, - contributor_attestation=request.packet.contributor_attestation, - media_type="application/zip", - byte_source=_empty_bytes(), - ) - - -async def _empty_bytes(): - if False: # pragma: no cover - preserve the async-iterable request shape - yield b"" - - -def evidence_workflow( - *, session, preparation, inspector, catalogue, materialization_authorization, - preparation_authorization, -) -> PreparedBundlePreSubmitEvidenceService: - """Compose the exact public-port evidence workflow for database proof.""" - return PreparedBundlePreSubmitEvidenceService( - session=session, - materialization=PreparedBundleMaterializationService( - session=session, - authorization=materialization_authorization, - preparation=preparation, - checker_execution=checker_execution(inspector, catalogue), - storage_scheme="s3", - ), - preparation_authorization=preparation_authorization, - task_contexts=TaskRepository(session), - project_contexts=ProjectLockedPolicyRepository(session), - ) - - -async def approved_pre_submit_fixture( - factory, namespace, *, guide_version, contribution_awards=(), human_review_required=True -): - """Build supported PROJECTS custody before the ART evidence transaction.""" - from app.interfaces.project_agents import SubmissionArtifactPolicyProposal - from app.modules.checkers.catalogue import build_pre_submission_checker_catalogue - from app.modules.checkers.api import EffectivePreSubmissionPlanLineage - from app.modules.projects.models import ProjectGuide, PostSubmitCheckerPolicy - from tests.projects.unified_policy_fixtures import create_standalone_unified_policy - - values, effective, pre = await create_standalone_unified_policy( - factory, - namespace, - guide_version=guide_version, - contribution_awards=contribution_awards, - human_review_required=human_review_required, - artifact_proposal=SubmissionArtifactPolicyProposal( - maximum_file_size_bytes=1_000_000, - maximum_package_size_bytes=5_000_000, - required_artifacts=("task.toml",), - required_evidence=("results",), - attestation_terms=("rights_confirmed",), - ), - ) - lineage = EffectivePreSubmissionPlanLineage( - project_id=values["project"], guide_id=values["guide"], guide_version=guide_version, - source_snapshot_id=values["snapshot"], source_snapshot_hash=effective["source_snapshot_hash"], - effective_policy_id=UUID(effective["id"]), effective_policy_hash=effective["effective_policy_hash"], - pre_submit_policy_id=UUID(pre.id), pre_submit_policy_bundle_hash=pre.compiled_bundle_hash, - ) - plan = build_pre_submission_checker_catalogue().compile_effective_plan( - lineage=lineage, effective_policy=effective["effective_policy"], compiled_bundle=pre.compiled_bundle, - ) - async with factory() as session: - guide = await session.get(ProjectGuide, str(values["guide"])) - post = await session.scalar(select(PostSubmitCheckerPolicy).where( - PostSubmitCheckerPolicy.effective_policy_id == effective["id"])) - assert post is not None - return plan, { - "post_policy": post.id, - "post_policy_hash": post.policy_hash, - "post_policy_body": json.dumps(post.policy_body), - "submission_policy": effective["submission_artifact_policy_id"], - "review_policy": guide.selected_review_policy_id, - "review_policy_hash": guide.selected_review_policy_hash, - "revision_policy": guide.selected_revision_policy_id, - "revision_policy_hash": guide.selected_revision_policy_hash, - "guide_version": guide_version, - "attestation_terms": effective["effective_policy"]["attestation_terms"], - "evidence_path": "evidence/" + effective["effective_policy"]["required_evidence"][0]["key"], - } - - -async def assert_pre_submit_evidence_immutable(connection): - """Reject edits, deletes and late appends to the existing canonical evidence.""" - immutable_statements = ( - "update pre_submit_evidence_sets set terminal_status='blocked'", - "update pre_submit_evidence_results set status='failed'", - "delete from pre_submit_evidence_results", - "truncate pre_submit_evidence_results", - "insert into pre_submit_evidence_results " - "select '00000000-0000-7000-8000-000000000001'," - "evidence_set_id,result_order+1000," - "schema_version,dispatch_authority,definition_id || '.forged'," - "definition_version,public_name,source,phase,classification,severity,status," - "failure_code,message_code,effective_plan_sha256,rule_instance_id," - "locked_policy_sha256,now(),checker_order,metadata_json " - "from pre_submit_evidence_results limit 1", - ) - for statement in immutable_statements: - with pytest.raises(DBAPIError): - async with connection.begin_nested(): - await connection.execute(text(statement)) - with pytest.raises(DBAPIError, match="pre_submit_evidence_sets rows are immutable"): - async with connection.begin_nested(): - await connection.execute( - text( - "insert into pre_submit_evidence_sets select " - "(jsonb_populate_record(null::pre_submit_evidence_sets, " - "to_jsonb(existing_row) || jsonb_build_object(" - "'id','00000000-0000-7000-8000-000000000003'," - "'operation_identity','sha256:' || repeat('e',64)," - "'attempt_id',null,'attempt_request_digest',null," - "'created_at',transaction_timestamp()))).* " - "from pre_submit_evidence_sets existing_row limit 1" - ) - ) - await connection.execute( - text( - "delete from pre_submit_evidence_sets " - "where id='00000000-0000-7000-8000-000000000003'" - ) - ) - with pytest.raises(DBAPIError, match="pre_submit_evidence_sets rows are immutable"): - async with connection.begin_nested(): - await connection.execute(text("truncate pre_submit_evidence_sets cascade")) - with pytest.raises(DBAPIError, match="creation timestamp is invalid"): - async with connection.begin_nested(): - await connection.execute( - text( - "insert into pre_submit_evidence_sets select " - "(jsonb_populate_record(null::pre_submit_evidence_sets, " - "to_jsonb(existing_row) || jsonb_build_object(" - "'id','00000000-0000-7000-8000-000000000002'," - "'operation_identity','sha256:' || repeat('f',64)," - "'created_at',existing_row.created_at - interval '1 day'))).* " - "from pre_submit_evidence_sets existing_row limit 1" - ) - ) - - -async def assert_admission_replay_state(session, evidence_id, attempt_id, admission_id, status): - """Both recovery reads expose an admission ID only while its real SQL row is ready.""" - from app.modules.artifacts.submission_admission import ( - PreparedSubmissionBundlePreparationCommand, current_submission_bundle_admission_id, - ) - command = PreparedSubmissionBundlePreparationCommand( - session=session, authority=SimpleNamespace(), task_contexts=SimpleNamespace(), - project_contexts=SimpleNamespace(), runtime_factory=None, - ) - result = await command._existing_durable_result(evidence_id) - assert result.submission_bundle_preparation_status == status - assert result.admission_id == (UUID(admission_id) if status == "ready" else None) - async with session.begin(): - current = await current_submission_bundle_admission_id(session, put_attempt_id=attempt_id) - assert current == (UUID(admission_id) if status == "ready" else None) - - -def durable_put_service(session, settings, namespace, storage, authorization): - """Compose final ART handoff with the same transaction-bound canonical owners.""" - from app.modules.artifacts.service import ArtifactAdmissionService - from app.modules.artifacts.submission_admission import SubmissionBundleDurablePutService - - return SubmissionBundleDurablePutService( - session=session, admission=ArtifactAdmissionService(session, settings, namespace), - storage=storage, authorization=authorization, - task_contexts=TaskRepository(session), - project_contexts=ProjectLockedPolicyRepository(session), - ) diff --git a/backend/tests/project_role_issue_fixtures.py b/backend/tests/project_role_issue_fixtures.py new file mode 100644 index 000000000..4f163e389 --- /dev/null +++ b/backend/tests/project_role_issue_fixtures.py @@ -0,0 +1,78 @@ +"""Shared real role-issuance helpers independent of retired checker execution.""" + +from uuid import UUID + +from app.core.identifiers import new_record_id +from app.modules.actors.models import ActorIdentityLink, ActorProfile +from app.modules.actors.service import ResolvedActor +from app.modules.authorization import router as authorization_router +from app.modules.authorization.kernel import AuthorizationService +from app.modules.authorization.prepared import PreparedAuthorizationService +from app.modules.authorization.project_role_schemas import ProjectRoleGrantIssueBody +from app.modules.authorization.repository import AdminAuthorizationRepository +from app.modules.authorization.runtime import ( + ActorKind, + ActorStatus, + HumanAuthorizationContext, + IdentityLinkStatus, +) + + +def issue_body(target_actor_id: UUID) -> ProjectRoleGrantIssueBody: + """Build the exact bounded reviewer grant request used by concurrency tests.""" + return ProjectRoleGrantIssueBody.model_validate({ + "target_actor_profile_id": target_actor_id, + "role": "reviewer", + "reason": "Concurrent project-role issue lock-order proof", + "qualification": { + "skills_snapshot": { + "availability": "available", + "reference_ids": ["skill:reviewer"], + "unavailable_reason": None, + }, + "reputation_snapshot": { + "availability": "unavailable", + "reference_ids": [], + "unavailable_reason": "no_record", + }, + "prior_project_work_refs": [], + "external_expertise_refs": [], + }, + }) + + +async def issue_runtime(session, actor_id: UUID, link_id: UUID): + """Compose the real prepared role authority for an existing manager.""" + context = HumanAuthorizationContext( + actor_profile_id=actor_id, + actor_kind=ActorKind.HUMAN, + actor_status=ActorStatus.ACTIVE, + identity_link_id=link_id, + identity_link_status=IdentityLinkStatus.ACTIVE, + request_id=new_record_id(), + correlation_id=new_record_id(), + ) + repository = AdminAuthorizationRepository(session) + authority = AuthorizationService(session, context, admin_repository=repository) + prepared = PreparedAuthorizationService(session, context, authority, repository) + profile = await session.get(ActorProfile, str(actor_id)) + link = await session.get(ActorIdentityLink, str(link_id)) + assert profile is not None and link is not None + await session.commit() + return prepared, ResolvedActor(profile, link) + + +async def issue_role(session, project_id, body, issue_key, resolved, prepared): + """Invoke the actual project-role route owner and preserve rollback behavior.""" + try: + return await authorization_router.issue_project_role_grant( + project_id=project_id, + payload=body, + idempotency_key=issue_key, + resolved=resolved, + prepared=prepared, + session=session, + ) + except BaseException: + await session.rollback() + raise diff --git a/backend/tests/projects/post_policy/test_compiler.py b/backend/tests/projects/post_policy/test_compiler.py deleted file mode 100644 index 5bff9adcb..000000000 --- a/backend/tests/projects/post_policy/test_compiler.py +++ /dev/null @@ -1,93 +0,0 @@ -"""Real saved-result compiler and discriminating selection enforcement proof.""" - -from copy import deepcopy -from uuid import uuid4 - -import pytest - -from app.interfaces.project_agents import ProjectGuideCompilationResult -from app.modules.checkers.api.historical_post_submit import current_post_submit_catalogue -from app.modules.projects.post_policy.compiler import compile_saved_post_policy -from tests.projects.guide_compilation.helpers import result - - -def selected_result(): - body = result().model_dump(mode="json") - body['requirements'] = [dict(requirement_id='criteria', statement='Task acceptance criteria are present', - disposition='supported_post_submit', platform_coverage=None, evidence_refs=[])] - body['post_submit_bindings'] = [dict(requirement_id='criteria', capability_id='check_acceptance_criteria_present', - capability_version='v0.1', stage='post_submit', parameters=[])] - return body - - -def compile_body(body, catalogue=None): - return compile_saved_post_policy(project_id=uuid4(), guide_version='guide-one', - result=ProjectGuideCompilationResult.model_validate(body), - catalogue=catalogue or current_post_submit_catalogue()) - - -def test_shared_requirements_compile_once_with_all_bindings_preserved(): - body = selected_result() - body['requirements'].append(body['requirements'][0] | dict(requirement_id='criteria-two')) - body['post_submit_bindings'].append(body['post_submit_bindings'][0] | dict(requirement_id='criteria-two')) - compiled = compile_body(body) - assert compiled.required_checkers == ['check_acceptance_criteria_present'] - assert len(compiled.entries) == 9 - assert len(body['post_submit_bindings']) == 2 - assert compiled.entries[-1].configuration.model_dump() == {} - - -@pytest.mark.parametrize('change', ['missing', 'unknown', 'stage', 'version', 'default', 'configuration', 'disposition', 'duplicate_requirement']) -def test_compiler_revalidates_each_malformed_binding(change): - body = selected_result() - assert len(compile_body(body).entries) == 9 - binding = body['post_submit_bindings'][0] - if change == 'missing': - body['post_submit_bindings'] = [] - elif change == 'unknown': - binding['capability_id'] = 'unsupported' - elif change == 'stage': - binding['stage'] = 'pre_submit' - elif change == 'version': - binding['capability_version'] = 'wrong' - elif change == 'default': - binding['capability_id'] = 'check_submission_packet' - elif change == 'configuration': - binding['parameters'] = [dict(name='disable', value=True)] - elif change == 'disposition': - body['requirements'][0]['disposition'] = 'human_review' - else: - body['requirements'].append(deepcopy(body['requirements'][0])) - with pytest.raises(ValueError): - compile_body(body) - - -def test_compiler_rejects_a_real_compiler_that_omits_the_required_selection(monkeypatch): - from app.modules.projects.post_policy import compiler - from app.modules.projects.post_submit_policy import compile_project_post_submit_checker_spec - - def missing_selection(**kwargs): - kwargs['spec'] = kwargs['spec'] | dict(required_checkers=[]) - return compile_project_post_submit_checker_spec(**kwargs) - - monkeypatch.setattr(compiler, 'compile_project_post_submit_checker_spec', missing_selection) - with pytest.raises(ValueError, match='omits or changes a required binding'): - compile_body(selected_result()) - - -@pytest.mark.parametrize('index', [0, 8]) -def test_disabled_default_or_selected_capability_is_unavailable(index): - from tests.checkers.post_submit.support import altered_catalogue - - with pytest.raises(ValueError, match='unavailable'): - compile_body(selected_result(), altered_catalogue(index=index, state='disabled')) - - -def test_blocked_result_never_yields_a_policy(): - body = selected_result() - body['status'] = 'guide_blocked' - body['submission_artifact_policy'] = None - body['requirements'].append(dict(requirement_id='gap', statement='The guide lacks necessary task context', - disposition='guide_blocker', platform_coverage=None, evidence_refs=[])) - with pytest.raises(ValueError, match='blocked guide cannot project'): - compile_body(body) diff --git a/backend/tests/projects/post_policy/test_direct_sql.py b/backend/tests/projects/post_policy/test_direct_sql.py deleted file mode 100644 index 4a4f5d7b1..000000000 --- a/backend/tests/projects/post_policy/test_direct_sql.py +++ /dev/null @@ -1,176 +0,0 @@ -"""Bypass ORM persistence with complete otherwise-valid approval output custody.""" - -import json -from datetime import UTC, datetime -from uuid import uuid4 - -import pytest -from sqlalchemy import text -from sqlalchemy.exc import DBAPIError - -from app.core.identifiers import new_record_id -from app.modules.checkers.api.historical_post_submit import current_post_submit_catalogue -from app.modules.projects.api.post_policy import PostPolicyApproval -from app.modules.projects.post_policy.models import PostPolicyOperation -from app.modules.projects.post_policy.service import PostPolicyService -from tests.projects.guide_compilation.helpers import service_actor -from tests.projects.guide_compilation.proposals.pg_support import proposal_case -from .pg_support import PostAuthority, prepare_post_policy, operate -from .test_authority import foreign_manager, state - - -@pytest.mark.parametrize('change,error', [ - ('output_digest', 'post-policy operation lineage mismatch'), - ('foreign_grant', 'guide proposal current authority missing'), - ('wrong_action', 'post-policy authority evidence mismatch'), -]) -async def test_direct_sql_rejects_one_substituted_commitment(clean_postgres_database, monkeypatch, change, error): - async with proposal_case(clean_postgres_database) as (values, factory, command, actor, grant): - _, projected = await prepare_post_policy(factory, command, actor, grant, service_actor(values)) - _, _, _, foreign_grant = await foreign_manager(factory, actor) - payload = PostPolicyApproval(target=projected.target, idempotency_key=uuid4()) - before = await state(factory) - async with factory() as session: - await session.begin() - captured = [] - original_add = session.add - - def capture_operation(row, **kwargs): - if isinstance(row, PostPolicyOperation): - captured.append(row) - else: - original_add(row, **kwargs) - - try: - # Arrange actual outputs and decision; capture only the yet-unpersisted operation. - with monkeypatch.context() as patch: - patch.setattr(session, 'add', capture_operation) - service = PostPolicyService(session, PostAuthority(session, actor, command.project_id, grant), current_post_submit_catalogue()) - receipt = await service.approve(payload, actor=actor, request_id=uuid4()) - assert len(captured) == 1 - row = {c.name: getattr(captured[0], c.name) for c in PostPolicyOperation.__table__.columns} - row['created_at'] = datetime.now(UTC) - assert row['operation_id'] == receipt.operation_id - if change == 'output_digest': - row['output_digest'] = 'sha256:'+'b'*64 - elif change == 'foreign_grant': - row['admin_role_grant_id'] = foreign_grant - else: - wrong_event = str(new_record_id()) - await session.execute(text( - 'INSERT INTO audit_events SELECT (jsonb_populate_record(NULL::audit_events, ' - 'to_jsonb(source)||CAST(:patch AS jsonb))).* FROM audit_events source WHERE id=:id'), - dict(id=row['authorization_decision_event_id'], patch=json.dumps(dict( - id=wrong_event, entity_id=wrong_event, - action_id='project.post_submit_checker_policy.correction.request')))) - row['authorization_decision_event_id'] = wrong_event - await session.execute(text( - 'INSERT INTO project_post_policy_operations SELECT ' - '(jsonb_populate_record(NULL::project_post_policy_operations, CAST(:row AS jsonb))).*'), - dict(row=json.dumps(row, default=str))) - # All immediate constraints pass; force this guard before other deferred constraints. - with pytest.raises(DBAPIError, match=error): - await session.execute(text('SET CONSTRAINTS post_policy_operation_custody IMMEDIATE')) - finally: - await session.rollback() - assert await state(factory) == before - assert (await operate(factory, actor, command.project_id, grant, 'approve', payload)).kind == 'approve' - - -@pytest.mark.parametrize('classification', ['project_required', 'project_warning']) -async def test_database_rejects_unrequested_project_selection(clean_postgres_database, monkeypatch, classification): - from app.modules.projects.post_policy import service - from app.modules.projects.post_submit_policy import ( - build_project_post_submit_checker_spec, compile_project_post_submit_checker_spec, - ) - from .pg_support import prepare_upstream - - async with proposal_case(clean_postgres_database) as (values, factory, command, actor, grant): - payload = await prepare_upstream(factory, command, actor, grant) - before = await state(factory) - calls = [] - - def extra_selection(*, project_id, guide_version, result, catalogue): - assert result.post_submit_bindings == () - field = 'required_checkers' if classification == 'project_required' else 'warning_checkers' - compiled = compile_project_post_submit_checker_spec( - project_id=str(project_id), guide_version=guide_version, - spec=build_project_post_submit_checker_spec( - project_id=str(project_id), guide_version=guide_version, - **{field: ['check_acceptance_criteria_present']}), - ) - compiled.validate_catalogue(catalogue) - calls.append(compiled) - return compiled - - with monkeypatch.context() as patch: - # Faulty compiler output remains a valid canonical body with real hash/custody. - patch.setattr(service, 'compile_saved_post_policy', extra_selection) - with pytest.raises(DBAPIError, match='post-policy compiled selection not requested'): - await operate(factory, service_actor(values), command.project_id, None, 'derive', payload) - assert len(calls) == 1 - assert calls[0].entries[-1].classification == classification - assert await state(factory) == before - # Platform defaults remain valid with no project bindings, including separate approval. - projected = await operate(factory, service_actor(values), command.project_id, None, 'derive', payload) - approved = await operate(factory, actor, command.project_id, grant, 'approve', - PostPolicyApproval(target=projected.target, idempotency_key=uuid4())) - assert approved.kind == 'approve' - - -@pytest.mark.parametrize('binding_count', [1, 2]) -async def test_database_accepts_exact_selection_shared_by_requirements(clean_postgres_database, binding_count): - from app.interfaces.project_agents import ProjectGuideCompilationResult - from .test_compiler import selected_result - - body = selected_result() - if binding_count == 2: - body['requirements'].append(body['requirements'][0] | dict(requirement_id='criteria-two')) - body['post_submit_bindings'].append(body['post_submit_bindings'][0] | dict(requirement_id='criteria-two')) - outcome = ProjectGuideCompilationResult.model_validate(body) - async with proposal_case(clean_postgres_database, outcome=outcome) as (values, factory, command, actor, grant): - _, projected = await prepare_post_policy(factory, command, actor, grant, service_actor(values)) - approved = await operate(factory, actor, command.project_id, grant, 'approve', - PostPolicyApproval(target=projected.target, idempotency_key=uuid4())) - async with factory() as session: - policy = await session.scalar(text('SELECT policy_body FROM checker_policies WHERE id=:id'), - dict(id=str(projected.target.policy_id))) - selections = [entry for entry in policy['entries'] if entry['classification'] != 'platform_default'] - assert len(selections) == 1 - assert selections[0]['checker_id'] == 'check_acceptance_criteria_present' - assert selections[0]['classification'] == 'project_required' - assert approved.kind == 'approve' - - -async def test_database_rejects_missing_required_selection(clean_postgres_database, monkeypatch): - from app.interfaces.project_agents import ProjectGuideCompilationResult - from app.modules.projects.post_policy import service - from app.modules.projects.post_submit_policy import ( - build_project_post_submit_checker_spec, compile_project_post_submit_checker_spec, - ) - from .pg_support import prepare_upstream - from .test_compiler import selected_result - - async with proposal_case(clean_postgres_database, outcome=ProjectGuideCompilationResult.model_validate( - selected_result() - )) as (values, factory, command, actor, grant): - payload = await prepare_upstream(factory, command, actor, grant) - before = await state(factory) - calls = [] - - def missing_selection(*, project_id, guide_version, result, catalogue): - assert len(result.post_submit_bindings) == 1 - compiled = compile_project_post_submit_checker_spec( - project_id=str(project_id), guide_version=guide_version, - spec=build_project_post_submit_checker_spec(project_id=str(project_id), guide_version=guide_version)) - compiled.validate_catalogue(catalogue) - calls.append(compiled) - return compiled - - with monkeypatch.context() as patch: - patch.setattr(service, 'compile_saved_post_policy', missing_selection) - with pytest.raises(DBAPIError, match='post-policy compiled required binding missing'): - await operate(factory, service_actor(values), command.project_id, None, 'derive', payload) - assert len(calls) == 1 - assert await state(factory) == before - assert (await operate(factory, service_actor(values), command.project_id, None, 'derive', payload)).kind == 'derive' diff --git a/backend/tests/projects/review_policy/test_activation.py b/backend/tests/projects/review_policy/test_activation.py deleted file mode 100644 index 1e757b4f2..000000000 --- a/backend/tests/projects/review_policy/test_activation.py +++ /dev/null @@ -1,52 +0,0 @@ -"""Current activation checks exact versioned semantics before mode availability.""" - -from copy import deepcopy -from types import SimpleNamespace - -import pytest - -from app.modules.projects.api.policy_lineage import ( - ReviewPolicySemantics, - RevisionPolicySemantics, - policy_digest, -) -from app.modules.projects.service import GuideActivationBlocked, ProjectService -from projects.test_activation_readiness import _activation_ready_bundle -from test_project_policy_mutations import _review_payload, _revision_payload - - -@pytest.mark.parametrize("format", ["v1", "v2"]) -def test_current_validator_accepts_true_then_rejects_valid_false(monkeypatch, format): - bundle = _activation_ready_bundle() - review = ReviewPolicySemantics.model_validate(_review_payload().model_dump()) - revision = RevisionPolicySemantics.model_validate(_revision_payload().model_dump()) - bundle["review_policy"] = SimpleNamespace( - **review.model_dump(), - semantics_status="complete", - semantics_format=format, - policy_hash=policy_digest("review", review, review_semantics_format=format), - ) - bundle["revision_policy"] = SimpleNamespace( - **revision.model_dump(), - semantics_status="complete", - policy_hash=policy_digest("revision", revision), - ) - service = ProjectService(None) - monkeypatch.setattr( - service, - "_merge_effective_submission_artifact_policy", - lambda _: deepcopy(bundle["effective_policy"].effective_policy), - ) - # The complete-policy validator remains real for both the positive and negative. - service.validate_activation_ready(**bundle) - false = ReviewPolicySemantics.model_validate( - {**review.model_dump(), "human_review_required": False} - ) - bundle["review_policy"] = SimpleNamespace( - **false.model_dump(), - semantics_status="complete", - semantics_format="v2", - policy_hash=policy_digest("review", false), - ) - with pytest.raises(GuideActivationBlocked, match="^automated acceptance is unavailable$"): - service.validate_activation_ready(**bundle) diff --git a/backend/tests/projects/test_activation_readiness.py b/backend/tests/projects/test_activation_readiness.py deleted file mode 100644 index 592f4055c..000000000 --- a/backend/tests/projects/test_activation_readiness.py +++ /dev/null @@ -1,281 +0,0 @@ -"""Guide readiness and persisted policy-summary custody guards.""" - -from __future__ import annotations - -from collections.abc import Iterator -from copy import deepcopy -from datetime import UTC, datetime -from types import SimpleNamespace -from typing import Any, cast -from uuid import UUID, uuid4 - -import pytest - -from app.core.config import get_settings -from app.core.hashing import canonical_json_hash -from app.modules.projects import service as project_service_module -from app.modules.projects.service import GuideActivationBlocked, ProjectService -from app.modules.projects.post_submit_policy import ( - build_project_post_submit_checker_spec, compile_project_post_submit_checker_spec, -) -from projects.client_fixtures import ( - project_client as project_client, - project_database_env as project_database_env, -) - - -@pytest.fixture(autouse=True) -def clear_settings_after_test() -> Iterator[None]: - """Preserve the originating module's settings-cache cleanup.""" - try: - yield - finally: - get_settings.cache_clear() - - -def _post_submit_policy( - guide: SimpleNamespace, - snapshot: SimpleNamespace, - effective: SimpleNamespace, - pre_submit: SimpleNamespace, -) -> SimpleNamespace: - """Bind post-submit readiness to the same guide and pre-submit lineage.""" - compiled = compile_project_post_submit_checker_spec( - project_id=guide.project_id, guide_version=guide.version, - spec=build_project_post_submit_checker_spec( - project_id=guide.project_id, guide_version=guide.version, - ), - ) - return SimpleNamespace( - id=str(uuid4()), - project_id=guide.project_id, - guide_id=guide.id, - guide_version="v1", - source_snapshot_id=snapshot.id, - source_snapshot_hash=snapshot.bundle_hash, - effective_policy_id=effective.id, - effective_policy_hash=effective.effective_policy_hash, - pre_submit_checker_policy_id=pre_submit.id, - pre_submit_checker_bundle_hash=pre_submit.compiled_bundle_hash, - lifecycle_status="approved", - projection_operation_id=uuid4(), - approval_operation_id=uuid4(), - approved_at=datetime.now(UTC), - policy_body=compiled.policy_body, - policy_hash=compiled.policy_hash, - required_checkers=compiled.required_checkers, - warning_checkers=compiled.warning_checkers, - blocking_severities=list(compiled.blocking_severities), - ) - - -def _review_and_revision_policies() -> tuple[SimpleNamespace, SimpleNamespace]: - """Supply complete review/revision facts without executing either lifecycle.""" - review = SimpleNamespace( - human_review_required=True, - semantics_format="v2", - semantics_status="complete", - policy_hash=f"sha256:{'c' * 64}", - review_preference_window_seconds=60, - review_lease_duration_seconds=60, - max_active_review_leases_per_reviewer=1, - self_review_allowed=False, - reject_policy="allowed", - finding_evidence_requirement="required", - requires_second_review=False, - allowed_decisions=["accept", "needs_revision", "reject"], - minimum_finding_fields=["summary"], - ) - revision = SimpleNamespace( - semantics_status="complete", - policy_hash=f"sha256:{'d' * 64}", - max_revision_rounds=2, - revision_deadline_hours=24, - allowed_resubmission_states=["needs_revision"], - reviewer_reassignment_rule="same_reviewer", - ) - return review, revision - - -def _activation_ready_bundle() -> dict[str, Any]: - """Build one internally consistent activation bundle for fast boundary tests.""" - project_id, guide_id, snapshot_id = (str(uuid4()) for _ in range(3)) - snapshot_hash = f"sha256:{'a' * 64}" - submission_body = {"allowed_extensions": [".zip"]} - submission_hash = canonical_json_hash(submission_body) - effective_body = {"allowed_extensions": [".zip"], "max_bytes": 10} - effective_hash = canonical_json_hash(effective_body) - checker_bundle = {"checks": ["archive_safety"]} - checker_hash = canonical_json_hash(checker_bundle) - guide = SimpleNamespace(id=guide_id, project_id=project_id, version="v1") - snapshot = SimpleNamespace( - id=snapshot_id, - project_id=project_id, - guide_id=guide_id, - guide_version="v1", - bundle_hash=snapshot_hash, - ) - sufficiency = SimpleNamespace( - source_snapshot_id=snapshot_id, - source_snapshot_hash=snapshot_hash, - status="passed", - warnings_acknowledged_by_actor=None, - warnings_acknowledged_at=None, - warnings_acknowledged_by_role=None, - ) - submission = SimpleNamespace( - id=str(uuid4()), - source_snapshot_id=snapshot_id, - source_snapshot_hash=snapshot_hash, - lifecycle_status="approved", - derivation_source="unified_compilation", - policy_body=submission_body, - policy_hash=submission_hash, - approved_by_actor="actor-1", - approved_at=datetime.now(UTC), - approved_by_role="project_manager", - ) - effective = SimpleNamespace( - id=str(uuid4()), - source_snapshot_id=snapshot_id, - source_snapshot_hash=snapshot_hash, - lifecycle_status="approved", - effective_policy=effective_body, - effective_policy_hash=effective_hash, - submission_artifact_policy_id=submission.id, - submission_artifact_policy_hash=submission_hash, - ) - pre_submit = SimpleNamespace( - id=str(uuid4()), - source_snapshot_id=snapshot_id, - source_snapshot_hash=snapshot_hash, - effective_policy_id=effective.id, - effective_policy_hash=effective_hash, - lifecycle_status="compiled", - compiled_bundle=checker_bundle, - compiled_bundle_hash=checker_hash, - ) - post_submit = _post_submit_policy(guide, snapshot, effective, pre_submit) - review, revision = _review_and_revision_policies() - return { - "guide": guide, - "source_snapshot": snapshot, - "sufficiency_report": sufficiency, - "submission_artifact_policy": submission, - "effective_policy": effective, - "pre_submit_checker_policy": pre_submit, - "post_submit_checker_policy": post_submit, - "review_policy": review, - "revision_policy": revision, - # Structural validator delegation only; PostgreSQL proposal tests prove custody. - "post_policy_custody": SimpleNamespace( - approval=SimpleNamespace(operation_id=post_submit.approval_operation_id), - projection=SimpleNamespace(operation_id=post_submit.projection_operation_id), - target=SimpleNamespace(upstream=SimpleNamespace(operation_id=pre_submit.id), policy_hash=post_submit.policy_hash), - ), - "approval_custody": SimpleNamespace( - operation=SimpleNamespace(artifact_policy_id=submission.id, operation_id=pre_submit.id), - effective=effective, pre=pre_submit, - ), - } - - -def _set_activation_fact(bundle: dict[str, Any], fact: str, value: Any) -> None: - target_name, attribute = fact.split(".", 1) - setattr(bundle[target_name], attribute, value) - - -@pytest.mark.parametrize( - ("fact", "value", "message"), - [ - ("source_snapshot.project_id", "other", "snapshot project mismatch"), - ("source_snapshot.guide_id", "other", "snapshot is not current"), - ("sufficiency_report.source_snapshot_id", "other", "stale snapshot"), - ("sufficiency_report.source_snapshot_hash", "other", "snapshot hash mismatch"), - ("sufficiency_report.status", "blocked", "blocking gaps"), - ( - "submission_artifact_policy.lifecycle_status", - "draft", - "approved submission artifact policy", - ), - ("submission_artifact_policy.source_snapshot_id", "other", "bound to a stale snapshot"), - ("submission_artifact_policy.source_snapshot_hash", "other", "snapshot hash mismatch"), - ("submission_artifact_policy.policy_hash", f"sha256:{'e' * 64}", "body hash mismatch"), - ("submission_artifact_policy.approved_by_actor", None, "approval provenance"), - ("submission_artifact_policy.approved_by_role", "submitter", "approver role is invalid"), - ("effective_policy.lifecycle_status", "draft", "effective.*not approved"), - ("effective_policy.source_snapshot_id", "other", "effective.*stale snapshot"), - ("effective_policy.source_snapshot_hash", "other", "effective.*hash mismatch"), - ("effective_policy.effective_policy_hash", f"sha256:{'e' * 64}", "body hash mismatch"), - ("effective_policy.submission_artifact_policy_id", "other", "wrong policy"), - ("effective_policy.submission_artifact_policy_hash", "other", "hash provenance mismatch"), - ("pre_submit_checker_policy.source_snapshot_id", "other", "pre-submit.*stale snapshot"), - ("pre_submit_checker_policy.source_snapshot_hash", "other", "pre-submit.*hash mismatch"), - ("pre_submit_checker_policy.effective_policy_id", "other", "wrong effective policy"), - ("pre_submit_checker_policy.effective_policy_hash", "other", "bundle provenance mismatch"), - ("pre_submit_checker_policy.lifecycle_status", "draft", "compiled project pre-submit"), - ("pre_submit_checker_policy.compiled_bundle_hash", "", "compiled bundle hash is required"), - ("pre_submit_checker_policy.compiled_bundle", {}, "compiled bundle is required"), - ("post_submit_checker_policy.guide_id", "other", "post-submit.*guide mismatch"), - ( - "post_submit_checker_policy.source_snapshot_id", - "other", - "post-submit.*snapshot mismatch", - ), - ("post_submit_checker_policy.effective_policy_id", "other", "wrong effective policy"), - ("post_submit_checker_policy.pre_submit_checker_policy_id", "other", "wrong pre-submit"), - ( - "post_submit_checker_policy.pre_submit_checker_bundle_hash", - "other", - "pre-submit hash mismatch", - ), - ("post_submit_checker_policy.lifecycle_status", "compiled", "approved post-submit"), - ("post_submit_checker_policy.approval_operation_id", None, "approval custody"), - ("post_submit_checker_policy.projection_operation_id", UUID("d8aed408-588e-4214-ae5e-c214e41e2b73"), "approval custody"), - ("review_policy.allowed_decisions", [], "allowed decisions"), - ("review_policy.allowed_decisions", ["maybe"], "invalid decisions"), - ("revision_policy.max_revision_rounds", 0, "revision policy is incomplete"), - ( - "revision_policy.allowed_resubmission_states", - ["accepted"], - "invalid resubmission states", - ), - ], -) -def test_activation_readiness_rejects_broken_chain_fact( - monkeypatch: pytest.MonkeyPatch, - fact: str, - value: Any, - message: str, -) -> None: - bundle = _activation_ready_bundle() - _set_activation_fact(bundle, fact, value) - service = ProjectService(cast(Any, None)) - monkeypatch.setattr( - service, - "_merge_effective_submission_artifact_policy", - lambda _body: deepcopy(bundle["effective_policy"].effective_policy), - ) - monkeypatch.setattr( - project_service_module, - "require_complete_policy", - lambda **_kwargs: None, - ) - - with pytest.raises(GuideActivationBlocked, match=message): - service.validate_activation_ready(**bundle) - - -def test_activation_readiness_accepts_complete_chain_without_payment( - monkeypatch: pytest.MonkeyPatch, -) -> None: - bundle = _activation_ready_bundle() - service = ProjectService(cast(Any, None)) - monkeypatch.setattr( - service, - "_merge_effective_submission_artifact_policy", - lambda _body: deepcopy(bundle["effective_policy"].effective_policy), - ) - monkeypatch.setattr(project_service_module, "require_complete_policy", lambda **_: None) - - service.validate_activation_ready(**bundle) diff --git a/backend/tests/tasks/submission_dispatch/test_concurrency.py b/backend/tests/tasks/submission_dispatch/test_concurrency.py index 584d007c2..7f113dfa5 100644 --- a/backend/tests/tasks/submission_dispatch/test_concurrency.py +++ b/backend/tests/tasks/submission_dispatch/test_concurrency.py @@ -104,7 +104,7 @@ async def _role_race(tmp_path, database_url, monkeypatch, operation): from app.modules.authorization.submission_creation_authorization import PreparedSubmissionCreationAuthorization from app.modules.tasks.models import WorkstreamTask from tests.test_artifact_admission import _context, _seed_human_actor - from tests.test_pre_submit_role_issue_lock_order import _issue_body, _issue_runtime + from tests.project_role_issue_fixtures import issue_body, issue_runtime async def writer(factory, context, request): manager = _context() @@ -135,10 +135,12 @@ async def create(): ).create(request) async def mutate(): async with role_factory() as session: - prepared, resolved = await _issue_runtime(session, manager.actor_profile_id, manager.identity_link_id) + prepared, resolved = await issue_runtime( + session, manager.actor_profile_id, manager.identity_link_id + ) if operation == "issue": return await router.issue_project_role_grant( - project_id=project_id, payload=_issue_body(context.actor_profile_id), + project_id=project_id, payload=issue_body(context.actor_profile_id), idempotency_key=new_record_id(), resolved=resolved, prepared=prepared, session=session, ) return await router.revoke_project_role_grant( diff --git a/backend/tests/tasks/test_contribution_claim_races.py b/backend/tests/tasks/test_contribution_claim_races.py index 5cecf5ce1..6db7b9d35 100644 --- a/backend/tests/tasks/test_contribution_claim_races.py +++ b/backend/tests/tasks/test_contribution_claim_races.py @@ -21,7 +21,7 @@ from app.modules.tasks.models import TaskAssignment, WorkstreamTask from tests.auth_concurrency_support import wait_for_named_database_lock from tests.authorization.task_authority.test_concurrency import actor_context -from tests.test_pre_submit_role_issue_lock_order import _issue_body, _issue_role, _issue_runtime +from tests.project_role_issue_fixtures import issue_body, issue_role, issue_runtime from tests.test_tasks import ( task_database_env as task_database_env, task_client as task_client, @@ -51,7 +51,7 @@ async def test_role_issuance_and_claim_linearize_at_real_authority( ) manager_id, link_id = UUID(manager_link.actor_profile_id), UUID(manager_link.id) body = ProjectRoleGrantIssueBody.model_validate( - _issue_body(UUID(contributor)).model_dump(mode="json") | {"role": "submitter"}, + issue_body(UUID(contributor)).model_dump(mode="json") | {"role": "submitter"}, ) entered, release = asyncio.Event(), asyncio.Event() names = {side: f"cp08_{side}_{new_record_id().hex}" for side in ("claim", "issue")} @@ -89,8 +89,8 @@ async def observe_denial(authority, facts): async def issue(): async with AsyncSession(engines["issue"], expire_on_commit=False) as session: session.info["cp08_issue"] = True - prepared, resolved = await _issue_runtime(session, manager_id, link_id) - return await _issue_role( + prepared, resolved = await issue_runtime(session, manager_id, link_id) + return await issue_role( session, UUID(project["id"]), body, new_record_id(), resolved, prepared ) diff --git a/backend/tests/test_approved_guide_intake.py b/backend/tests/test_approved_guide_intake.py deleted file mode 100644 index a0110de13..000000000 --- a/backend/tests/test_approved_guide_intake.py +++ /dev/null @@ -1,277 +0,0 @@ -"""Final intake revalidation uses exact activated owner facts, not current selectors.""" - -from app.adapters.checkers import submission_evaluation_content - -from dataclasses import replace -from types import SimpleNamespace - -import pytest -from sqlalchemy import func, select, text - -from app.core.config import Settings -from app.core.hashing import canonical_json_hash -from app.modules.artifacts.models import ArtifactPutAttempt, PreSubmitEvidenceSet, SubmissionBundleDurableIntent -from app.modules.artifacts.schemas import SubmissionBundleArtifactAdmissionRequest -from app.modules.artifacts.service import ArtifactAdmissionRelationshipError, ArtifactAdmissionService -from app.modules.artifacts.submission_custody import SubmissionBundlePreparedCustody -from app.modules.artifacts.service import ArtifactStorageNamespaceSpec -from app.modules.projects.locked_policy_repository import ProjectLockedPolicyRepository -from app.modules.projects.models import ProjectGuide -from app.modules.projects.guide_activation.custody import load_guide_activation -from app.modules.tasks.repository import TaskRepository -from tests.pre_submit_test_helpers import execute_evidence_workflow -from tests.artifact_store_helpers import artifact_admission_limit_settings -from tests.test_pre_submit_attempt_recovery import _harness - - -async def _checked(harness, session): - calls = [] - workflow = harness.workflow(session, calls) - result = await execute_evidence_workflow( - workflow, harness.request, preparation_request=harness.preparation_request, - ) - assert calls == [1] and result.pass_capability is not None - custody = SubmissionBundlePreparedCustody._from_live_preparation( - prepared=harness.request.prepared_artifact, capability=result.pass_capability, - ) - return SubmissionBundleArtifactAdmissionRequest( - pre_submit_evidence_set_id=result.evidence.evidence_set_id, custody=custody, - replay_durable_intent_id=None, - ) - - -def _admission(session, tmp_path): - namespace = ArtifactStorageNamespaceSpec( - backend="local", adapter="local", provider_profile="test", - namespace_descriptor={"test": "submission-bundle"}, - namespace_fingerprint=canonical_json_hash({"test": "submission-bundle"}), - ) - return ArtifactAdmissionService(session, Settings(_env_file=None, environment="test", artifact_store_backend="local", - artifact_local_root=tmp_path / "durable", artifact_scratch_root=tmp_path / "scratch", - artifact_scratch_minimum_free_bytes=0, - **artifact_admission_limit_settings(1024 * 1024)), namespace) - - -async def _admit(session, request, authority, tmp_path, *, task_contexts=None): - # This is the real durable-admission writer, including final AUTH and custody. - return await _admission(session, tmp_path).admit( - request, submission_prepared_authorization=authority, - submission_task_contexts=task_contexts or TaskRepository(session), - submission_project_contexts=ProjectLockedPolicyRepository(session), - existing_transaction=True, - ) - - -async def _assert_intent(factory, request, admission, lineage): - # Read committed facts independently of the writer's session. - async with factory() as session: - intent, evidence, attempt = (await session.execute( - select(SubmissionBundleDurableIntent, PreSubmitEvidenceSet, ArtifactPutAttempt) - .join(PreSubmitEvidenceSet, PreSubmitEvidenceSet.id == SubmissionBundleDurableIntent.pre_submit_evidence_set_id) - .join(ArtifactPutAttempt, ArtifactPutAttempt.id == SubmissionBundleDurableIntent.put_attempt_id) - )).one() - assert intent.put_attempt_id == str(admission.attempt_id) == attempt.id - assert intent.pre_submit_evidence_set_id == str(request.pre_submit_evidence_set_id) == evidence.id - assert attempt.task_id == evidence.task_id - assert attempt.project_id == evidence.project_id == str(lineage.project_id) - assert evidence.guide_id == str(lineage.guide_id) - assert evidence.source_snapshot_id == str(lineage.source_snapshot_id) - assert evidence.effective_policy_id == str(lineage.effective_policy_id) - assert evidence.pre_submit_policy_id == str(lineage.pre_submit_policy_id) - assert evidence.locked_checker_policy_sha256 == lineage.pre_submit_policy_bundle_hash - - -async def test_final_intake_keeps_original_guide_after_successor(tmp_path, isolated_database_env): - from tests.projects.guide_activation.test_successor import successor_command - from tests.projects.guide_activation.pg_support import publish_policy - from tests.authorization.guide_activation.pg_support import activate - - harness = await _harness(tmp_path, isolated_database_env) - try: - async with harness.factory() as session: - request = await _checked(harness, session) - async with session.begin(): - lineage = harness.request.effective_plan.lineage - guide = await session.get(ProjectGuide, str(lineage.guide_id)) - first = await load_guide_activation(session, guide) - target = first.command.target.proposal - from app.modules.actors.models import ActorIdentityLink - from app.modules.authorization.models import AdminRoleGrant - from app.modules.authorization.api import ActorIdentityFacts, ActorKind - from uuid import UUID - async with harness.factory() as manager_session: - grant_row, link = (await manager_session.execute( - select(AdminRoleGrant, ActorIdentityLink) - .join(ActorIdentityLink, ActorIdentityLink.actor_profile_id == AdminRoleGrant.target_actor_profile_id) - .where(AdminRoleGrant.scope_project_id == str(target.project_id), - AdminRoleGrant.role == "project_manager", AdminRoleGrant.status == "active", - AdminRoleGrant.target_actor_profile_id != str(harness.actor_id), - ActorIdentityLink.status == "active") - .order_by(AdminRoleGrant.id, ActorIdentityLink.id).limit(1) - )).one() - actor = ActorIdentityFacts(UUID(str(grant_row.target_actor_profile_id)), UUID(str(link.id)), ActorKind.HUMAN) - grant = UUID(str(grant_row.id)) - _, policy = await publish_policy(harness.factory, target.project_id) - successor = await successor_command( - harness.factory, first.command, actor, grant, policy, - ) - successor = successor.model_copy(update={ - "expected_previous_active_guide_id": first.command.target.proposal.guide_id, - "expected_previous_active_guide_generation": first.activation_generation, - }) - next_receipt = await activate(harness.factory, actor, successor) - assert next_receipt.command.contribution_policy_version_id != first.command.contribution_policy_version_id - async with session.begin(): - authority = harness.contributor_authority(session) - await authority.revalidate(request=harness.preparation_request, project_id=lineage.project_id) - admission = await _admit(session, request, authority, tmp_path) - guide = await session.get(ProjectGuide, str(lineage.guide_id), populate_existing=True) - assert guide.status == "superseded" - await _assert_intent(harness.factory, request, admission, lineage) - finally: - await harness.close() - - -@pytest.mark.parametrize("drift", ["archived_project", "foreign_contribution_version"]) -async def test_final_intake_rejects_invalid_owner_context(tmp_path, isolated_database_env, drift): - harness = await _harness(tmp_path, isolated_database_env) - try: - async with harness.factory() as session: - request = await _checked(harness, session) - lineage = harness.request.effective_plan.lineage - authority = harness.contributor_authority(session) - async with session.begin(): - await authority.revalidate(request=harness.preparation_request, project_id=lineage.project_id) - if drift == "archived_project": - await session.execute(text("UPDATE projects SET status='archived' WHERE id=:id"), - {"id": str(lineage.project_id)}) - await session.flush() - with pytest.raises(ArtifactAdmissionRelationshipError, match="pre_submit_locked_context_changed"): - await _admit(session, request, authority, tmp_path) - else: - # Substitute a same-shaped owner result; database guards are not disabled. - from app.core.identifiers import new_record_id - real = TaskRepository(session) - from app.modules.tasks.api import TaskSubmissionContextRequest - facts = await real.lock_submission_context(TaskSubmissionContextRequest( - task_id=harness.request.task_id, assignment_id=harness.request.assignment_id, - contributor_id=harness.actor_id, predecessor_submission_id=None, - )) - foreign = new_record_id() - substituted = replace(facts, - submitter_contribution_policy_version_id=foreign, - locked_policy=facts.locked_policy.model_copy(update={ - "locked_contribution_policy_version_id": foreign, - }), - locked_project_context=replace(facts.locked_project_context, - locked_contribution_policy_version_id=foreign)) - async def wrong_context(_): - return substituted - with pytest.raises(ArtifactAdmissionRelationshipError, match="locked context changed"): - await _admit(session, request, authority, tmp_path, - task_contexts=SimpleNamespace(lock_submission_context=wrong_context)) - assert await session.scalar(select(func.count()).select_from(SubmissionBundleDurableIntent)) == 0 - await session.rollback() - async with session.begin(): - # The same passing custody remains valid after the rejected transaction rolls back. - await authority.revalidate(request=harness.preparation_request, project_id=lineage.project_id) - control = await _admit(session, request, authority, tmp_path) - await _assert_intent(harness.factory, request, control, lineage) - finally: - await harness.close() - - -async def test_command_holds_authorized_context_before_final_handoff(tmp_path, isolated_database_env): - """Observe real row locks at the final handoff of the actual async command.""" - from contextlib import asynccontextmanager - from sqlalchemy.exc import DBAPIError - from app.adapters.artifacts import CheckerPhaseService - from app.modules.artifacts.authorization import PreparedPreSubmitMaterializationAuthorization - from app.modules.artifacts.submission_admission import ( - PreparedSubmissionBundlePreparationCommand, SubmissionBundlePreparationRuntime, - SubmissionBundleDurablePutService, SubmissionBundleDurablePutResult, - ) - from tests.checkers.execution.support import forbidden_post_submission - from tests.authorization.test_pre_submit_attempt_authority import _seed_materializer - from tests.archive_fixtures import byte_source as _bytes, submission_archive as _archive - - harness = await _harness(tmp_path, isolated_database_env) - try: - await _seed_materializer(harness.factory) - await harness.request.prepared_artifact.close() - async with harness.factory() as session: - contributor = harness.contributor_authority(session) - materializer = PreparedPreSubmitMaterializationAuthorization( - session, request_id=harness.preparation_request.request_id, - correlation_id=harness.preparation_request.correlation_id, - ) - calls = [] - workflow = harness.workflow(session, calls, preparation_authorization=contributor) - workflow._materialization._authorization = materializer - admission = _admission(session, tmp_path) - durable = SubmissionBundleDurablePutService( - session=session, admission=admission, storage=object(), authorization=contributor, - task_contexts=TaskRepository(session), project_contexts=ProjectLockedPolicyRepository(session), - ) - observed = [] - async def final_handoff(request): - grant_id = (await session.execute(text( - "SELECT id FROM project_role_grants WHERE actor_profile_id=:actor " - "AND project_id=:project AND role='submitter' AND status='active'" - ), {"actor": str(harness.actor_id), - "project": str(harness.request.effective_plan.lineage.project_id)})).scalar_one() - for table, record_id in ( - ("workstream_tasks", harness.request.task_id), - ("task_assignments", harness.request.assignment_id), - ("actor_profiles", harness.actor_id), - ("actor_identity_links", harness.identity_link_id), - ("projects", harness.request.effective_plan.lineage.project_id), - ("project_role_grants", grant_id), - ): - async with harness.factory() as probe: - with pytest.raises(DBAPIError, match="lock timeout"): - async with probe.begin(): - await probe.execute(text("SET LOCAL lock_timeout='150ms'")) - await probe.execute(text(f"SELECT id FROM {table} WHERE id=:id FOR UPDATE"), - {"id": str(record_id)}) - result = await durable.admit_in_transaction(request) - observed.append(result[2].attempt_id) - return result - - async def stop_before_provider(prepared, evidence_id, admission_result): - # Byte execution ends at committed durable intent in this proof. - await prepared.close() - return SubmissionBundleDurablePutResult( - put_attempt_id=admission_result.attempt_id, - pre_submit_evidence_set_id=evidence_id, - operation_identity=admission_result.operation_identity, - status="prepared", replayed=False, admission_id=None, - ) - - @asynccontextmanager - async def runtime(): - yield SubmissionBundlePreparationRuntime( - evaluation_content=submission_evaluation_content, - preparation=harness.preparation, inspector=harness.inspector, - catalogue=harness.catalogue, materialization=workflow._materialization, - evidence=workflow, checker_service=CheckerPhaseService( - pre_submission=workflow, post_submission=forbidden_post_submission()), - durable_put=SimpleNamespace(admit_in_transaction=final_handoff, - publish_after_commit=stop_before_provider), - ) - - command = PreparedSubmissionBundlePreparationCommand( - session=session, authority=contributor, task_contexts=TaskRepository(session), - project_contexts=ProjectLockedPolicyRepository(session), runtime_factory=runtime, - ) - try: - result = await command.prepare(replace(harness.preparation_request, - byte_source=_bytes(_archive(evidence_path=harness.evidence_path)))) - assert observed == [result.put_attempt_id] and calls == [1] - async with harness.factory() as assertion: - intent = (await assertion.scalars(select(SubmissionBundleDurableIntent))).one() - assert intent.put_attempt_id == str(result.put_attempt_id) - finally: - materializer.close() - finally: - await harness.close() diff --git a/backend/tests/test_behavior_ownership.py b/backend/tests/test_behavior_ownership.py index af342acc9..38c347e51 100644 --- a/backend/tests/test_behavior_ownership.py +++ b/backend/tests/test_behavior_ownership.py @@ -1951,6 +1951,22 @@ def test_arch03a_partition_transition_accepts_only_exact_policy_lineage_relocati ownership._validate_additive_partition_transition(_partition(after), _partition(before)) +def test_pilot04_partition_allows_only_the_selected_flow_and_retired_catalogues() -> None: + """The selected checker cutover admits its exact owners and retirements.""" + retained = "backend/app/core/config.py" + retired = ownership.PILOT_04_RETIRED_CATALOGUE_TARGETS + trusted = _partition(sorted({retained, *retired})) + selected = ownership.PILOT_04_SELECTED_FLOW_TARGETS + ownership._validate_additive_partition_transition( + _partition(sorted({retained, *selected})), trusted + ) + with pytest.raises(ownership.BehaviorOwnershipError, match="untrusted_partition_change"): + ownership._validate_additive_partition_transition( + _partition(sorted({*selected, "backend/app/modules/checkers/unreviewed.py"})), + trusted, + ) + + def test_command_replay_partition_addition_does_not_authorize_neighbors() -> None: """Admit the exact replay owner without opening adjacent unreviewed paths.""" retained = "backend/app/core/config.py" diff --git a/backend/tests/test_blocked_pre_submit_feedback_postgresql.py b/backend/tests/test_blocked_pre_submit_feedback_postgresql.py deleted file mode 100644 index 13d768e7b..000000000 --- a/backend/tests/test_blocked_pre_submit_feedback_postgresql.py +++ /dev/null @@ -1,232 +0,0 @@ -"""Real blocked preparation feedback, replay, and no-product-effect proof.""" - -from __future__ import annotations - -from contextlib import asynccontextmanager -from dataclasses import replace -from pathlib import Path - -import pytest -from sqlalchemy import func, select, text - -from app.adapters.artifacts import CheckerPhaseService -from app.adapters.checkers import submission_evaluation_content -from app.core.hashing import canonical_json_hash -from app.core.identifiers import new_record_id -from app.modules.artifacts.api import SubmissionBundlePreparationCheckFailed -from app.modules.artifacts.authorization import ( - PreparedPreSubmitMaterializationAuthorization, -) -from app.modules.artifacts.models import ( - PreSubmitEvidenceResult, - PreSubmitEvidenceSet, - PreSubmitExecutionAttempt, -) -from app.modules.artifacts.submission_admission import ( - PreparedSubmissionBundlePreparationCommand, - SubmissionBundlePreparationRuntime, -) -from app.modules.checkers.api.execution import REQUEST_EVENT -from app.modules.outbox.api import OutboxAppendDisposition, OutboxAppendInput -from app.modules.outbox.service import OutboxService -from app.modules.projects.locked_policy_repository import ProjectLockedPolicyRepository -from app.modules.tasks.repository import TaskRepository -from tests.authorization.test_pre_submit_attempt_authority import _seed_materializer -from tests.checkers.execution.support import forbidden_post_submission -from tests.archive_fixtures import byte_source as _bytes, submission_archive as _archive -from tests.test_pre_submit_attempt_recovery import _harness - - -async def _authorized_harness(tmp_path: Path, database_url: str): - harness = await _harness(tmp_path, database_url) - await harness.request.prepared_artifact.close() - await _seed_materializer(harness.factory) - return harness - - -async def _product_state(harness) -> dict[str, object]: - async with harness.factory() as session: - values = ( - await session.execute( - text( - "select " - "(select status from workstream_tasks where id=:task) as task_status," - "(select count(*) from submissions) as submissions," - "(select max(version) from submissions) as max_version," - "(select count(*) from submission_bundle_admissions) as admissions," - "(select count(*) from submission_bundle_admissions " - " where status='ready') as ready_admissions," - "(select count(*) from checker_runs) as checker_runs," - "(select count(*) from audit_events " - " where event_domain<>'authority') as lifecycle_audit_events," - "(select count(*) from outbox_events) as outbox_events" - ), - {"task": str(harness.request.task_id)}, - ) - ).mappings().one() - await session.rollback() - return dict(values) - - -def _assert_no_product_effects( - actual: dict[str, object], expected: dict[str, object] -) -> None: - for field, expected_value in expected.items(): - assert actual[field] == expected_value, f"{field} changed" - assert set(actual) == set(expected) - - -async def _evidence_state(harness): - async with harness.factory() as session: - attempt = await session.scalar( - select(PreSubmitExecutionAttempt).where( - PreSubmitExecutionAttempt.task_id == str(harness.request.task_id) - ) - ) - assert attempt is not None and attempt.status == "completed" - evidence = await session.get(PreSubmitEvidenceSet, attempt.evidence_set_id) - assert evidence is not None and evidence.eligible is False - result_ids = tuple( - await session.scalars( - select(PreSubmitEvidenceResult.id) - .where(PreSubmitEvidenceResult.evidence_set_id == evidence.id) - .order_by(PreSubmitEvidenceResult.result_order) - ) - ) - counts = ( - await session.scalar(select(func.count()).select_from(PreSubmitEvidenceSet)), - await session.scalar(select(func.count()).select_from(PreSubmitEvidenceResult)), - await session.scalar(text("select count(*) from checker_runs")), - ) - identity = evidence.id, result_ids, counts - await session.rollback() - return identity - - -async def _invoke_blocked(harness, calls: list[int]): - async with harness.factory() as session: - contributor = harness.contributor_authority(session) - materializer = PreparedPreSubmitMaterializationAuthorization( - session, - request_id=harness.preparation_request.request_id, - correlation_id=harness.preparation_request.correlation_id, - ) - workflow = harness.workflow( - session, - calls, - preparation_authorization=contributor, - ) - workflow._materialization._authorization = materializer - - @asynccontextmanager - async def runtime(): - try: - yield SubmissionBundlePreparationRuntime( - preparation=harness.preparation, - inspector=harness.inspector, - catalogue=harness.catalogue, - materialization=workflow._materialization, - evidence=workflow, - checker_service=CheckerPhaseService( - pre_submission=workflow, - post_submission=forbidden_post_submission(), - ), - durable_put=object(), - evaluation_content=submission_evaluation_content, - ) - finally: - materializer.close() - - command = PreparedSubmissionBundlePreparationCommand( - session=session, - authority=contributor, - task_contexts=TaskRepository(session), - project_contexts=ProjectLockedPolicyRepository(session), - runtime_factory=runtime, - ) - request = replace( - harness.preparation_request, - contributor_attestation="", - byte_source=_bytes(_archive(evidence_path=harness.evidence_path)), - ) - with pytest.raises(SubmissionBundlePreparationCheckFailed) as failure: - await command.prepare(request) - return failure.value.facts - - -def _submission_event(harness) -> OutboxAppendInput: - submission_id = new_record_id() - request_id = new_record_id() - digest = canonical_json_hash({"submission_id": str(submission_id)}) - return OutboxAppendInput( - event_type=REQUEST_EVENT, - event_version=1, - aggregate_type="submission", - aggregate_id=submission_id, - project_id=harness.request.effective_plan.lineage.project_id, - correlation_id=str(request_id), - idempotency_key=f"submission-evaluation:{submission_id}", - payload={ - "project_id": str(harness.request.effective_plan.lineage.project_id), - "task_id": str(harness.request.task_id), - "submission_id": str(submission_id), - "submission_version": 1, - "request_id": str(request_id), - "request_digest": digest, - "evaluation_generation": 1, - "attempt_id": str(new_record_id()), - "result_id": str(new_record_id()), - "creation_decision_id": str(new_record_id()), - "binding_decision_id": str(new_record_id()), - }, - ) - - -@pytest.mark.asyncio -async def test_authorized_blocked_command_replays_exact_feedback_without_product_effects( - tmp_path: Path, - isolated_database_env: str, -) -> None: - harness = await _authorized_harness(tmp_path, isolated_database_env) - calls: list[int] = [] - try: - before = await _product_state(harness) - assert before["task_status"] == "in_progress" - assert before["submissions"] == 0 - assert before["max_version"] is None - - first_feedback = await _invoke_blocked(harness, calls) - assert first_feedback.eligible is False - assert any(entry.failure_code is not None for entry in first_feedback.entries) - assert calls == [1] - - first_identity = await _evidence_state(harness) - _assert_no_product_effects(await _product_state(harness), before) - - replay_feedback = await _invoke_blocked(harness, calls) - assert replay_feedback == first_feedback - assert calls == [1] - assert await _evidence_state(harness) == first_identity - _assert_no_product_effects(await _product_state(harness), before) - finally: - await harness.close() - - -@pytest.mark.asyncio -async def test_no_product_effect_snapshot_detects_submission_aggregate_outbox( - tmp_path: Path, - isolated_database_env: str, -) -> None: - harness = await _harness(tmp_path, isolated_database_env) - try: - before = await _product_state(harness) - async with harness.factory() as session, session.begin(): - result = await OutboxService(session).append(_submission_event(harness)) - assert result.disposition is OutboxAppendDisposition.CREATED - - after = await _product_state(harness) - assert after["outbox_events"] == before["outbox_events"] + 1 - with pytest.raises(AssertionError, match="outbox_events changed"): - _assert_no_product_effects(after, before) - finally: - await harness.close() diff --git a/backend/tests/test_checker_catalogue.py b/backend/tests/test_checker_catalogue.py deleted file mode 100644 index d6eb249bc..000000000 --- a/backend/tests/test_checker_catalogue.py +++ /dev/null @@ -1,686 +0,0 @@ -"""Proof for the single pre-submission catalogue and effective plan compiler.""" - -from __future__ import annotations - -from app.core.config import get_settings - -from app.adapters.tasks import task_service - -from dataclasses import replace -import json -from app.core.identifiers import new_record_id - -import pytest - -from app.core.hashing import canonical_json_hash -from app.core.config import Settings -from app.main import create_app -from app.modules.checkers.catalogue import ( - PRE_SUBMISSION_CATALOGUE_ID, - PRE_SUBMISSION_CATALOGUE_SCHEMA_VERSION, - PreSubmissionCatalogueError, - PreSubmissionCheckerCatalogue, - PreSubmissionDisabledBehavior, - PreSubmissionCheckerPhase, - PreSubmissionCheckerState, - build_pre_submission_checker_catalogue, - parse_disabled_pre_submission_checker_ids, -) -from app.modules.checkers.compiler import ( - compile_effective_project_submission_artifact_policy, -) -from app.modules.checkers.effective_plan import ( - EffectivePreSubmissionPlanError, - EffectivePreSubmissionPlanLineage, - PreSubmissionInfrastructureUnavailableError, - compile_effective_pre_submission_execution_plan, -) - - -def _effective_policy() -> dict[str, object]: - default_policy = { - "required_packet_fields": ["summary", "worker_attestation"], - "forbidden_artifacts": [{"pattern": ".env"}, {"pattern": ".git/**"}], - "attestation_terms": ["rights_confirmed"], - } - return { - "workstream_default_policy": default_policy, - "project_policy": {}, - "required_packet_fields": default_policy["required_packet_fields"], - "required_artifacts": [ - {"key": "task.toml", "path": "task.toml", "required": True} - ], - "required_evidence": [{"key": "results", "required": True}], - "forbidden_artifacts": default_policy["forbidden_artifacts"], - "attestation_terms": default_policy["attestation_terms"], - "manifest_required": True, - "artifact_hash_required": True, - "artifact_hash_algorithm": "sha256", - "allowed_storage_schemes": ["s3"], - "maximum_file_size_bytes": 1_000_000, - "maximum_package_size_bytes": 5_000_000, - "packaging": {"package_required": True, "allowed_package_formats": ["zip"]}, - } - - -def _compiled_and_lineage() -> tuple[dict[str, object], EffectivePreSubmissionPlanLineage]: - effective_policy_hash = canonical_json_hash(_effective_policy()) - compiled = compile_effective_project_submission_artifact_policy( - _effective_policy(), effective_policy_hash - ) - lineage = EffectivePreSubmissionPlanLineage( - project_id=new_record_id(), - guide_id=new_record_id(), - guide_version="3", - source_snapshot_id=new_record_id(), - source_snapshot_hash="sha256:" + "2" * 64, - effective_policy_id=new_record_id(), - effective_policy_hash=effective_policy_hash, - pre_submit_policy_id=new_record_id(), - pre_submit_policy_bundle_hash=compiled.compiled_bundle_hash, - ) - return compiled.compiled_bundle, lineage - - -def test_catalogue_is_single_canonical_closed_namespace() -> None: - catalogue = build_pre_submission_checker_catalogue() - ids = [entry.stable_id for entry in catalogue.entries] - - assert catalogue.catalogue_id == PRE_SUBMISSION_CATALOGUE_ID - assert catalogue.schema_version == PRE_SUBMISSION_CATALOGUE_SCHEMA_VERSION - assert len(ids) == len(set(ids)) == 28 - assert ids == [ - entry.stable_id - for entry in sorted( - catalogue.entries, - key=lambda entry: ( - list(PreSubmissionCheckerPhase).index(entry.phase), - entry.order, - entry.stable_id, - ), - ) - ] - assert catalogue.manifest_sha256 == canonical_json_hash(dict(catalogue.manifest)) - - expected = { - "enforce_storage_scheme": ("policy.storage_scheme.enforce", "check_evidence_integrity"), - "require_manifest_field": ("policy.manifest_field.require", "check_evidence_integrity"), - "limit_file_size": ("policy.file_size.limit", "check_evidence_integrity"), - "limit_package_size": ("policy.package_size.limit", "check_evidence_integrity"), - "limit_archive_entries": ("policy.archive_entries.limit", "check_evidence_integrity"), - "limit_archive_size": ("policy.archive_size.limit", "check_evidence_integrity"), - } - for primitive, (stable_id, public_name) in expected.items(): - definition = catalogue.primitive_definition(primitive) - assert (definition.stable_id, definition.public_name) == (stable_id, public_name) - - -@pytest.mark.parametrize("limit", [True, False, 0, -1, "100", 1.5]) -@pytest.mark.parametrize("field", ["maximum_archive_entries", "maximum_archive_size_bytes"]) -def test_archive_limit_rejects_invalid_policy_and_compiler_input(limit, field) -> None: - from pydantic import ValidationError - from app.interfaces.project_agents import SubmissionArtifactPolicyProposal - from app.modules.projects.schemas import SubmissionArtifactPolicyInput - from app.modules.checkers.compiler import PreSubmitCheckerCompilerError - - with pytest.raises(ValidationError): - SubmissionArtifactPolicyInput(**{field: limit}) - with pytest.raises(ValidationError): - SubmissionArtifactPolicyProposal( - maximum_file_size_bytes=100, maximum_package_size_bytes=1000, - **{field: limit}, - ) - policy = {**_effective_policy(), field: limit} - with pytest.raises(PreSubmitCheckerCompilerError): - compile_effective_project_submission_artifact_policy(policy, canonical_json_hash(policy)) - - -@pytest.mark.parametrize("alteration", ["missing", "weakened", "boolean", "warning"]) -@pytest.mark.parametrize("field, primitive", [ - ("maximum_archive_entries", "limit_archive_entries"), - ("maximum_archive_size_bytes", "limit_archive_size"), -]) -def test_archive_limit_compiler_rejects_rule_substitution(alteration, field, primitive) -> None: - from copy import deepcopy - from app.modules.checkers.compiler import ( - PreSubmitCheckerCompilerError, validate_compiled_pre_submit_checker_bundle, - ) - - policy = {**_effective_policy(), field: 1} - digest = canonical_json_hash(policy) - compiled = compile_effective_project_submission_artifact_policy(policy, digest) - bundle = deepcopy(compiled.compiled_bundle) - rule = next(item for item in bundle["rules"] if item["primitive"] == primitive) - if alteration == "missing": - bundle["rules"].remove(rule) - elif alteration == "warning": - rule["severity"] = "warning" - else: - rule["config"][field] = True if alteration == "boolean" else 2 - with pytest.raises(PreSubmitCheckerCompilerError): - validate_compiled_pre_submit_checker_bundle(policy, digest, bundle) - - -@pytest.mark.parametrize("value", [True, 0, -1, "2", 2.5]) -@pytest.mark.parametrize("field", ["maximum_archive_entries", "maximum_archive_size_bytes"]) -def test_locked_archive_limit_rejects_malformed_values(value, field): - from app.modules.tasks.service import TaskLockedContextInvalid - - policy = {**_effective_policy(), field: value} - with pytest.raises(TaskLockedContextInvalid): - task_service(None, settings=get_settings())._optional_policy_non_negative_int(policy, field, minimum=1) - - -@pytest.mark.parametrize("field, primitive", [ - ("maximum_archive_entries", "limit_archive_entries"), - ("maximum_archive_size_bytes", "limit_archive_size"), -]) -def test_archive_limit_changes_locked_hashes_and_preserves_null_semantics(field, primitive): - - hashes = set() - for limit in (None, 1, 100): - policy = {**_effective_policy(), field: limit} - digest = canonical_json_hash(policy) - compiled = compile_effective_project_submission_artifact_policy(policy, digest) - rules = [item for item in compiled.compiled_bundle["rules"] - if item["primitive"] == primitive] - assert len(rules) == (0 if limit is None else 1) - assert task_service(None, settings=get_settings())._optional_policy_non_negative_int( - policy, field, minimum=1, - ) == limit - hashes.add((digest, compiled.compiled_bundle_hash)) - assert len(hashes) == 3 - - -@pytest.mark.parametrize("count, size, archive_delta, file_limit, failure, task_path", [ - (3, 4101, None, None, None, "task.toml"), - (2, 4101, None, None, "policy.archive_entries.limit", "task.toml"), - (3, 4100, None, None, "policy.package_size.limit", "task.toml"), - (None, 4101, None, None, None, "task.toml"), - (4, 4101, None, None, "policy.file.require", "wrapper/task.toml"), - (3, 4101, 0, None, None, "task.toml"), - (3, 4101, -1, None, "policy.archive_size.limit", "task.toml"), - (3, 4101, None, 4096, None, "task.toml"), - (3, 4101, None, 4095, "policy.file_size.limit", "task.toml"), -]) -@pytest.mark.parametrize("explicit_directory", [True, False]) -def test_real_zip_enforces_locked_archive_limits( - tmp_path, count, size, archive_delta, file_limit, failure, task_path, explicit_directory, -) -> None: - from hashlib import sha256 - from io import BytesIO - from zipfile import ZipFile, ZIP_DEFLATED, ZIP_STORED - from app.modules.artifacts.sources import ArtifactCommitment - from app.modules.artifacts.submission_archive import SubmissionArchiveInspector, SubmissionArchiveLimits - from app.modules.artifacts.submission_manifest import build_submission_manifest, evaluate_submission_change - from app.modules.checkers.pre_submit_execution import ( - DefaultPreSubmissionExecutionInput, EffectivePreSubmissionProcessor, - SubmissionPacketView, PreSubmissionResultStatus, - ) - - source = BytesIO() - with ZipFile(source, "w", compression=ZIP_DEFLATED) as archive: - if explicit_directory: - archive.writestr("evidence/", b"", compress_type=ZIP_STORED) - archive.writestr(task_path, bytes(range(256)) * 16) - archive.writestr("evidence/results", b"proof") - data = source.getvalue() - inspector = SubmissionArchiveInspector(SubmissionArchiveLimits()) - inspection = inspector.inspect(BytesIO(data)) - manifest = build_submission_manifest(inspection) - assert manifest.entry_count == (4 if task_path.startswith("wrapper/") else 3) - assert inspection.file_count == 2 - assert len(data) < 4100 < manifest.total_expanded_bytes == 4101 - commitment = ArtifactCommitment("sha256:" + sha256(data).hexdigest(), len(data), "application/zip") - policy = {**_effective_policy(), "maximum_archive_entries": count, "maximum_package_size_bytes": size} - policy["maximum_archive_size_bytes"] = None if archive_delta is None else len(data) + archive_delta - if file_limit is not None: - policy["maximum_file_size_bytes"] = file_limit - digest = canonical_json_hash(policy) - compiled = compile_effective_project_submission_artifact_policy(policy, digest) - _, lineage = _compiled_and_lineage() - lineage = replace(lineage, effective_policy_hash=digest, - pre_submit_policy_bundle_hash=compiled.compiled_bundle_hash) - catalogue = build_pre_submission_checker_catalogue() - plan = compile_effective_pre_submission_execution_plan( - lineage=lineage, effective_policy=policy, compiled_bundle=compiled.compiled_bundle, catalogue=catalogue, - ) - execution = DefaultPreSubmissionExecutionInput( - plan=plan, commitment=commitment, inspection=inspection, manifest=manifest, - change_gate=evaluate_submission_change(commitment=commitment, manifest=manifest, - predecessor=None, predecessor_exists=False), - packet=SubmissionPacketView(summary="Completed work", contributor_attestation=( - "No confidential client data, credentials, or copied source material; rights_confirmed." - )), - prepared_generation_id=new_record_id(), storage_scheme="s3", - ) - workspace = tmp_path / "private" - workspace.mkdir(mode=0o700) - result = EffectivePreSubmissionProcessor( - archive_inspector=inspector, catalogue=catalogue, execution_input=execution, - ).process_blocking(BytesIO(data), workspace) - failed = [item.definition.definition_id for item in result.entries - if item.status is PreSubmissionResultStatus.FAILED] - assert failed == ([] if failure is None else [failure]) - assert result.eligible is (failure is None) - - -def test_compressed_limit_declares_commitment_in_catalogue_projection_and_plan(): - from app.modules.checkers.catalogue import project_guide_pre_submission_capabilities - - catalogue = build_pre_submission_checker_catalogue() - expected = ("LockedProjectCheckerRule", "ArtifactCommitment") - definition = catalogue.definition("policy.archive_size.limit") - assert definition.typed_inputs == expected - projection = project_guide_pre_submission_capabilities(catalogue) - projected = next(item for item in projection.definitions if item.stable_id == definition.stable_id) - assert projected.typed_inputs == expected - policy = {**_effective_policy(), "maximum_archive_size_bytes": 1000} - digest = canonical_json_hash(policy) - compiled = compile_effective_project_submission_artifact_policy(policy, digest) - _, lineage = _compiled_and_lineage() - lineage = replace(lineage, effective_policy_hash=digest, - pre_submit_policy_bundle_hash=compiled.compiled_bundle_hash) - plan = compile_effective_pre_submission_execution_plan( - lineage=lineage, effective_policy=policy, - compiled_bundle=compiled.compiled_bundle, catalogue=catalogue, - ) - entry = next(item for item in plan.entries if item.definition_id == definition.stable_id) - assert entry.typed_inputs == expected - manifest_entry = next(item for item in catalogue.manifest["entries"] - if item["stable_id"] == definition.stable_id) - assert manifest_entry["typed_inputs"] == list(expected) - assert plan.plan_sha256 == canonical_json_hash(plan.as_dict()) - - -def test_catalogue_exact_v01_contract_is_locked() -> None: - catalogue = build_pre_submission_checker_catalogue() - actual = { - "|".join( - ( - entry.stable_id, - entry.version, - entry.public_name, - entry.classification.value, - entry.phase.value, - str(entry.order), - entry.dispatch_kind.value, - entry.dispatch_capability, - entry.primitive or "-", - entry.disabled_behavior.value, - ",".join(f"{name}={value}" for name, value in entry.resource_budget), - ) - ) - for entry in catalogue.entries - } - expected = { - "artifact.outer_zip.valid|v1|artifact.outer_zip.valid|mandatory_security|custody|10|platform_capability|submission_archive.outer_zip_valid|-|infrastructure_unavailable|maximum_results=1", - "artifact.archive.paths_safe|v1|artifact.archive.paths_safe|mandatory_security|custody|20|platform_capability|submission_archive.paths_safe|-|infrastructure_unavailable|maximum_results=1", - "artifact.archive.entries_safe|v1|Reject encrypted ZIP entries, symbolic links and special files|mandatory_security|custody|30|platform_capability|submission_archive.entries_safe|-|infrastructure_unavailable|maximum_results=1", - "artifact.archive.resources_bounded|v1|artifact.archive.resources_bounded|mandatory_security|custody|40|platform_capability|submission_archive.resources_bounded|-|infrastructure_unavailable|maximum_results=1", - "artifact.archive.integrity_verified|v1|artifact.archive.integrity_verified|mandatory_integrity|custody|50|platform_capability|submission_archive.integrity_verified|-|infrastructure_unavailable|maximum_results=1", - "artifact.archive.identity_computed|v1|artifact.archive.identity_computed|mandatory_integrity|identity|10|platform_capability|artifact_commitment.identity|-|infrastructure_unavailable|maximum_results=1", - "artifact.manifest.semantic_identity_computed|v1|artifact.manifest.semantic_identity_computed|mandatory_integrity|identity|20|platform_capability|submission_manifest.semantic_identity|-|infrastructure_unavailable|maximum_results=1", - "artifact.manifest.executable_normalized|v1|artifact.manifest.executable_normalized|mandatory_integrity|identity|30|platform_capability|submission_manifest.executable_normalized|-|infrastructure_unavailable|maximum_results=1", - "artifact.revision.content_changed|v1|artifact.revision.content_changed|mandatory_integrity|identity|40|platform_capability|submission_change.changed|-|infrastructure_unavailable|maximum_results=1", - "artifact.scratch.sealed_tree_verified|v1|artifact.scratch.sealed_tree_verified|mandatory_integrity|materialization|10|platform_capability|submission_materialization.sealed_tree_verified|-|infrastructure_unavailable|maximum_results=1", - "submission.packet.required_fields|v1|check_submission_packet|mandatory_accountability|default_policy|10|platform_capability|validate_submission_packet|-|infrastructure_unavailable|maximum_results=1", - "submission.attestation.required_topics|v1|check_confidentiality_attestation|mandatory_accountability|default_policy|20|platform_capability|require_attestation|-|infrastructure_unavailable|maximum_results=1", - "artifact.sensitive_paths.high_confidence|v1|check_forbidden_files|mandatory_security|default_policy|30|platform_capability|forbid_high_confidence_sensitive_path|-|infrastructure_unavailable|maximum_results=1", - "artifact.quality.placeholder_signal|v1|check_low_quality_generated_artifacts|advisory|default_policy|40|platform_capability|warn_low_quality_generated_artifact|-|record_disabled_and_continue|maximum_results=1", - "policy.submission_packet.validate|v1|check_submission_packet|mandatory_accountability|project_policy|10|policy_primitive|validate_submission_packet|validate_submission_packet|infrastructure_unavailable|maximum_results=1", - "policy.storage_scheme.enforce|v1|check_evidence_integrity|mandatory_integrity|project_policy|20|policy_primitive|enforce_storage_scheme|enforce_storage_scheme|infrastructure_unavailable|maximum_results=1", - "policy.manifest_field.require|v1|check_evidence_integrity|mandatory_integrity|project_policy|30|policy_primitive|require_manifest_field|require_manifest_field|infrastructure_unavailable|maximum_results=1", - "policy.hash.verify|v1|check_evidence_integrity|mandatory_integrity|project_policy|40|policy_primitive|verify_hash|verify_hash|infrastructure_unavailable|maximum_results=1", - "policy.file.require|v1|check_required_files|mandatory_accountability|project_policy|50|policy_primitive|require_file|require_file|infrastructure_unavailable|maximum_results=1", - "policy.evidence.minimum|v1|check_evidence_present|mandatory_accountability|project_policy|60|policy_primitive|require_minimum_evidence|require_minimum_evidence|infrastructure_unavailable|maximum_results=1", - "policy.artifact.forbid|v1|check_forbidden_files|mandatory_security|project_policy|70|policy_primitive|forbid_artifact|forbid_artifact|infrastructure_unavailable|maximum_results=1", - "policy.attestation.require|v1|check_confidentiality_attestation|mandatory_accountability|project_policy|80|policy_primitive|require_attestation|require_attestation|infrastructure_unavailable|maximum_results=1", - "policy.file_size.limit|v1|check_evidence_integrity|mandatory_integrity|project_policy|90|policy_primitive|limit_file_size|limit_file_size|infrastructure_unavailable|maximum_results=1", - "policy.package_size.limit|v1|check_evidence_integrity|mandatory_integrity|project_policy|100|policy_primitive|limit_package_size|limit_package_size|infrastructure_unavailable|maximum_results=1", - "policy.archive_entries.limit|v1|check_evidence_integrity|mandatory_integrity|project_policy|105|policy_primitive|limit_archive_entries|limit_archive_entries|infrastructure_unavailable|maximum_results=1", - "policy.archive_size.limit|v1|check_evidence_integrity|mandatory_integrity|project_policy|102|policy_primitive|limit_archive_size|limit_archive_size|infrastructure_unavailable|maximum_results=1", - "policy.packaging.require|v1|check_submission_packet|mandatory_accountability|project_policy|110|policy_primitive|require_packaging|require_packaging|infrastructure_unavailable|maximum_results=1", - "policy.generated_quality.warn|v1|check_low_quality_generated_artifacts|advisory|project_policy|120|policy_primitive|warn_low_quality_generated_artifact|warn_low_quality_generated_artifact|record_disabled_and_continue|maximum_results=1", - } - - assert actual == expected - - -def test_catalogue_manifest_does_not_install_broad_generic_path_heuristics() -> None: - manifest = json.dumps(dict(build_pre_submission_checker_catalogue().manifest), sort_keys=True) - for forbidden_heuristic in ("token*", "secret*", "credential*", "node_modules"): - assert forbidden_heuristic not in manifest - - -def test_catalogue_rejects_unknown_duplicate_and_unsafe_dependency_configuration() -> None: - with pytest.raises(PreSubmissionCatalogueError, match="unknown"): - build_pre_submission_checker_catalogue(disabled_entry_ids=frozenset({"unknown"})) - with pytest.raises(PreSubmissionCatalogueError, match="duplicates"): - parse_disabled_pre_submission_checker_ids( - "artifact.outer_zip.valid,artifact.outer_zip.valid" - ) - - valid = build_pre_submission_checker_catalogue() - first = valid.entries[0] - duplicate = tuple( - sorted( - (*valid.entries, first), key=lambda entry: (entry.phase, entry.order, entry.stable_id) - ) - ) - with pytest.raises(PreSubmissionCatalogueError, match="duplicate stable IDs"): - PreSubmissionCheckerCatalogue( - valid.catalogue_id, valid.version, valid.schema_version, duplicate - ) - - version_alias = tuple( - sorted( - (*valid.entries, replace(first, version="v2")), - key=lambda entry: (entry.phase, entry.order, entry.stable_id), - ) - ) - with pytest.raises(PreSubmissionCatalogueError, match="duplicate stable IDs"): - PreSubmissionCheckerCatalogue( - valid.catalogue_id, valid.version, valid.schema_version, version_alias - ) - - broken = (replace(first, dependencies=("missing.definition",)), *valid.entries[1:]) - with pytest.raises(PreSubmissionCatalogueError, match="dependency is missing"): - PreSubmissionCheckerCatalogue( - valid.catalogue_id, valid.version, valid.schema_version, broken - ) - - -@pytest.mark.parametrize( - ("mutation", "message"), - [ - ({"stable_id": ""}, "identity"), - ({"order": -1}, "order"), - ( - {"dependencies": ("artifact.outer_zip.valid", "artifact.outer_zip.valid")}, - "duplicate dependencies", - ), - ({"typed_inputs": ()}, "typed inputs"), - ({"resource_budget": (("maximum_results", -1),)}, "resource budget"), - ( - {"disabled_behavior": PreSubmissionDisabledBehavior.RECORD_DISABLED_AND_CONTINUE}, - "mandatory catalogue definition may not skip", - ), - ({"dispatch_capability": "unknown.capability"}, "capability is unknown"), - ], -) -def test_catalogue_definition_validation_fails_closed( - mutation: dict[str, object], message: str -) -> None: - definition = build_pre_submission_checker_catalogue().entries[0] - with pytest.raises(PreSubmissionCatalogueError, match=message): - replace(definition, **mutation) - - -def test_catalogue_rejects_noncanonical_order_and_dependency_order() -> None: - catalogue = build_pre_submission_checker_catalogue() - with pytest.raises(PreSubmissionCatalogueError, match="not canonical"): - PreSubmissionCheckerCatalogue( - catalogue.catalogue_id, - catalogue.version, - catalogue.schema_version, - tuple(reversed(catalogue.entries)), - ) - first, second, *rest = catalogue.entries - broken_first = replace(first, dependencies=(second.stable_id,)) - broken = tuple( - sorted( - (broken_first, second, *rest), - key=lambda entry: ( - list(PreSubmissionCheckerPhase).index(entry.phase), - entry.order, - entry.stable_id, - ), - ) - ) - with pytest.raises(PreSubmissionCatalogueError, match="dependency order"): - PreSubmissionCheckerCatalogue( - catalogue.catalogue_id, - catalogue.version, - catalogue.schema_version, - broken, - ) - - -def test_mandatory_disabled_fails_closed_and_advisory_disabled_stays_visible() -> None: - compiled_bundle, lineage = _compiled_and_lineage() - mandatory_disabled = build_pre_submission_checker_catalogue( - disabled_entry_ids=frozenset({"artifact.outer_zip.valid"}) - ) - assert mandatory_disabled.available is False - with pytest.raises( - PreSubmissionInfrastructureUnavailableError, - match="pre_submission_infrastructure_unavailable", - ): - compile_effective_pre_submission_execution_plan( - lineage=lineage, - effective_policy=_effective_policy(), - compiled_bundle=compiled_bundle, - catalogue=mandatory_disabled, - ) - - advisory_disabled = build_pre_submission_checker_catalogue( - disabled_entry_ids=frozenset({"artifact.quality.placeholder_signal"}) - ) - plan = compile_effective_pre_submission_execution_plan( - lineage=lineage, - effective_policy=_effective_policy(), - compiled_bundle=compiled_bundle, - catalogue=advisory_disabled, - ) - entry = next( - item for item in plan.entries if item.definition_id == "artifact.quality.placeholder_signal" - ) - assert entry.checker_definition_state == PreSubmissionCheckerState.DISABLED.value - assert entry.disabled_behavior == "record_disabled_and_continue" - - -def test_effective_plan_is_deterministic_and_commits_to_lineage_catalogue_and_config() -> None: - compiled_bundle, lineage = _compiled_and_lineage() - first = compile_effective_pre_submission_execution_plan( - lineage=lineage, - effective_policy=_effective_policy(), - compiled_bundle=compiled_bundle, - catalogue=build_pre_submission_checker_catalogue(), - ) - second = compile_effective_pre_submission_execution_plan( - lineage=lineage, - effective_policy=_effective_policy(), - compiled_bundle=compiled_bundle, - catalogue=build_pre_submission_checker_catalogue(), - ) - assert first == second - assert first.plan_sha256 == canonical_json_hash(first.as_dict()) - assert ( - first.catalogue_manifest_sha256 == build_pre_submission_checker_catalogue().manifest_sha256 - ) - assert {entry.definition_id for entry in first.entries}.issuperset( - { - "artifact.outer_zip.valid", - "artifact.manifest.semantic_identity_computed", - "submission.packet.required_fields", - "policy.file.require", - } - ) - assert all(entry.configuration_sha256 for entry in first.entries) - required_file = next( - entry for entry in first.entries if entry.definition_id == "policy.file.require" - ) - exported = required_file.as_dict() - exported["configuration"]["artifact_paths"].append("mutated-after-hash") - assert required_file.as_dict()["configuration"]["artifact_paths"] == ["task.toml"] - assert hash(required_file) - assert first.plan_sha256 == canonical_json_hash(first.as_dict()) - - changed_lineage = replace(lineage, project_id=new_record_id()) - changed = compile_effective_pre_submission_execution_plan( - lineage=changed_lineage, - effective_policy=_effective_policy(), - compiled_bundle=compiled_bundle, - catalogue=build_pre_submission_checker_catalogue(), - ) - assert changed.plan_sha256 != first.plan_sha256 - - advisory_disabled = build_pre_submission_checker_catalogue( - disabled_entry_ids=frozenset({"artifact.quality.placeholder_signal"}) - ) - state_changed = compile_effective_pre_submission_execution_plan( - lineage=lineage, - effective_policy=_effective_policy(), - compiled_bundle=compiled_bundle, - catalogue=advisory_disabled, - ) - assert state_changed.plan_sha256 != first.plan_sha256 - first_rule_ids = { - entry.definition_id: entry.rule_instance_id - for entry in first.entries - if entry.rule_instance_id is not None - } - state_changed_rule_ids = { - entry.definition_id: entry.rule_instance_id - for entry in state_changed.entries - if entry.rule_instance_id is not None - } - assert state_changed_rule_ids.keys() == first_rule_ids.keys() - assert all( - state_changed_rule_ids[definition_id] != rule_instance_id - for definition_id, rule_instance_id in first_rule_ids.items() - ) - - -def test_effective_plan_rejects_stale_or_non_catalogue_bundle_facts() -> None: - compiled_bundle, lineage = _compiled_and_lineage() - with pytest.raises(EffectivePreSubmissionPlanError, match="hash mismatch"): - compile_effective_pre_submission_execution_plan( - lineage=replace( - lineage, - pre_submit_policy_bundle_hash="sha256:" + "9" * 64, - ), - effective_policy=_effective_policy(), - compiled_bundle=compiled_bundle, - catalogue=build_pre_submission_checker_catalogue(), - ) - - altered = {**compiled_bundle, "rules": [dict(rule) for rule in compiled_bundle["rules"]]} - altered["rules"][0]["primitive"] = "legacy_alias" - altered_lineage = replace( - lineage, - pre_submit_policy_bundle_hash=canonical_json_hash(altered), - ) - with pytest.raises(EffectivePreSubmissionPlanError, match="unknown"): - compile_effective_pre_submission_execution_plan( - lineage=altered_lineage, - effective_policy=_effective_policy(), - compiled_bundle=altered, - catalogue=build_pre_submission_checker_catalogue(), - ) - - stale_envelope = {**compiled_bundle, "compiler_version": "obsolete"} - with pytest.raises(EffectivePreSubmissionPlanError, match="envelope"): - compile_effective_pre_submission_execution_plan( - lineage=replace( - lineage, - pre_submit_policy_bundle_hash=canonical_json_hash(stale_envelope), - ), - effective_policy=_effective_policy(), - compiled_bundle=stale_envelope, - catalogue=build_pre_submission_checker_catalogue(), - ) - - -def test_effective_plan_rejects_bundle_that_omits_locked_required_rule() -> None: - compiled_bundle, lineage = _compiled_and_lineage() - altered = { - **compiled_bundle, - "rules": [ - dict(rule) - for rule in compiled_bundle["rules"] - if rule["primitive"] != "require_file" - ], - } - altered_lineage = replace( - lineage, - pre_submit_policy_bundle_hash=canonical_json_hash(altered), - ) - - with pytest.raises(EffectivePreSubmissionPlanError, match="locked effective policy"): - compile_effective_pre_submission_execution_plan( - lineage=altered_lineage, - effective_policy=_effective_policy(), - compiled_bundle=altered, - catalogue=build_pre_submission_checker_catalogue(), - ) - - -def test_effective_plan_rejects_policy_body_that_does_not_match_locked_hash() -> None: - compiled_bundle, lineage = _compiled_and_lineage() - weakened_policy = { - **_effective_policy(), - "required_artifacts": [], - } - - with pytest.raises(EffectivePreSubmissionPlanError, match="policy hash mismatch"): - compile_effective_pre_submission_execution_plan( - lineage=lineage, - effective_policy=weakened_policy, - compiled_bundle=compiled_bundle, - catalogue=build_pre_submission_checker_catalogue(), - ) - - -def test_effective_plan_lineage_rejects_ambiguous_identity_version_and_hash() -> None: - _, lineage = _compiled_and_lineage() - with pytest.raises(EffectivePreSubmissionPlanError, match="lineage id"): - replace(lineage, project_id="not-a-uuid") - with pytest.raises(EffectivePreSubmissionPlanError, match="guide version"): - replace(lineage, guide_version=0) - with pytest.raises(EffectivePreSubmissionPlanError, match="lineage hash"): - replace(lineage, source_snapshot_hash="sha256:bad") - - -def test_compiler_uses_catalogue_without_durable_checker_registry( - monkeypatch: pytest.MonkeyPatch, -) -> None: - from app.modules.checkers import runner - - monkeypatch.setattr( - runner, - "default_checker_registry", - lambda: (_ for _ in ()).throw(AssertionError("durable registry used")), - ) - compiled = compile_effective_project_submission_artifact_policy( - _effective_policy(), "sha256:" + "3" * 64 - ) - assert "check_evidence_integrity" in compiled.checker_names - assert "check_submission_packet" in compiled.checker_names - - -async def test_application_startup_installs_fixed_catalogue_configuration(clean_postgres_database) -> None: - app = create_app( - Settings( - environment="test", - artifact_pre_submission_checker_disabled_ids="artifact.quality.placeholder_signal", - ) - ) - async with app.router.lifespan_context(app): - catalogue = app.state.pre_submission_checker_catalogue - assert catalogue.definition("artifact.quality.placeholder_signal").state is ( - PreSubmissionCheckerState.DISABLED - ) - - -async def test_application_startup_rejects_unknown_catalogue_configuration() -> None: - app = create_app( - Settings( - environment="test", - artifact_pre_submission_checker_disabled_ids="unknown.definition", - ) - ) - with pytest.raises(PreSubmissionCatalogueError, match="unknown"): - async with app.router.lifespan_context(app): - pass diff --git a/backend/tests/test_checkers.py b/backend/tests/test_checkers.py deleted file mode 100644 index 1c679c3ef..000000000 --- a/backend/tests/test_checkers.py +++ /dev/null @@ -1,1186 +0,0 @@ -# pyright: reportAttributeAccessIssue=false -from __future__ import annotations - -from collections.abc import AsyncIterator, Iterator -from copy import deepcopy -import math -from pathlib import Path -from typing import Any, cast - -import pytest -from alembic.config import Config -from httpx import ASGITransport, AsyncClient -from pydantic import TypeAdapter, ValidationError -from sqlalchemy import inspect, select - -from app.core.config import get_settings -from app.core.hashing import canonical_json_hash -from app.db import models as db_models -from app.db import session as db_session -from app.db.base import Base -from app.main import create_app -from app.modules.checkers import compiler as checker_compiler_module -from app.modules.checkers.compiler import ( - PRE_SUBMIT_COMPILER_VERSION, - PreSubmitCheckerCompilerError, - build_project_pre_submit_checker_spec, - compile_effective_project_submission_artifact_policy, - compile_project_pre_submit_checker_spec, - validate_compiled_pre_submit_checker_bundle, -) -from app.modules.checkers.models import CheckerResult, CheckerRun -from app.modules.checkers import runner as checker_runner_module -from app.modules.checkers.pre_submit_defaults import attestation_term_is_satisfied -from app.modules.checkers.runner import ( - CheckerContext, - CheckerNameConflict, - CheckerOutcome, - CheckerRegistry, - FunctionChecker, - UnknownChecker, - canonical_artifact_manifest_hash, -) -from app.modules.checkers.api.history import CheckerRoutingRecommendation -from app.modules.checkers.api.historical_post_submit import current_post_submit_catalogue -from app.modules.projects.post_submit_policy import ( - DEFAULT_DURABLE_CHECKERS, - POST_SUBMIT_CHECKER_POLICY_SPEC_SCHEMA_VERSION, - PostSubmitCheckerCompilerError, - build_project_post_submit_checker_spec, - compile_project_post_submit_checker_spec, - parse_locked_post_submit_checker_policy_body, -) -from app.modules.tasks.models import AuditEvent, EvidenceItem, Submission, WorkstreamTask -from tests.test_tasks import ( - auth_headers, - set_dev_actor, -) -from project_create_fixtures import ( - grant_system_project_manager, -) - - -@pytest.fixture -def checker_database_env( - monkeypatch: pytest.MonkeyPatch, - clean_postgres_database: str, -) -> Iterator[str]: - monkeypatch.setenv("WORKSTREAM_DATABASE_URL", clean_postgres_database) - monkeypatch.setenv("WORKSTREAM_CELERY_TASK_ALWAYS_EAGER", "true") - monkeypatch.setenv( - "WORKSTREAM_API_RATE_LIMIT_KEY_SECRET", - "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8=", - ) - set_dev_actor(monkeypatch, roles="project_manager", subject="project-manager-subject") - get_settings.cache_clear() - try: - yield clean_postgres_database - finally: - get_settings.cache_clear() - - -@pytest.fixture -async def checker_client(checker_database_env: str) -> AsyncIterator[AsyncClient]: - app = create_app() - async with AsyncClient( - transport=ASGITransport(app=app), - base_url="http://testserver", - ) as client: - admission = await client.get("/api/v1/actors/me", headers=auth_headers()) - assert admission.status_code == 200, admission.text - async with db_session.get_session_factory()() as session: - await grant_system_project_manager( - session, - issuer="flow-test", - subject="project-manager-subject", - ) - await session.commit() - yield client - - -def alembic_config() -> Config: - project_root = Path(__file__).resolve().parents[1] - config = Config(str(project_root / "alembic.ini")) - config.set_main_option("script_location", str(project_root / "alembic")) - return config - - -async def task_side_effect_snapshot(task_id: str) -> dict: - """Capture durable task-scoped rows that denied requests must not change.""" - async with db_session.get_session_factory()() as session: - task = await session.get(WorkstreamTask, task_id) - submissions = ( - await session.scalars( - select(Submission).where(Submission.task_id == task_id).order_by(Submission.id) - ) - ).all() - submission_ids = [submission.id for submission in submissions] - evidence_items = [] - if submission_ids: - evidence_items = ( - await session.scalars( - select(EvidenceItem) - .where(EvidenceItem.submission_id.in_(submission_ids)) - .order_by(EvidenceItem.id) - ) - ).all() - checker_runs = ( - await session.scalars( - select(CheckerRun).where(CheckerRun.task_id == task_id).order_by(CheckerRun.id) - ) - ).all() - checker_results = ( - await session.scalars( - select(CheckerResult) - .where(CheckerResult.task_id == task_id) - .order_by(CheckerResult.id) - ) - ).all() - audit_events = ( - await session.scalars( - select(AuditEvent) - .where(AuditEvent.entity_type == "task", AuditEvent.entity_id == task_id) - .order_by(AuditEvent.id) - ) - ).all() - submission_audit_events = [] - if submission_ids: - submission_audit_events = ( - await session.scalars( - select(AuditEvent) - .where( - AuditEvent.entity_type == "submission", - AuditEvent.entity_id.in_(submission_ids), - ) - .order_by(AuditEvent.id) - ) - ).all() - return { - "task_status": None if task is None else task.status, - "task_assigned_to": None if task is None else task.assigned_to, - "submissions": [ - ( - submission.id, - submission.version, - submission.status, - submission.package_hash, - submission.supersedes_submission_id, - ) - for submission in submissions - ], - "evidence_items": [ - (item.id, item.submission_id, item.type, item.hash) for item in evidence_items - ], - "checker_runs": [ - ( - run.id, - run.submission_id, - run.submission_version, - run.attempt_number, - run.routing_recommendation, - run.status, - run.is_current_for_submission, - run.failure_code, - run.failure_message, - run.queued_at, - run.started_at, - run.completed_at, - run.created_at, - ) - for run in checker_runs - ], - "checker_results": [ - (result.id, result.checker_run_id, result.checker_name, result.status) - for result in checker_results - ], - "audit_events": [ - ( - event.id, - event.event_type, - event.from_status, - event.to_status, - event.event_payload, - ) - for event in audit_events - ], - "submission_audit_events": [ - ( - event.id, - event.entity_id, - event.event_type, - event.from_status, - event.to_status, - event.event_payload, - ) - for event in submission_audit_events - ], - } - - -def _current_locked_test_facts() -> dict: - """Supply real current lock types to orchestration tests.""" - from tests.checkers.post_submit.support import request - - facts = request().expected_context.model_dump(mode="json") - return { - "locked_guide_version": facts["guide_version"], - "locked_guide_source_snapshot_id": facts["source_id"], - "locked_guide_source_snapshot_hash": facts["source_hash"], - "locked_effective_project_submission_artifact_policy_id": facts["effective_policy_id"], - "locked_effective_project_submission_artifact_policy_hash": facts["effective_policy_hash"], - "locked_pre_submit_checker_policy_id": facts["pre_policy_id"], - "locked_pre_submit_checker_bundle_hash": facts["pre_policy_hash"], - "locked_post_submit_checker_policy_id": facts["post_policy_id"], - "locked_post_submit_checker_policy_version": facts["post_policy_version"], - "locked_post_submit_checker_policy_hash": facts["post_policy_hash"], - "locked_review_policy_id": facts["review_policy_id"], - "locked_review_policy_generation": facts["review_generation"], - "locked_review_policy_hash": facts["review_hash"], - "locked_revision_policy_id": facts["revision_policy_id"], - "locked_revision_policy_generation": facts["revision_generation"], - "locked_revision_policy_hash": facts["revision_hash"], - } - - -def _canonical_test_post_policy(): - project_id = "11111111-1111-4111-8111-111111111111" - return compile_project_post_submit_checker_spec( - project_id=project_id, - guide_version="v1", - spec=build_project_post_submit_checker_spec(project_id=project_id, guide_version="v1"), - ) - - -def _validate_test_post_body(body): - parsed = parse_locked_post_submit_checker_policy_body( - body, - project_id=body["project_id"], - guide_version=body["guide_version"], - policy_hash=canonical_json_hash(body), - ) - - parsed.validate_catalogue(current_post_submit_catalogue()) - return parsed - - -def test_locked_post_submit_policy_parser_uses_persisted_body_hash() -> None: - compiled = _canonical_test_post_policy() - parsed = parse_locked_post_submit_checker_policy_body( - compiled.policy_body, project_id=str(compiled.project_id), - guide_version=compiled.guide_version, policy_hash=compiled.policy_hash, - ) - assert parsed == compiled - with pytest.raises(ValueError, match="policy hash is invalid"): - parse_locked_post_submit_checker_policy_body( - compiled.policy_body, project_id=str(compiled.project_id), - guide_version=compiled.guide_version, policy_hash="sha256:" + "0" * 64, - ) - - -def test_post_submit_compiler_accepts_default_only_policy() -> None: - spec = build_project_post_submit_checker_spec( - project_id="11111111-1111-4111-8111-111111111111", - guide_version="v1", - ) - - compiled = compile_project_post_submit_checker_spec( - project_id="11111111-1111-4111-8111-111111111111", - guide_version="v1", - spec=spec, - ) - - assert compiled.compiler_version == "workstream-post-submit-compiler" - assert compiled.policy_body["compiler_version"] == compiled.compiler_version - assert compiled.required_checkers == [] - assert compiled.warning_checkers == [] - assert compiled.execution_checkers == DEFAULT_DURABLE_CHECKERS - assert compiled.default_checkers == DEFAULT_DURABLE_CHECKERS - assert [entry["checker_id"] for entry in compiled.policy_body["entries"]] == DEFAULT_DURABLE_CHECKERS - assert compiled.policy_hash == canonical_json_hash(compiled.policy_body) - assert list(compiled.blocking_severities) == ["critical", "high"] - - -def test_post_submit_compiler_canonicalizes_project_specific_checker_spec() -> None: - spec = build_project_post_submit_checker_spec( - project_id="11111111-1111-4111-8111-111111111111", - guide_version="v1", - required_checkers=[ - "check_acceptance_criteria_present", - ], - warning_checkers=[], - blocking_severities=["critical", "high", "medium"], - ) - - compiled = compile_project_post_submit_checker_spec( - project_id="11111111-1111-4111-8111-111111111111", - guide_version="v1", - spec=spec, - ) - - assert compiled.required_checkers == [ - "check_acceptance_criteria_present", - ] - assert compiled.execution_checkers == [ - *DEFAULT_DURABLE_CHECKERS, - "check_acceptance_criteria_present", - ] - assert list(compiled.blocking_severities) == ["critical", "high", "medium"] - - -def test_post_submit_compiler_rejects_unknown_checker_name() -> None: - spec = build_project_post_submit_checker_spec( - project_id="11111111-1111-4111-8111-111111111111", - guide_version="v1", - required_checkers=["missing_checker"], - ) - - with pytest.raises(PostSubmitCheckerCompilerError, match="selection is unavailable"): - compile_project_post_submit_checker_spec( - project_id="11111111-1111-4111-8111-111111111111", - guide_version="v1", - spec=spec, - ) - - -def test_post_submit_compiler_rejects_non_object_spec() -> None: - spec: Any = [] - - with pytest.raises(PostSubmitCheckerCompilerError, match="spec shape"): - compile_project_post_submit_checker_spec( - project_id="11111111-1111-4111-8111-111111111111", - guide_version="v1", - spec=spec, - ) - - -def test_post_submit_compiler_rejects_tuple_spec_lists() -> None: - spec = { - "schema_version": POST_SUBMIT_CHECKER_POLICY_SPEC_SCHEMA_VERSION, - "project_id": "11111111-1111-4111-8111-111111111111", - "guide_version": "v1", - "required_checkers": ("check_acceptance_criteria_present",), - "warning_checkers": [], - "blocking_severities": ["critical", "high"], - } - - with pytest.raises(PostSubmitCheckerCompilerError, match="required_checkers"): - compile_project_post_submit_checker_spec( - project_id="11111111-1111-4111-8111-111111111111", - guide_version="v1", - spec=spec, - ) - - -def test_post_submit_compiler_rejects_duplicate_checker_names() -> None: - spec = { - "schema_version": POST_SUBMIT_CHECKER_POLICY_SPEC_SCHEMA_VERSION, - "project_id": "11111111-1111-4111-8111-111111111111", - "guide_version": "v1", - "required_checkers": [ - "check_acceptance_criteria_present", - "check_acceptance_criteria_present", - ], - "warning_checkers": [], - "blocking_severities": ["critical", "high"], - } - - with pytest.raises(PostSubmitCheckerCompilerError, match="duplicate checker"): - compile_project_post_submit_checker_spec( - project_id="11111111-1111-4111-8111-111111111111", - guide_version="v1", - spec=spec, - ) - - -def test_post_submit_compiler_rejects_conflicting_checker_classification() -> None: - spec = { - "schema_version": POST_SUBMIT_CHECKER_POLICY_SPEC_SCHEMA_VERSION, - "project_id": "11111111-1111-4111-8111-111111111111", - "guide_version": "v1", - "required_checkers": ["check_acceptance_criteria_present"], - "warning_checkers": ["check_acceptance_criteria_present"], - "blocking_severities": ["critical", "high"], - } - - with pytest.raises(PostSubmitCheckerCompilerError, match="conflicting checker"): - compile_project_post_submit_checker_spec( - project_id="11111111-1111-4111-8111-111111111111", - guide_version="v1", - spec=spec, - ) - - -def test_post_submit_compiler_rejects_warning_only_default_checker_override() -> None: - with pytest.raises(PostSubmitCheckerCompilerError, match="default checkers"): - build_project_post_submit_checker_spec( - project_id="11111111-1111-4111-8111-111111111111", - guide_version="v1", - warning_checkers=["check_submission_packet"], - ) - - -def test_post_submit_compiler_rejects_raw_spec_warning_only_default_checker_override() -> None: - spec = { - "schema_version": POST_SUBMIT_CHECKER_POLICY_SPEC_SCHEMA_VERSION, - "project_id": "11111111-1111-4111-8111-111111111111", - "guide_version": "v1", - "required_checkers": [], - "warning_checkers": ["check_submission_packet"], - "blocking_severities": ["critical", "high"], - } - - with pytest.raises(PostSubmitCheckerCompilerError, match="default checkers"): - compile_project_post_submit_checker_spec( - project_id="11111111-1111-4111-8111-111111111111", - guide_version="v1", - spec=spec, - ) - - -def test_post_submit_compiler_rejects_raw_spec_blocking_severity_downgrade() -> None: - spec = { - "schema_version": POST_SUBMIT_CHECKER_POLICY_SPEC_SCHEMA_VERSION, - "project_id": "11111111-1111-4111-8111-111111111111", - "guide_version": "v1", - "required_checkers": [], - "warning_checkers": [], - "blocking_severities": ["high"], - } - - with pytest.raises(PostSubmitCheckerCompilerError, match="blocking severities"): - compile_project_post_submit_checker_spec( - project_id="11111111-1111-4111-8111-111111111111", - guide_version="v1", - spec=spec, - ) - - -@pytest.mark.parametrize( - "blocking_severities", - [[], ["critical"], ["high"]], -) -def test_post_submit_compiler_rejects_blocking_severity_downgrade( - blocking_severities: list[str], -) -> None: - with pytest.raises(PostSubmitCheckerCompilerError, match="blocking severities"): - build_project_post_submit_checker_spec( - project_id="11111111-1111-4111-8111-111111111111", - guide_version="v1", - blocking_severities=blocking_severities, - ) - - -@pytest.mark.parametrize( - "default_checkers", - [ - list(DEFAULT_DURABLE_CHECKERS[:-1]), - list(reversed(DEFAULT_DURABLE_CHECKERS)), - [*DEFAULT_DURABLE_CHECKERS[:-1], "renamed_default_checker"], - [*DEFAULT_DURABLE_CHECKERS, "extra_default_checker"], - ], -) -def test_locked_post_submit_policy_validation_rejects_default_checker_drift(default_checkers: list[str]) -> None: - body = _canonical_test_post_policy().policy_body - by_name = {entry["checker_id"]: entry for entry in body["entries"]} - template = body["entries"][0] - body["entries"] = [by_name.get(name, {**template, "checker_id": name}) for name in default_checkers] - with pytest.raises(ValueError): - _validate_test_post_body(body) - - -@pytest.mark.parametrize( - "drifted_defaults", - [ - list(DEFAULT_DURABLE_CHECKERS[:-1]), - list(reversed(DEFAULT_DURABLE_CHECKERS)), - [*DEFAULT_DURABLE_CHECKERS[:-1], "renamed_default_checker"], - [*DEFAULT_DURABLE_CHECKERS, "extra_default_checker"], - ], -) -def test_locked_post_submit_policy_validation_rejects_self_consistent_default_drift(drifted_defaults: list[str]) -> None: - body = _canonical_test_post_policy().policy_body - template = body["entries"][0] - body["entries"] = [{**template, "checker_id": name} for name in drifted_defaults] - # Recomputed digest proves the canonical catalogue rejects changed defaults. - with pytest.raises(ValueError): - _validate_test_post_body(body) - - -def test_locked_post_submit_policy_validation_rejects_unsupported_compiler_version() -> None: - body = _canonical_test_post_policy().policy_body - body["compiler_version"] = "unsupported" - with pytest.raises(ValueError, match="compiler_version"): - _validate_test_post_body(body) - - -@pytest.mark.parametrize( - ("required_checkers", "warning_checkers", "execution_checkers"), - [ - ( - ["check_acceptance_criteria_present"], - ["check_acceptance_criteria_present"], - [*DEFAULT_DURABLE_CHECKERS, "check_acceptance_criteria_present"], - ), - ([], ["check_submission_packet"], list(DEFAULT_DURABLE_CHECKERS)), - ], -) -def test_locked_post_submit_policy_validation_rejects_conflicting_classifications( - required_checkers: list[str], warning_checkers: list[str], execution_checkers: list[str], -) -> None: - body = _canonical_test_post_policy().policy_body - template = {**body["entries"][0], "checker_id": "check_acceptance_criteria_present"} - if required_checkers: - body["entries"] = body["entries"][:-1] + [{**template, "classification": "project_required"}, - {**template, "classification": "project_warning"}] - else: - body["entries"][0]["classification"] = "project_warning" - with pytest.raises(ValueError, match="duplicate entries|classification mismatch"): - _validate_test_post_body(body) - - -@pytest.mark.parametrize( - "blocking_severities", - [[], ["critical"], ["high"]], -) -def test_locked_post_submit_policy_validation_rejects_blocking_severity_downgrade(blocking_severities: list[str]) -> None: - body = _canonical_test_post_policy().policy_body - body["blocking_severities"] = blocking_severities - with pytest.raises(ValueError, match="blocking_severities"): - _validate_test_post_body(body) - - -def test_checker_models_are_registered_for_alembic_metadata() -> None: - expected_tables = {"checker_runs", "checker_results"} - - assert expected_tables.issubset(Base.metadata.tables) - assert db_models.CheckerRun is CheckerRun - assert db_models.CheckerResult is CheckerResult - - -def test_checker_routing_recommendation_schema_uses_canonical_routing_tokens() -> None: - adapter = TypeAdapter(CheckerRoutingRecommendation) - - for token in ("not_evaluated", "allow_review", "needs_revision", "task_setup_blocked"): - assert adapter.validate_python(token) == token - with pytest.raises(ValidationError): - adapter.validate_python("checker_retry") - with pytest.raises(ValidationError): - adapter.validate_python("operator" + "_retry") - - -async def test_checker_migration_creates_expected_tables(checker_database_env: str) -> None: - async with db_session.get_engine().connect() as connection: - table_names = await connection.run_sync( - lambda sync_connection: set(inspect(sync_connection).get_table_names()) - ) - - assert {"checker_runs", "checker_results"}.issubset(table_names) - - -def test_checker_run_binds_to_locked_post_submit_policy_context() -> None: - expected_constraints = { - "fk_checker_runs_locked_post_submit_policy_hash": [ - "locked_post_submit_checker_policy_id", - "locked_post_submit_checker_policy_version", - "locked_post_submit_checker_policy_hash", - ], - "fk_checker_runs_submission_locked_post_submit_policy_hash": [ - "submission_id", - "locked_post_submit_checker_policy_id", - "locked_post_submit_checker_policy_version", - "locked_post_submit_checker_policy_hash", - ], - } - - for constraint_name, local_columns in expected_constraints.items(): - constraint = next( - constraint - for constraint in CheckerRun.__table__.foreign_key_constraints - if constraint.name == constraint_name - ) - assert [column.name for column in constraint.columns] == local_columns - for name in expected_constraints["fk_checker_runs_locked_post_submit_policy_hash"]: - assert CheckerRun.__table__.c[name].nullable is False - - -def test_artifact_manifest_hash_is_stable_and_rejects_duplicates() -> None: - first = [ - {"artifact": "b.txt", "hash": "sha256:b", "size_bytes": 2, "notes": None}, - {"hash": "sha256:a", "artifact": "a.txt", "notes": "main", "size_bytes": 1}, - ] - second = [ - {"size_bytes": 1, "notes": "main", "artifact": "a.txt", "hash": "sha256:a"}, - {"notes": None, "artifact": "b.txt", "hash": "sha256:b", "size_bytes": 2}, - ] - - assert canonical_artifact_manifest_hash(first) == canonical_artifact_manifest_hash(second) - - with pytest.raises(ValueError, match="duplicate artifact"): - canonical_artifact_manifest_hash( - [ - {"artifact": "a.txt", "hash": "sha256:a"}, - {"artifact": "a.txt", "hash": "sha256:b"}, - ] - ) - - -def compiler_effective_policy() -> dict: - """Return a minimal effective project policy for compiler tests.""" - default_policy = { - "required_packet_fields": ["summary", "artifact_hash_manifest", "worker_attestation"], - "required_artifacts": [], - "required_evidence": [], - "forbidden_artifacts": [ - {"pattern": ".env", "source": "workstream_default", "severity": "blocking"}, - ], - "attestation_terms": ["original_work"], - "manifest_required": True, - "artifact_hash_required": True, - "artifact_hash_algorithm": "sha256", - "allowed_storage_schemes": ["local", "s3", "r2"], - "maximum_file_size_bytes": None, - "maximum_package_size_bytes": None, - "packaging": {}, - } - project_policy = { - "schema_version": "project_submission_artifact_policy.v1", - "required_artifacts": [ - { - "key": "answer", - "path": "outputs/answer.md", - "hash_required": True, - "required": True, - "description": "Answer artifact.", - } - ], - "required_evidence": [ - { - "key": "work_evidence", - "label": "Work evidence", - "hash_required": True, - "required": True, - "description": "Evidence for the answer.", - } - ], - "forbidden_artifacts": [ - {"pattern": "*.tmp", "reason": "Temporary files are not reviewable."}, - ], - "attestation_terms": ["project_specific_originality"], - "manifest_required": True, - "artifact_hash_required": True, - "artifact_hash_algorithm": "sha256", - "allowed_storage_schemes": ["local", "s3", "r2"], - "maximum_file_size_bytes": 1_000_000, - "maximum_package_size_bytes": 5_000_000, - "packaging": {"package_required": False}, - } - return { - "schema_version": "effective_project_submission_artifact_policy.v1", - "merge_algorithm_version": "workstream_default_merge.v1", - "workstream_default_policy": default_policy, - "project_policy": project_policy, - "required_packet_fields": default_policy["required_packet_fields"], - "required_artifacts": project_policy["required_artifacts"], - "required_evidence": project_policy["required_evidence"], - "forbidden_artifacts": [ - *default_policy["forbidden_artifacts"], - *project_policy["forbidden_artifacts"], - ], - "attestation_terms": [ - *default_policy["attestation_terms"], - *project_policy["attestation_terms"], - ], - "manifest_required": True, - "artifact_hash_required": True, - "artifact_hash_algorithm": "sha256", - "allowed_storage_schemes": ["local", "s3", "r2"], - "maximum_file_size_bytes": 1_000_000, - "maximum_package_size_bytes": 5_000_000, - "packaging": {"package_required": False}, - } - - -def test_pre_submit_compiler_emits_stable_approved_project_bundle() -> None: - effective_policy = compiler_effective_policy() - effective_policy_hash = "sha256:" + "1" * 64 - - first = compile_effective_project_submission_artifact_policy( - effective_policy, - effective_policy_hash, - ) - second = compile_effective_project_submission_artifact_policy( - effective_policy, - effective_policy_hash, - ) - - assert first.compiler_version == PRE_SUBMIT_COMPILER_VERSION - assert first.compiled_bundle == second.compiled_bundle - assert first.compiled_bundle_hash == second.compiled_bundle_hash - assert first.compiled_bundle["effective_policy_hash"] == effective_policy_hash - assert { - "validate_submission_packet", - "require_manifest_field", - "verify_hash", - "require_file", - "require_minimum_evidence", - "forbid_artifact", - "require_attestation", - }.issubset({rule["primitive"] for rule in first.compiled_bundle["rules"]}) - assert "check_required_files" in first.checker_names - assert "check_evidence_present" in first.checker_names - - -def test_pre_submit_compiler_rejects_unknown_primitive() -> None: - effective_policy = compiler_effective_policy() - effective_policy_hash = "sha256:" + "2" * 64 - spec = build_project_pre_submit_checker_spec(effective_policy, effective_policy_hash) - spec["rules"].append( - { - "primitive": "run_arbitrary_python", - "severity": "blocking", - "policy_fields": ["required_artifacts"], - "config": {}, - } - ) - - with pytest.raises(PreSubmitCheckerCompilerError, match="unknown primitive"): - compile_project_pre_submit_checker_spec(effective_policy, effective_policy_hash, spec) - - -def test_pre_submit_compiler_rejects_omitted_required_artifact_coverage() -> None: - effective_policy = compiler_effective_policy() - effective_policy_hash = "sha256:" + "3" * 64 - spec = build_project_pre_submit_checker_spec(effective_policy, effective_policy_hash) - spec["rules"] = [rule for rule in spec["rules"] if rule["primitive"] != "require_file"] - - with pytest.raises(PreSubmitCheckerCompilerError, match="require_file"): - compile_project_pre_submit_checker_spec(effective_policy, effective_policy_hash, spec) - - -def test_pre_submit_compiler_rejects_skipped_evidence_coverage() -> None: - effective_policy = compiler_effective_policy() - effective_policy_hash = "sha256:" + "4" * 64 - spec = build_project_pre_submit_checker_spec(effective_policy, effective_policy_hash) - for rule in spec["rules"]: - if rule["primitive"] == "require_minimum_evidence": - rule["config"]["evidence_paths"] = [] - - with pytest.raises(PreSubmitCheckerCompilerError, match="required evidence"): - compile_project_pre_submit_checker_spec(effective_policy, effective_policy_hash, spec) - - -def test_pre_submit_compiler_rejects_weakened_default_severity() -> None: - effective_policy = compiler_effective_policy() - effective_policy_hash = "sha256:" + "5" * 64 - spec = build_project_pre_submit_checker_spec(effective_policy, effective_policy_hash) - for rule in spec["rules"]: - if rule["primitive"] == "verify_hash": - rule["severity"] = "warning" - - with pytest.raises(PreSubmitCheckerCompilerError, match="weakens severity"): - compile_project_pre_submit_checker_spec(effective_policy, effective_policy_hash, spec) - - -def test_pre_submit_compiler_rejects_escalated_warning_only_rule() -> None: - effective_policy = compiler_effective_policy() - effective_policy_hash = "sha256:" + "c" * 64 - spec = build_project_pre_submit_checker_spec(effective_policy, effective_policy_hash) - for rule in spec["rules"]: - if rule["primitive"] == "warn_low_quality_generated_artifact": - rule["severity"] = "blocking" - - with pytest.raises(PreSubmitCheckerCompilerError, match="warning-only"): - compile_project_pre_submit_checker_spec(effective_policy, effective_policy_hash, spec) - - -def test_pre_submit_compiler_rejects_configured_warning_only_rule() -> None: - effective_policy = compiler_effective_policy() - effective_policy_hash = "sha256:" + "c" * 64 - spec = build_project_pre_submit_checker_spec(effective_policy, effective_policy_hash) - for rule in spec["rules"]: - if rule["primitive"] == "warn_low_quality_generated_artifact": - rule["config"] = {"threshold": "strict"} - - with pytest.raises(PreSubmitCheckerCompilerError, match="warning-only rule"): - compile_project_pre_submit_checker_spec(effective_policy, effective_policy_hash, spec) - - -def test_canonical_json_hash_rejects_non_finite_numbers() -> None: - with pytest.raises(ValueError): - canonical_json_hash({"score": math.nan}) - - -def test_pre_submit_compiler_rejects_missing_workstream_defaults() -> None: - effective_policy = compiler_effective_policy() - effective_policy_hash = "sha256:" + "6" * 64 - spec = build_project_pre_submit_checker_spec(effective_policy, effective_policy_hash) - for rule in spec["rules"]: - if rule["primitive"] == "forbid_artifact": - rule["config"]["patterns"] = ["*.tmp"] - - with pytest.raises(PreSubmitCheckerCompilerError, match="forbidden artifacts"): - compile_project_pre_submit_checker_spec(effective_policy, effective_policy_hash, spec) - - -def test_pre_submit_compiler_rejects_untraceable_policy_fields() -> None: - effective_policy = compiler_effective_policy() - effective_policy_hash = "sha256:" + "7" * 64 - spec = build_project_pre_submit_checker_spec(effective_policy, effective_policy_hash) - for rule in spec["rules"]: - if rule["primitive"] == "require_file": - rule["policy_fields"] = ["required_artifacts", "operator_override"] - - with pytest.raises(PreSubmitCheckerCompilerError, match="untraceable policy fields"): - compile_project_pre_submit_checker_spec(effective_policy, effective_policy_hash, spec) - - -def test_pre_submit_compiler_rejects_weakened_size_limits() -> None: - effective_policy = compiler_effective_policy() - effective_policy_hash = "sha256:" + "8" * 64 - spec = build_project_pre_submit_checker_spec(effective_policy, effective_policy_hash) - for rule in spec["rules"]: - if rule["primitive"] == "limit_file_size": - rule["config"]["maximum_file_size_bytes"] = 2_000_000 - - with pytest.raises(PreSubmitCheckerCompilerError, match="file size"): - compile_project_pre_submit_checker_spec(effective_policy, effective_policy_hash, spec) - - -def test_pre_submit_compiler_rejects_weakened_package_limits() -> None: - effective_policy = compiler_effective_policy() - effective_policy_hash = "sha256:" + "9" * 64 - spec = build_project_pre_submit_checker_spec(effective_policy, effective_policy_hash) - for rule in spec["rules"]: - if rule["primitive"] == "limit_package_size": - rule["config"]["maximum_package_size_bytes"] = 6_000_000 - - with pytest.raises(PreSubmitCheckerCompilerError, match="package size"): - compile_project_pre_submit_checker_spec(effective_policy, effective_policy_hash, spec) - - -def test_pre_submit_compiler_rejects_weakened_packaging_config() -> None: - effective_policy = compiler_effective_policy() - effective_policy["packaging"] = { - "package_required": True, - "allowed_package_formats": ["zip"], - } - effective_policy_hash = "sha256:" + "a" * 64 - spec = build_project_pre_submit_checker_spec(effective_policy, effective_policy_hash) - for rule in spec["rules"]: - if rule["primitive"] == "require_packaging": - rule["config"]["package_required"] = False - - with pytest.raises(PreSubmitCheckerCompilerError, match="packaging"): - compile_project_pre_submit_checker_spec(effective_policy, effective_policy_hash, spec) - - -def test_pre_submit_compiler_rejects_untraceable_extra_rules() -> None: - effective_policy = compiler_effective_policy() - effective_policy_hash = "sha256:" + "b" * 64 - spec = build_project_pre_submit_checker_spec(effective_policy, effective_policy_hash) - spec["rules"].append( - { - "primitive": "require_packaging", - "severity": "blocking", - "policy_fields": ["packaging"], - "config": {"package_required": True}, - } - ) - - with pytest.raises(PreSubmitCheckerCompilerError, match="untraceable primitive"): - compile_project_pre_submit_checker_spec(effective_policy, effective_policy_hash, spec) - - -def test_manifest_hash_rejects_incomplete_entries() -> None: - for manifest in ([{"artifact": "answer.md"}], [{"hash": "sha256:a"}]): - with pytest.raises(ValueError, match="require artifact and hash"): - canonical_artifact_manifest_hash(manifest) - - -def test_evidence_integrity_reports_each_untrusted_reference_shape() -> None: - traversal = checker_runner_module._evidence_integrity_outcome( - [{"artifact": "../secret.txt", "hash": "sha256:a"}], - [], - ) - malformed_hash = checker_runner_module._evidence_integrity_outcome( - [{"artifact": "answer.md", "hash": "md5:a"}], - [], - ) - missing_evidence_hash = checker_runner_module._evidence_integrity_outcome( - [{"artifact": "answer.md", "hash": "sha256:a"}], - [{"label": "proof", "uri": "s3://bucket/proof", "hash": None}], - ) - - assert traversal.blocks_review is True - assert "integrity_error" in traversal.metadata - assert malformed_hash.metadata == {"invalid_artifact_count": 1} - assert missing_evidence_hash.metadata == {"missing_evidence_hash_count": 1} - - -def test_required_file_checker_handles_empty_invalid_and_missing_contracts() -> None: - no_requirement = checker_runner_module._required_files_outcome([], []) - invalid = checker_runner_module._required_files_outcome(["../answer.md"], []) - missing = checker_runner_module._required_files_outcome( - ["answer.md"], - [{"artifact": "notes.md", "hash": "sha256:notes"}], - ) - - assert no_requirement.status == "passed" - assert invalid.blocks_review is True - assert "relative artifact paths" in (invalid.worker_suggested_fix or "") - assert missing.metadata == {"missing_required_files": ["answer.md"]} - - -def test_forbidden_file_checker_classifies_without_leaking_paths() -> None: - outcome = checker_runner_module._forbidden_files_outcome( - [ - {"artifact": "../ignored"}, - {"artifact": "config/.env"}, - {"artifact": "keys/client.pem"}, - {"artifact": "build/debug.tmp"}, - ], - [], - ["*.tmp"], - ) - - assert outcome.blocks_review is True - assert outcome.metadata == { - "forbidden_categories": [ - "forbidden_file_suffix", - "forbidden_path_segment", - "forbidden_policy_pattern", - ] - } - assert "client.pem" not in outcome.message - - -def test_packet_shape_reports_all_required_fields_without_echoing_values() -> None: - outcome = checker_runner_module._packet_shape_outcome("", "", []) - - assert outcome.blocks_review is True - assert outcome.metadata == { - "missing_fields": ["summary", "package_hash", "artifact_hash_manifest"] - } - - -def test_artifact_path_and_pattern_normalization_fail_closed() -> None: - assert checker_runner_module._normalize_artifact_path("./folder//answer.md") == ( - "folder/answer.md" - ) - with pytest.raises(ValueError, match="relative and non-empty"): - checker_runner_module._normalize_artifact_path("/absolute.txt") - assert not checker_runner_module._path_matches_forbidden_pattern("answer.md", "") - - -@pytest.mark.asyncio -async def test_policy_context_checker_blocks_incomplete_lock_without_exposing_details() -> None: - from dataclasses import replace - from app.modules.checkers.api import ObservedPostSubmitContext - from app.modules.checkers.post_submit_implementations import detached_checker_context - from tests.checkers.post_submit.support import request - source = request() - context = detached_checker_context(source) - assert (await checker_runner_module.check_policy_context_present(context)).status == "passed" - observed = source.structural_input.observed_context.model_dump() - observed["pre_policy_id"] = None - outcome = await checker_runner_module.check_policy_context_present( - replace(context, observed_context=ObservedPostSubmitContext(**observed)) - ) - assert outcome.status == "failed" - assert outcome.worker_visible is False - assert outcome.routing_recommendation == "task_setup_blocked" - assert outcome.metadata == {"invalid_context": ["pre_policy_id"]} - - -def test_attestation_and_policy_projection_helpers_preserve_required_only_rules() -> None: - policy = { - "required_artifacts": [ - {"path": "answer.md", "required": True}, - {"path": "optional.md", "required": False}, - ], - "required_evidence": [ - {"key": "proof", "required": True}, - {"key": "optional", "required": False}, - ], - "forbidden_artifacts": [{"pattern": "*.key"}, {"pattern": ""}], - "attestation_terms": ["original work", ""], - } - - assert checker_runner_module._required_artifact_paths(policy) == ["answer.md"] - assert checker_runner_module._required_evidence_keys(policy) == ["proof"] - assert checker_runner_module._forbidden_artifact_patterns(policy) == ["*.key"] - assert checker_runner_module._required_attestation_terms(policy) == ["original work"] - assert checker_runner_module._required_artifact_paths(None) == [] - assert checker_runner_module._required_evidence_keys(None) == [] - assert checker_runner_module._forbidden_artifact_patterns(None) == [] - assert checker_runner_module._required_attestation_terms(None) == [] - assert attestation_term_is_satisfied("anything", "") - assert attestation_term_is_satisfied( - "i_confirm_original_work", - "original work", - ) - assert not attestation_term_is_satisfied( - "i_confirm_original_work", - "client confidentiality", - ) - - -@pytest.mark.asyncio -async def test_checker_registry_preserves_policy_order_and_rejects_name_drift() -> None: - from app.modules.checkers.api.historical_post_submit import structural_definition - registry = CheckerRegistry() - async def outcome(name: str) -> CheckerOutcome: - return CheckerOutcome(name, "passed", "info", f"{name} passed") - policy = _canonical_test_post_policy() - for name in policy.execution_checkers: - registry.register(FunctionChecker(name, lambda _context, name=name: outcome(name)), - definition=structural_definition(name)) - results = await registry.run(cast(CheckerContext, object()), policy.entries) - assert [result.checker_name for result in results] == policy.execution_checkers - name = policy.execution_checkers[0] - with pytest.raises(CheckerNameConflict, match="already registered"): - registry.register(FunctionChecker(name, lambda _context: outcome(name)), - definition=structural_definition(name)) - with pytest.raises(UnknownChecker, match="missing, unknown"): - registry.require_registered({"unknown", "missing"}) - - -@pytest.mark.parametrize( - ("mutation", "message"), - [ - ({"schema_version": "invalid"}, "schema version"), - ({"compiler_version": "invalid"}, "compiler version"), - ({"primitives_version": "invalid"}, "primitives version"), - ({"effective_policy_hash": "sha256:other"}, "policy hash mismatch"), - ({"rules": []}, "requires rules"), - ], -) -def test_compiled_checker_bundle_rejects_envelope_drift( - mutation: dict[str, Any], - message: str, -) -> None: - effective_policy = compiler_effective_policy() - effective_policy_hash = "sha256:" + "d" * 64 - compiled = compile_effective_project_submission_artifact_policy( - effective_policy, - effective_policy_hash, - ) - bundle = deepcopy(compiled.compiled_bundle) - bundle.update(mutation) - - with pytest.raises(PreSubmitCheckerCompilerError, match=message): - validate_compiled_pre_submit_checker_bundle( - effective_policy, - effective_policy_hash, - bundle, - compiler_version=compiled.compiler_version, - ) - - -@pytest.mark.parametrize( - ("mutation", "message"), - [ - ({"schema_version": "invalid"}, "schema version"), - ({"effective_policy_hash": "sha256:other"}, "policy hash mismatch"), - ({"rules": []}, "requires rules"), - ], -) -def test_checker_spec_rejects_envelope_drift( - mutation: dict[str, Any], - message: str, -) -> None: - effective_policy = compiler_effective_policy() - effective_policy_hash = "sha256:" + "e" * 64 - spec = build_project_pre_submit_checker_spec(effective_policy, effective_policy_hash) - spec.update(mutation) - - with pytest.raises(PreSubmitCheckerCompilerError, match=message): - compile_project_pre_submit_checker_spec(effective_policy, effective_policy_hash, spec) - - -@pytest.mark.parametrize( - ("mutation", "message"), - [ - ({"severity": "low"}, "invalid severity"), - ({"policy_fields": []}, "lacks policy trace"), - ({"policy_fields": [None]}, "invalid policy trace"), - ({"config": []}, "config must be an object"), - ], -) -def test_checker_spec_rejects_ambiguous_rule_shape( - mutation: dict[str, Any], - message: str, -) -> None: - effective_policy = compiler_effective_policy() - effective_policy_hash = "sha256:" + "f" * 64 - spec = build_project_pre_submit_checker_spec(effective_policy, effective_policy_hash) - spec["rules"][0].update(mutation) - - with pytest.raises(PreSubmitCheckerCompilerError, match=message): - compile_project_pre_submit_checker_spec(effective_policy, effective_policy_hash, spec) - - -def test_checker_spec_rejects_duplicate_primitive_and_hash_algorithm_drift() -> None: - effective_policy = compiler_effective_policy() - effective_policy_hash = "sha256:" + "1" * 64 - duplicate = build_project_pre_submit_checker_spec(effective_policy, effective_policy_hash) - duplicate["rules"].append(deepcopy(duplicate["rules"][0])) - - with pytest.raises(PreSubmitCheckerCompilerError, match="duplicate primitive"): - compile_project_pre_submit_checker_spec( - effective_policy, - effective_policy_hash, - duplicate, - ) - - hash_drift = build_project_pre_submit_checker_spec(effective_policy, effective_policy_hash) - next(rule for rule in hash_drift["rules"] if rule["primitive"] == "verify_hash")[ - "config" - ]["algorithm"] = "md5" - with pytest.raises(PreSubmitCheckerCompilerError, match="hash algorithm"): - compile_project_pre_submit_checker_spec( - effective_policy, - effective_policy_hash, - hash_drift, - ) - - -@pytest.mark.parametrize( - ("field", "value", "message"), - [ - ("packaging", [], "packaging must be an object"), - ("required_artifacts", {}, "required_artifacts must be a list"), - ("required_evidence", ["proof"], "required_evidence entries are invalid"), - ], -) -def test_checker_policy_rejects_non_executable_collection_shapes( - field: str, - value: Any, - message: str, -) -> None: - policy = compiler_effective_policy() - policy[field] = value - - with pytest.raises(PreSubmitCheckerCompilerError, match=message): - checker_compiler_module._expected_primitives(policy) - - -@pytest.mark.parametrize( - "old_checker_name", - ["check_evidence_references_present", "check_artifact_manifest_integrity"], -) -def test_old_checker_name_blocks_post_submit_compilation_without_alias( - old_checker_name: str, -) -> None: - spec = build_project_post_submit_checker_spec( - project_id="00000000-0000-0000-0000-000000000001", - guide_version="v1", - required_checkers=[old_checker_name], - ) - - with pytest.raises(PostSubmitCheckerCompilerError, match="post-submit project selection is unavailable"): - compile_project_post_submit_checker_spec( - project_id="00000000-0000-0000-0000-000000000001", - guide_version="v1", - spec=spec, - ) diff --git a/backend/tests/test_ci_lane_catalogue.py b/backend/tests/test_ci_lane_catalogue.py index 6d24dc950..aca4ef77e 100644 --- a/backend/tests/test_ci_lane_catalogue.py +++ b/backend/tests/test_ci_lane_catalogue.py @@ -58,7 +58,6 @@ def test_checker_delivery_and_routing_preparation_partition_every_node_once() -> "tests/checkers/external/test_selected_pre_submit_coordination.py", "tests/checkers/external/test_selected_pre_submit_service.py", "tests/checkers/external/test_selected_preparation_command.py", - "tests/checkers/execution/test_results.py", "tests/checkers/execution/test_execution.py", "tests/checkers/execution/test_coordination.py", "tests/checkers/execution/test_concurrency.py", @@ -68,7 +67,6 @@ def test_checker_delivery_and_routing_preparation_partition_every_node_once() -> "tests/checkers/execution/test_material_migration.py", "tests/test_post_submit_materialization.py", "tests/test_post_submit_selection.py", - "tests/test_submission_evaluation_capacity.py", "tests/test_checker_output_custody.py", "tests/test_checker_output_storage.py", } @@ -196,7 +194,6 @@ def test_measured_hotspots_have_explicit_semantic_owners() -> None: "tests/projects/guide_compilation/finalization/test_structure.py", "tests/projects/guide_compilation/proposals/test_approved_tip.py", "tests/projects/guide_compilation/proposals/test_artifact_paths.py", - "tests/projects/guide_compilation/proposals/test_selected_checks.py", "tests/projects/guide_compilation/proposals/test_authority_contract.py", "tests/projects/guide_compilation/proposals/test_contracts.py", "tests/projects/guide_compilation/proposals/test_audit_schema.py", @@ -210,13 +207,11 @@ def test_measured_hotspots_have_explicit_semantic_owners() -> None: "tests/projects/public_activation/test_failures.py", "tests/projects/public_activation/test_workflow.py", "tests/projects/post_policy/test_authority.py", - "tests/projects/post_policy/test_compiler.py", "tests/projects/post_policy/test_public_api.py", "tests/projects/post_policy/test_public_recovery.py", "tests/projects/post_policy/test_delivery_worker.py", "tests/projects/post_policy/test_concurrency.py", "tests/projects/post_policy/test_correction.py", - "tests/projects/post_policy/test_direct_sql.py", "tests/projects/post_policy/test_guards.py", "tests/projects/post_policy/test_inventory.py", "tests/projects/post_policy/test_schema.py", @@ -259,7 +254,6 @@ def test_measured_hotspots_have_explicit_semantic_owners() -> None: "tests/projects/test_locked_policy_custody.py", "tests/projects/test_locked_policy_concurrency.py", "tests/projects/test_locked_policy_contract.py", - "tests/projects/test_activation_readiness.py", "tests/projects/test_policy_read_composition.py", "tests/projects/test_active_guide_read_composition.py", "tests/projects/test_diagnostic_read_composition.py", @@ -295,7 +289,6 @@ def test_measured_hotspots_have_explicit_semantic_owners() -> None: == { "tests/checkers/execution/test_completion_evidence.py", "tests/checkers/execution/test_completion_contract.py", - "tests/tasks/post_submit_routing/test_failure_completion.py", "tests/tasks/post_submit_routing/test_remediation.py", "tests/tasks/post_submit_routing/test_remediation_storage.py", "tests/tasks/post_submit_routing/test_remediation_currentness.py", @@ -364,29 +357,12 @@ def test_measured_hotspots_have_explicit_semantic_owners() -> None: "tests/tasks/test_payment_policy_migration.py", "tests/tasks/test_contribution_claim_races.py", "tests/tasks/test_submission_lineage.py", - "tests/checkers/post_submit/test_catalogue.py", - "tests/checkers/post_submit/test_compiled_policy.py", "tests/checkers/post_submit/test_configuration.py", - "tests/checkers/post_submit/test_conformance.py", "tests/checkers/post_submit/test_input_bounds.py", "tests/checkers/post_submit/test_public_boundary.py", "tests/checkers/post_submit/test_request.py", "tests/checkers/post_submit/test_requirement_dispositions.py", "tests/checkers/post_submit/test_result_contract.py", - "tests/checkers/test_effective_intake_rules.py", - "tests/test_blocked_pre_submit_feedback_postgresql.py", - "tests/test_checker_catalogue.py", - "tests/test_checkers.py", - "tests/test_default_pre_submit_execution.py", - "tests/test_approved_guide_intake.py", - "tests/test_pre_submit_attempt_recovery.py", - "tests/test_pre_submit_attempt_contracts.py", - "tests/test_pre_submit_attempt_authority_integration.py", - "tests/test_pre_submit_attempt_lock_order.py", - "tests/test_pre_submit_role_issue_lock_order.py", - "tests/test_pre_submit_related_lock_order.py", - "tests/test_pre_submit_attempt_schema.py", - "tests/test_effective_pre_submit_execution.py", "tests/test_project_guide_compilation_contracts.py", "tests/test_review_lease_persistence.py", "tests/test_review_queue_persistence.py", diff --git a/backend/tests/test_default_pre_submit_execution.py b/backend/tests/test_default_pre_submit_execution.py deleted file mode 100644 index 02fac5d0b..000000000 --- a/backend/tests/test_default_pre_submit_execution.py +++ /dev/null @@ -1,1558 +0,0 @@ -"""Proof for plan-bound hidden Workstream-default pre-submit execution.""" - -from __future__ import annotations - -from tests.tasks.lineage_fixtures import seed_started_task_for_artifact_test - -from project_create_fixtures import guide_snapshot_columns - -import asyncio -from io import BytesIO -from dataclasses import replace -from pathlib import Path -import threading -from types import SimpleNamespace -from typing import Any, cast -from unittest.mock import AsyncMock -import zipfile -from uuid import UUID -from app.core.identifiers import new_record_id - -import pytest -from sqlalchemy import func, select, text -from sqlalchemy.exc import DBAPIError -from sqlalchemy.ext.asyncio import async_sessionmaker, create_async_engine - -from app.core.hashing import canonical_json_hash -from app.core.config import Settings -from app.modules.artifacts.preparation import ( - HARD_MAXIMUM_ARTIFACT_BYTES, - ArtifactPreparationLimits, - ArtifactPreparationService, - ArtifactPreparationDeadlineError, - ArtifactScratchManager, -) -from app.modules.artifacts.schemas import ArtifactAuthorityDeniedError -from app.modules.artifacts.models import ( - ArtifactContent, - ArtifactOperationReceipt, - ArtifactPutAttempt, - ArtifactReplica, - ArtifactVerificationJob, - ArtifactVerificationReceipt, - SubmissionBundleDurableIntent, -) -from app.modules.artifacts.pre_submit_evidence import PreSubmitEvidenceConflict, _validate_execution -from app.modules.artifacts.service import ( - ArtifactAdmissionRelationshipError, - ArtifactStorageNamespaceSpec, -) -from app.modules.artifacts.submission_admission import ( - SubmissionBundleAdmissionPublisher, - SubmissionBundleDurablePutRequest, -) -from app.modules.artifacts.operator import ArtifactOperatorService -from app.modules.artifacts.metrics import artifact_admission_metrics -from app.modules.artifacts.schemas import ArtifactOperatorAuthorizationEvidence -from app.modules.artifacts.submission_authorization import ( - DenySubmissionBundlePreparedAuthorization, -) -from app.modules.artifacts.submission_archive import ( - SubmissionArchiveInspector, - SubmissionArchiveLimits, -) -from app.modules.artifacts.submission_manifest import ( - build_submission_manifest, - evaluate_submission_change, -) -from app.modules.artifacts.submission_materialization import ( - DenyPreSubmitMaterializationAuthorization, - PreparedBundleMaterializationRequest, - PreparedBundlePreSubmitEvidenceService, - PreparedBundleMaterializationService, -) -from app.modules.authorization.prepared import PreparedAuthorizationHandle -from app.modules.authorization.catalogue import ACTION_BY_ID -from app.modules.checkers.catalogue import ( - PreSubmissionCheckerPhase, - build_pre_submission_checker_catalogue, -) -from app.modules.checkers.compiler import compile_effective_project_submission_artifact_policy -from app.modules.checkers.effective_plan import ( - EffectivePreSubmissionPlanLineage, - compile_effective_pre_submission_execution_plan, -) -from app.modules.checkers.pre_submit_execution import ( - PreSubmissionResultStatus, - SubmissionPacketView, -) -from app.modules.checkers.api import PreSubmissionInfrastructureUnavailableError -from tests.artifact_store_helpers import artifact_admission_limit_settings -from tests.pre_submit_test_helpers import ( - approved_pre_submit_fixture, - durable_put_service, - assert_pre_submit_evidence_immutable, - assert_admission_replay_state, - materialize_member_fixture, - execute_evidence_workflow, - checker_execution as _CheckerExecution, - evidence_workflow, - submission_preparation_request, -) -from tests.submission_preparation_auth_helpers import ( - install_submitter_grant, - prepared_submitter_authority, - table_counts, -) - - -async def _bytes(value: bytes): - yield value - - -class _AllowOperatorAuthority: - async def authorize(self, *, facts, **_values) -> ArtifactOperatorAuthorizationEvidence: - return ArtifactOperatorAuthorizationEvidence(action_id=facts.action_id, - permission_id=ACTION_BY_ID[facts.action_id].permission_id.value, decision_id=new_record_id()) - - -@pytest.mark.asyncio -async def test_evidence_workflow_requires_transaction_free_session() -> None: - materialization = SimpleNamespace(materialize_prepared_bundle=lambda _request: None) - workflow = PreparedBundlePreSubmitEvidenceService( - session=cast(Any, SimpleNamespace(in_transaction=lambda: True)), - materialization=cast(Any, materialization), - preparation_authorization=cast(Any, SimpleNamespace()), - task_contexts=cast(Any, SimpleNamespace()), - project_contexts=cast(Any, SimpleNamespace()), - ) - - with pytest.raises(RuntimeError, match="requires a transaction-free session"): - await workflow.execute_reserved( - cast(Any, object()), object(), - preparation_request=cast(Any, object()), - ) - - -def _archive(path: str = "task.toml", *, primary_bytes: bytes = b"[task]\nname='proof'\n", extra_path: str | None = None, evidence_path="evidence/results") -> bytes: - output = BytesIO() - with zipfile.ZipFile(output, "w") as archive: - def write(name: str, value: bytes) -> None: - entry = zipfile.ZipInfo(name, date_time=(1980, 1, 1, 0, 0, 0)) - archive.writestr(entry, value) - - write(path, primary_bytes) - if extra_path is not None: - write(extra_path, b"blocked\n") - if path != evidence_path: - write(evidence_path, b"verified\n") - return output.getvalue() - - -def _effective_policy() -> dict[str, object]: - defaults = { - "required_packet_fields": ["summary", "worker_attestation", "artifact_hash_manifest"], - "forbidden_artifacts": [{"pattern": ".env"}, {"pattern": ".git/**"}], - "attestation_terms": ["rights_confirmed"], - } - return { - "workstream_default_policy": defaults, - "project_policy": {}, - "required_packet_fields": defaults["required_packet_fields"], - "required_artifacts": [{"key": "task.toml", "path": "task.toml", "required": True}], - "required_evidence": [{"key": "results", "required": True}], - "forbidden_artifacts": defaults["forbidden_artifacts"], - "attestation_terms": defaults["attestation_terms"], - "manifest_required": True, - "artifact_hash_required": True, - "artifact_hash_algorithm": "sha256", - "allowed_storage_schemes": ["s3"], - "maximum_file_size_bytes": 1_000_000, - "maximum_package_size_bytes": 5_000_000, - "packaging": {"package_required": True, "allowed_package_formats": ["zip"]}, - } - - -def _plan(catalogue, *, policy=None): - policy = _effective_policy() if policy is None else policy - policy_hash = canonical_json_hash(policy) - compiled = compile_effective_project_submission_artifact_policy(policy, policy_hash) - snapshot_id = new_record_id() - lineage = EffectivePreSubmissionPlanLineage( - project_id=new_record_id(), - guide_id=new_record_id(), - guide_version="v0.1", - source_snapshot_id=snapshot_id, - source_snapshot_hash=guide_snapshot_columns(str(snapshot_id))["bundle_hash"], - effective_policy_id=new_record_id(), - effective_policy_hash=policy_hash, - pre_submit_policy_id=new_record_id(), - pre_submit_policy_bundle_hash=compiled.compiled_bundle_hash, - ) - return compile_effective_pre_submission_execution_plan( - lineage=lineage, - effective_policy=policy, - compiled_bundle=compiled.compiled_bundle, - catalogue=catalogue, - ) - - -def _rehash_plan(plan, *, entries=None, catalogue_manifest_sha256=None): - changed = replace( - plan, - entries=plan.entries if entries is None else tuple(entries), - catalogue_manifest_sha256=( - plan.catalogue_manifest_sha256 - if catalogue_manifest_sha256 is None - else catalogue_manifest_sha256 - ), - ) - return replace(changed, plan_sha256=canonical_json_hash(changed.as_dict())) - - -def _limits() -> ArtifactPreparationLimits: - return ArtifactPreparationLimits( - aggregate_reserved_bytes=2 * HARD_MAXIMUM_ARTIFACT_BYTES, - maximum_files=2, - maximum_concurrency=2, - minimum_free_bytes=0, - reservation_ttl_seconds=30, - total_deadline_seconds=10, - cleanup_margin_seconds=5, - stream_buffer_bytes=1024, - maximum_source_bytes=1024 * 1024, - maximum_workspace_entries=2_000, - ) - - -class _AllowAuthority: - def __init__(self) -> None: - self.preparation_facts = None - self.facts = None - self.action_id = None - self.service_identity = None - - async def prepare(self, *, facts, idempotency_key): - del idempotency_key - self.preparation_facts = facts - return _handle() - - async def consume(self, **values): - self.facts = values["facts"] - - -class _TestPreparedAuthorizationHandle: - """Typed sentinel accepted only by the bounded authorization protocol double.""" - - -def _handle() -> PreparedAuthorizationHandle: - return cast(PreparedAuthorizationHandle, _TestPreparedAuthorizationHandle()) - - -async def _request( - tmp_path: Path, - *, - path: str = "task.toml", - primary_bytes: bytes = b"[task]\nname='proof'\n", - extra_path: str | None = None, - catalogue=None, - plan=None, - evidence_path="evidence/results", -): - selected_catalogue = catalogue or build_pre_submission_checker_catalogue() - plan = _plan(selected_catalogue) if plan is None else plan - data = _archive(path, primary_bytes=primary_bytes, extra_path=extra_path, evidence_path=evidence_path) - inspector = SubmissionArchiveInspector(SubmissionArchiveLimits()) - manager = ArtifactScratchManager(root=tmp_path / "scratch", limits=_limits()) - preparation = ArtifactPreparationService(manager) - prepared = await preparation.prepare(_bytes(data), media_type="application/zip") - inspection = await prepared.inspect(inspector) - manifest = build_submission_manifest(inspection) - change = evaluate_submission_change( - commitment=prepared.commitment, - manifest=manifest, - predecessor=None, - predecessor_exists=False, - ) - request = PreparedBundleMaterializationRequest( - prepared_authorization=_handle(), - task_id=new_record_id(), - assignment_id=new_record_id(), - submission_artifact_policy_id=plan.lineage.effective_policy_id, - checker_policy_id=plan.lineage.pre_submit_policy_id, - predecessor_submission_version=None, - prepared_artifact=prepared, - effective_plan=plan, - inspection=inspection, - manifest=manifest, - change_gate=change, - packet=SubmissionPacketView( - summary="Completed exact project work.", - contributor_attestation=( - "I confirm no confidential client data, credentials, or copied source " - "material is included in this submission; rights_confirmed." - ), - ), - ) - return request, inspector, manager, preparation, selected_catalogue - - -@pytest.mark.asyncio -async def test_authority_denial_precedes_workspace_and_checker_access(tmp_path: Path) -> None: - request, inspector, manager, preparation, catalogue = await _request(tmp_path) - service = PreparedBundleMaterializationService( - session=SimpleNamespace(), - authorization=DenyPreSubmitMaterializationAuthorization(), - preparation=preparation, - checker_execution=_CheckerExecution(inspector, catalogue), - storage_scheme="s3", - ) - - with pytest.raises(ArtifactAuthorityDeniedError): - await materialize_member_fixture(service, request) - - assert list((tmp_path / "scratch" / "workspaces").iterdir()) == [] - await request.prepared_artifact.close() - manager.close() - - -@pytest.mark.asyncio -async def test_authority_preparation_denies_before_zip_inspection( - tmp_path: Path, - monkeypatch: pytest.MonkeyPatch, -) -> None: - catalogue = build_pre_submission_checker_catalogue() - plan = _plan(catalogue) - manager = ArtifactScratchManager(root=tmp_path / "scratch", limits=_limits()) - preparation = ArtifactPreparationService(manager) - prepared = await preparation.prepare(_bytes(_archive()), media_type="application/zip") - inspection_calls = 0 - - async def forbidden_inspection(*_args, **_kwargs): - nonlocal inspection_calls - inspection_calls += 1 - raise AssertionError("ZIP inspection preceded authority preparation") - - monkeypatch.setattr(type(prepared), "inspect", forbidden_inspection) - service = PreparedBundleMaterializationService( - session=SimpleNamespace(), - authorization=DenyPreSubmitMaterializationAuthorization(), - preparation=preparation, - checker_execution=_CheckerExecution( - SubmissionArchiveInspector(SubmissionArchiveLimits()), catalogue - ), - storage_scheme="s3", - ) - - with pytest.raises(ArtifactAuthorityDeniedError): - await service.prepare_authorization( - task_id=new_record_id(), - assignment_id=new_record_id(), - submission_artifact_policy_id=plan.lineage.effective_policy_id, - checker_policy_id=plan.lineage.pre_submit_policy_id, - prepared_artifact=prepared, - effective_plan=plan, - idempotency_key=new_record_id(), - ) - - assert list((tmp_path / "scratch" / "workspaces").iterdir()) == [] - assert inspection_calls == 0 - await prepared.close() - manager.close() - - -@pytest.mark.asyncio -async def test_manifest_drift_denies_before_authority_and_workspace(tmp_path: Path) -> None: - request, inspector, manager, preparation, catalogue = await _request(tmp_path) - first = next(entry for entry in request.inspection.entries if entry.sha256 is not None) - forged_entry = replace(first, sha256="sha256:" + "f" * 64) - forged_inspection = replace( - request.inspection, - entries=tuple( - forged_entry if entry is first else entry for entry in request.inspection.entries - ), - ) - forged_manifest = build_submission_manifest(forged_inspection) - forged_change = evaluate_submission_change( - commitment=request.prepared_artifact.commitment, - manifest=forged_manifest, - predecessor=None, - predecessor_exists=False, - ) - authority = _AllowAuthority() - service = PreparedBundleMaterializationService( - session=SimpleNamespace(), - authorization=authority, - preparation=preparation, - checker_execution=_CheckerExecution(inspector, catalogue), - storage_scheme="s3", - ) - - with pytest.raises( - PreSubmissionInfrastructureUnavailableError, - match="materialization_context_invalid", - ): - await materialize_member_fixture(service, - replace(request, manifest=forged_manifest, change_gate=forged_change) - ) - - assert authority.facts is None - assert list((tmp_path / "scratch" / "workspaces").iterdir()) == [] - await request.prepared_artifact.close() - manager.close() - - -@pytest.mark.asyncio -async def test_two_stage_authority_uses_one_handle_and_exact_final_facts( - tmp_path: Path, -) -> None: - request, inspector, manager, preparation, catalogue = await _request(tmp_path) - authority = _AllowAuthority() - service = PreparedBundleMaterializationService( - session=SimpleNamespace(), - authorization=authority, - preparation=preparation, - checker_execution=_CheckerExecution(inspector, catalogue), - storage_scheme="s3", - ) - handle = await service.prepare_authorization( - task_id=request.task_id, - assignment_id=request.assignment_id, - submission_artifact_policy_id=request.submission_artifact_policy_id, - checker_policy_id=request.checker_policy_id, - prepared_artifact=request.prepared_artifact, - effective_plan=request.effective_plan, - idempotency_key=new_record_id(), - ) - - result = await materialize_member_fixture(service, - replace(request, prepared_authorization=handle) - ) - - assert result.eligible is True - assert authority.preparation_facts is not None - assert authority.facts is not None - assert authority.facts.preparation == authority.preparation_facts - assert authority.facts.semantic_manifest_sha256 == request.manifest.sha256 - await request.prepared_artifact.close() - manager.close() - - -@pytest.mark.asyncio -async def test_effective_evidence_workflow_persists_once_and_replays_exactly( - tmp_path: Path, - isolated_database_env: str, -) -> None: - engine = create_async_engine(isolated_database_env) - session_factory = async_sessionmaker(engine, expire_on_commit=False) - namespace = ArtifactStorageNamespaceSpec( - backend="local", adapter="local", provider_profile="test", - namespace_descriptor={"test": "submission-bundle"}, - namespace_fingerprint=canonical_json_hash({"test": "submission-bundle"}), - ) - plan, policy_params = await approved_pre_submit_fixture(session_factory, namespace, guide_version="v0.1") - evidence_path = policy_params.pop("evidence_path") - request, inspector, manager, preparation, catalogue = await _request(tmp_path, plan=plan, evidence_path=evidence_path) - request = replace(request, packet=replace(request.packet, contributor_attestation=( - request.packet.contributor_attestation + " " + " ".join(policy_params.pop("attestation_terms")) - ))) - actor_id = new_record_id() - identity_link_id = new_record_id() - lineage = request.effective_plan.lineage - blocked_prepared = replay_prepared = drift_prepared = denied_prepared = None - original_prepared_closed = False - tables = ( - "artifact_contents", - "artifact_replicas", - "artifact_put_attempts", - "submission_bundle_admissions", - "submissions", - "checker_runs", - "review_queue_entries", - "pre_submit_evidence_sets", - "pre_submit_evidence_results", - ) - try: - async with engine.begin() as connection: - params = { - "actor": str(actor_id), "subject": str(actor_id), - "link": str(identity_link_id), - "project": str(lineage.project_id), - "guide": str(lineage.guide_id), - "snapshot": str(lineage.source_snapshot_id), - "snapshot_hash": lineage.source_snapshot_hash, - **policy_params, - "effective_policy": str(lineage.effective_policy_id), - "effective_hash": lineage.effective_policy_hash, - "checker_policy": str(lineage.pre_submit_policy_id), - "checker_hash": lineage.pre_submit_policy_bundle_hash, - "task": str(request.task_id), - "assignment": str(request.assignment_id), - } - await connection.execute( - text( - "insert into actor_profiles " - "(id,actor_kind,status,provisioning_method,created_by) values " - "(:actor,'human','active','automatic_first_access','test')" - ), - params, - ) - await connection.execute( - text( - "insert into actor_identity_links " - "(id,actor_profile_id,issuer,subject,subject_kind,status,linked_by," - "last_verified_at) values " - "(:link,:actor,'flow-test',:subject,'human','active','test',now())" - ), - params, - ) - await seed_started_task_for_artifact_test(connection, params) - await install_submitter_grant(connection, params) - before = await table_counts(connection, tables) - session_factory = async_sessionmaker(engine, expire_on_commit=False) - async with session_factory() as session: - preparation_authority = cast(Any, SimpleNamespace(lock_actor=AsyncMock(), revalidate=AsyncMock())) - workflow = evidence_workflow( - session=session, - preparation=preparation, - inspector=inspector, - catalogue=catalogue, - materialization_authorization=_AllowAuthority(), - preparation_authorization=preparation_authority, - ) - preparation_request = submission_preparation_request( - request, - actor_profile_id=actor_id, - identity_link_id=identity_link_id, - ) - async def fresh_checked_bundle(): - prepared = await preparation.prepare( - _bytes(_archive(evidence_path=evidence_path)), - media_type="application/zip", - ) - inspection = await prepared.inspect(inspector) - manifest = build_submission_manifest(inspection) - fresh_request = replace( - request, - prepared_artifact=prepared, - inspection=inspection, - manifest=manifest, - change_gate=evaluate_submission_change( - commitment=prepared.commitment, - manifest=manifest, - predecessor=None, - predecessor_exists=False, - ), - ) - result = await execute_evidence_workflow(workflow, - fresh_request, - preparation_request=replace(preparation_request, idempotency_key=new_record_id()), - ) - assert result.pass_capability is not None - return prepared, result - - first = await execute_evidence_workflow(workflow, - request, - preparation_request=preparation_request, - ) - replay = await execute_evidence_workflow(workflow, - request, - preparation_request=preparation_request, - ) - assert first.pass_capability is not None, first.failure_audit - admission_settings = Settings(_env_file=None, - **artifact_admission_limit_settings(1024 * 1024), - environment="test", - artifact_store_backend="local", - artifact_local_root=tmp_path / "durable", - artifact_scratch_root=tmp_path / "scratch", - artifact_scratch_minimum_free_bytes=0, - ) - provider = SimpleNamespace( - execute_committed_put=AsyncMock(), - resume_committed_put=AsyncMock(), - ) - async with session.begin(): - final_authority = await prepared_submitter_authority( - session, preparation_request, actor_id, identity_link_id, lineage.project_id, - ) - durable_service = durable_put_service( - session, admission_settings, namespace, provider, final_authority, - ) - ( - retained, - selected_evidence_id, - first_admission, - ) = await durable_service.admit_in_transaction( - SubmissionBundleDurablePutRequest( - prepared_authorization=None, - prepared_artifact=request.prepared_artifact, - pass_capability=first.pass_capability, - ) - ) - provider.execute_committed_put.assert_not_awaited() - provider.resume_committed_put.assert_not_awaited() - intent = await session.scalar( - select(SubmissionBundleDurableIntent).where( - SubmissionBundleDurableIntent.put_attempt_id == str(first_admission.attempt_id) - ) - ) - assert intent is not None - replay_intent_id = UUID(intent.id) - await session.rollback() - assert retained is request.prepared_artifact - await retained.close() - original_prepared_closed = True - - replay_prepared, fresh = await fresh_checked_bundle() - async with session.begin(): - ( - replay_retained, - replay_evidence_id, - replay_admission, - ) = await durable_service.admit_in_transaction( - SubmissionBundleDurablePutRequest( - prepared_authorization=None, - prepared_artifact=replay_prepared, - pass_capability=fresh.pass_capability, - replay_durable_intent_id=replay_intent_id, - ) - ) - assert replay_admission.replayed is True - assert replay_admission.attempt_id == first_admission.attempt_id - assert replay_evidence_id == fresh.evidence.evidence_set_id - await replay_retained.close() - intent_count = int( - await session.scalar( - select(func.count()).select_from(SubmissionBundleDurableIntent) - ) - or 0 - ) - assert intent_count == 1 - await session.rollback() - - drift_prepared, drift = await fresh_checked_bundle() - await session.execute( - text("update task_assignments set status='inactive' where id=:assignment"), - {"assignment": str(request.assignment_id)}, - ) - await session.commit() - with pytest.raises( - ArtifactAdmissionRelationshipError, - match="passing evidence is unavailable|locked_context", - ): - async with session.begin(): - await durable_service.admit_in_transaction( - SubmissionBundleDurablePutRequest( - prepared_authorization=None, - prepared_artifact=drift_prepared, - pass_capability=drift.pass_capability, - ) - ) - await session.execute( - text("update task_assignments set status='active' where id=:assignment"), - {"assignment": str(request.assignment_id)}, - ) - await session.commit() - - denied_prepared, denied = await fresh_checked_bundle() - denied_service = durable_put_service( - session, admission_settings, namespace, provider, - DenySubmissionBundlePreparedAuthorization(), - ) - with pytest.raises(ArtifactAuthorityDeniedError): - async with session.begin(): - await denied_service.admit_in_transaction( - SubmissionBundleDurablePutRequest( - prepared_authorization=None, - prepared_artifact=denied_prepared, - pass_capability=denied.pass_capability, - ) - ) - async with session.begin(): - attempt = await session.get( - ArtifactPutAttempt, - str(first_admission.attempt_id), - with_for_update=True, - ) - assert attempt is not None - content = ArtifactContent( - id=str(new_record_id()), - sha256=attempt.sha256, - byte_count=attempt.byte_count, - media_type=attempt.media_type, - normalized_display_name=None, - ) - replica = ArtifactReplica( - id=str(new_record_id()), - content_id=content.id, - storage_namespace_id=attempt.storage_namespace_id, - namespace_fingerprint=attempt.namespace_fingerprint, - adapter="local", - provider_profile="test", - provider_object_ref=attempt.canonical_target, - verification_state="verified", - availability_state="available", - integrity_state="valid", - ) - session.add_all((content, replica)) - await session.flush() - put_receipt = ArtifactOperationReceipt( - id=str(new_record_id()), - put_attempt_id=attempt.id, - guide_source_item_id=None, - checker_run_id=None, - logical_role=None, - replica_id=replica.id, - operation="put", - idempotency_key=attempt.operation_identity, - request_digest=attempt.request_digest, - provider_object_ref=attempt.canonical_target, - replayed=False, - outcome="stored_pending_verification", - attempt_number=1, - correlation_id=attempt.operation_identity, - details=[], - ) - job = ArtifactVerificationJob( - id=str(new_record_id()), - originating_put_attempt_id=attempt.id, - replica_id=replica.id, - status="verified", - maximum_attempts=5, - execution_generation=1, - ) - session.add_all((put_receipt, job)) - attempt.status = "object_confirmed" - attempt.replica_id = replica.id - attempt.receipt_id = put_receipt.id - verification_receipt = ArtifactVerificationReceipt( - id=str(new_record_id()), - verification_job_id=job.id, - execution_generation=1, - outcome="verified", - observed_sha256=attempt.sha256, - observed_byte_count=attempt.byte_count, - ) - session.add(verification_receipt) - await session.flush() - job_id = job.id - verification_receipt_id = verification_receipt.id - attempt_byte_count = attempt.byte_count - - async def publish_ready() -> str: - async with session_factory() as publisher_session: - async with publisher_session.begin(): - ready = await SubmissionBundleAdmissionPublisher( - publisher_session - ).publish_verified( - verification_job_id=job_id, - verification_receipt_id=verification_receipt_id, - ) - assert ready is not None and ready.status == "ready" - return ready.id - - published_ids = await asyncio.gather(publish_ready(), publish_ready()) - assert published_ids[0] == published_ids[1] - async with session.begin(): - usage = await ArtifactOperatorService( - session, - _AllowOperatorAuthority(), - admission_settings, - artifact_admission_metrics, - ).admission_usage( - authorization_context=cast(Any, object()), - project_id=lineage.project_id, - task_id=request.task_id, - cursor=None, - limit=10, - ) - assert len(usage.items) == 3 - assert all(item["unbound_ready_count"] == 1 for item in usage.items) - assert all( - item["unbound_ready_bytes"] == attempt_byte_count for item in usage.items - ) - assert all(item["stale_count"] == 0 for item in usage.items) - durable_counts = { - table: int(await session.scalar(text(f"select count(*) from {table}")) or 0) - for table in ( - "artifact_put_attempts", - "submission_bundle_durable_intents", - "artifact_admission_charges", - ) - } - guide_continuation_matches = int( - await session.scalar( - text( - "select count(*) from artifact_put_attempts attempt " - "join guide_source_snapshot_items item " - "on item.id=attempt.guide_source_item_id " - "where attempt.producer_request_type='submission_bundle'" - ) - ) - or 0 - ) - await session.rollback() - assert durable_counts == { - "artifact_put_attempts": before["artifact_put_attempts"] + 1, - "submission_bundle_durable_intents": 1, - "artifact_admission_charges": 4, - } - assert guide_continuation_matches == 0 - provider.execute_committed_put.assert_not_awaited() - provider.resume_committed_put.assert_not_awaited() - assert selected_evidence_id == first.evidence.evidence_set_id - await assert_admission_replay_state(session, selected_evidence_id, - first_admission.attempt_id, published_ids[0], "ready") - await session.execute( - text( - "update submission_bundle_admissions set status='stale', " - "stale_at=now(), stale_reason='predecessor_advanced' where id=:id" - ), - {"id": published_ids[0]}, - ) - await session.commit() - await assert_admission_replay_state(session, selected_evidence_id, - first_admission.attempt_id, published_ids[0], "stale") - async with session.begin(): - stale_usage = await ArtifactOperatorService( - session, - _AllowOperatorAuthority(), - admission_settings, - artifact_admission_metrics, - ).admission_usage( - authorization_context=cast(Any, object()), - project_id=lineage.project_id, - task_id=request.task_id, - cursor=None, - limit=10, - ) - assert all(item["unbound_ready_count"] == 0 for item in stale_usage.items) - assert all(item["stale_count"] == 1 for item in stale_usage.items) - assert all(item["stale_bytes"] == attempt_byte_count for item in stale_usage.items) - with pytest.raises(DBAPIError): - await session.execute( - text( - "update submission_bundle_admissions set archive_sha256=:digest " - "where id=:id" - ), - {"id": published_ids[0], "digest": "sha256:" + "9" * 64}, - ) - await session.commit() - await session.rollback() - with pytest.raises(DBAPIError): - await session.execute( - text("delete from submission_bundle_admissions where id=:id"), - {"id": published_ids[0]}, - ) - await session.commit() - await session.rollback() - blocked_prepared = await preparation.prepare( - _bytes(_archive("task.toml", evidence_path=evidence_path)), media_type="application/zip" - ) - blocked_inspection = await blocked_prepared.inspect(inspector) - blocked_manifest = build_submission_manifest(blocked_inspection) - blocked_request = replace( - request, - prepared_artifact=blocked_prepared, - inspection=blocked_inspection, - manifest=blocked_manifest, - change_gate=evaluate_submission_change( - commitment=blocked_prepared.commitment, - manifest=blocked_manifest, - predecessor=None, - predecessor_exists=False, - ), - packet=SubmissionPacketView( - summary="Completed exact project work.", - contributor_attestation="", - ), - ) - blocked = await execute_evidence_workflow(workflow, - blocked_request, - preparation_request=replace( - preparation_request, idempotency_key=new_record_id(), - contributor_attestation=blocked_request.packet.contributor_attestation, - summary=blocked_request.packet.summary, - ), - ) - async with engine.begin() as connection: - evidence_count = int( - await connection.scalar(text("select count(*) from pre_submit_evidence_sets")) or 0 - ) - result_count = int( - await connection.scalar(text("select count(*) from pre_submit_evidence_results")) - or 0 - ) - after = { - table: int(await connection.scalar(text(f"select count(*) from {table}")) or 0) - for table in tables - } - await assert_pre_submit_evidence_immutable(connection) - finally: - for prepared in ( - blocked_prepared, - replay_prepared, - drift_prepared, - denied_prepared, - ): - if prepared is not None: - await prepared.close() - if not original_prepared_closed: - await request.prepared_artifact.close() - try: - manager.close() - finally: - await engine.dispose() - - assert first.evidence.replayed is False - assert replay.evidence.replayed is True - assert replay.evidence.evidence_set_id == first.evidence.evidence_set_id - assert first.pass_capability is not None - assert replay.pass_capability is None - assert first.failure_audit is None - assert blocked.pass_capability is None - assert blocked.evidence.replayed is False - assert blocked.failure_audit is not None - assert blocked.failure_audit["event_type"] == "pre_submission_check_failed" - assert blocked.failure_audit["failed_count"] >= 1 - assert "task.toml" not in repr(blocked.failure_audit) - assert (evidence_count, result_count) == (5, 5 * len(request.effective_plan.entries)) - assert after == { - **before, - "artifact_contents": before["artifact_contents"] + 1, - "artifact_replicas": before["artifact_replicas"] + 1, - "artifact_put_attempts": before["artifact_put_attempts"] + 1, - "submission_bundle_admissions": before["submission_bundle_admissions"] + 1, - "pre_submit_evidence_sets": evidence_count, "pre_submit_evidence_results": result_count, # noqa: E501 - } - - -@pytest.mark.asyncio -async def test_materializer_rejects_policy_lineage_mismatch_before_authority( - tmp_path: Path, -) -> None: - """Reject caller-selected policy identity before consuming authority.""" - request, inspector, manager, preparation, catalogue = await _request(tmp_path) - authority = _AllowAuthority() - service = PreparedBundleMaterializationService( - session=SimpleNamespace(), - authorization=authority, - preparation=preparation, - checker_execution=_CheckerExecution(inspector, catalogue), - storage_scheme="s3", - ) - - with pytest.raises( - PreSubmissionInfrastructureUnavailableError, - match="pre_submission_materialization_context_invalid", - ): - await materialize_member_fixture(service, - replace(request, submission_artifact_policy_id=new_record_id()) - ) - - assert authority.facts is None - await request.prepared_artifact.close() - await preparation.release_prepared_artifact(request.prepared_artifact._binding) - manager.close() - - -@pytest.mark.asyncio -async def test_effective_executor_uses_plan_order_and_dispatches_project_rules( - tmp_path: Path, -) -> None: - request, inspector, manager, preparation, catalogue = await _request(tmp_path) - authority = _AllowAuthority() - service = PreparedBundleMaterializationService( - session=SimpleNamespace(), - authorization=authority, - preparation=preparation, - checker_execution=_CheckerExecution(inspector, catalogue), - storage_scheme="s3", - ) - - result = await materialize_member_fixture(service, request) - - expected = [ - entry.definition_id - for entry in request.effective_plan.entries - if entry.phase in set(PreSubmissionCheckerPhase) - ] - assert [entry.definition_id for entry in result.entries] == expected - assert any(entry.definition_id.startswith("policy.") for entry in result.entries) - assert all( - entry.checker_execution_status == PreSubmissionResultStatus.PASSED.value - for entry in result.entries - ) - assert result.eligible is True - assert authority.facts is not None - assert authority.facts.task_id == request.task_id - assert authority.facts.assignment_id == request.assignment_id - assert authority.facts.project_id == request.effective_plan.lineage.project_id - assert authority.facts.guide_version == "v0.1" - assert authority.facts.submission_artifact_policy_id == request.submission_artifact_policy_id - assert authority.facts.checker_policy_id == request.checker_policy_id - assert authority.facts.prepared_generation_id == request.prepared_artifact.generation_id - assert authority.facts.plan_sha256 == request.effective_plan.plan_sha256 - assert ( - authority.facts.catalogue_manifest_sha256 - == request.effective_plan.catalogue_manifest_sha256 - ) - assert authority.facts.archive_sha256 == request.prepared_artifact.commitment.sha256 - assert authority.facts.archive_byte_count == request.prepared_artifact.commitment.byte_count - assert authority.facts.semantic_manifest_sha256 == request.manifest.sha256 - assert authority.facts.storage_scheme == "s3" - assert list((tmp_path / "scratch" / "workspaces").iterdir()) == [] - await request.prepared_artifact.close() - manager.close() - - -@pytest.mark.asyncio -async def test_blocking_default_stops_later_dependency_without_review_decision( - tmp_path: Path, -) -> None: - request, inspector, manager, preparation, catalogue = await _request(tmp_path, path=".env") - service = PreparedBundleMaterializationService( - session=SimpleNamespace(), - authorization=_AllowAuthority(), - preparation=preparation, - checker_execution=_CheckerExecution(inspector, catalogue), - storage_scheme="s3", - ) - - result = await materialize_member_fixture(service, request) - by_id = {entry.definition_id: entry for entry in result.entries} - - assert ( - by_id["artifact.sensitive_paths.high_confidence"].checker_execution_status - == PreSubmissionResultStatus.FAILED.value - ) - assert ( - by_id["artifact.quality.placeholder_signal"].checker_execution_status - == PreSubmissionResultStatus.DEPENDENCY_NOT_RUN.value - ) - assert result.eligible is False - assert all( - value not in {"accept", "needs_revision", "reject"} - for entry in result.entries - for value in (entry.checker_execution_status, entry.message_code, entry.failure_code) - if value is not None - ) - await request.prepared_artifact.close() - manager.close() - - -@pytest.mark.asyncio -async def test_disabled_advisory_is_explicit_and_not_skipped_success(tmp_path: Path) -> None: - catalogue = build_pre_submission_checker_catalogue( - disabled_entry_ids=frozenset({"artifact.quality.placeholder_signal"}) - ) - request, inspector, manager, preparation, _ = await _request(tmp_path, catalogue=catalogue) - service = PreparedBundleMaterializationService( - session=SimpleNamespace(), - authorization=_AllowAuthority(), - preparation=preparation, - checker_execution=_CheckerExecution(inspector, catalogue), - storage_scheme="s3", - ) - - result = await materialize_member_fixture(service, request) - advisory = next( - entry - for entry in result.entries - if entry.definition_id == "artifact.quality.placeholder_signal" - ) - - assert advisory.checker_execution_status == PreSubmissionResultStatus.ADVISORY_DISABLED.value - assert result.eligible is True - await request.prepared_artifact.close() - manager.close() - - -@pytest.mark.asyncio -async def test_quality_warning_emits_only_a_bounded_category_count(tmp_path: Path) -> None: - request, inspector, manager, preparation, catalogue = await _request(tmp_path) - request = replace( - request, - packet=replace(request.packet, summary="Completed work; TODO placeholder removed."), - ) - service = PreparedBundleMaterializationService( - session=SimpleNamespace(), - authorization=_AllowAuthority(), - preparation=preparation, - checker_execution=_CheckerExecution(inspector, catalogue), - storage_scheme="s3", - ) - - result = await materialize_member_fixture(service, request) - warning = next( - entry - for entry in result.entries - if entry.definition_id == "artifact.quality.placeholder_signal" - ) - - assert warning.checker_execution_status == PreSubmissionResultStatus.WARNING.value - assert warning.metadata == (("matched_category_count", 2),) - assert result.eligible is True - await request.prepared_artifact.close() - manager.close() - - -@pytest.mark.asyncio -async def test_forged_plan_identity_fails_closed_and_cleans_workspace(tmp_path: Path) -> None: - request, inspector, manager, preparation, catalogue = await _request(tmp_path) - forged = replace(request.effective_plan, plan_sha256="sha256:" + "0" * 64) - request = replace(request, effective_plan=forged) - service = PreparedBundleMaterializationService( - session=SimpleNamespace(), - authorization=_AllowAuthority(), - preparation=preparation, - checker_execution=_CheckerExecution(inspector, catalogue), - storage_scheme="s3", - ) - - with pytest.raises(PreSubmissionInfrastructureUnavailableError, match="plan_identity"): - await materialize_member_fixture(service, request) - - assert list((tmp_path / "scratch" / "workspaces").iterdir()) == [] - await request.prepared_artifact.close() - manager.close() - - -@pytest.mark.asyncio -@pytest.mark.parametrize( - ("invalid_state", "expected_message"), - ( - ("stale_entry", "pre_submission_plan_entry_stale"), - ("duplicate", "pre_submission_duplicate_result"), - ("unknown", "pre_submission_dispatch_capability_unknown"), - ), -) -async def test_invalid_executor_state_fails_closed_and_cleans_workspace( - tmp_path: Path, - invalid_state: str, - expected_message: str, -) -> None: - request, inspector, manager, preparation, catalogue = await _request(tmp_path) - entries = list(request.effective_plan.entries) - target_index = next( - index - for index, entry in enumerate(entries) - if entry.definition_id == "submission.packet.required_fields" - ) - selected_catalogue = catalogue - if invalid_state == "stale_entry": - entries[target_index] = replace(entries[target_index], definition_version="stale") - elif invalid_state == "duplicate": - entries.insert(target_index + 1, entries[target_index]) - else: - unknown = replace(entries[target_index], dispatch_capability="unknown.capability") - entries[target_index] = unknown - original = catalogue.definition(unknown.definition_id) - - class _UnknownCatalogue: - manifest_sha256 = catalogue.manifest_sha256 - - def definition(self, definition_id): - definition = catalogue.definition(definition_id) - if definition_id != original.stable_id: - return definition - - class _UnknownDefinition: - dispatch_capability = "unknown.capability" - - def __getattr__(self, name): - return getattr(definition, name) - - return _UnknownDefinition() - - selected_catalogue = _UnknownCatalogue() - request = replace( - request, - effective_plan=_rehash_plan(request.effective_plan, entries=entries), - ) - service = PreparedBundleMaterializationService( - session=SimpleNamespace(), - authorization=_AllowAuthority(), - preparation=preparation, - checker_execution=_CheckerExecution(inspector, selected_catalogue), - storage_scheme="s3", - ) - - with pytest.raises(PreSubmissionInfrastructureUnavailableError, match=expected_message): - await materialize_member_fixture(service, request) - - assert list((tmp_path / "scratch" / "workspaces").iterdir()) == [] - await request.prepared_artifact.close() - manager.close() - - -@pytest.mark.asyncio -async def test_disabled_mandatory_executor_state_fails_closed(tmp_path: Path) -> None: - request, inspector, manager, preparation, _ = await _request(tmp_path) - catalogue = build_pre_submission_checker_catalogue( - disabled_entry_ids=frozenset({"artifact.outer_zip.valid"}) - ) - entries = [ - replace(entry, checker_definition_state="disabled") - if entry.definition_id == "artifact.outer_zip.valid" - else entry - for entry in request.effective_plan.entries - ] - request = replace( - request, - effective_plan=_rehash_plan( - request.effective_plan, - entries=entries, - catalogue_manifest_sha256=catalogue.manifest_sha256, - ), - ) - service = PreparedBundleMaterializationService( - session=SimpleNamespace(), - authorization=_AllowAuthority(), - preparation=preparation, - checker_execution=_CheckerExecution(inspector, catalogue), - storage_scheme="s3", - ) - - with pytest.raises(PreSubmissionInfrastructureUnavailableError): - await materialize_member_fixture(service, request) - - assert list((tmp_path / "scratch" / "workspaces").iterdir()) == [] - await request.prepared_artifact.close() - manager.close() - - -@pytest.mark.asyncio -async def test_effective_execution_enforces_project_only_forbidden_rule(tmp_path: Path) -> None: - catalogue = build_pre_submission_checker_catalogue() - policy = _effective_policy() - project_rule = {"pattern": "project-only.blocked"} - policy["project_policy"] = {"forbidden_artifacts": [project_rule]} - policy["forbidden_artifacts"] = [*policy["forbidden_artifacts"], project_rule] - policy_hash = canonical_json_hash(policy) - compiled = compile_effective_project_submission_artifact_policy(policy, policy_hash) - lineage = replace( - _plan(catalogue).lineage, - effective_policy_hash=policy_hash, - pre_submit_policy_bundle_hash=compiled.compiled_bundle_hash, - ) - plan = compile_effective_pre_submission_execution_plan( - lineage=lineage, - effective_policy=policy, - compiled_bundle=compiled.compiled_bundle, - catalogue=catalogue, - ) - request, inspector, manager, preparation, _ = await _request( - tmp_path, - extra_path="project-only.blocked", - catalogue=catalogue, - ) - request = replace( - request, - submission_artifact_policy_id=plan.lineage.effective_policy_id, - checker_policy_id=plan.lineage.pre_submit_policy_id, - effective_plan=plan, - ) - service = PreparedBundleMaterializationService( - session=SimpleNamespace(), - authorization=_AllowAuthority(), - preparation=preparation, - checker_execution=_CheckerExecution(inspector, catalogue), - storage_scheme="s3", - ) - - result = await materialize_member_fixture(service, request) - - assert result.eligible is False - project_result = next( - entry for entry in result.entries if entry.definition_id == "policy.artifact.forbid" - ) - assert project_result.checker_execution_status == PreSubmissionResultStatus.FAILED.value - await request.prepared_artifact.close() - manager.close() - - -@pytest.mark.asyncio -async def test_effective_execution_enforces_server_owned_storage_scheme(tmp_path: Path) -> None: - request, inspector, manager, preparation, catalogue = await _request(tmp_path) - service = PreparedBundleMaterializationService( - session=SimpleNamespace(), - authorization=_AllowAuthority(), - preparation=preparation, - checker_execution=_CheckerExecution(inspector, catalogue), - storage_scheme="local", - ) - - result = await materialize_member_fixture(service, request) - - policy_result = next( - entry for entry in result.entries if entry.definition_id == "policy.storage_scheme.enforce" - ) - assert policy_result.checker_execution_status == PreSubmissionResultStatus.FAILED.value - assert policy_result.message_code == "storage_scheme_not_allowed" - await request.prepared_artifact.close() - manager.close() - - -@pytest.mark.asyncio -async def test_canonical_result_validator_rejects_forged_definition(tmp_path: Path) -> None: - request, inspector, manager, preparation, catalogue = await _request(tmp_path) - service = PreparedBundleMaterializationService( - session=SimpleNamespace(), - authorization=_AllowAuthority(), - preparation=preparation, - checker_execution=_CheckerExecution(inspector, catalogue), - storage_scheme="s3", - ) - result = await materialize_member_fixture(service, request) - first = result.entries[0] - forged = replace( - result, - checker_facts=replace( - result.checker_facts, - entries=( - replace( - first, - public_name="caller-selected", - ), - *result.entries[1:], - ), - ), - ) - - with pytest.raises( - PreSubmitEvidenceConflict, - match="pre_submission_result_context_invalid", - ): - _validate_execution(request.effective_plan, forged) - await request.prepared_artifact.close() - manager.close() - - -@pytest.mark.asyncio -async def test_post_submit_registry_is_not_an_intake_execution_dependency( - tmp_path: Path, monkeypatch: pytest.MonkeyPatch -) -> None: - request, inspector, manager, preparation, catalogue = await _request(tmp_path) - import app.modules.checkers.runner as post_submit_runner - - def forbidden(*_args, **_kwargs): - raise AssertionError("post-submit registry was called") - - monkeypatch.setattr(post_submit_runner, "default_checker_registry", forbidden) - service = PreparedBundleMaterializationService( - session=SimpleNamespace(), - authorization=_AllowAuthority(), - preparation=preparation, - checker_execution=_CheckerExecution(inspector, catalogue), - storage_scheme="s3", - ) - - result = await materialize_member_fixture(service, request) - - assert result.eligible is True - await request.prepared_artifact.close() - manager.close() - - -@pytest.mark.asyncio -async def test_authorized_cancellation_cleans_before_propagating( - tmp_path: Path, monkeypatch: pytest.MonkeyPatch -) -> None: - request, inspector, manager, preparation, catalogue = await _request(tmp_path) - entered = threading.Event() - release = threading.Event() - from app.modules.checkers.pre_submit_execution import EffectivePreSubmissionProcessor - - original = EffectivePreSubmissionProcessor.process_blocking - - def blocking_process(self, reader, workspace): - entered.set() - assert release.wait(timeout=5) - return original(self, reader, workspace) - - monkeypatch.setattr(EffectivePreSubmissionProcessor, "process_blocking", blocking_process) - service = PreparedBundleMaterializationService( - session=SimpleNamespace(), - authorization=_AllowAuthority(), - preparation=preparation, - checker_execution=_CheckerExecution(inspector, catalogue), - storage_scheme="s3", - ) - task = asyncio.create_task(materialize_member_fixture(service, request)) - assert await asyncio.to_thread(entered.wait, 5) - task.cancel() - release.set() - - with pytest.raises(asyncio.CancelledError): - await task - - assert list((tmp_path / "scratch" / "workspaces").iterdir()) == [] - await request.prepared_artifact.close() - manager.close() - - -@pytest.mark.asyncio -async def test_cancellation_during_member_projection_cleans_workspace( - tmp_path: Path, -) -> None: - request, _inspector, manager, preparation, catalogue = await _request(tmp_path) - entered = threading.Event() - release = threading.Event() - - class _BlockingProjectionInspector(SubmissionArchiveInspector): - def _project_file(self, *args, **kwargs): - entered.set() - assert release.wait(timeout=5) - return super()._project_file(*args, **kwargs) - - service = PreparedBundleMaterializationService( - session=SimpleNamespace(), - authorization=_AllowAuthority(), - preparation=preparation, - checker_execution=_CheckerExecution( - _BlockingProjectionInspector(SubmissionArchiveLimits()), catalogue - ), - storage_scheme="s3", - ) - task = asyncio.create_task(materialize_member_fixture(service, request)) - assert await asyncio.to_thread(entered.wait, 5) - task.cancel() - release.set() - - with pytest.raises(asyncio.CancelledError): - await task - - assert list((tmp_path / "scratch" / "workspaces").iterdir()) == [] - await request.prepared_artifact.close() - manager.close() - - -@pytest.mark.asyncio -async def test_timeout_during_checker_access_cleans_workspace( - tmp_path: Path, - monkeypatch: pytest.MonkeyPatch, -) -> None: - request, inspector, manager, preparation, catalogue = await _request(tmp_path) - entered = threading.Event() - release = threading.Event() - from app.modules.checkers.pre_submit_execution import EffectivePreSubmissionProcessor - - original = EffectivePreSubmissionProcessor.process_blocking - - def blocking_process(self, reader, workspace): - entered.set() - assert release.wait(timeout=5) - return original(self, reader, workspace) - - monkeypatch.setattr(EffectivePreSubmissionProcessor, "process_blocking", blocking_process) - preparation._active[request.prepared_artifact._binding].deadline = ( - asyncio.get_running_loop().time() + 0.01 - ) - service = PreparedBundleMaterializationService( - session=SimpleNamespace(), - authorization=_AllowAuthority(), - preparation=preparation, - checker_execution=_CheckerExecution(inspector, catalogue), - storage_scheme="s3", - ) - task = asyncio.create_task(materialize_member_fixture(service, request)) - assert await asyncio.to_thread(entered.wait, 5) - await asyncio.sleep(0.02) - release.set() - - with pytest.raises(ArtifactPreparationDeadlineError): - await task - - assert list((tmp_path / "scratch" / "workspaces").iterdir()) == [] - await request.prepared_artifact.close() - manager.close() - - -@pytest.mark.asyncio -@pytest.mark.parametrize("terminal", ("cancel", "timeout")) -async def test_terminal_event_during_sealing_precedes_checker_access_and_cleans( - tmp_path: Path, - terminal: str, - monkeypatch: pytest.MonkeyPatch, -) -> None: - request, _inspector, manager, preparation, catalogue = await _request(tmp_path) - entered = threading.Event() - release = threading.Event() - - class _BlockingSealInspector(SubmissionArchiveInspector): - def _seal_projected_content(self, root_fd, entries): - entered.set() - assert release.wait(timeout=5) - return super()._seal_projected_content(root_fd, entries) - - from app.modules.checkers.pre_submit_execution import EffectivePreSubmissionProcessor - - checker_called = threading.Event() - original_execute = EffectivePreSubmissionProcessor._execute - - def observed_execute(self, tree): - checker_called.set() - return original_execute(self, tree) - - monkeypatch.setattr(EffectivePreSubmissionProcessor, "_execute", observed_execute) - - if terminal == "timeout": - preparation._active[request.prepared_artifact._binding].deadline = ( - asyncio.get_running_loop().time() + 0.01 - ) - service = PreparedBundleMaterializationService( - session=SimpleNamespace(), - authorization=_AllowAuthority(), - preparation=preparation, - checker_execution=_CheckerExecution( - _BlockingSealInspector(SubmissionArchiveLimits()), catalogue - ), - storage_scheme="s3", - ) - task = asyncio.create_task(materialize_member_fixture(service, request)) - assert await asyncio.to_thread(entered.wait, 5) - if terminal == "cancel": - task.cancel() - await asyncio.sleep(0) - else: - await asyncio.sleep(0.02) - release.set() - - expected = asyncio.CancelledError if terminal == "cancel" else ArtifactPreparationDeadlineError - with pytest.raises(expected): - await task - - assert checker_called.is_set() is False - assert list((tmp_path / "scratch" / "workspaces").iterdir()) == [] - await request.prepared_artifact.close() - manager.close() - - -@pytest.mark.asyncio -@pytest.mark.parametrize("field", ["artifact_hash_manifest", "unknown_packet_field"]) -async def test_policy_packet_fields_use_inspected_manifest_and_reject_unknown(tmp_path, field): - catalogue = build_pre_submission_checker_catalogue() - policy = _effective_policy() - policy["required_packet_fields"] = [field] - policy["workstream_default_policy"]["required_packet_fields"] = [field] - request, inspector, manager, preparation, _ = await _request( - tmp_path, catalogue=catalogue, plan=_plan(catalogue, policy=policy), - ) - service = PreparedBundleMaterializationService( - session=SimpleNamespace(), - authorization=_AllowAuthority(), preparation=preparation, - checker_execution=_CheckerExecution(inspector, catalogue), storage_scheme="s3", - ) - try: - if field == "unknown_packet_field": - with pytest.raises(PreSubmissionInfrastructureUnavailableError, match="pre_submission_policy_field_unmappable"): - await materialize_member_fixture(service, request) - else: - outcome = await materialize_member_fixture(service, request) - assert outcome.eligible - assert outcome.custody.semantic_manifest_sha256 == request.manifest.sha256 - finally: - await request.prepared_artifact.close() - manager.close() diff --git a/backend/tests/test_effective_pre_submit_execution.py b/backend/tests/test_effective_pre_submit_execution.py deleted file mode 100644 index 2b4cf70b1..000000000 --- a/backend/tests/test_effective_pre_submit_execution.py +++ /dev/null @@ -1,500 +0,0 @@ -"""Focused proof for canonical effective pre-submit execution and evidence custody.""" - -from dataclasses import replace -from types import SimpleNamespace -from uuid import UUID -from app.core.identifiers import new_record_id - -from submission_context_fixtures import submission_context_facts - -import pytest - -from app.core.hashing import canonical_json_hash - -from app.modules.artifacts.pre_submit_evidence import ( - PreSubmitExecutionCustody, - PreSubmitExecutionResult, - PreSubmitEvidenceConflict, - PreSubmitEvidenceContext, - PreSubmitEvidenceService, - PersistedPreSubmitEvidence, - pre_submit_failure_audit_payload, - semantic_manifest_identity, - validate_predecessor_lineage, -) -from app.modules.tasks.api import ( - SubmissionPredecessorFacts, - TaskLockedProjectContextReferences, -) -from app.modules.checkers.api import ( - PreSubmissionExecutionEntryFacts, - PreSubmissionExecutionFacts, -) -from app.modules.checkers.compiler import ( - PreSubmitCheckerCompilerError, - compile_effective_project_submission_artifact_policy, -) -from app.modules.checkers.pre_submit_execution import ( - PreSubmissionEntryResult, - PreSubmissionExecutionResult, - PreSubmissionExecutionCustody, - PreSubmissionResultDefinition, - PreSubmissionResultPolicyTrace, - PreSubmissionResultStatus, - PreSubmissionInfrastructureUnavailable, - validate_pre_submission_execution_result, -) - - -def _sha(character: str) -> str: - return "sha256:" + character * 64 - - -def _context() -> PreSubmitEvidenceContext: - return PreSubmitEvidenceContext( - actor_profile_id=new_record_id(), - identity_link_id=new_record_id(), - project_id=new_record_id(), - task_id=new_record_id(), - assignment_id=new_record_id(), - predecessor_submission_id=None, - predecessor_submission_version=None, - prepared_generation_id=new_record_id(), - archive_sha256=_sha("1"), - archive_byte_count=1024, - semantic_manifest_id=new_record_id(), - semantic_manifest_sha256=_sha("2"), - guide_id=new_record_id(), - guide_version="1", - source_snapshot_id=new_record_id(), - source_snapshot_sha256=_sha("8"), - locked_guide_sha256=_sha("3"), - effective_policy_id=new_record_id(), - locked_artifact_policy_sha256=_sha("4"), - pre_submit_policy_id=new_record_id(), - locked_checker_policy_sha256=_sha("5"), - catalogue_id="workstream.pre_submission_checkers", - catalogue_version="v0.1", - catalogue_manifest_sha256=_sha("6"), - storage_scheme="s3", - ) - - -def test_evidence_operation_identity_binds_every_custody_fact() -> None: - context = _context() - identity = context.operation_identity(attempt_id=UUID(int=1), attempt_request_digest=_sha("9"), effective_plan_sha256=_sha("7")) - - assert identity == context.operation_identity(attempt_id=UUID(int=1), attempt_request_digest=_sha("9"), effective_plan_sha256=_sha("7")) - assert identity != replace(context, prepared_generation_id=new_record_id()).operation_identity( - attempt_id=UUID(int=1), attempt_request_digest=_sha("9"), effective_plan_sha256=_sha("7") - ) - assert identity != context.operation_identity(attempt_id=UUID(int=1), attempt_request_digest=_sha("9"), effective_plan_sha256=_sha("8")) - assert identity != context.operation_identity( - attempt_id=UUID(int=2), attempt_request_digest=_sha("9"), effective_plan_sha256=_sha("7"), - ) - assert identity != context.operation_identity( - attempt_id=UUID(int=1), attempt_request_digest=_sha("a"), effective_plan_sha256=_sha("7"), - ) - - -def test_post_byte_relock_rejects_advanced_predecessor_version() -> None: - predecessor_id = new_record_id() - task_context = submission_context_facts(submitter_contribution_policy_version_id=UUID(int=100), - task_id=new_record_id(), - assignment_id=new_record_id(), - contributor_id=new_record_id(), - status="needs_revision", - kind="revision", - predecessor=SubmissionPredecessorFacts( - submission_id=predecessor_id, - version=2, - ), - locked_project_context=TaskLockedProjectContextReferences(locked_contribution_policy_version_id=UUID(int=100), - project_id=new_record_id(), - guide_version="1", - source_snapshot_id=new_record_id(), - source_snapshot_hash=_sha("1"), - effective_policy_id=new_record_id(), - effective_policy_hash=_sha("2"), - pre_submit_policy_id=new_record_id(), - pre_submit_policy_bundle_hash=_sha("3"), - ), - ) - - with pytest.raises(PreSubmitEvidenceConflict, match="pre_submit_locked_context_changed"): - validate_predecessor_lineage( - task_context, - predecessor_submission_id=predecessor_id, - predecessor_submission_version=1, - ) - - -def test_semantic_manifest_identity_is_server_deterministic() -> None: - assert semantic_manifest_identity(_sha("a")) == semantic_manifest_identity(_sha("a")) - assert semantic_manifest_identity(_sha("a")) != semantic_manifest_identity(_sha("b")) - - -def test_pass_capability_is_generation_bound_and_single_use() -> None: - evidence_set_id = new_record_id() - generation_id = new_record_id() - capability = PreSubmitEvidenceService( - SimpleNamespace(), - task_contexts=SimpleNamespace(), - project_contexts=SimpleNamespace(), - )._mint_pass_capability( - evidence_set_id=evidence_set_id, - prepared_generation_id=generation_id, - predecessor_submission_id=None, - effective_plan_sha256=_sha("7"), - archive_sha256=_sha("1"), - semantic_manifest_sha256=_sha("2"), - storage_scheme="s3", - ) - - with pytest.raises(PreSubmitEvidenceConflict, match="pre_submit_pass_capability_invalid"): - capability.consume( - prepared_generation_id=new_record_id(), - predecessor_submission_id=None, - effective_plan_sha256=_sha("7"), - archive_sha256=_sha("1"), - semantic_manifest_sha256=_sha("2"), - storage_scheme="s3", - ) - - assert ( - capability.consume( - prepared_generation_id=generation_id, - predecessor_submission_id=None, - effective_plan_sha256=_sha("7"), - archive_sha256=_sha("1"), - semantic_manifest_sha256=_sha("2"), - storage_scheme="s3", - ) - == evidence_set_id - ) - with pytest.raises(PreSubmitEvidenceConflict, match="pre_submit_pass_capability_invalid"): - capability.consume( - prepared_generation_id=generation_id, - predecessor_submission_id=None, - effective_plan_sha256=_sha("7"), - archive_sha256=_sha("1"), - semantic_manifest_sha256=_sha("2"), - storage_scheme="s3", - ) - - -def test_compiler_projects_policy_artifact_path_not_contributor_label() -> None: - effective_policy = { - "workstream_default_policy": { - "required_packet_fields": [], - "forbidden_artifacts": [{"pattern": ".env"}], - "attestation_terms": ["rights_confirmed"], - }, - "project_policy": {}, - "required_packet_fields": [], - "required_artifacts": [{"key": "answer", "path": "outputs/final.md", "required": True}], - "required_evidence": [], - "forbidden_artifacts": [{"pattern": ".env"}], - "attestation_terms": ["rights_confirmed"], - "manifest_required": False, - "artifact_hash_required": False, - "allowed_storage_schemes": ["s3"], - "maximum_file_size_bytes": None, - "maximum_package_size_bytes": None, - "packaging": {"package_required": False}, - } - - compiled = compile_effective_project_submission_artifact_policy(effective_policy, _sha("9")) - required = next( - rule for rule in compiled.compiled_bundle["rules"] if rule["primitive"] == "require_file" - ) - - assert required["config"] == {"artifact_paths": ["outputs/final.md"]} - - -@pytest.mark.parametrize("path", [None, "", "../answer.md", "/answer.md", "a\\b"]) -def test_compiler_rejects_unmappable_artifact_paths(path: object) -> None: - policy = { - "workstream_default_policy": { - "required_packet_fields": ["summary", "worker_attestation"], - "forbidden_artifacts": [{"pattern": ".env"}], - "attestation_terms": ["rights_confirmed"], - }, - "project_policy": {}, - "required_packet_fields": ["summary", "worker_attestation"], - "required_artifacts": [{"key": "answer", "path": path, "required": True}], - "required_evidence": [], - "forbidden_artifacts": [{"pattern": ".env"}], - "attestation_terms": ["rights_confirmed"], - "manifest_required": False, - "artifact_hash_required": False, - "allowed_storage_schemes": ["s3"], - "maximum_file_size_bytes": None, - "maximum_package_size_bytes": None, - "packaging": {"package_required": False}, - } - - with pytest.raises(PreSubmitCheckerCompilerError, match="path is invalid"): - compile_effective_project_submission_artifact_policy(policy, _sha("9")) - - -@pytest.mark.parametrize("key", [".", ".."]) -def test_compiler_rejects_noncanonical_evidence_keys(key: str) -> None: - policy = { - "workstream_default_policy": {}, - "project_policy": {}, - "required_packet_fields": [], - "required_artifacts": [], - "required_evidence": [{"key": key, "required": True}], - "forbidden_artifacts": [], - "attestation_terms": [], - "manifest_required": False, - "artifact_hash_required": False, - "allowed_storage_schemes": ["s3"], - "maximum_file_size_bytes": None, - "maximum_package_size_bytes": None, - "packaging": {"package_required": False}, - } - - with pytest.raises(PreSubmitCheckerCompilerError, match="key is unmappable"): - compile_effective_project_submission_artifact_policy(policy, _sha("9")) - - -def test_compiler_rejects_duplicate_policy_keys_and_projected_paths() -> None: - base = { - "workstream_default_policy": {}, - "project_policy": {}, - "required_packet_fields": [], - "required_evidence": [], - "forbidden_artifacts": [], - "attestation_terms": [], - "manifest_required": False, - "artifact_hash_required": False, - "allowed_storage_schemes": ["s3"], - "maximum_file_size_bytes": None, - "maximum_package_size_bytes": None, - "packaging": {"package_required": False}, - } - duplicate_keys = { - **base, - "required_artifacts": [ - {"key": "answer", "path": "a.md"}, - {"key": "answer", "path": "b.md"}, - ], - } - duplicate_paths = { - **base, - "required_artifacts": [ - {"key": "answer", "path": "a.md"}, - {"key": "report", "path": "a.md"}, - ], - } - - with pytest.raises(PreSubmitCheckerCompilerError, match="keys are invalid"): - compile_effective_project_submission_artifact_policy(duplicate_keys, _sha("9")) - with pytest.raises(PreSubmitCheckerCompilerError, match="paths are ambiguous"): - compile_effective_project_submission_artifact_policy(duplicate_paths, _sha("9")) - - -def test_failure_audit_projection_is_bounded_and_path_free() -> None: - actor_id = new_record_id() - project_id = new_record_id() - task_id = new_record_id() - generation_id = new_record_id() - evidence = PersistedPreSubmitEvidence(new_record_id(), _sha("1"), False) - execution = PreSubmitExecutionResult( - custody=PreSubmitExecutionCustody( - prepared_generation_id=generation_id, - archive_sha256=_sha("5"), - archive_byte_count=1, - semantic_manifest_sha256=_sha("6"), - storage_scheme="s3", - ), - checker_facts=PreSubmissionExecutionFacts( - plan_sha256=_sha("2"), - eligible=False, - entries=( - PreSubmissionExecutionEntryFacts( - dispatch_authority="workstream.pre_submission_checker_catalogue", - definition_id="policy.file.require", - definition_version="v1", - public_name="check_required_files", - policy_source="locked_effective_project_submission_artifact_policy", - effective_plan_sha256=_sha("2"), - rule_instance_id=_sha("3"), - locked_policy_sha256=_sha("4"), - phase="project_policy", - order=10, - classification="mandatory_accountability", - severity="blocking", - checker_execution_status="failed", - failure_code="pre_submission_checker_failed", - message_code="required_file_missing", - metadata=(("finding_count", 1),), - ), - ), - ), - ) - - payload = pre_submit_failure_audit_payload( - actor_profile_id=actor_id, - project_id=project_id, - task_id=task_id, - prepared_generation_id=generation_id, - evidence=evidence, - execution=execution, - catalogue_id="workstream.pre_submission_checkers", - catalogue_version="v0.1", - ) - - assert payload["event_type"] == "pre_submission_check_failed" - assert payload["failed_count"] == 1 - serialized = repr(payload) - assert payload["result_outcomes"] == [ - { - "definition_id": "policy.file.require", - "definition_version": "v1", - "status": "failed", - "message_code": "required_file_missing", - } - ] - assert "finding_count" not in serialized - assert "/" not in serialized - - -def test_result_validation_rejects_failure_code_on_non_failed_result() -> None: - from app.modules.checkers.catalogue import build_pre_submission_checker_catalogue - from app.modules.checkers.effective_plan import ( - EffectivePreSubmissionPlanLineage, - compile_effective_pre_submission_execution_plan, - ) - - effective_policy = { - "workstream_default_policy": { - "required_packet_fields": ["summary", "worker_attestation"], - "forbidden_artifacts": [{"pattern": ".env"}], - "attestation_terms": ["rights_confirmed"], - }, - "project_policy": {}, - "required_packet_fields": ["summary", "worker_attestation"], - "required_artifacts": [], - "required_evidence": [], - "forbidden_artifacts": [{"pattern": ".env"}], - "attestation_terms": ["rights_confirmed"], - "manifest_required": False, - "artifact_hash_required": False, - "allowed_storage_schemes": ["s3"], - "maximum_file_size_bytes": None, - "maximum_package_size_bytes": None, - "packaging": {"package_required": False}, - } - policy_hash = canonical_json_hash(effective_policy) - compiled = compile_effective_project_submission_artifact_policy(effective_policy, policy_hash) - lineage = EffectivePreSubmissionPlanLineage( - project_id=new_record_id(), - guide_id=new_record_id(), - guide_version="1", - source_snapshot_id=new_record_id(), - source_snapshot_hash=_sha("a"), - effective_policy_id=new_record_id(), - effective_policy_hash=policy_hash, - pre_submit_policy_id=new_record_id(), - pre_submit_policy_bundle_hash=compiled.compiled_bundle_hash, - ) - plan = compile_effective_pre_submission_execution_plan( - lineage=lineage, - effective_policy=effective_policy, - compiled_bundle=compiled.compiled_bundle, - catalogue=build_pre_submission_checker_catalogue(), - ) - forged = PreSubmissionExecutionResult( - plan_sha256=plan.plan_sha256, - custody=PreSubmissionExecutionCustody( - prepared_generation_id=new_record_id(), - archive_sha256=_sha("b"), - archive_byte_count=1, - semantic_manifest_sha256=_sha("c"), - storage_scheme="s3", - ), - eligible=True, - entries=tuple( - PreSubmissionEntryResult( - schema_version=entry.result_schema, - definition=PreSubmissionResultDefinition( - dispatch_authority="workstream.pre_submission_checker_catalogue", - definition_id=entry.definition_id, - definition_version=entry.definition_version, - public_name=entry.public_name, - source=entry.policy_trace_source, - ), - policy_trace=PreSubmissionResultPolicyTrace( - effective_plan_sha256=plan.plan_sha256, - rule_instance_id=entry.rule_instance_id, - locked_policy_sha256=lineage.effective_policy_hash, - ), - phase=entry.phase, - order=entry.order, - classification=entry.classification, - severity="warning" if entry.classification == "advisory" else "blocking", - status=PreSubmissionResultStatus.PASSED, - failure_code="forged" if index == 0 else None, - message_code="passed", - ) - for index, entry in enumerate(plan.entries) - ), - ) - - with pytest.raises( - PreSubmissionInfrastructureUnavailable, - match="pre_submission_result_context_invalid", - ): - validate_pre_submission_execution_result(plan, forged) - - class _ForgedStatus: - value = "failed" - - forged_entry = replace( - forged.entries[0], - status=_ForgedStatus(), # type: ignore[arg-type] - failure_code=None, - ) - forged_status = replace( - forged, - eligible=True, - entries=(forged_entry, *forged.entries[1:]), - ) - - with pytest.raises( - PreSubmissionInfrastructureUnavailable, - match="pre_submission_result_context_invalid", - ): - validate_pre_submission_execution_result(plan, forged_status) - - with pytest.raises( - PreSubmissionInfrastructureUnavailable, - match="pre_submission_result_context_invalid", - ): - validate_pre_submission_execution_result(plan, replace(forged, eligible=1)) # type: ignore[arg-type] - - for metadata in ( - (("finding_count",),), - ((["finding_count"], 1),), - (("unknown_count", 1),), - (("finding_count", 1), ("finding_count", 2)), - (("finding_count", "1"),), - (("finding_count", -1),), - ): - malformed_entry = replace( - forged.entries[0], - failure_code=None, - metadata=metadata, # type: ignore[arg-type] - ) - malformed = replace( - forged, - entries=(malformed_entry, *forged.entries[1:]), - ) - with pytest.raises( - PreSubmissionInfrastructureUnavailable, - match="pre_submission_result_context_invalid", - ): - validate_pre_submission_execution_result(plan, malformed) diff --git a/backend/tests/test_pre_submit_attempt_authority_integration.py b/backend/tests/test_pre_submit_attempt_authority_integration.py deleted file mode 100644 index 06821dbd3..000000000 --- a/backend/tests/test_pre_submit_attempt_authority_integration.py +++ /dev/null @@ -1,154 +0,0 @@ -"""Integrated ART replay proof for original-generation fixed-service authority.""" - -from dataclasses import replace -from pathlib import Path - -import pytest - -from app.adapters.artifacts import CheckerPhaseService -from tests.checkers.execution.support import forbidden_post_submission -from sqlalchemy import select - -from app.modules.artifacts.authorization import PreparedPreSubmitMaterializationAuthorization -from app.modules.artifacts.pre_submit_evidence import PreSubmitEvidencePersistenceResult -from app.modules.artifacts.schemas import ArtifactAuthorityDeniedError -from app.modules.authorization.catalogue import ActionId -from app.modules.tasks.models import AuditEvent -from tests.authorization.test_pre_submit_attempt_authority import _seed_materializer -from tests.test_pre_submit_attempt_recovery import _harness - - -async def _reserve_with_real_materializer(workflow, request, preparation_request): - """Issue the exact transaction-bound handle consumed by ART reservation.""" - materialization = workflow._materialization - async with workflow._session.begin(): - await workflow._lock_authorized_context(request, preparation_request) - handle = await materialization.prepare_authorization( - task_id=request.task_id, assignment_id=request.assignment_id, - submission_artifact_policy_id=request.submission_artifact_policy_id, - checker_policy_id=request.checker_policy_id, - prepared_artifact=request.prepared_artifact, - effective_plan=request.effective_plan, - idempotency_key=preparation_request.idempotency_key, - ) - return await workflow.reserve( - replace(request, prepared_authorization=handle), - preparation_request=preparation_request, - ) - - -async def _materializer_audits(factory): - async with factory() as session: - return (await session.scalars(select(AuditEvent).where( - AuditEvent.action_id - == ActionId.ARTIFACT_PRE_SUBMIT_CHECKER_INPUT_MATERIALIZE.value, - ).order_by(AuditEvent.created_at, AuditEvent.id))).all() - - -@pytest.mark.asyncio -async def test_completed_replay_authorizes_retry_custody_and_stored_original_generation( - tmp_path: Path, isolated_database_env: str, -) -> None: - harness = await _harness(tmp_path, isolated_database_env) - calls: list[int] = [] - retry = None - try: - await _seed_materializer(harness.factory) - async with harness.factory() as session: - contributor = harness.contributor_authority(session) - await contributor.preflight(request=harness.preparation_request) - async with session.begin(): - await contributor.revalidate( - request=harness.preparation_request, - project_id=harness.request.effective_plan.lineage.project_id, - ) - authority = PreparedPreSubmitMaterializationAuthorization( - session, request_id=harness.preparation_request.request_id, - correlation_id=harness.preparation_request.correlation_id, - ) - workflow = harness.workflow( - session, calls, preparation_authorization=contributor, - ) - workflow._materialization._authorization = authority - phases = CheckerPhaseService( - pre_submission=workflow, post_submission=forbidden_post_submission(), - ) - try: - reservation = await _reserve_with_real_materializer( - workflow, harness.request, harness.preparation_request, - ) - original = await phases.evaluate_pre_submission( - replace(harness.request, prepared_authorization=None), reservation, - preparation_request=harness.preparation_request, - ) - assert original.pass_capability is not None - assert len(calls) == 1 - original_generation = original.execution.custody.prepared_generation_id - initial_audits = await _materializer_audits(harness.factory) - assert [event.resource_id for event in initial_audits] == [ - str(original_generation), str(original_generation), - ] - - await harness.request.prepared_artifact.close() - retry = await harness.fresh_request() - retry_generation = retry.prepared_artifact.generation_id - assert retry_generation != original_generation - - # A failed original-generation AUTH consume must abort recovery. - # The inspected retry consume has already passed in that root - # transaction, but both its audit and the replay read roll back. - real_consume = authority.consume - - async def deny_original(*, prepared_authorization, facts): - if facts.prepared_generation_id == original_generation: - facts = replace(facts, archive_sha256="sha256:" + "f" * 64) - await real_consume( - prepared_authorization=prepared_authorization, facts=facts, - ) - - authority.consume = deny_original - try: - with pytest.raises(ArtifactAuthorityDeniedError): - await _reserve_with_real_materializer( - workflow, retry, harness.preparation_request, - ) - finally: - authority.consume = real_consume - assert len(calls) == 1 - assert len(await _materializer_audits(harness.factory)) == 2 - - # The injected invalid consume intentionally leaves its exact - # handle unconsumed. A subsequent request gets a new adapter. - authority.close() - authority = PreparedPreSubmitMaterializationAuthorization( - session, request_id=harness.preparation_request.request_id, - correlation_id=harness.preparation_request.correlation_id, - ) - workflow._materialization._authorization = authority - replay = await _reserve_with_real_materializer( - workflow, retry, harness.preparation_request, - ) - selected = replay - replay = await phases.evaluate_pre_submission( - replace(retry, prepared_authorization=None), selected, - preparation_request=harness.preparation_request, - ) - assert replay is selected - assert isinstance(replay, PreSubmitEvidencePersistenceResult) - assert replay.evidence.evidence_set_id == original.evidence.evidence_set_id - assert replay.execution.custody.prepared_generation_id == original_generation - assert replay.pass_capability is None - assert len(calls) == 1 - audits = await _materializer_audits(harness.factory) - assert len(audits) == 4 - assert sorted(event.resource_id for event in audits) == sorted([ - str(original_generation), str(original_generation), - str(original_generation), str(retry_generation), - ]) - assert all(event.event_type == "SensitiveAuthorizationAllowed" for event in audits) - finally: - authority.close() - finally: - if retry is not None: - await retry.prepared_artifact.close() - await harness.close() diff --git a/backend/tests/test_pre_submit_attempt_contracts.py b/backend/tests/test_pre_submit_attempt_contracts.py deleted file mode 100644 index 743ab44b0..000000000 --- a/backend/tests/test_pre_submit_attempt_contracts.py +++ /dev/null @@ -1,330 +0,0 @@ -"""Negative boundaries for ART attempt identity, replay and invocation claims.""" - -from dataclasses import replace -import pickle -from types import SimpleNamespace -from unittest.mock import AsyncMock, Mock -from uuid import UUID -from app.core.identifiers import new_record_id - -import pytest - -from app.core.hashing import canonical_json_hash -from app.modules.artifacts.pre_submit_attempts import ( - PreSubmitAttemptClaim, - PreSubmitAttemptStore, - logical_request, -) -from app.modules.artifacts.pre_submit_evidence import PreSubmitEvidenceConflict -from app.modules.artifacts.submission_materialization import ( - PreparedBundleMaterializationRequest, - PreparedBundleMaterializationService, -) -from app.modules.checkers.api import SubmissionPacketView -from app.modules.checkers.catalogue import build_pre_submission_checker_catalogue -from tests.test_default_pre_submit_execution import _plan, _request -from tests.test_effective_pre_submit_execution import _context -from tests.test_submission_manifest import _archive, _manifest - - -def test_attempt_claim_cannot_be_constructed_or_serialized() -> None: - with pytest.raises(TypeError, match="issued by ART"): - PreSubmitAttemptClaim() - with pytest.raises(TypeError, match="cannot be serialized"): - pickle.dumps(object.__new__(PreSubmitAttemptClaim)) - - -def test_logical_attempt_identity_binds_packet_policy_and_archive_but_not_retry_generation() -> ( - None -): - context = _context() - plan = _plan(build_pre_submission_checker_catalogue()) - packet = SimpleNamespace(summary="Original work", contributor_attestation="rights_confirmed") - - def digest(current_context=context, current_packet=packet): - # logical_request consumes a dataclass packet; use the real typed view. - from app.modules.checkers.api import SubmissionPacketView - - view = SubmissionPacketView( - summary=current_packet.summary, - contributor_attestation=current_packet.contributor_attestation, - ) - return canonical_json_hash(logical_request(current_context, plan, view)) - - original = digest() - assert digest(replace(context, prepared_generation_id=new_record_id())) == original - assert ( - digest( - current_packet=SimpleNamespace( - summary="Changed work", - contributor_attestation=packet.contributor_attestation, - ) - ) - != original - ) - assert digest(replace(context, locked_checker_policy_sha256="sha256:" + "e" * 64)) != original - assert digest(replace(context, archive_sha256="sha256:" + "f" * 64)) != original - - -@pytest.mark.asyncio -async def test_initial_attempt_reservation_uses_fresh_record_identity(monkeypatch) -> None: - context = _context() - plan = _plan(build_pre_submission_checker_catalogue()) - packet = SubmissionPacketView( - summary="Completed exact work.", - contributor_attestation="rights_confirmed", - ) - request = PreparedBundleMaterializationRequest( - prepared_authorization=object(), - task_id=context.task_id, - assignment_id=context.assignment_id, - submission_artifact_policy_id=plan.lineage.effective_policy_id, - checker_policy_id=plan.lineage.pre_submit_policy_id, - predecessor_submission_version=None, - prepared_artifact=SimpleNamespace(generation_id=context.prepared_generation_id), - effective_plan=plan, - inspection=object(), - manifest=object(), - change_gate=object(), - packet=packet, - ) - attempt_id = UUID("018f0000-0000-7000-8000-000000000001") - nonce = UUID("62c5f90b-1a80-4c62-8ba6-ec76168e2d73") - monkeypatch.setattr( - "app.modules.artifacts.pre_submit_attempts.new_record_id", - lambda: attempt_id, - ) - monkeypatch.setattr( - "app.modules.artifacts.pre_submit_attempts.uuid4", - lambda: nonce, - ) - session = SimpleNamespace( - in_transaction=lambda: True, - in_nested_transaction=lambda: False, - scalar=AsyncMock(return_value=str(attempt_id)), - ) - - reservation = await PreSubmitAttemptStore(session).reserve( - context=context, - plan=plan, - packet=packet, - idempotency_key=new_record_id(), - request=request, - ) - - assert reservation.attempt_id == attempt_id - assert reservation.claim_nonce == nonce - assert reservation.attempt_id.version == 7 - assert reservation.claim_nonce.version == 4 - values = session.scalar.await_args.args[0].compile().params - assert values["id"] == str(attempt_id) - assert values["claim_nonce"] == str(nonce) - - -def _claim(request, session, *, spent=False, foreign=False): - claim = object.__new__(PreSubmitAttemptClaim) - claim.attempt_id, claim._nonce = new_record_id(), new_record_id() - claim.request_digest = "sha256:" + "1" * 64 - claim._request = replace(request, prepared_authorization=None) - claim._started, claim._execution = spent, None - claim._session = object() if foreign else session - return claim - - -@pytest.mark.parametrize("claim_kind", ("absent", "foreign", "spent", "missing_reservation")) -async def test_invalid_attempt_claim_never_builds_processor_or_opens_workspace( - tmp_path, - claim_kind: str, -) -> None: - request, _inspector, manager, _preparation, catalogue = await _request(tmp_path) - session = SimpleNamespace( - in_transaction=lambda: True, - in_nested_transaction=lambda: False, - scalar=AsyncMock(return_value=None), - ) - authorization = SimpleNamespace(consume=AsyncMock()) - processor_build = Mock(side_effect=AssertionError("invalid claim built CHECKER processor")) - preparation = SimpleNamespace( - _process_prepared_submission=AsyncMock( - side_effect=AssertionError("invalid claim opened scratch"), - ) - ) - service = PreparedBundleMaterializationService( - session=session, - authorization=authorization, - preparation=preparation, - checker_execution=SimpleNamespace( - catalogue_manifest_sha256=catalogue.manifest_sha256, - build=processor_build, - ), - storage_scheme="s3", - ) - claim = { - "absent": None, - "foreign": _claim(request, session, foreign=True), - "spent": _claim(request, session, spent=True), - "missing_reservation": _claim(request, session), - }[claim_kind] - try: - with pytest.raises(PreSubmitEvidenceConflict, match="pre_submit_attempt_claim_invalid"): - await service.authorize_prepared_bundle(request, claim=claim) - processor_build.assert_not_called() - preparation._process_prepared_submission.assert_not_awaited() - assert list((tmp_path / "scratch" / "workspaces").iterdir()) == [] - finally: - await request.prepared_artifact.close() - manager.close() - - -@pytest.mark.asyncio -async def test_checker_processor_starts_only_after_authority_transaction_commits( - tmp_path, -) -> None: - request, _inspector, manager, _preparation, catalogue = await _request(tmp_path) - transaction = True - reservation = SimpleNamespace( - status="reserved", - evidence_set_id=None, - claim_nonce=None, - request_digest="sha256:" + "1" * 64, - prepared_generation_id=str(request.prepared_artifact.generation_id), - ) - session = SimpleNamespace( - in_transaction=lambda: transaction, - in_nested_transaction=lambda: False, - scalar=AsyncMock(return_value=reservation), - ) - claim = _claim(request, session) - reservation.claim_nonce = str(claim._nonce) - processor_build = Mock( - side_effect=RuntimeError("processor reached after authority transaction") - ) - service = PreparedBundleMaterializationService( - session=session, - authorization=SimpleNamespace(consume=AsyncMock()), - preparation=SimpleNamespace(_process_prepared_submission=AsyncMock()), - checker_execution=SimpleNamespace( - catalogue_manifest_sha256=catalogue.manifest_sha256, - build=processor_build, - ), - storage_scheme="s3", - ) - try: - await service.authorize_prepared_bundle(request, claim=claim) - with pytest.raises( - PreSubmitEvidenceConflict, match="pre_submit_attempt_claim_invalid" - ): - await service.materialize_prepared_bundle( - replace(request, prepared_authorization=None), claim=claim - ) - processor_build.assert_not_called() - - transaction = False - with pytest.raises( - RuntimeError, match="processor reached after authority transaction" - ): - await service.materialize_prepared_bundle( - replace(request, prepared_authorization=None), claim=claim - ) - processor_build.assert_called_once() - finally: - await request.prepared_artifact.close() - manager.close() - - -@pytest.mark.parametrize("missing_field", ("metadata_json", "checker_order")) -async def test_completed_replay_rejects_missing_result_metadata_before_capability( - missing_field: str, -) -> None: - plan = _plan(build_pre_submission_checker_catalogue()) - attempt_id, evidence_id = str(new_record_id()), str(new_record_id()) - request_digest = "sha256:" + "a" * 64 - manifest = _manifest(_archive([("answer.txt", b"verified")])) - evidence = SimpleNamespace( - semantic_manifest_body=manifest.as_dict(), - id=evidence_id, - attempt_id=attempt_id, - attempt_request_digest=request_digest, - packet_sha256="sha256:" + "b" * 64, - semantic_manifest_sha256=manifest.sha256, - ) - row = SimpleNamespace( - id=attempt_id, - status="completed", - evidence_set_id=evidence_id, - request_json={"packet_sha256": "sha256:" + "b" * 64}, - request_digest=request_digest, - ) - members = [ - SimpleNamespace(metadata_json=[], checker_order=entry.order) for entry in plan.entries - ] - setattr(members[0], missing_field, None) - session = SimpleNamespace( - get=AsyncMock(return_value=evidence), - scalars=AsyncMock(return_value=SimpleNamespace(all=lambda: members)), - ) - with pytest.raises(PreSubmitEvidenceConflict, match="pre_submit_attempt_result_unavailable"): - await PreSubmitAttemptStore(session).read_completed(row=row, context=_context(), plan=plan) - - -@pytest.mark.parametrize("corruption", ("definition_order", "metadata")) -async def test_completed_replay_rejects_nonnull_corrupt_result_before_capability( - corruption: str, -) -> None: - plan = _plan(build_pre_submission_checker_catalogue()) - context = _context() - attempt_id, evidence_id = str(new_record_id()), str(new_record_id()) - request_digest = "sha256:" + "a" * 64 - manifest = _manifest(_archive([("answer.txt", b"verified")])) - evidence = SimpleNamespace( - semantic_manifest_body=manifest.as_dict(), - id=evidence_id, - attempt_id=attempt_id, - attempt_request_digest=request_digest, - packet_sha256="sha256:" + "b" * 64, - archive_sha256=context.archive_sha256, - archive_byte_count=context.archive_byte_count, - semantic_manifest_sha256=manifest.sha256, - storage_scheme=context.storage_scheme, - effective_plan_sha256=plan.plan_sha256, - eligible=True, - ) - row = SimpleNamespace( - id=attempt_id, - status="completed", - evidence_set_id=evidence_id, - request_json={"packet_sha256": "sha256:" + "b" * 64}, - request_digest=request_digest, - prepared_generation_id=str(context.prepared_generation_id), - ) - members = [ - SimpleNamespace( - dispatch_authority="workstream.pre_submission_checker_catalogue", - definition_id=entry.definition_id, - definition_version=entry.definition_version, - public_name=entry.public_name, - source=entry.policy_trace_source, - effective_plan_sha256=plan.plan_sha256, - rule_instance_id=entry.rule_instance_id, - locked_policy_sha256=plan.lineage.effective_policy_hash, - phase=entry.phase, - checker_order=entry.order, - classification=entry.classification, - severity="warning" if entry.classification == "advisory" else "blocking", - status="passed", - failure_code=None, - message_code="passed", - metadata_json=[], - ) - for entry in plan.entries - ] - if corruption == "definition_order": - members[0].checker_order += 1 - else: - members[0].metadata_json = [["unregistered_count", 1]] - session = SimpleNamespace( - get=AsyncMock(return_value=evidence), - scalars=AsyncMock(return_value=SimpleNamespace(all=lambda: members)), - ) - with pytest.raises(PreSubmitEvidenceConflict, match="pre_submission_result_context_invalid"): - await PreSubmitAttemptStore(session).read_completed(row=row, context=context, plan=plan) diff --git a/backend/tests/test_pre_submit_attempt_lock_order.py b/backend/tests/test_pre_submit_attempt_lock_order.py deleted file mode 100644 index ed187f5ab..000000000 --- a/backend/tests/test_pre_submit_attempt_lock_order.py +++ /dev/null @@ -1,334 +0,0 @@ -"""Real PostgreSQL proof of shared-project pre-submit AUTH/ART lock order.""" - -from __future__ import annotations - - -import asyncio -from contextlib import asynccontextmanager -from dataclasses import dataclass, replace -from pathlib import Path -from typing import Any -from app.core.identifiers import new_record_id - -import pytest - -from app.adapters.artifacts import CheckerPhaseService -from tests.checkers.execution.support import forbidden_post_submission -from sqlalchemy import func, select, text -from sqlalchemy.ext.asyncio import async_sessionmaker, create_async_engine - -from app.modules.artifacts.authorization import ( - PreparedPreSubmitMaterializationAuthorization, - PreparedSubmissionBundlePreparationAuthorization, -) -from app.modules.artifacts.models import PreSubmitEvidenceSet, PreSubmitExecutionAttempt -from app.modules.artifacts.submission_admission import ( - PreparedSubmissionBundlePreparationCommand, - SubmissionBundlePreparationRuntime, -) -from app.modules.authorization.runtime import ( - ActorKind, ActorStatus, HumanAuthorizationContext, IdentityLinkStatus, -) -from tests.tasks.lineage_fixtures import seed_started_task_for_artifact_test -from tests.authorization.test_pre_submit_attempt_authority import _seed_materializer -from tests.pre_submit_test_helpers import submission_preparation_request -from tests.submission_preparation_auth_helpers import install_submitter_grant -from tests.archive_fixtures import byte_source as _bytes, submission_archive as _archive -from tests.test_pre_submit_attempt_authority_integration import _reserve_with_real_materializer -from tests.test_pre_submit_attempt_recovery import _harness - - -class _AfterEvidenceCommitted(Exception): - """Stop before durable provider work after the real B evidence transaction.""" - - -class _PauseAfterSpool: - def __init__(self, preparation, spooled: asyncio.Event, resume: asyncio.Event): - self._preparation = preparation - self._spooled, self._resume = spooled, resume - - async def prepare(self, byte_source, *, media_type): - prepared = await self._preparation.prepare(byte_source, media_type=media_type) - self._spooled.set() - try: - await self._resume.wait() - except BaseException: - await prepared.close() - raise - return prepared - - -class _PauseAfterProjectLock: - def __init__(self, repository, session, locked: asyncio.Event, resume: asyncio.Event): - self._repository, self._session = repository, session - self._locked, self._resume = locked, resume - self.backend_pid: int | None = None - self._paused = False - - async def lock_locked_policy_context(self, request): - facts = await self._repository.lock_locked_policy_context(request) - if not self._paused: - self._paused = True - self.backend_pid = int(await self._session.scalar(text("select pg_backend_pid()"))) - self._locked.set() - await self._resume.wait() - return facts - - -class _CompleteBeforeDurable: - def __init__(self, workflow): - self._workflow = workflow - self.evidence = None - - async def reserve(self, request, *, preparation_request): - return await self._workflow.reserve(request, preparation_request=preparation_request) - - async def execute_reserved(self, request, reservation, *, preparation_request): - self.evidence = await self._workflow.execute_reserved( - request, reservation, preparation_request=preparation_request, - ) - raise _AfterEvidenceCommitted - - -async def _seed_second_contributor_task(harness): - """Share PROJECT locks while avoiding actor, grant, task and assignment collisions.""" - actor_id, link_id, task_id, assignment_id = (new_record_id() for _ in range(4)) - project_id = harness.request.effective_plan.lineage.project_id - async with harness.engine.begin() as connection: - await connection.execute(text( - "insert into actor_profiles " - "(id,actor_kind,status,provisioning_method,created_by) values " - "(:actor,'human','active','automatic_first_access','test')" - ), {"actor": str(actor_id)}) - await connection.execute(text( - "insert into actor_identity_links " - "(id,actor_profile_id,issuer,subject,subject_kind,status,linked_by,last_verified_at) " - "values (:link,:actor,'flow-test',:subject,'human','active','test',now())" - ), {"actor": str(actor_id), "subject": str(actor_id), "link": str(link_id)}) - await seed_started_task_for_artifact_test(connection, { - "project": str(project_id), "task": str(task_id), - "assignment": str(assignment_id), "actor": str(actor_id), - }) - await install_submitter_grant(connection, { - "project": str(project_id), "actor": str(actor_id), - }) - return actor_id, link_id, task_id, assignment_id - - -def _contributor_authority(session, request): - actor = request.actor - return PreparedSubmissionBundlePreparationAuthorization( - session, - HumanAuthorizationContext( - actor_profile_id=actor.actor_profile_id, - actor_kind=ActorKind.HUMAN, - actor_status=ActorStatus.ACTIVE, - identity_link_id=actor.identity_link_id, - identity_link_status=IdentityLinkStatus.ACTIVE, - request_id=request.request_id, - correlation_id=request.correlation_id, - ), - ) - - -def _second_preparation_request(harness, actor_id, link_id, task_id, assignment_id): - template = replace(harness.request, task_id=task_id, assignment_id=assignment_id) - return replace( - submission_preparation_request( - template, actor_profile_id=actor_id, identity_link_id=link_id, - ), - byte_source=_bytes(_archive(evidence_path=harness.evidence_path)), - ) - - -@dataclass(slots=True) -class _RaceParticipants: - first_workflow: Any - second_command: Any - second_request: Any - evidence_owner: _CompleteBeforeDurable - pause_project: _PauseAfterProjectLock - first_materializer: PreparedPreSubmitMaterializationAuthorization - second_materializer: PreparedPreSubmitMaterializationAuthorization - first_calls: list[int] - second_calls: list[int] - - -async def _configure_participants( - harness, first_session, second_session, second_request, - spooled, resume_spool, project_locked, resume_project, -) -> _RaceParticipants: - first_contributor = _contributor_authority(first_session, harness.preparation_request) - await first_contributor.preflight(request=harness.preparation_request) - async with first_session.begin(): - await first_contributor.revalidate( - request=harness.preparation_request, - project_id=harness.request.effective_plan.lineage.project_id, - ) - first_materializer = PreparedPreSubmitMaterializationAuthorization( - first_session, - request_id=harness.preparation_request.request_id, - correlation_id=harness.preparation_request.correlation_id, - ) - first_calls: list[int] = [] - first_workflow = harness.workflow( - first_session, first_calls, preparation_authorization=first_contributor, - ) - first_workflow._materialization._authorization = first_materializer - second_contributor = _contributor_authority(second_session, second_request) - second_materializer = PreparedPreSubmitMaterializationAuthorization( - second_session, - request_id=second_request.request_id, - correlation_id=second_request.correlation_id, - ) - second_calls: list[int] = [] - second_workflow = harness.workflow( - second_session, second_calls, preparation_authorization=second_contributor, - ) - second_workflow._materialization._authorization = second_materializer - evidence_owner = _CompleteBeforeDurable(second_workflow) - from app.adapters.checkers import submission_evaluation_content - runtime = SubmissionBundlePreparationRuntime( - evaluation_content=submission_evaluation_content, - preparation=_PauseAfterSpool(harness.preparation, spooled, resume_spool), - inspector=harness.inspector, - catalogue=harness.catalogue, - materialization=second_workflow._materialization, - evidence=evidence_owner, - checker_service=CheckerPhaseService( - pre_submission=evidence_owner, - post_submission=forbidden_post_submission(), - ), - durable_put=object(), - ) - - @asynccontextmanager - async def runtime_factory(): - yield runtime - - second_command = PreparedSubmissionBundlePreparationCommand( - session=second_session, - authority=second_contributor, - task_contexts=second_workflow._task_contexts, - project_contexts=second_workflow._project_contexts, - runtime_factory=runtime_factory, - ) - pause_project = _PauseAfterProjectLock( - first_workflow._project_contexts, - first_session, project_locked, resume_project, - ) - return _RaceParticipants( - first_workflow, second_command, second_request, evidence_owner, - pause_project, first_materializer, second_materializer, - first_calls, second_calls, - ) - - -async def _wait_for_project_block(engine, *, application_name: str, blocker_pid: int): - """Observe the competing command's actual PostgreSQL row-lock wait.""" - async with engine.connect() as observer: - async with asyncio.timeout(8): - while True: - await observer.execute(text("select pg_stat_clear_snapshot()")) - waits = (await observer.execute(text( - "select wait_event_type,pg_blocking_pids(pid) from pg_stat_activity " - "where application_name=:application and datname=current_database()" - ), {"application": application_name})).all() - if any(kind == "Lock" and blocker_pid in blocked_by - for kind, blocked_by in waits): - return - await asyncio.sleep(0.02) - - -@pytest.mark.asyncio -async def test_same_project_reservation_and_execution_complete_without_auth_project_deadlock( - tmp_path: Path, isolated_database_env: str, monkeypatch, -) -> None: - # The fixture's ordinary ten-second scratch deadline is too short for an - # intentional database barrier; only this test extends the temporary lease. - import tests.archive_fixtures as default_tests - - original_limits = default_tests._limits - monkeypatch.setattr(default_tests, "_limits", lambda: replace( - original_limits(), total_deadline_seconds=90, reservation_ttl_seconds=120, - aggregate_reserved_bytes=4 * default_tests.HARD_MAXIMUM_ARTIFACT_BYTES, - )) - harness = await _harness(tmp_path, isolated_database_env) - second_engine = None - first_task = second_task = None - resume_spool, resume_project = asyncio.Event(), asyncio.Event() - try: - second_actor, second_link, second_task_id, second_assignment_id = ( - await _seed_second_contributor_task(harness) - ) - await _seed_materializer(harness.factory) - second_request = _second_preparation_request( - harness, second_actor, second_link, second_task_id, second_assignment_id, - ) - application_name = f"pol07a_lock_order_{new_record_id().hex[:12]}" - second_engine = create_async_engine( - isolated_database_env, - connect_args={"server_settings": {"application_name": application_name}}, - ) - second_factory = async_sessionmaker(second_engine, expire_on_commit=False) - spooled, project_locked = asyncio.Event(), asyncio.Event() - async with harness.factory() as first_session, second_factory() as second_session: - participants = await _configure_participants( - harness, first_session, second_session, second_request, - spooled, resume_spool, project_locked, resume_project, - ) - try: - first_reservation = await _reserve_with_real_materializer( - participants.first_workflow, - harness.request, harness.preparation_request, - ) - participants.first_workflow._project_contexts = participants.pause_project - second_task = asyncio.create_task( - participants.second_command.prepare(second_request) - ) - await asyncio.wait_for(spooled.wait(), timeout=30) - first_task = asyncio.create_task(participants.first_workflow.execute_reserved( - harness.request, first_reservation, - preparation_request=harness.preparation_request, - )) - await asyncio.wait_for(project_locked.wait(), timeout=30) - assert participants.pause_project.backend_pid is not None - resume_spool.set() - await _wait_for_project_block( - harness.engine, - application_name=application_name, - blocker_pid=participants.pause_project.backend_pid, - ) - resume_project.set() - first_outcome, second_outcome = await asyncio.wait_for( - asyncio.gather(first_task, second_task, return_exceptions=True), - timeout=30, - ) - assert not isinstance(first_outcome, BaseException), first_outcome - assert isinstance(second_outcome, _AfterEvidenceCommitted), second_outcome - assert participants.evidence_owner.evidence is not None - assert first_outcome.pass_capability is not None - assert participants.evidence_owner.evidence.pass_capability is not None - assert participants.first_calls == [1] - assert participants.second_calls == [1] - finally: - participants.first_materializer.close() - participants.second_materializer.close() - async with harness.factory() as session: - attempts = (await session.scalars(select(PreSubmitExecutionAttempt))).all() - assert len(attempts) == 2 - assert {attempt.actor_profile_id for attempt in attempts} == { - str(harness.actor_id), str(second_actor), - } - assert all(attempt.status == "completed" for attempt in attempts) - assert await session.scalar(select(func.count()).select_from(PreSubmitEvidenceSet)) == 2 - finally: - resume_spool.set() - resume_project.set() - await asyncio.gather( - *(task for task in (first_task, second_task) if task is not None), - return_exceptions=True, - ) - if second_engine is not None: - await second_engine.dispose() - await harness.close() diff --git a/backend/tests/test_pre_submit_attempt_recovery.py b/backend/tests/test_pre_submit_attempt_recovery.py deleted file mode 100644 index cbea23a6e..000000000 --- a/backend/tests/test_pre_submit_attempt_recovery.py +++ /dev/null @@ -1,613 +0,0 @@ -"""Real PostgreSQL and scratch proof for ART pre-submit invocation custody.""" - -from __future__ import annotations - -from tests.tasks.lineage_fixtures import seed_started_task_for_artifact_test - -import asyncio -from dataclasses import asdict, dataclass, replace -from pathlib import Path -from types import SimpleNamespace -from unittest.mock import AsyncMock -from uuid import UUID -from app.core.identifiers import new_record_id - -import pytest -from sqlalchemy import func, select, text -from sqlalchemy.exc import DBAPIError -from sqlalchemy.ext.asyncio import async_sessionmaker, create_async_engine - -from app.core.hashing import canonical_json_hash -from app.modules.artifacts.models import ( - PreSubmitEvidenceResult, PreSubmitEvidenceSet, PreSubmitExecutionAttempt, -) -from app.modules.artifacts.authorization import PreparedSubmissionBundlePreparationAuthorization -from app.modules.artifacts.pre_submit_attempts import PreSubmitAttemptClaim -from app.modules.artifacts.schemas import ArtifactAuthorityDeniedError -from app.modules.artifacts.pre_submit_evidence import ( - PreSubmitEvidenceConflict, - PreSubmitEvidencePersistenceResult, - PreSubmitEvidenceService, -) -from app.modules.artifacts.submission_manifest import ( - build_submission_manifest, - evaluate_submission_change, -) -from tests.pre_submit_test_helpers import ( - approved_pre_submit_fixture, - evidence_workflow, - submission_preparation_request, -) -from tests.submission_preparation_auth_helpers import install_submitter_grant -from tests.test_default_pre_submit_execution import _AllowAuthority, _archive, _bytes, _request -from app.modules.artifacts.service import ArtifactStorageNamespaceSpec -from app.modules.authorization.runtime import ( - ActorKind, ActorStatus, HumanAuthorizationContext, IdentityLinkStatus, -) - - -class _CountedProcessor: - def __init__(self, wrapped, calls: list[int], entered=None, release=None): - self._wrapped, self._calls = wrapped, calls - self._entered, self._release = entered, release - - def abort(self): - return self._wrapped.abort() - - async def process(self, reader, workspace): - self._calls.append(1) - if self._entered is not None: - self._entered.set() - await self._release.wait() - return await self._wrapped.process(reader, workspace) - - -class _CountedExecution: - def __init__(self, wrapped, calls, entered=None, release=None): - self._wrapped, self._calls = wrapped, calls - self._entered, self._release = entered, release - - @property - def catalogue_manifest_sha256(self): - return self._wrapped.catalogue_manifest_sha256 - - def build(self, request): - return _CountedProcessor( - self._wrapped.build(request), self._calls, self._entered, self._release, - ) - - -@dataclass -class _Harness: - engine: object - factory: object - request: object - preparation_request: object - preparation: object - inspector: object - catalogue: object - manager: object - evidence_path: str - actor_id: UUID - identity_link_id: UUID - - def workflow(self, session, calls, *, entered=None, release=None, - preparation_authorization=None): - workflow = evidence_workflow( - session=session, - preparation=self.preparation, - inspector=self.inspector, - catalogue=self.catalogue, - materialization_authorization=_AllowAuthority(), - preparation_authorization=( - preparation_authorization - if preparation_authorization is not None - else SimpleNamespace(lock_actor=AsyncMock(), revalidate=AsyncMock()) - ), - ) - materialization = workflow._materialization - materialization._checker_execution = _CountedExecution( - materialization._checker_execution, calls, entered, release, - ) - return workflow - - async def fresh_request(self, data=None): - prepared = await self.preparation.prepare( - _bytes(data if data is not None else _archive(evidence_path=self.evidence_path)), - media_type="application/zip", - ) - inspection = await prepared.inspect(self.inspector) - manifest = build_submission_manifest(inspection) - request = replace( - self.request, - prepared_artifact=prepared, - inspection=inspection, - manifest=manifest, - change_gate=evaluate_submission_change( - commitment=prepared.commitment, - manifest=manifest, - predecessor=None, - predecessor_exists=False, - ), - ) - return request - - async def close(self): - await self.request.prepared_artifact.close() - self.manager.close() - await self.engine.dispose() - - def contributor_authority(self, session): - return PreparedSubmissionBundlePreparationAuthorization( - session, - HumanAuthorizationContext( - actor_profile_id=self.actor_id, - actor_kind=ActorKind.HUMAN, - actor_status=ActorStatus.ACTIVE, - identity_link_id=self.identity_link_id, - identity_link_status=IdentityLinkStatus.ACTIVE, - request_id=self.preparation_request.request_id, - correlation_id=self.preparation_request.correlation_id, - ), - ) - - -async def _harness(tmp_path: Path, database_url: str) -> _Harness: - engine = create_async_engine(database_url) - factory = async_sessionmaker(engine, expire_on_commit=False) - namespace = ArtifactStorageNamespaceSpec( - backend="local", adapter="local", provider_profile="test", - namespace_descriptor={"test": "submission-bundle"}, - namespace_fingerprint=canonical_json_hash({"test": "submission-bundle"}), - ) - plan, policy = await approved_pre_submit_fixture(factory, namespace, guide_version="v0.1") - evidence_path = policy.pop("evidence_path") - request, inspector, manager, preparation, catalogue = await _request( - tmp_path, plan=plan, evidence_path=evidence_path, - ) - request = replace(request, packet=replace( - request.packet, - contributor_attestation=( - request.packet.contributor_attestation + " " + " ".join(policy.pop("attestation_terms")) - ), - )) - actor_id, identity_link_id = new_record_id(), new_record_id() - lineage = request.effective_plan.lineage - params = { - "actor": str(actor_id), "subject": str(actor_id), "link": str(identity_link_id), - "project": str(lineage.project_id), "guide": str(lineage.guide_id), - "snapshot": str(lineage.source_snapshot_id), - "snapshot_hash": lineage.source_snapshot_hash, **policy, - "effective_policy": str(lineage.effective_policy_id), - "effective_hash": lineage.effective_policy_hash, - "checker_policy": str(lineage.pre_submit_policy_id), - "checker_hash": lineage.pre_submit_policy_bundle_hash, - "task": str(request.task_id), "assignment": str(request.assignment_id), - } - async with engine.begin() as connection: - await connection.execute(text( - "insert into actor_profiles " - "(id,actor_kind,status,provisioning_method,created_by) values " - "(:actor,'human','active','automatic_first_access','test')" - ), params) - await connection.execute(text( - "insert into actor_identity_links " - "(id,actor_profile_id,issuer,subject,subject_kind,status,linked_by,last_verified_at) " - "values (:link,:actor,'flow-test',:subject,'human','active','test',now())" - ), params) - await seed_started_task_for_artifact_test(connection, params) - await install_submitter_grant(connection, params) - preparation_request = submission_preparation_request( - request, actor_profile_id=actor_id, identity_link_id=identity_link_id, - ) - return _Harness( - engine, factory, request, preparation_request, preparation, inspector, - catalogue, manager, evidence_path, actor_id, identity_link_id, - ) - - -async def _reserve(workflow, request, preparation_request): - async with workflow._session.begin(): - return await workflow.reserve(request, preparation_request=preparation_request) - - -@pytest.mark.asyncio -async def test_completed_replay_after_original_scratch_closes( - tmp_path: Path, isolated_database_env: str, -) -> None: - harness = await _harness(tmp_path, isolated_database_env) - calls: list[int] = [] - retry = None - try: - async with harness.factory() as session: - workflow = harness.workflow(session, calls) - reservation = await _reserve(workflow, harness.request, harness.preparation_request) - first = await workflow.execute_reserved( - harness.request, reservation, preparation_request=harness.preparation_request, - ) - assert len(calls) == 1 - assert first.pass_capability is not None - original_generation = first.execution.custody.prepared_generation_id - await harness.request.prepared_artifact.close() - retry = await harness.fresh_request() - assert retry.prepared_artifact.generation_id != original_generation - replay = await _reserve(workflow, retry, harness.preparation_request) - assert isinstance(replay, PreSubmitEvidencePersistenceResult) - assert replay.evidence.evidence_set_id == first.evidence.evidence_set_id - assert replay.execution == first.execution - assert replay.execution.custody.prepared_generation_id == original_generation - assert replay.pass_capability is None - assert len(calls) == 1 - changed_packet = replace(retry, packet=replace( - retry.packet, summary="Different work was completed.", - )) - changed_preparation = replace( - harness.preparation_request, summary=changed_packet.packet.summary, - ) - with pytest.raises(PreSubmitEvidenceConflict, match="pre_submit_attempt_request_conflict"): - await _reserve(workflow, changed_packet, changed_preparation) - assert len(calls) == 1 - await retry.prepared_artifact.close() - retry = await harness.fresh_request( - _archive(extra_path="different.txt", evidence_path=harness.evidence_path) - ) - with pytest.raises(PreSubmitEvidenceConflict, match="pre_submit_attempt_request_conflict"): - await _reserve(workflow, retry, harness.preparation_request) - assert len(calls) == 1 - finally: - if retry is not None: - await retry.prepared_artifact.close() - await harness.close() - - -@pytest.mark.asyncio -async def test_crash_after_member_before_evidence_commit_cannot_rerun( - tmp_path: Path, isolated_database_env: str, monkeypatch, -) -> None: - harness = await _harness(tmp_path, isolated_database_env) - calls: list[int] = [] - original_persist = PreSubmitEvidenceService.persist - - async def crash_after_member(self, request): - raise RuntimeError("simulated crash before evidence commit") - - try: - async with harness.factory() as session: - workflow = harness.workflow(session, calls) - reservation = await _reserve(workflow, harness.request, harness.preparation_request) - monkeypatch.setattr(PreSubmitEvidenceService, "persist", crash_after_member) - with pytest.raises(RuntimeError, match="simulated crash"): - await workflow.execute_reserved( - harness.request, reservation, preparation_request=harness.preparation_request, - ) - monkeypatch.setattr(PreSubmitEvidenceService, "persist", original_persist) - assert len(calls) == 1 - async with harness.factory() as retry_session: - retry_workflow = harness.workflow(retry_session, calls) - with pytest.raises( - PreSubmitEvidenceConflict, match="pre_submit_attempt_outcome_unresolved" - ): - await _reserve( - retry_workflow, harness.request, harness.preparation_request, - ) - assert len(calls) == 1 - attempt = await session.scalar(select(PreSubmitExecutionAttempt)) - assert attempt is not None and attempt.status == "reserved" - assert await session.scalar(select(func.count()).select_from(PreSubmitEvidenceSet)) == 0 - await session.rollback() - finally: - monkeypatch.setattr(PreSubmitEvidenceService, "persist", original_persist) - await harness.close() - - -@pytest.mark.asyncio -async def test_completion_failure_rolls_back_evidence_and_keeps_attempt_reserved( - tmp_path: Path, isolated_database_env: str, monkeypatch, -) -> None: - harness = await _harness(tmp_path, isolated_database_env) - calls: list[int] = [] - original_complete = PreSubmitAttemptClaim.complete - - async def fail_completion(self, session, evidence_id): - # The repository has already inserted the evidence and all result rows. - assert await session.get(PreSubmitEvidenceSet, str(evidence_id)) is not None - raise RuntimeError("simulated completion failure") - - try: - async with harness.factory() as session: - workflow = harness.workflow(session, calls) - reservation = await _reserve(workflow, harness.request, harness.preparation_request) - monkeypatch.setattr(PreSubmitAttemptClaim, "complete", fail_completion) - with pytest.raises(RuntimeError, match="simulated completion failure"): - await workflow.execute_reserved( - harness.request, reservation, preparation_request=harness.preparation_request, - ) - monkeypatch.setattr(PreSubmitAttemptClaim, "complete", original_complete) - assert len(calls) == 1 - attempt = await session.scalar(select(PreSubmitExecutionAttempt)) - assert attempt is not None and attempt.status == "reserved" - assert await session.scalar(select(func.count()).select_from(PreSubmitEvidenceSet)) == 0 - await session.rollback() - with pytest.raises( - PreSubmitEvidenceConflict, match="pre_submit_attempt_outcome_unresolved" - ): - await _reserve(workflow, harness.request, harness.preparation_request) - finally: - monkeypatch.setattr(PreSubmitAttemptClaim, "complete", original_complete) - await harness.close() - - -@pytest.mark.asyncio -async def test_independent_sessions_same_key_invoke_members_once( - tmp_path: Path, isolated_database_env: str, -) -> None: - harness = await _harness(tmp_path, isolated_database_env) - calls: list[int] = [] - entered, release = asyncio.Event(), asyncio.Event() - executing = competing = None - try: - async with harness.factory() as first_session, harness.factory() as second_session: - first_workflow = harness.workflow(first_session, calls, entered=entered, release=release) - second_workflow = harness.workflow(second_session, calls) - competing_pid = asyncio.get_running_loop().create_future() - task_contexts = second_workflow._task_contexts - - class _ObservedTaskContexts: - async def lock_submission_context(self, request): - pid = await second_session.scalar(text("select pg_backend_pid()")) - competing_pid.set_result(pid) - return await task_contexts.lock_submission_context(request) - - second_workflow._task_contexts = _ObservedTaskContexts() - reservation = await _reserve( - first_workflow, harness.request, harness.preparation_request, - ) - executing = asyncio.create_task(first_workflow.execute_reserved( - harness.request, reservation, preparation_request=harness.preparation_request, - )) - await asyncio.wait_for(entered.wait(), timeout=10) - competing = asyncio.create_task(_reserve( - second_workflow, harness.request, harness.preparation_request, - )) - pid = await asyncio.wait_for(competing_pid, timeout=3) - async with harness.engine.connect() as observer: - wait_type = None - async with asyncio.timeout(3): - while not competing.done(): - await observer.execute(text("select pg_stat_clear_snapshot()")) - wait_type = await observer.scalar(text( - "select wait_event_type from pg_stat_activity where pid=:pid" - ), {"pid": pid}) - if wait_type == "Lock": - break - await asyncio.sleep(0.02) - assert competing.done() or wait_type == "Lock" - release.set() - result = await executing - recovered = (await asyncio.gather(competing, return_exceptions=True))[0] - assert result.pass_capability is not None - if isinstance(recovered, PreSubmitEvidencePersistenceResult): - assert recovered.pass_capability is None - assert recovered.evidence.evidence_set_id == result.evidence.evidence_set_id - else: - assert isinstance(recovered, PreSubmitEvidenceConflict) - assert str(recovered) == "pre_submit_attempt_outcome_unresolved" - assert len(calls) == 1 - finally: - release.set() - await asyncio.gather( - *(task for task in (executing, competing) if task is not None), - return_exceptions=True, - ) - await harness.close() - - -@pytest.mark.asyncio -async def test_uncommitted_reservation_never_issues_a_claim( - tmp_path: Path, isolated_database_env: str, -) -> None: - harness = await _harness(tmp_path, isolated_database_env) - calls: list[int] = [] - try: - async with harness.factory() as session: - workflow = harness.workflow(session, calls) - async with session.begin(): - reservation = await workflow.reserve( - harness.request, preparation_request=harness.preparation_request, - ) - with pytest.raises(PreSubmitEvidenceConflict, match="pre_submit_attempt_not_committed"): - await workflow._attempts.committed_claim(reservation) - await session.rollback() - assert await session.scalar(select(func.count()).select_from(PreSubmitExecutionAttempt)) == 0 - await session.rollback() - with pytest.raises(PreSubmitEvidenceConflict, match="pre_submit_attempt_not_committed"): - await workflow._attempts.committed_claim(reservation) - assert calls == [] - finally: - await harness.close() - - -@pytest.mark.asyncio -async def test_attempt_database_guards_reject_rewrite_delete_and_orphan_completion( - tmp_path: Path, isolated_database_env: str, -) -> None: - harness = await _harness(tmp_path, isolated_database_env) - try: - async with harness.factory() as session: - workflow = harness.workflow(session, []) - reservation = await _reserve(workflow, harness.request, harness.preparation_request) - attempt_id = str(reservation.attempt_id) - statements = ( - ("update pre_submit_execution_attempts set request_digest=:digest where id=:id", - {"digest": "sha256:" + "0" * 64}), - ("update pre_submit_execution_attempts set status='completed',evidence_set_id=:evidence " - "where id=:id", {"evidence": str(new_record_id())}), - ("delete from pre_submit_execution_attempts where id=:id", {}), - ) - for sql, values in statements: - with pytest.raises(DBAPIError): - async with harness.engine.begin() as connection: - await connection.execute(text(sql), {"id": attempt_id, **values}) - async with harness.factory() as session: - attempt = await session.get(PreSubmitExecutionAttempt, attempt_id) - assert attempt is not None and attempt.status == "reserved" - assert attempt.evidence_set_id is None - finally: - await harness.close() - - -@pytest.mark.asyncio -async def test_database_rejects_same_resource_different_packet_evidence_completion( - tmp_path: Path, isolated_database_env: str, -) -> None: - harness = await _harness(tmp_path, isolated_database_env) - try: - async with harness.factory() as first_session: - first_workflow = harness.workflow(first_session, []) - first_reservation = await _reserve( - first_workflow, harness.request, harness.preparation_request, - ) - first = await first_workflow.execute_reserved( - harness.request, first_reservation, - preparation_request=harness.preparation_request, - ) - changed_request = replace(harness.request, packet=replace( - harness.request.packet, summary="A different packet for the same work artifact.", - )) - changed_preparation = replace( - harness.preparation_request, - idempotency_key=new_record_id(), - summary=changed_request.packet.summary, - ) - async with harness.factory() as second_session: - second_workflow = harness.workflow(second_session, []) - second_reservation = await _reserve( - second_workflow, changed_request, changed_preparation, - ) - assert first_reservation.request_digest != second_reservation.request_digest - new_evidence = str(new_record_id()) - source_evidence = str(first.evidence.evidence_set_id) - async with harness.factory() as session: - original_evidence = await session.get(PreSubmitEvidenceSet, source_evidence) - second_attempt = await session.get( - PreSubmitExecutionAttempt, str(second_reservation.attempt_id), - ) - assert original_evidence is not None and second_attempt is not None - assert original_evidence.packet_sha256 == canonical_json_hash( - asdict(harness.request.packet) - ) - assert original_evidence.packet_sha256 != second_attempt.request_json["packet_sha256"] - columns = tuple(column.name for column in PreSubmitEvidenceSet.__table__.columns) - replacements = { - "id": ":new_evidence", - "operation_identity": ":new_operation", - "attempt_id": ":new_attempt", - "created_at": "transaction_timestamp()", - # The request digest is valid for the second attempt. Only the - # evidence's independently captured packet hash remains original. - "attempt_request_digest": ":correct_request_digest", - } - copy_sql = ( - f"insert into pre_submit_evidence_sets ({', '.join(columns)}) " - f"select {', '.join(replacements.get(column, column) for column in columns)} " - "from pre_submit_evidence_sets where id=:source_evidence" - ) - result_columns = tuple(column.name for column in PreSubmitEvidenceResult.__table__.columns) - result_replacements = { - "id": ":new_result", - "evidence_set_id": ":new_evidence", - "created_at": "transaction_timestamp()", - } - copy_results_sql = ( - f"insert into pre_submit_evidence_results ({', '.join(result_columns)}) " - f"select {', '.join(result_replacements.get(column, column) for column in result_columns)} " - "from pre_submit_evidence_results where evidence_set_id=:source_evidence " - "and result_order=:result_order" - ) - with pytest.raises(DBAPIError, match="pre-submit evidence packet mismatch"): - async with harness.engine.begin() as connection: - await connection.execute(text(copy_sql), { - "new_evidence": new_evidence, - "new_operation": canonical_json_hash({"counterexample": new_evidence}), - "new_attempt": str(second_reservation.attempt_id), - "correct_request_digest": second_reservation.request_digest, - "source_evidence": source_evidence, - }) - copied_results = 0 - for result_order in range(len(first.execution.entries)): - copied = await connection.execute(text(copy_results_sql), { - "new_result": str(new_record_id()), - "new_evidence": new_evidence, - "source_evidence": source_evidence, - "result_order": result_order, - }) - copied_results += copied.rowcount - assert copied_results == len(first.execution.entries) - await connection.execute(text( - "update pre_submit_execution_attempts set status='completed'," - "evidence_set_id=:evidence where id=:attempt" - ), {"evidence": new_evidence, "attempt": str(second_reservation.attempt_id)}) - async with harness.factory() as session: - attempt = await session.get( - PreSubmitExecutionAttempt, str(second_reservation.attempt_id), - ) - assert attempt is not None and attempt.status == "reserved" - assert await session.get(PreSubmitEvidenceSet, new_evidence) is None - assert await session.get(PreSubmitEvidenceSet, source_evidence) is not None - finally: - await harness.close() - - -@pytest.mark.asyncio -@pytest.mark.parametrize("phase", ("before_execution", "completed_replay")) -async def test_revoked_contributor_cannot_execute_or_replay_after_reservation( - tmp_path: Path, isolated_database_env: str, phase: str, -) -> None: - harness = await _harness(tmp_path, isolated_database_env) - calls: list[int] = [] - retry = None - try: - async with harness.factory() as session: - authority = harness.contributor_authority(session) - await authority.preflight(request=harness.preparation_request) - async with session.begin(): - await authority.revalidate( - request=harness.preparation_request, - project_id=harness.request.effective_plan.lineage.project_id, - ) - workflow = harness.workflow( - session, calls, preparation_authorization=authority, - ) - reservation = await _reserve( - workflow, harness.request, harness.preparation_request, - ) - if phase == "completed_replay": - completed = await workflow.execute_reserved( - harness.request, reservation, - preparation_request=harness.preparation_request, - ) - assert completed.pass_capability is not None - assert len(calls) == 1 - await harness.request.prepared_artifact.close() - retry = await harness.fresh_request() - else: - assert calls == [] - async with harness.engine.begin() as connection: - await connection.execute(text( - "update actor_identity_links set status='revoked'," - "revoked_by='test',revoked_at=now(),revoked_reason='test revocation' " - "where id=:link" - ), {"link": str(harness.identity_link_id)}) - with pytest.raises(ArtifactAuthorityDeniedError): - if phase == "before_execution": - await workflow.execute_reserved( - harness.request, reservation, - preparation_request=harness.preparation_request, - ) - else: - await _reserve(workflow, retry, harness.preparation_request) - assert len(calls) == (0 if phase == "before_execution" else 1) - finally: - if retry is not None: - await retry.prepared_artifact.close() - await harness.close() diff --git a/backend/tests/test_pre_submit_attempt_schema.py b/backend/tests/test_pre_submit_attempt_schema.py deleted file mode 100644 index 4c14f2933..000000000 --- a/backend/tests/test_pre_submit_attempt_schema.py +++ /dev/null @@ -1,408 +0,0 @@ -"""Current pre-submit result ordering and metadata schema proof.""" - - - -import pytest -from sqlalchemy import text -from sqlalchemy.exc import DBAPIError - -from app.core.identifiers import new_record_id -from tests.test_pre_submit_attempt_recovery import _harness, _reserve - - -pytestmark = pytest.mark.postgres_schema_contract - - -@pytest.mark.asyncio -async def test_new_result_rows_require_valid_order_and_bounded_metadata( - tmp_path, - isolated_database_env: str, -) -> None: - harness = await _harness(tmp_path, isolated_database_env) - try: - async with harness.factory() as session: - workflow = harness.workflow(session, []) - reservation = await _reserve(workflow, harness.request, harness.preparation_request) - completed = await workflow.execute_reserved( - harness.request, - reservation, - preparation_request=harness.preparation_request, - ) - retained_id = str(completed.evidence.evidence_set_id) - new_id = str(new_record_id()) - attempt_id = str(new_record_id()) - packet_sha256 = "sha256:" + "d" * 64 - async with harness.engine.connect() as connection: - transaction = await connection.begin() - try: - await connection.execute( - text( - "insert into pre_submit_execution_attempts (" - "id,idempotency_key,actor_profile_id,identity_link_id,task_id," - "assignment_id,prepared_generation_id,claim_nonce,request_json," - "request_digest,status) select :attempt,:key,e.actor_profile_id," - "e.identity_link_id,e.task_id,e.assignment_id,e.prepared_generation_id," - ":nonce,(to_jsonb(e)||jsonb_build_object('packet_sha256'," - "cast(:packet_sha256 as text)))::json,'sha256:'||encode(sha256(" - "convert_to(project_guide_projection_canonical_json(to_jsonb(e)||" - "jsonb_build_object('packet_sha256',cast(:packet_sha256 as text)))," - "'UTF8')),'hex'),'reserved' from pre_submit_evidence_sets e " - "where e.id=:retained" - ), - { - "attempt": attempt_id, - "key": str(new_record_id()), - "nonce": str(new_record_id()), - "packet_sha256": packet_sha256, - "retained": retained_id, - }, - ) - await connection.execute( - text( - "insert into pre_submit_evidence_sets select " - "(jsonb_populate_record(null::pre_submit_evidence_sets,to_jsonb(e)||" - "jsonb_build_object('id',cast(:new_id as text),'operation_identity'," - "'sha256:'||repeat('c',64),'packet_sha256',cast(:packet_sha256 as text)," - "'attempt_id',cast(:attempt as text),'attempt_request_digest'," - "a.request_digest,'created_at',transaction_timestamp()))).* " - "from pre_submit_evidence_sets e join pre_submit_execution_attempts a " - "on a.id=:attempt where e.id=:retained" - ), - { - "new_id": new_id, - "retained": retained_id, - "packet_sha256": packet_sha256, - "attempt": attempt_id, - }, - ) - await connection.execute( - text( - "update pre_submit_execution_attempts set status='completed'," - "evidence_set_id=:evidence where id=:attempt" - ), - {"evidence": new_id, "attempt": attempt_id}, - ) - await connection.execute(text("set constraints all immediate")) - insert_result = text( - "insert into pre_submit_evidence_results (id,evidence_set_id," - "result_order,schema_version,dispatch_authority,definition_id," - "definition_version,public_name,source,phase,classification,severity," - "status,message_code,effective_plan_sha256,locked_policy_sha256," - "checker_order,metadata_json) values (:id,:parent,0,'v1'," - "'schema-test','test.check','v1','Test check','test','custody'," - "'mandatory_integrity','blocking','passed','test.passed',:digest," - ":digest,:checker_order,cast(:metadata as json))" - ) - parameters = {"parent": new_id, "digest": "sha256:" + "a" * 64} - invalid = ( - (None, "[]", "pre-submit result reconstruction fields required"), - (-1, "[]", "pre-submit result reconstruction fields required"), - (0, None, "pre-submit result reconstruction fields required"), - (0, '{"entry_count":1}', "pre-submit result reconstruction fields required"), - (0, '[["entry_count",-1]]', "pre-submit result metadata invalid"), - ( - 0, - '[["entry_count",1],["entry_count",2]]', - "pre-submit result metadata invalid", - ), - ) - for checker_order, metadata, expected in invalid: - with pytest.raises(DBAPIError, match=expected): - async with connection.begin_nested(): - await connection.execute( - insert_result, - { - **parameters, - "id": str(new_record_id()), - "checker_order": checker_order, - "metadata": metadata, - }, - ) - await connection.execute( - insert_result, - { - **parameters, - "id": str(new_record_id()), - "checker_order": 0, - "metadata": '[["entry_count",1],["finding_count",0]]', - }, - ) - assert ( - await connection.scalar( - text( - "select count(*) from pre_submit_evidence_results " - "where evidence_set_id=:id and checker_order=0" - ), - {"id": new_id}, - ) - == 1 - ) - finally: - await transaction.rollback() - finally: - await harness.close() - - -async def test_manifest_metadata_is_hash_bound_on_insert_and_immutable( - tmp_path, isolated_database_env, -): - """Real inspected evidence is the valid control for direct storage rejections.""" - import json - from copy import deepcopy - from app.core.hashing import canonical_json_hash - - harness = await _harness(tmp_path, isolated_database_env) - try: - async with harness.factory() as session: - workflow = harness.workflow(session, []) - reservation = await _reserve(workflow, harness.request, harness.preparation_request) - completed = await workflow.execute_reserved( - harness.request, reservation, preparation_request=harness.preparation_request, - ) - evidence_id = str(completed.evidence.evidence_set_id) - async with harness.factory() as session: - body, digest = (await session.execute(text( - "select semantic_manifest_body,semantic_manifest_sha256 " - "from pre_submit_evidence_sets where id=:id" - ), {"id": evidence_id})).one() - assert canonical_json_hash(body) == digest - from tests.test_submission_manifest import _archive, _manifest - unicode_manifest = _manifest(_archive([("café/α.txt", b"verified")])) - malformed = deepcopy(body) - malformed["entries"][0]["content"] = "not metadata" - async with harness.factory() as session, session.begin(): - for candidate, commitment, valid in ( - (body, digest, True), (unicode_manifest.as_dict(), unicode_manifest.sha256, True), - (body, "sha256:" + "f" * 64, False), - (None, digest, False), (malformed, canonical_json_hash(malformed), False), - ): - assert await session.scalar(text( - "select public.submission_manifest_metadata_valid(cast(:body as jsonb),:digest)" - ), {"body": json.dumps(candidate), "digest": commitment}) is valid - for path in ("../outside.txt", "/absolute.txt", "dir\\file.txt", "a//b", "a/./b", "a./b", "drive:c/file", "cafe\u0301.txt", "x" * 4097): - candidate = deepcopy(unicode_manifest.as_dict()) - candidate["entries"] = [candidate["entries"][-1]] - candidate["entries"][0]["normalized_path"] = path - assert not await session.scalar(text( - "select public.submission_manifest_metadata_valid(cast(:body as jsonb),:digest)" - ), {"body": json.dumps(candidate), "digest": canonical_json_hash(candidate)}) - for candidate, commitment in ((None, digest), (malformed, digest), (body, "sha256:" + "f" * 64)): - with pytest.raises(DBAPIError, match="pre-submit manifest metadata invalid"): - async with session.begin_nested(): - await session.execute(text( - "insert into pre_submit_evidence_sets select " - "(jsonb_populate_record(null::pre_submit_evidence_sets,to_jsonb(e)||" - "jsonb_build_object('semantic_manifest_body',cast(:body as jsonb)," - "'semantic_manifest_sha256',cast(:digest as text),'created_at',transaction_timestamp()))).* " - "from pre_submit_evidence_sets e where e.id=:id" - ), {"body": json.dumps(candidate), "digest": commitment, "id": evidence_id}) - with pytest.raises(DBAPIError, match="immutable"): - async with session.begin_nested(): - await session.execute(text( - "update pre_submit_evidence_sets set semantic_manifest_body=null where id=:id" - ), {"id": evidence_id}) - assert await session.scalar(text( - "select semantic_manifest_body from pre_submit_evidence_sets where id=:id" - ), {"id": evidence_id}) == body - finally: - await harness.close() - - -async def test_manifest_upgrade_preserves_old_evidence_without_inventing_metadata( - tmp_path, isolated_database_env, migration_lock, -): - import asyncio - import asyncpg - from alembic import command - from app.db import session as db_session - from app.modules.artifacts.pre_submit_evidence import PreSubmitEvidenceConflict - from tests.migration_fixtures import ( - _config, add_current_art_seed_column, restore_predecessor_evidence_schema, - ) - - with migration_lock(): - await db_session.dispose_engine() - connection = await asyncpg.connect(isolated_database_env.replace("+asyncpg", "")) - try: - await connection.execute("drop schema public cascade; create schema public") - finally: - await connection.close() - await asyncio.to_thread(command.upgrade, _config(), "0020_review_admission_lock_order") - original_columns = await add_current_art_seed_column(isolated_database_env) - harness = await _harness(tmp_path, isolated_database_env) - try: - calls = [] - async with harness.factory() as session: - workflow = harness.workflow(session, calls) - reservation = await _reserve(workflow, harness.request, harness.preparation_request) - completed = await workflow.execute_reserved( - harness.request, reservation, preparation_request=harness.preparation_request, - ) - evidence_id = str(completed.evidence.evidence_set_id) - await restore_predecessor_evidence_schema(isolated_database_env, original_columns) - async with harness.factory() as session: - before = await session.scalar(text( - "select to_jsonb(e) from pre_submit_evidence_sets e where id=:id" - ), {"id": evidence_id}) - await asyncio.to_thread(command.upgrade, _config(), "head") - async with harness.factory() as session: - after = await session.scalar(text( - "select to_jsonb(e) from pre_submit_evidence_sets e where id=:id" - ), {"id": evidence_id}) - assert after.pop("semantic_manifest_body") is None - assert after == before - async with harness.factory() as session: - workflow = harness.workflow(session, calls) - with pytest.raises(PreSubmitEvidenceConflict, match="pre_submit_attempt_manifest_invalid"): - await _reserve(workflow, harness.request, harness.preparation_request) - assert calls == [1] - finally: - await harness.close() - - -async def test_upgraded_consumed_admission_without_metadata_is_unavailable( - tmp_path, isolated_database_env, migration_lock, -): - """Real retained admission recovery denies without rewriting its consumed facts.""" - import asyncio - import asyncpg - from alembic import command - from app.db import session as db_session - from app.modules.artifacts.api import SubmissionAdmissionConsumptionError - from app.modules.checkers.api import SubmissionPacketView - from app.modules.artifacts.submission_bindings import SubmissionAdmissionConsumptionService - from tests.migration_fixtures import ( - _config, add_current_art_seed_column, restore_predecessor_evidence_schema, - ) - from tests.historical_submission_fixtures import historical_material_fixture - from app.modules.artifacts.api.submission_admission import ConsumedSubmissionAdmissionRequest - from tests.test_artifact_bindings import _Allow - - with migration_lock(): - await db_session.dispose_engine() - connection = await asyncpg.connect(isolated_database_env.replace("+asyncpg", "")) - try: - await connection.execute("drop schema public cascade; create schema public") - finally: - await connection.close() - await asyncio.to_thread(command.upgrade, _config(), "0020_review_admission_lock_order") - original_columns = await add_current_art_seed_column(isolated_database_env) - async with historical_material_fixture(tmp_path, isolated_database_env) as h: - request = ConsumedSubmissionAdmissionRequest( - admission_id=h.created.admission_id, project_id=h.request.project_id, - task_id=h.request.task_id, assignment_id=h.request.assignment_id, - contributor_id=h.facts.contributor_id, submission_id=h.created.submission_id, - submission_version=h.created.submission_version, - packet_sha256=SubmissionPacketView(h.creation_request.summary, h.creation_request.contributor_attestation).sha256, - ) - await restore_predecessor_evidence_schema(isolated_database_env, original_columns) - async with h.factory() as session: - before = await session.scalar(text( - "select to_jsonb(a) from submission_bundle_admissions a where id=:id" - ), {"id": str(request.admission_id)}) - bindings = await session.scalar(text("select count(*) from artifact_bindings")) - await asyncio.to_thread(command.upgrade, _config(), "head") - authority = _Allow() - async with h.factory() as session, session.begin(): - with pytest.raises(SubmissionAdmissionConsumptionError, match="submission_bundle_admission_unavailable"): - await SubmissionAdmissionConsumptionService(session, authority).read_consumed(request) - assert await session.scalar(text( - "select to_jsonb(a) from submission_bundle_admissions a where id=:id" - ), {"id": str(request.admission_id)}) == before - assert await session.scalar(text("select count(*) from artifact_bindings")) == bindings - authority.consume.assert_not_awaited() - assert h.store.opens == [] - - -async def _create_manifest_insert_probe(connection): - """Use the real column types and INSERT guard without unrelated parent constraints.""" - await connection.execute( - 'CREATE TEMP TABLE manifest_insert_probe AS SELECT semantic_manifest_body, ' - 'semantic_manifest_sha256 FROM public.pre_submit_evidence_sets WITH NO DATA' - ) - await connection.execute( - 'CREATE TRIGGER manifest_probe BEFORE INSERT ON manifest_insert_probe ' - 'FOR EACH ROW EXECUTE FUNCTION public.guard_submission_manifest_metadata()' - ) - - -async def test_native_json_insert_recovers_the_validated_numeric_representation(isolated_database_env): - import asyncpg - import json - from app.modules.artifacts.submission_manifest import SubmissionManifest - from app.core.hashing import canonical_json_hash - from tests.test_submission_manifest import _archive, _manifest - - connection = await asyncpg.connect(isolated_database_env.replace('+asyncpg', '')) - try: - await _create_manifest_insert_probe(connection) - for count, literal in ((1, '1'), (1, '1e0'), (10, '1e1')): - manifest = _manifest(_archive([('a', b'x' * count)])) - native_json = json.dumps(manifest.as_dict()).replace(f'"byte_count": {count}', f'"byte_count": {literal}') - assert f'"byte_count": {literal}' in native_json - if 'e' in literal: - assert type(json.loads(native_json)['entries'][0]['byte_count']) is float - stored = await connection.fetchval( - 'INSERT INTO manifest_insert_probe VALUES ($1::json,$2) RETURNING semantic_manifest_body', - native_json, manifest.sha256, - ) - recovered = json.loads(stored) - assert type(recovered['entries'][0]['byte_count']) is int - assert SubmissionManifest.from_dict(recovered, sha256=manifest.sha256) == manifest - for literal in ('1.0', '1.5'): - manifest = _manifest(_archive([('a', b'x')])) - native_json = json.dumps(manifest.as_dict()).replace('"byte_count": 1', f'"byte_count": {literal}') - with pytest.raises(asyncpg.CheckViolationError, match='pre-submit manifest metadata invalid'): - await connection.execute('INSERT INTO manifest_insert_probe VALUES ($1::json,$2)', native_json, canonical_json_hash(json.loads(native_json))) - finally: - await connection.close() - - -async def test_manifest_insert_guard_rejects_hash_consistent_inventory_collisions(isolated_database_env): - import asyncpg - import json - from app.core.hashing import canonical_json_hash - from tests.test_submission_manifest import _archive, _manifest - - connection = await asyncpg.connect(isolated_database_env.replace('+asyncpg', '')) - try: - await _create_manifest_insert_probe(connection) - valid = _manifest(_archive([('café/a', b'x'), ('cafe', b'x')])) - await connection.execute('INSERT INTO manifest_insert_probe VALUES ($1::json,$2)', json.dumps(valid.as_dict()), valid.sha256) - template = _manifest(_archive([('safe', b'x')])).as_dict() - entry = template['entries'][0] - for paths in (('A', 'a'), ('dir', 'dir/x'), ('DIR/x', 'dir'), ('STRASSE', 'Straße'), ('Σ', 'ς'), ('İ', 'i\u0307')): - body = dict(template, entries=sorted([dict(entry, normalized_path=path) for path in paths], key=lambda item: item['normalized_path'])) - with pytest.raises(asyncpg.CheckViolationError, match='pre-submit manifest metadata invalid'): - await connection.execute('INSERT INTO manifest_insert_probe VALUES ($1::json,$2)', json.dumps(body), canonical_json_hash(body)) - assert await connection.fetchval('SELECT count(*) FROM manifest_insert_probe') == 1 - finally: - await connection.close() - - -async def test_database_casefold_matches_frozen_unicode_15(isolated_database_env): - import asyncpg - import hashlib - import importlib.util - import json - from pathlib import Path - import unicodedata - - spec = importlib.util.spec_from_file_location('manifest_migration', Path(__file__).parents[1] / 'alembic/versions/0021_submission_manifest.py') - migration = importlib.util.module_from_spec(spec) - spec.loader.exec_module(migration) - mapping = json.loads(migration._UNICODE_15_CASEFOLD_JSON) - assert unicodedata.unidata_version == '15.0.0' - assert len(mapping) == 1530 - assert hashlib.sha256(migration._UNICODE_15_CASEFOLD_JSON.encode()).hexdigest() == 'c0d6e0ca212805674e7443c1212d732e11fb9faf16d92326aa1a9536caadbf3a' - expected = {chr(i): chr(i).casefold() for i in range(0x110000) if chr(i).casefold() != chr(i)} - assert mapping == expected - connection = await asyncpg.connect(isolated_database_env.replace('+asyncpg', '')) - try: - values = list(mapping) + ['', 'café/cafe', 'dir/file', '123', '中', '🙂', 'Straße/İΣ'] - observed = await connection.fetch( - 'SELECT value,public.submission_archive_casefold(value) AS folded FROM unnest($1::text[]) AS values(value)', values, - ) - assert [(row['value'], row['folded']) for row in observed] == [(value, value.casefold()) for value in values] - finally: - await connection.close() diff --git a/backend/tests/test_pre_submit_related_lock_order.py b/backend/tests/test_pre_submit_related_lock_order.py deleted file mode 100644 index 0b9ab6289..000000000 --- a/backend/tests/test_pre_submit_related_lock_order.py +++ /dev/null @@ -1,369 +0,0 @@ -"""Real PostgreSQL races between pre-submit, grant revocation, and TASK reads.""" - -from __future__ import annotations - -from app.adapters.artifacts import task_guide_documents_port -from app.adapters.contributions import locked_compensation_terms_port -from app.core.config import get_settings - -from app.adapters.tasks import task_service - -import asyncio -from datetime import UTC, datetime -from pathlib import Path -from uuid import UUID -from app.core.identifiers import new_record_id - -import pytest -from sqlalchemy import func, select, text -from sqlalchemy.exc import DBAPIError -from sqlalchemy.ext.asyncio import async_sessionmaker, create_async_engine - -from app.adapters.audit import task_transition_audit -from app.modules.actors.models import ActorIdentityLink, ActorProfile -from app.modules.artifacts.authorization import PreparedPreSubmitMaterializationAuthorization -from app.modules.artifacts.models import PreSubmitEvidenceSet, PreSubmitExecutionAttempt -from app.modules.artifacts.schemas import ArtifactAuthorityDeniedError -from app.modules.actors.service import ResolvedActor -from app.modules.authorization import router as authorization_router -from app.modules.authorization.kernel import AuthorizationService -from app.modules.authorization.models import ProjectRoleGrant -from app.modules.authorization.prepared import PreparedAuthorizationService -from app.modules.authorization.project_role_schemas import ProjectRoleGrantRevokeBody -from app.modules.authorization.repository import AdminAuthorizationRepository -from app.modules.authorization.runtime import ( - ActorKind, ActorStatus, HumanAuthorizationContext, IdentityLinkStatus, -) -from app.modules.authorization.task_authorization import PreparedTaskAuthorization -from app.modules.tasks.authorized_commands import AuthorizedTaskCommands -from project_create_fixtures import grant_fixture_admin_role -from tests.authorization.test_pre_submit_attempt_authority import _seed_materializer -from tests.test_pre_submit_attempt_authority_integration import _reserve_with_real_materializer -from tests.test_pre_submit_attempt_lock_order import _wait_for_project_block -from tests.auth_concurrency_support import wait_for_named_database_lock -from tests.test_pre_submit_attempt_recovery import _harness - - -class _PauseBeforeProject: - """Hold ART after its TASK and actor/link fence, before the PROJECT fence.""" - - def __init__(self, repository, entered: asyncio.Event, release: asyncio.Event): - self.repository, self.entered, self.release = repository, entered, release - - async def lock_locked_policy_context(self, request): - self.entered.set() - await self.release.wait() - return await self.repository.lock_locked_policy_context(request) - - -async def _assert_row_locked(engine, table: str, row_id: UUID) -> None: - """NOWAIT proves the first operation owns the contributor fence.""" - assert table in {"actor_profiles", "actor_identity_links"} - async with engine.connect() as observer: - try: - await observer.execute( - text(f"select id from {table} where id=:id for update nowait"), - {"id": str(row_id)}, - ) - except DBAPIError as exc: - assert getattr(exc.orig, "sqlstate", None) == "55P03", exc - else: - pytest.fail(f"First operation did not lock {table} before PROJECT") - - -async def _ready_workflow(harness, session, calls): - contributor = harness.contributor_authority(session) - await contributor.preflight(request=harness.preparation_request) - async with session.begin(): - await contributor.revalidate( - request=harness.preparation_request, - project_id=harness.request.effective_plan.lineage.project_id, - ) - materializer = PreparedPreSubmitMaterializationAuthorization( - session, - request_id=harness.preparation_request.request_id, - correlation_id=harness.preparation_request.correlation_id, - ) - workflow = harness.workflow( - session, calls, preparation_authorization=contributor, - ) - workflow._materialization._authorization = materializer - return workflow, materializer - - -async def _manager_runtime(harness, session): - """Use the canonical AUTH PREP service and a real project-manager grant.""" - manager_id, link_id = new_record_id(), new_record_id() - session.add_all([ - ActorProfile( - id=str(manager_id), actor_kind="human", status="active", - provisioning_method="automatic_first_access", created_by="test", - ), - ActorIdentityLink( - id=str(link_id), actor_profile_id=str(manager_id), issuer="flow-test", - subject=f"revoke-lock-{manager_id}", subject_kind="human", - status="active", linked_by="test", last_verified_at=datetime.now(UTC), - ), - ]) - await session.flush() - await grant_fixture_admin_role( - session, manager_id, scope="project", - project_id=harness.request.effective_plan.lineage.project_id, - ) - await session.commit() - context = HumanAuthorizationContext( - actor_profile_id=manager_id, actor_kind=ActorKind.HUMAN, - actor_status=ActorStatus.ACTIVE, identity_link_id=link_id, - identity_link_status=IdentityLinkStatus.ACTIVE, - request_id=new_record_id(), correlation_id=new_record_id(), - ) - repository = AdminAuthorizationRepository(session) - authority = AuthorizationService(session, context, admin_repository=repository) - prepared = PreparedAuthorizationService(session, context, authority, repository) - profile = await session.get(ActorProfile, str(manager_id)) - link = await session.get(ActorIdentityLink, str(link_id)) - assert profile is not None and link is not None - await session.commit() - return prepared, ResolvedActor(profile, link) - - -async def _submitter_grant(harness): - """Read the exact active grant whose revocation races with ART.""" - async with harness.factory() as session: - grant_id = await session.scalar(select(ProjectRoleGrant.id).where( - ProjectRoleGrant.project_id == str(harness.request.effective_plan.lineage.project_id), - ProjectRoleGrant.actor_profile_id == str(harness.actor_id), - ProjectRoleGrant.role == "submitter", ProjectRoleGrant.status == "active", - )) - assert grant_id is not None - return grant_id - - -def _named_factory(database_url, name): - """Give each competing owner an independently observable database session.""" - engine = create_async_engine(database_url, connect_args={"server_settings": {"application_name": name}}) - return engine, async_sessionmaker(engine, expire_on_commit=False) - - -async def _wait_for_named_owner(harness, database_url, waiter, blocker): - """Bind the actual waiter to the independently observed blocking backend.""" - async with harness.engine.connect() as observer: - pid = await observer.scalar(text( - "select pid from pg_stat_activity where application_name=:name" - ), {"name": blocker}) - assert pid is not None - await wait_for_named_database_lock(database_url, waiter, expected_blocker_pid=pid) - - -@pytest.mark.asyncio -@pytest.mark.parametrize("ordering", ["materialization_first", "revoke_first"]) -async def test_revocation_fences_art_materialization_and_evidence_persistence( - tmp_path: Path, isolated_database_env: str, monkeypatch, ordering: str, -) -> None: - """Revocation fences both checking and the later evidence-persistence transaction.""" - harness = await _harness(tmp_path, isolated_database_env) - art_engine = revoke_engine = None - art_task = revoke_task = None - release_art, release_revoke = asyncio.Event(), asyncio.Event() - try: - await _seed_materializer(harness.factory) - project_id = harness.request.effective_plan.lineage.project_id - grant_id = await _submitter_grant(harness) - revoke_name = f"pol07a_revoke_{new_record_id().hex[:12]}" - art_name = f"pol07a_revoke_art_{new_record_id().hex[:12]}" - art_engine, art_factory = _named_factory(isolated_database_env, art_name) - revoke_engine, revoke_factory = _named_factory(isolated_database_env, revoke_name) - art_before_project, revoke_has_project = asyncio.Event(), asyncio.Event() - async with art_factory() as art_session, revoke_factory() as revoke_session: - calls: list[int] = [] - workflow, materializer = await _ready_workflow(harness, art_session, calls) - prepared_revoke, resolved_manager = await _manager_runtime(harness, revoke_session) - reservation = await _reserve_with_real_materializer( - workflow, harness.request, harness.preparation_request, - ) - workflow._project_contexts = _PauseBeforeProject( - workflow._project_contexts, art_before_project, release_art, - ) - original_lock_project = AdminAuthorizationRepository.lock_project - revoke_pid: int | None = None - - async def pause_revoke_project(repository, locked_project_id): - nonlocal revoke_pid - project = await original_lock_project(repository, locked_project_id) - if repository._session is revoke_session: - revoke_pid = int(await revoke_session.scalar(text("select pg_backend_pid()"))) - revoke_has_project.set() - await release_revoke.wait() - return project - - monkeypatch.setattr( - AdminAuthorizationRepository, "lock_project", pause_revoke_project, - ) - try: - async def execute_art(): - return await workflow.execute_reserved( - harness.request, reservation, - preparation_request=harness.preparation_request, - ) - - async def revoke(): - return await authorization_router.revoke_project_role_grant( - project_id=project_id, grant_id=UUID(str(grant_id)), - payload=ProjectRoleGrantRevokeBody(reason="Concurrent pre-submit grant revocation"), - idempotency_key=new_record_id(), resolved=resolved_manager, - prepared=prepared_revoke, session=revoke_session, - ) - - if ordering == "materialization_first": - art_task = asyncio.create_task(execute_art()) - await asyncio.wait_for(art_before_project.wait(), timeout=30) - await _assert_row_locked(harness.engine, "actor_profiles", harness.actor_id) - await _assert_row_locked(harness.engine, "actor_identity_links", harness.identity_link_id) - revoke_task = asyncio.create_task(revoke()) - await _wait_for_named_owner(harness, isolated_database_env, revoke_name, art_name) - assert not revoke_has_project.is_set() - release_art.set() - await asyncio.wait_for(revoke_has_project.wait(), timeout=30) - assert revoke_pid is not None - await wait_for_named_database_lock( - isolated_database_env, art_name, expected_blocker_pid=revoke_pid, - ) - else: - revoke_task = asyncio.create_task(revoke()) - await asyncio.wait_for(revoke_has_project.wait(), timeout=30) - await _assert_row_locked(harness.engine, "actor_profiles", harness.actor_id) - await _assert_row_locked(harness.engine, "actor_identity_links", harness.identity_link_id) - release_art.set() - art_task = asyncio.create_task(execute_art()) - assert revoke_pid is not None - await wait_for_named_database_lock( - isolated_database_env, art_name, expected_blocker_pid=revoke_pid, - ) - assert not art_before_project.is_set() - release_revoke.set() - art_outcome, revoke_outcome = await asyncio.wait_for( - asyncio.gather(art_task, revoke_task, return_exceptions=True), - timeout=30, - ) - # Materialization and evidence persistence reauthorize in separate - # transactions. Revocation after checking still prevents evidence. - assert isinstance(art_outcome, ArtifactAuthorityDeniedError), art_outcome - assert calls == ([1] if ordering == "materialization_first" else []) - assert not isinstance(revoke_outcome, BaseException), revoke_outcome - assert revoke_outcome.status == "revoked" - finally: - release_art.set() - release_revoke.set() - for pending in (art_task, revoke_task): - if pending is not None and not pending.done(): - pending.cancel() - await asyncio.gather( - *(task for task in (art_task, revoke_task) if task is not None), - return_exceptions=True, - ) - materializer.close() - prepared_revoke.close() - async with harness.factory() as session: - grant = await session.get(ProjectRoleGrant, grant_id) - assert grant is not None and grant.status == "revoked" and grant.version == 2 - assert await session.scalar(select(func.count()).select_from(PreSubmitEvidenceSet)) == 0 - finally: - release_art.set() - release_revoke.set() - if art_engine is not None: - await art_engine.dispose() - if revoke_engine is not None: - await revoke_engine.dispose() - await harness.close() - - -@pytest.mark.asyncio -async def test_work_context_task_lock_precedes_art_actor_lock( - tmp_path: Path, isolated_database_env: str, -) -> None: - """TASK T then AUTH C and ART T then C complete without a cycle.""" - harness = await _harness(tmp_path, isolated_database_env) - art_engine = None - art_task = task_command = None - release_task = asyncio.Event() - try: - await _seed_materializer(harness.factory) - art_name = f"pol07a_task_art_{new_record_id().hex[:12]}" - art_engine = create_async_engine( - isolated_database_env, - connect_args={"server_settings": {"application_name": art_name}}, - ) - art_factory = async_sessionmaker(art_engine, expire_on_commit=False) - task_locked = asyncio.Event() - async with harness.factory() as task_session, art_factory() as art_session: - calls: list[int] = [] - workflow, materializer = await _ready_workflow(harness, art_session, calls) - reservation = await _reserve_with_real_materializer( - workflow, harness.request, harness.preparation_request, - ) - context = HumanAuthorizationContext( - actor_profile_id=harness.actor_id, actor_kind=ActorKind.HUMAN, - actor_status=ActorStatus.ACTIVE, - identity_link_id=harness.identity_link_id, - identity_link_status=IdentityLinkStatus.ACTIVE, - request_id=new_record_id(), correlation_id=new_record_id(), - ) - task_authority = PreparedTaskAuthorization(task_session, context) - real_prepare = task_authority.prepare - task_pid: int | None = None - - async def pause_before_auth(facts): - nonlocal task_pid - task_pid = int(await task_session.scalar(text("select pg_backend_pid()"))) - task_locked.set() - await release_task.wait() - return await real_prepare(facts) - - task_authority.prepare = pause_before_auth - commands = AuthorizedTaskCommands( - task_session, - authorization=task_authority, - audit=task_transition_audit(task_session), - actor_profile_id=harness.actor_id, - contexts=task_service(task_session, settings=get_settings()), - guide_documents=task_guide_documents_port(task_session, get_settings()), - compensation_terms=locked_compensation_terms_port(task_session), - ) - try: - task_command = asyncio.create_task(commands.contributor_work_context(harness.request.task_id)) - await asyncio.wait_for(task_locked.wait(), timeout=30) - assert task_pid is not None - art_task = asyncio.create_task(workflow.execute_reserved( - harness.request, reservation, - preparation_request=harness.preparation_request, - )) - await _wait_for_project_block( - harness.engine, application_name=art_name, blocker_pid=task_pid, - ) - release_task.set() - task_result, art_result = await asyncio.wait_for( - asyncio.gather(task_command, art_task, return_exceptions=True), - timeout=30, - ) - assert not isinstance(task_result, BaseException), task_result - assert task_result.task.status == "in_progress" - assert task_result.lifecycle.assigned_to_current_actor is True - assert not isinstance(art_result, BaseException), art_result - assert art_result.pass_capability is not None - assert calls == [1] - finally: - release_task.set() - await asyncio.gather( - *(task for task in (art_task, task_command) if task is not None), - return_exceptions=True, - ) - materializer.close() - async with harness.factory() as session: - attempts = (await session.scalars(select(PreSubmitExecutionAttempt))).all() - assert len(attempts) == 1 and attempts[0].status == "completed" - assert await session.scalar(select(func.count()).select_from(PreSubmitEvidenceSet)) == 1 - finally: - release_task.set() - if art_engine is not None: - await art_engine.dispose() - await harness.close() diff --git a/backend/tests/test_pre_submit_role_issue_lock_order.py b/backend/tests/test_pre_submit_role_issue_lock_order.py deleted file mode 100644 index d6db93590..000000000 --- a/backend/tests/test_pre_submit_role_issue_lock_order.py +++ /dev/null @@ -1,330 +0,0 @@ -"""Real PostgreSQL proof of role issuance versus pre-submit execution lock order.""" - -from __future__ import annotations - -import asyncio -from dataclasses import replace -from datetime import UTC, datetime -from pathlib import Path -from uuid import UUID -from app.core.identifiers import new_record_id - -import pytest -from sqlalchemy import func, select -from sqlalchemy.exc import DBAPIError -from sqlalchemy.ext.asyncio import async_sessionmaker, create_async_engine - -from app.modules.actors.models import ActorIdentityLink, ActorProfile -from app.modules.actors.service import ResolvedActor -from app.modules.artifacts.authorization import PreparedPreSubmitMaterializationAuthorization -from app.modules.artifacts.models import PreSubmitEvidenceSet, PreSubmitExecutionAttempt -from app.core.api_controls import StructuredHTTPException -from app.modules.authorization import router as authorization_router -from app.modules.authorization.kernel import AuthorizationService -from app.modules.authorization.models import ProjectRoleGrant -from app.modules.authorization.prepared import PreparedAuthorizationService -from app.modules.authorization.project_role_schemas import ProjectRoleGrantIssueBody -from app.modules.authorization.repository import AdminAuthorizationRepository -from app.modules.authorization.runtime import ( - ActorKind, ActorStatus, HumanAuthorizationContext, IdentityLinkStatus, -) -from app.modules.authorization.schemas import AdminRole, ProjectRole -from project_create_fixtures import grant_fixture_admin_role -from tests.authorization.test_pre_submit_attempt_authority import _seed_materializer -from tests.test_pre_submit_attempt_authority_integration import _reserve_with_real_materializer -from tests.test_pre_submit_attempt_lock_order import ( - _PauseAfterProjectLock, _wait_for_project_block, -) -from tests.test_pre_submit_attempt_recovery import _harness - - -async def _seed_manager(harness) -> tuple[UUID, UUID]: - actor_id, link_id = new_record_id(), new_record_id() - project_id = harness.request.effective_plan.lineage.project_id - async with harness.factory() as session: - session.add_all([ - ActorProfile( - id=str(actor_id), actor_kind="human", status="active", - provisioning_method="automatic_first_access", created_by="test", - ), - ActorIdentityLink( - id=str(link_id), actor_profile_id=str(actor_id), issuer="flow-test", - subject=f"role-issue-{actor_id}", subject_kind="human", - status="active", linked_by="test", last_verified_at=datetime.now(UTC), - ), - ]) - await session.flush() - await grant_fixture_admin_role( - session, actor_id, role=AdminRole.PROJECT_MANAGER.value, - scope="project", project_id=project_id, - ) - await session.commit() - return actor_id, link_id - - -def _issue_body(target_actor_id: UUID) -> ProjectRoleGrantIssueBody: - return ProjectRoleGrantIssueBody.model_validate({ - "target_actor_profile_id": target_actor_id, - "role": "reviewer", - "reason": "Concurrent project-role issue lock-order proof", - "qualification": { - "skills_snapshot": { - "availability": "available", "reference_ids": ["skill:reviewer"], - "unavailable_reason": None, - }, - "reputation_snapshot": { - "availability": "unavailable", "reference_ids": [], - "unavailable_reason": "no_record", - }, - "prior_project_work_refs": [], "external_expertise_refs": [], - }, - }) - - -async def _issue_runtime(session, actor_id: UUID, link_id: UUID): - context = HumanAuthorizationContext( - actor_profile_id=actor_id, actor_kind=ActorKind.HUMAN, - actor_status=ActorStatus.ACTIVE, identity_link_id=link_id, - identity_link_status=IdentityLinkStatus.ACTIVE, - request_id=new_record_id(), correlation_id=new_record_id(), - ) - repository = AdminAuthorizationRepository(session) - authority = AuthorizationService(session, context, admin_repository=repository) - prepared = PreparedAuthorizationService(session, context, authority, repository) - profile = await session.get(ActorProfile, str(actor_id)) - link = await session.get(ActorIdentityLink, str(link_id)) - assert profile is not None and link is not None - await session.commit() - return prepared, ResolvedActor(profile, link) - - -async def _issue_role(session, project_id, body, issue_key, resolved, prepared): - try: - return await authorization_router.issue_project_role_grant( - project_id=project_id, payload=body, idempotency_key=issue_key, - resolved=resolved, prepared=prepared, session=session, - ) - except BaseException: - await session.rollback() - raise - - -async def _assert_persisted_outcomes(harness, project_id, target_id, target_kind, issue_result): - async with harness.factory() as session: - assert await session.scalar(select(func.count()).select_from(PreSubmitEvidenceSet)) == 1 - attempts = (await session.scalars(select(PreSubmitExecutionAttempt))).all() - assert len(attempts) == 1 and attempts[0].status == "completed" - grants = (await session.scalars(select(ProjectRoleGrant).where( - ProjectRoleGrant.project_id == str(project_id), - ProjectRoleGrant.actor_profile_id == str(target_id), - ProjectRoleGrant.role == "reviewer", ProjectRoleGrant.status == "active", - ))).all() - if target_kind == "contributor": - assert len(grants) == 1 and grants[0].id == issue_result.id - else: - assert grants == [] - - -def _sqlstate_cause(error: BaseException) -> str | None: - cause: BaseException | None = error - while cause is not None: - original = getattr(cause, "orig", None) - sqlstate = getattr(original, "sqlstate", None) - if sqlstate is not None: - return sqlstate - cause = cause.__cause__ - return None - - -@pytest.mark.parametrize("target_kind", ["contributor", "materializer_service"]) -@pytest.mark.asyncio -async def test_role_issue_and_pre_submit_execution_complete_without_project_contributor_deadlock( - tmp_path: Path, isolated_database_env: str, monkeypatch, target_kind: str, -) -> None: - import tests.test_default_pre_submit_execution as default_tests - - original_limits = default_tests._limits - monkeypatch.setattr(default_tests, "_limits", lambda: replace( - original_limits(), total_deadline_seconds=90, reservation_ttl_seconds=120, - aggregate_reserved_bytes=4 * default_tests.HARD_MAXIMUM_ARTIFACT_BYTES, - )) - harness = await _harness(tmp_path, isolated_database_env) - issue_engine = None - execution_task = issue_task = None - resume_project = asyncio.Event() - try: - manager_id, manager_link_id = await _seed_manager(harness) - materializer_link_id = await _seed_materializer(harness.factory) - target_id = harness.actor_id - if target_kind == "materializer_service": - async with harness.factory() as session: - target_id = UUID(await session.scalar(select( - ActorIdentityLink.actor_profile_id, - ).where(ActorIdentityLink.id == materializer_link_id))) - application_name = f"pol07a_role_issue_{new_record_id().hex[:12]}" - issue_engine = create_async_engine( - isolated_database_env, - connect_args={"server_settings": {"application_name": application_name}}, - ) - issue_factory = async_sessionmaker(issue_engine, expire_on_commit=False) - project_id = harness.request.effective_plan.lineage.project_id - async with harness.factory() as execution_session, issue_factory() as issue_session: - contributor_authority = harness.contributor_authority(execution_session) - await contributor_authority.preflight(request=harness.preparation_request) - async with execution_session.begin(): - await contributor_authority.revalidate( - request=harness.preparation_request, project_id=project_id, - ) - materializer = PreparedPreSubmitMaterializationAuthorization( - execution_session, - request_id=harness.preparation_request.request_id, - correlation_id=harness.preparation_request.correlation_id, - ) - calls: list[int] = [] - workflow = harness.workflow( - execution_session, calls, preparation_authorization=contributor_authority, - ) - workflow._materialization._authorization = materializer - prepared_issue, resolved_manager = await _issue_runtime( - issue_session, manager_id, manager_link_id, - ) - project_locked = asyncio.Event() - try: - reservation = await _reserve_with_real_materializer( - workflow, harness.request, harness.preparation_request, - ) - paused_project = _PauseAfterProjectLock( - workflow._project_contexts, execution_session, - project_locked, resume_project, - ) - workflow._project_contexts = paused_project - execution_task = asyncio.create_task(workflow.execute_reserved( - harness.request, reservation, - preparation_request=harness.preparation_request, - )) - await asyncio.wait_for(project_locked.wait(), timeout=30) - assert paused_project.backend_pid is not None - issue_key = new_record_id() - body = _issue_body(target_id) - issue_task = asyncio.create_task(_issue_role( - issue_session, project_id, body, issue_key, - resolved_manager, prepared_issue, - )) - await _wait_for_project_block( - harness.engine, application_name=application_name, - blocker_pid=paused_project.backend_pid, - ) - resume_project.set() - execution_result, issue_result = await asyncio.wait_for( - asyncio.gather(execution_task, issue_task, return_exceptions=True), - timeout=30, - ) - assert not isinstance(execution_result, BaseException), execution_result - assert execution_result.pass_capability is not None - if target_kind == "contributor": - assert not isinstance(issue_result, BaseException), ( - issue_result, _sqlstate_cause(issue_result) - ) - assert issue_result.status == "active" - assert issue_result.role is ProjectRole.REVIEWER - assert issue_result.actor_profile_id == harness.actor_id - replay = await authorization_router.issue_project_role_grant( - project_id=project_id, payload=body, idempotency_key=issue_key, - resolved=resolved_manager, prepared=prepared_issue, - session=issue_session, - ) - assert replay == issue_result - else: - assert isinstance(issue_result, StructuredHTTPException), issue_result - assert issue_result.status_code == 404, _sqlstate_cause(issue_result) - assert calls == [1] - finally: - resume_project.set() - await asyncio.gather( - *(task for task in (execution_task, issue_task) if task is not None), - return_exceptions=True, - ) - materializer.close() - prepared_issue.close() - await _assert_persisted_outcomes( - harness, project_id, target_id, target_kind, issue_result, - ) - finally: - resume_project.set() - await asyncio.gather( - *(task for task in (execution_task, issue_task) if task is not None), - return_exceptions=True, - ) - if issue_engine is not None: - await issue_engine.dispose() - await harness.close() - - -async def _assert_target_rows_locked(harness, target_id, link_id): - for model, row_id in ((ActorProfile, target_id), (ActorIdentityLink, link_id)): - async with harness.factory() as observer: - with pytest.raises(DBAPIError) as blocked: - await observer.scalar(select(model).where( - model.id == str(row_id), - ).with_for_update(nowait=True)) - assert blocked.value.orig.sqlstate == "55P03" - await observer.rollback() - - -@pytest.mark.asyncio -async def test_target_created_after_prepare_is_locked_before_project( - tmp_path: Path, isolated_database_env: str, monkeypatch, -) -> None: - harness = await _harness(tmp_path, isolated_database_env) - try: - manager_id, manager_link_id = await _seed_manager(harness) - project_id = harness.request.effective_plan.lineage.project_id - target_id, target_link_id = new_record_id(), new_record_id() - async with harness.factory() as session: - prepared, resolved = await _issue_runtime(session, manager_id, manager_link_id) - original_prepare = prepared.prepare - original_lock_project = AdminAuthorizationRepository.lock_project - project_probes = [] - - async def prepare_then_create(*args, **kwargs): - handle = await original_prepare(*args, **kwargs) - async with harness.factory.begin() as creator: - creator.add_all([ - ActorProfile( - id=str(target_id), actor_kind="human", status="active", - provisioning_method="automatic_first_access", created_by="test", - ), - ActorIdentityLink( - id=str(target_link_id), actor_profile_id=str(target_id), - issuer="flow-test", subject=f"late-target-{target_id}", - subject_kind="human", status="active", linked_by="test", - last_verified_at=datetime.now(UTC), - ), - ]) - return handle - - async def observe_project_lock(repository, requested_project_id): - await _assert_target_rows_locked(harness, target_id, target_link_id) - project_probes.append(requested_project_id) - return await original_lock_project(repository, requested_project_id) - - monkeypatch.setattr(prepared, "prepare", prepare_then_create) - monkeypatch.setattr( - AdminAuthorizationRepository, "lock_project", observe_project_lock, - ) - try: - issued = await _issue_role( - session, project_id, _issue_body(target_id), new_record_id(), - resolved, prepared, - ) - assert issued.status == "active" - assert issued.actor_profile_id == target_id - assert project_probes == [project_id] - finally: - prepared.close() - async with harness.factory() as session: - assert await session.scalar(select(func.count()).select_from( - ProjectRoleGrant, - ).where(ProjectRoleGrant.actor_profile_id == str(target_id))) == 1 - finally: - await harness.close() diff --git a/backend/tests/test_submission_evaluation_capacity.py b/backend/tests/test_submission_evaluation_capacity.py deleted file mode 100644 index 44640cbd0..000000000 --- a/backend/tests/test_submission_evaluation_capacity.py +++ /dev/null @@ -1,157 +0,0 @@ -"""Real inspected ZIP capacity and exact locked input projection before durable admission.""" - -from dataclasses import replace -from io import BytesIO -from unittest.mock import patch -from zipfile import ZipFile - -import json -import pytest -from sqlalchemy import func, select - -from app.adapters.artifacts.local import LocalStorageAdapter -from app.adapters.checkers import submission_evaluation_content -from app.core.identifiers import new_record_id -from app.modules.artifacts.api import SubmissionBundleFile, SubmissionBundlePreparationRejected -from app.modules.artifacts.models import ( - ArtifactPutAttempt, PreSubmitEvidenceSet, PreSubmitExecutionAttempt, - SubmissionBundleAdmission, SubmissionBundleDurableIntent, -) -from app.modules.artifacts.submission_materialization import PreparedBundlePreSubmitEvidenceService -from app.modules.checkers.api import SubmissionPacketView -from app.modules.checkers.api.post_submit import make_post_submit_request -from app.modules.checkers.runner import check_acceptance_criteria_present, check_evidence_present -from app.modules.checkers.post_submit_implementations import detached_checker_context -from app.modules.projects.api import ProjectLockedPolicyContextRequest -from app.modules.projects.api.locked_policy import CanonicalJsonObject -from app.modules.projects.api.policy_lineage import ReviewPolicySemantics, policy_digest -from app.modules.projects.locked_policy_repository import ProjectLockedPolicyRepository -from app.modules.tasks.api import TaskSubmissionContextRequest -from app.modules.tasks.repository import TaskRepository -from tests.submission_capacity_fixtures import capacity_fixture -from tests.pre_submit_test_helpers import approved_pre_submit_fixture -from tests.tasks.submission_lineage_support import _verified_admission -from tests.archive_fixtures import byte_source as _bytes, submission_archive as _archive -from tests.checkers.post_submit.support import request as evaluation_request - - -async def test_real_zip_capacity_rejects_before_effects_and_valid_control_passes( - isolated_database_env, tmp_path, -): - async with capacity_fixture(isolated_database_env, tmp_path) as h: - base = _archive(evidence_path=h.policy["evidence_path"]) - many = BytesIO(base) - with ZipFile(many, "a") as archive: - for index in range(1023): - archive.writestr(f"f{index:04d}", b"x") - # Exactly 1001 characters, each component portable and within ART limits. - path = "/".join(["a" * 200] * 4 + ["b" * 197]) - assert len(path) == 1001 - long_path = _archive(evidence_path=h.policy["evidence_path"], extra_path=path) - models = (ArtifactPutAttempt, PreSubmitExecutionAttempt, PreSubmitEvidenceSet, - SubmissionBundleDurableIntent, SubmissionBundleAdmission) - async with h.factory() as session: - # Guide setup already uploaded its own documents; retain that custody. - before = {model: await session.scalar(select(func.count()).select_from(model)) for model in models} - assert await session.scalar(select(func.count()).select_from(ArtifactPutAttempt).where( - ArtifactPutAttempt.task_id == str(h.request.task_id))) == 0 - for payload in (many.getvalue(), long_path): - key = new_record_id() - for _ in range(2): - with patch.object(PreparedBundlePreSubmitEvidenceService, "reserve", autospec=True, - side_effect=PreparedBundlePreSubmitEvidenceService.reserve) as reserve, \ - patch.object(LocalStorageAdapter, "put", autospec=True, side_effect=LocalStorageAdapter.put) as put: - with pytest.raises(SubmissionBundlePreparationRejected, match="^submission_evaluation_content_invalid$"): - await _verified_admission(h.factory, h.store, h.namespace, h.settings, h.context, - replace(h.request, idempotency_key=key, byte_source=_bytes(payload))) - reserve.assert_not_called() - put.assert_not_called() - async with h.factory() as session: - for model in models: - assert await session.scalar(select(func.count()).select_from(model)) == before[model], model.__tablename__ - for folder in ("files", "workspaces"): - assert list((h.settings.artifact_scratch_root / folder).iterdir()) == [] - admission = await _verified_admission(h.factory, h.store, h.namespace, h.settings, h.context, - replace(h.request, byte_source=_bytes(base))) - async with h.factory() as session: - row = await session.get(SubmissionBundleAdmission, str(admission)) - assert row.status == "ready" - - -async def _locked_facts(h): - async with h.factory.begin() as session: - task = await TaskRepository(session).lock_submission_context(TaskSubmissionContextRequest( - task_id=h.request.task_id, assignment_id=h.request.assignment_id, - contributor_id=h.context.actor_profile_id, predecessor_submission_id=None, - )) - refs = task.locked_project_context - project = await ProjectLockedPolicyRepository(session).lock_locked_policy_context(ProjectLockedPolicyContextRequest( - project_id=refs.project_id, guide_version=refs.guide_version, - source_snapshot_id=refs.source_snapshot_id, source_snapshot_hash=refs.source_snapshot_hash, - effective_policy_id=refs.effective_policy_id, effective_policy_hash=refs.effective_policy_hash, - pre_submit_policy_id=refs.pre_submit_policy_id, pre_submit_policy_bundle_hash=refs.pre_submit_policy_bundle_hash, - )) - return task, project - - -async def test_projection_exact_files_criteria_and_all_locked_stamps(isolated_database_env, tmp_path): - async with capacity_fixture(isolated_database_env, tmp_path) as h: - task, project = await _locked_facts(h) - packet = SubmissionPacketView(summary=h.request.summary, contributor_attestation=h.request.contributor_attestation) - evidence_file = SubmissionBundleFile(normalized_path=h.policy["evidence_path"], sha256="sha256:" + "1" * 64, byte_count=19) - other_file = SubmissionBundleFile(normalized_path="evidence/other", sha256="sha256:" + "2" * 64, byte_count=23) - project_hash = "sha256:" + "3" * 64 - def project_content(task_facts=task, files=(evidence_file, other_file)): - return submission_evaluation_content(task_facts, project, packet, files, project_hash) - content = project_content() - assert content.structural_input.criteria == task.acceptance_criteria - assert content.structural_input.package_hash == project_hash - assert [(m.artifact, m.hash, m.size_bytes) for m in content.structural_input.manifest] == [ - (f.normalized_path, f.sha256, f.byte_count) for f in (evidence_file, other_file)] - assert [(e.key, e.uri, e.hash) for e in content.structural_input.evidence] == [ - (json.loads(project.effective_policy.value)["required_evidence"][0]["key"], - evidence_file.normalized_path, evidence_file.sha256)] - # Detached false-policy facts prove the same capacity rules, not live activation. - for required in (True, False): - semantics = ReviewPolicySemantics(**{**json.loads(project.review_policy.value), "human_review_required": required}) - digest = policy_digest("review", semantics) - receipt = project.activation_receipt - selection = type(receipt.command.review)(**{**receipt.command.review.model_dump(), "policy_hash": digest}) - command = type(receipt.command)(**{**receipt.command.model_dump(), "review": selection}) - updated_receipt = type(receipt)(**{**receipt.model_dump(), "command": command}) - updated_project = replace(project, activation_receipt=updated_receipt, review_semantics_format="v2", - review_policy=CanonicalJsonObject.from_mapping(semantics.model_dump(mode="json"))) - updated_policy = type(task.locked_policy)(**{**task.locked_policy.model_dump(), "locked_review_policy_hash": digest}) - updated_task = replace(task, locked_policy=updated_policy) - projected = submission_evaluation_content(updated_task, updated_project, packet, (evidence_file,), project_hash) - assert projected.expected_context.review_hash == digest - with pytest.raises(ValueError, match="1024"): - submission_evaluation_content(updated_task, updated_project, packet, (evidence_file,) * 1025, project_hash) - base = evaluation_request() - envelope = base.model_dump(exclude=set(type(content).model_fields) | {"request_sha256"}) - for files in ((), (other_file,)): - missing = project_content(files=files) - assert missing.structural_input.evidence == () - outcome = await check_evidence_present(detached_checker_context(make_post_submit_request(**envelope, **missing.model_dump()))) - assert outcome.status == "failed" - for criteria in (None, ""): - empty = project_content(replace(task, acceptance_criteria=criteria)) - assert empty.structural_input.criteria == "" - outcome = await check_acceptance_criteria_present(detached_checker_context(make_post_submit_request(**envelope, **empty.model_dump()))) - assert outcome.status == "failed" - with pytest.raises(ValueError, match="65536"): - project_content(replace(task, acceptance_criteria="x" * 65537)) - # Every selected downstream identity/generation/hash is varied independently. - for field in type(task.locked_policy).model_fields: - if not field.startswith(("locked_post_", "locked_review_", "locked_revision_")): - continue - value = getattr(task.locked_policy, field) - changed = new_record_id() if field.endswith("_id") else value + 1 if type(value) is int else "sha256:" + "f" * 64 if field.endswith("hash") else "different" - altered = type(task.locked_policy)(**{**task.locked_policy.model_dump(), field: changed}) - with pytest.raises(ValueError, match="task submission policy differs"): - project_content(replace(task, locked_policy=altered)) - foreign_plan, _ = await approved_pre_submit_fixture(h.factory, h.namespace, guide_version="v1") - async with h.factory.begin() as session: - foreign_project = await ProjectLockedPolicyRepository(session).lock_active_policy_context(foreign_plan.lineage.project_id) - with pytest.raises(ValueError, match="task submission project differs"): - submission_evaluation_content(task, foreign_project, packet, (evidence_file,), project_hash) diff --git a/backend/tests/test_submission_predecessor_custody.py b/backend/tests/test_submission_predecessor_custody.py index 8a6f5fd6b..6c88d957e 100644 --- a/backend/tests/test_submission_predecessor_custody.py +++ b/backend/tests/test_submission_predecessor_custody.py @@ -35,7 +35,6 @@ SubmissionChangeRejectedError, ) from app.modules.authorization.api import ActorIdentityFacts, ActorKind -from app.modules.checkers.catalogue import build_pre_submission_checker_catalogue from tests.artifact_store_helpers import artifact_byte_stream from tests.post_submit_materialization_helpers import material_fixture from tests.tasks.post_submit_routing.support import revision_archive @@ -80,7 +79,6 @@ def _http_request(settings) -> Request: "app": SimpleNamespace( state=SimpleNamespace( settings=settings, - pre_submission_checker_catalogue=(build_pre_submission_checker_catalogue()), ) ), } diff --git a/backend/tests/test_tasks.py b/backend/tests/test_tasks.py index 89a2cf5ab..292e39580 100644 --- a/backend/tests/test_tasks.py +++ b/backend/tests/test_tasks.py @@ -266,23 +266,6 @@ async def test_task_repository_locks_initial_and_revision_submission_context() - for statement in assignment_statements ) - session.scalar = AsyncMock(return_value=assignment) - repository.get_latest_submission_for_task = AsyncMock(return_value=MagicMock( - id=str(predecessor_id), version=1, contributor_id=str(contributor_id), - )) - from app.modules.projects.post_submit_policy import build_project_post_submit_checker_spec, compile_project_post_submit_checker_spec - substituted = compile_project_post_submit_checker_spec( - project_id=str(references.project_id), guide_version=references.guide_version, - spec=build_project_post_submit_checker_spec(project_id=str(references.project_id), - guide_version=references.guide_version, required_checkers=[]), - ) - assert substituted.policy_hash != lineage.locked_post_submit_checker_policy_hash - task.locked_post_submit_checker_policy_body = substituted.model_dump(mode="json") - with pytest.raises(TaskSubmissionContextUnavailable, match="task_submission_context_invalid"): - await repository.lock_submission_context(TaskSubmissionContextRequest( - task_id=task_id, assignment_id=assignment_id, contributor_id=contributor_id, - predecessor_submission_id=predecessor_id, - )) @pytest.mark.asyncio @@ -2924,63 +2907,3 @@ async def test_task_metadata_round_trips(task_client: AsyncClient) -> None: assert task is not None assert task.skill_tags == ["stem", "proofs"] assert task.source_payload_hash == "hash-123" - - -@pytest.mark.parametrize("transition", ("screen", "release")) -@pytest.mark.parametrize("phase", ("pre", "post_missing", "post_substituted")) -async def test_catalogue_rollout_blocks_task_transition_without_writes( - task_client: AsyncClient, monkeypatch: pytest.MonkeyPatch, transition: str, phase: str, -) -> None: - from app.modules.checkers.api.historical_post_submit import current_post_submit_catalogue - from app.modules.checkers.runner import default_checker_registry - - project = await create_active_project(task_client) - task = await create_draft_task(task_client, project["id"]) - if transition == "release": - screened = await task_client.post( - f"/api/v1/tasks/{task['id']}/screen", headers=auth_headers(), - json={"reason": "initial screening"}, - ) - assert screened.status_code == 200, screened.text - task_query = select(WorkstreamTask.__table__).where(WorkstreamTask.id == task["id"]) - audit_query = select(AuditEvent.id).where(AuditEvent.entity_id == task["id"]).order_by(AuditEvent.id) - async with db_session.get_session_factory()() as session: - before = dict((await session.execute(task_query)).mappings().one()) - audits = list(await session.scalars(audit_query)) - if transition == "screen": - assert before["status"] == "draft" - assert all(value is None for key, value in before.items() if key.startswith("locked_")) - else: - assert before["status"] == "screening" - if phase.startswith("post_"): - metadata = current_post_submit_catalogue() - registry = default_checker_registry() - missing = "check_acceptance_criteria_present" - if phase == "post_missing": - registry._checkers.pop(missing) - else: - registry._checkers[missing] = registry.resolve("check_evidence_present") - monkeypatch.setattr("app.modules.checkers.runner.default_checker_registry", lambda: registry) - assert current_post_submit_catalogue() == metadata - else: - from app.modules.checkers.catalogue import build_pre_submission_checker_catalogue - disabled = build_pre_submission_checker_catalogue().entries[0].stable_id - monkeypatch.setattr(get_settings(), "artifact_pre_submission_checker_disabled_ids", disabled) - if transition == "release": - historical = await task_client.get( - f"/api/v1/projects/{project['id']}/tasks/{task['id']}/locked-context", headers=auth_headers(), - ) - assert historical.status_code == 200, historical.text - response = await task_client.post( - f"/api/v1/tasks/{task['id']}/{transition}", headers=auth_headers(), - json={"reason": "must remain unchanged"}, - ) - assert response.status_code == 422, response.text - expected = "installed checkers cannot execute the locked policies" - assert expected in response.text - async with db_session.get_session_factory()() as session: - assert dict((await session.execute(task_query)).mappings().one()) == before - assert list(await session.scalars(audit_query)) == audits - assert list(await session.scalars(select(TaskAssignment.id).where( - TaskAssignment.task_id == task["id"], - ))) == [] From 55948ca1295c9af6d3736d5a28ac2aaf5edb9938 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 00:02:03 +0100 Subject: [PATCH 134/283] [PILOT-04] prove capability recovery activation --- .../pilot04-workstream-default-checker.md | 13 +- .../tests/checkers/external/test_policy.py | 51 +++-- .../guide_activation/source_fixtures.py | 39 ++-- .../guide_activation/test_postgresql.py | 182 ++++++++++++++++++ .../guide_compilation/proposals/pg_support.py | 14 +- 5 files changed, 261 insertions(+), 38 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index d28613ea8..278cf8c9b 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -63,8 +63,10 @@ it; retained legacy envelopes remain read-only decoding inputs. Admission, routing completion and remediation fixtures now exercise the selected PRE/POST owners. Both obsolete executable catalogues and their isolated callers and tests have been removed; retained immutable evidence has only its bounded -historical decoder. F-020 recovery and the combined public/native journey remain -unfinished. +historical decoder. F-020 recovery now proves that registration alone cannot +activate the retained warning-bearing generation and that only an exact +registered binding in a corrected, linked approval can activate. The combined +public/native journey remains unfinished. ## Bounded change @@ -167,12 +169,12 @@ intermediate-wait regression. ## Acceptance criteria -- [ ] Approval binds the default behavior digest and every project binding to +- [x] Approval binds the default behavior digest and every project binding to an exact immutable registry row, phase, image, schemas, configuration and limits; substitutions and stale approvals fail closed. -- [ ] Activation enforces exact F-020 requirement/stage/generation coverage and +- [x] Activation enforces exact F-020 requirement/stage/generation coverage and retains false-policy and warning-acknowledgment guards. -- [ ] F-020 recovery is proven by register -> recompile -> approve -> activate +- [x] F-020 recovery is proven by register -> recompile -> approve -> activate in one current generation; registration alone and wrong generation, stage, requirement, registry digest or stale approval remain blocked. - [ ] ART verifies server receipt identity and a bounded safe manifest before @@ -234,6 +236,7 @@ intermediate-wait regression. | Production delivery registration and owner boundaries | `pytest -q backend/tests/architecture/test_module_boundaries.py backend/tests/test_artifact_architecture.py backend/tests/outbox/test_contracts.py`; focused Ruff and a direct registry construction probe | 116 passed; the existing production outbox registry exposes assignment invalidation and evaluation request handlers, selected Rust configuration is lazy, and PRE coordination stays behind CHECKERS' public adapter root | Database-backed legacy/selected delivery and worker restart proofs remain pending | | New Submission selected-only boundary | `pytest -q backend/tests/test_submission_bundle_admission.py backend/tests/checkers/external/test_selected_post_submit.py backend/tests/test_artifact_architecture.py::test_checker_custody_ports_have_exact_owner_and_art_consumers`; focused Ruff | 59 passed; retained legacy and selected admission projections are mutually exclusive, and the TASK writer accepts only selected POST custody for a new immutable Submission | Native rollback proof for a retained unresolved legacy admission remains pending | | Obsolete catalogue removal | Focused lane/architecture/ownership suite; recursive collection of every modified surviving test module; Ruff, module-boundary inventory and stale-import scan | 84 focused tests passed and 94 surviving tests collected. Ten obsolete executable catalogue/runner targets, their private-edge debt and tests are absent; exact ownership metadata admits only the selected owners and those retirements. | The stacked branch still has separately tracked structural-debt growth from earlier P02/P10/P04 source, so the repository-wide structural-debt gate is not claimed by this deletion checkpoint. | +| F-020 recovery | `python3 /tmp/p04_selected_runner.py /tmp/pilot04-f020-native6 600 tests/projects/guide_activation/test_postgresql.py::test_checker_registration_requires_corrected_approval_before_activation`; focused external-policy tests and Ruff | PostgreSQL 16 PASS 1 with schema 0037 and database/role/MinIO cleanup complete, plus 6 pure compiler tests. A real Operator registration does not clear the existing warning generation; correction observes the current registry projection, a linked successor approval binds the exact row/digest, the successor activates, and the old generation remains refused. Wrong stage, requirement, identity and registry digest substitutions fail closed. | This proves the activation recovery gate, not the combined intake-to-POST journey. | | Retained admission migration shape | `pytest -q backend/tests/test_submission_bundle_admission.py backend/tests/checkers/external/test_selected_pre_submit_coordination.py backend/tests/checkers/external/test_selected_preparation_command.py backend/tests/test_artifact_architecture.py::test_checker_materialization_contract_has_one_canonical_consumer_owner`; focused Ruff | 62 passed; selected rows require complete new custody while every new column stays null on retained legacy rows, avoiding fabricated backfill or historical hash rewrites | Successor SQL and direct retained/selected row controls remain pending | | Owner/caller trace | PROJECT approval/activation, ART preparation/admission, TASK composition and CHECKERS dispatch | Selected PRE uses durable reserve/lease/finalize roots around the genuine ART callback; a pass is consumed only by TASK's existing atomic Submission/evaluation reservation/outbox composition, while POST uses immutable Submission/ART custody | Final F-020 recovery, retained-history transition and combined native journey remain pending | | End-to-end replacement | Real PostgreSQL/MinIO/Rust public and worker journey | Not run | Implementation incomplete | diff --git a/backend/tests/checkers/external/test_policy.py b/backend/tests/checkers/external/test_policy.py index c81c1ffca..50758ccf9 100644 --- a/backend/tests/checkers/external/test_policy.py +++ b/backend/tests/checkers/external/test_policy.py @@ -45,8 +45,7 @@ def _entry(capability_id: str, phase: str) -> ExternalCheckerRegistryEntry: class _Registry: def __init__(self, entries): self.entries = { - (entry.capability_id, entry.capability_version, entry.phase): entry - for entry in entries + (entry.capability_id, entry.capability_version, entry.phase): entry for entry in entries } self.calls = [] @@ -102,17 +101,21 @@ def _proposal(): @pytest.mark.asyncio async def test_compilation_locks_exact_phase_registry_entries_and_default(): - entries = (_entry("acme.safe_archive", "pre_submit"), - _entry("acme.quality_review", "post_submit")) + entries = ( + _entry("acme.safe_archive", "pre_submit"), + _entry("acme.quality_review", "post_submit"), + ) registry = _Registry(entries) pre, post = await compile_external_checker_policies(_proposal(), registry) assert pre.workstream_default.checker_id == "workstream.default" - assert [(item.requirement_id, item.registry.registry_entry_id) - for item in pre.entries] == [("safe_archive", entries[0].registry_entry_id)] - assert [(item.requirement_id, item.registry.registry_entry_id) - for item in post.entries] == [("quality_review", entries[1].registry_entry_id)] + assert [(item.requirement_id, item.registry.registry_entry_id) for item in pre.entries] == [ + ("safe_archive", entries[0].registry_entry_id) + ] + assert [(item.requirement_id, item.registry.registry_entry_id) for item in post.entries] == [ + ("quality_review", entries[1].registry_entry_id) + ] assert pre.entries[0].configuration == {} assert post.entries[0].configuration == {} assert [call["phase"] for call in registry.calls] == ["pre_submit", "post_submit"] @@ -136,6 +139,30 @@ async def read_identity(self, **_identity): await compile_external_checker_policies(proposal, _SubstitutedRegistry()) +@pytest.mark.asyncio +async def test_compilation_refuses_requirement_and_registry_digest_substitution(): + proposal = _proposal() + wrong_requirement = proposal.model_copy( + update={ + "pre_submit_bindings": ( + proposal.pre_submit_bindings[0].model_copy( + update={"requirement_id": "quality_review"} + ), + ) + } + ) + with pytest.raises(ExternalCheckerPolicyError, match="does not cover"): + await compile_external_checker_policies( + wrong_requirement, + _Registry((_entry("acme.safe_archive", "pre_submit"),)), + ) + + entry = _entry("acme.safe_archive", "pre_submit") + corrupt = entry.model_copy(update={"entry_digest": "sha256:" + "f" * 64}) + with pytest.raises(ValueError, match="entry digest"): + await compile_external_checker_policies(proposal, _Registry((corrupt,))) + + @pytest.mark.asyncio async def test_compilation_refuses_blocked_capability_coverage(): proposal = _proposal().model_copy( @@ -165,10 +192,6 @@ async def test_selected_pre_budget_binds_ordered_deadlines_to_art_custody(): ) ), ) - assert selected_pre_submit_execution_budget_ms( - pre, artifact_deadline_ms=150_000 - ) == 150_000 + assert selected_pre_submit_execution_budget_ms(pre, artifact_deadline_ms=150_000) == 150_000 with pytest.raises(ExternalCheckerPolicyError, match="exceeds ART"): - selected_pre_submit_execution_budget_ms( - pre, artifact_deadline_ms=149_999 - ) + selected_pre_submit_execution_budget_ms(pre, artifact_deadline_ms=149_999) diff --git a/backend/tests/projects/guide_activation/source_fixtures.py b/backend/tests/projects/guide_activation/source_fixtures.py index cb09d9ce8..de354768e 100644 --- a/backend/tests/projects/guide_activation/source_fixtures.py +++ b/backend/tests/projects/guide_activation/source_fixtures.py @@ -45,6 +45,7 @@ async def create_compiled_guide( artifact_proposal=None, pre_submit_registry_entry=None, post_submit_registry_entry=None, + compilation_outcome=None, ): """Create declarations with real AUTH, then execute/project/finalize scripted findings.""" async with factory() as session, session.begin(): @@ -109,10 +110,8 @@ async def create_compiled_guide( values, guide_version=version, checker_capabilities=checker_capabilities, - ).model_copy( - update={"material": manifest} - ) - outcome = result() + ).model_copy(update={"material": manifest}) + outcome = compilation_outcome or result() if artifact_proposal is not None: outcome = outcome.model_copy(update={"submission_artifact_policy": artifact_proposal}) refs = tuple( @@ -124,7 +123,12 @@ async def create_compiled_guide( for item in manifest.documents ) outcome = outcome.model_copy( - update={"findings": (outcome.findings[0].model_copy(update={"evidence_refs": refs}),)} + update={ + field: tuple( + item.model_copy(update={"evidence_refs": refs}) for item in getattr(outcome, field) + ) + for field in ("findings", "requirements", "capability_suggestions") + } ) if registry_entries: from app.interfaces.project_agents import ( @@ -199,6 +203,7 @@ async def source_case( artifact_proposal=None, pre_submit_registry_spec=None, post_submit_registry_spec=None, + compilation_outcome=None, ): """An authorized draft Project plus a genuinely created complete guide source.""" engine = create_async_engine(url) @@ -206,15 +211,20 @@ async def source_case( try: if namespace is not None: from app.modules.artifacts.models import ArtifactStorageNamespace + async with factory() as session, session.begin(): existing = await session.get(ArtifactStorageNamespace, "primary") if existing is None: - session.add(ArtifactStorageNamespace( - id="primary", backend=namespace.backend, adapter=namespace.adapter, - provider_profile=namespace.provider_profile, - namespace_descriptor=namespace.namespace_descriptor, - namespace_fingerprint=namespace.namespace_fingerprint, - )) + session.add( + ArtifactStorageNamespace( + id="primary", + backend=namespace.backend, + adapter=namespace.adapter, + provider_profile=namespace.provider_profile, + namespace_descriptor=namespace.namespace_descriptor, + namespace_fingerprint=namespace.namespace_fingerprint, + ) + ) else: assert existing.namespace_fingerprint == namespace.namespace_fingerprint values = ids() @@ -238,11 +248,13 @@ async def source_case( actor, grant = await seed_review_actor(factory, values["project"]) pre_registry_entry = ( await _register_external_checker_fixture(factory, pre_submit_registry_spec) - if pre_submit_registry_spec is not None else None + if pre_submit_registry_spec is not None + else None ) post_registry_entry = ( await _register_external_checker_fixture(factory, post_submit_registry_spec) - if post_submit_registry_spec is not None else None + if post_submit_registry_spec is not None + else None ) async with current_art_attempt_seed_schema(url): values, finalization = await create_compiled_guide( @@ -253,6 +265,7 @@ async def source_case( artifact_proposal=artifact_proposal, pre_submit_registry_entry=pre_registry_entry, post_submit_registry_entry=post_registry_entry, + compilation_outcome=compilation_outcome, ) yield values, factory, finalization, actor, grant finally: diff --git a/backend/tests/projects/guide_activation/test_postgresql.py b/backend/tests/projects/guide_activation/test_postgresql.py index 2ced53190..6b5fe4e7e 100644 --- a/backend/tests/projects/guide_activation/test_postgresql.py +++ b/backend/tests/projects/guide_activation/test_postgresql.py @@ -11,6 +11,102 @@ from .pg_support import activation_case, activation_service +def _capability_outcome(*, supported): + """Return the same requirement before and after exact capability coverage.""" + from app.interfaces.project_agents import ( + AtomicGuideRequirement, + CapabilitySuggestion, + PreSubmissionBindingProposal, + ) + from tests.projects.guide_compilation.helpers import result + + outcome = result() + refs = outcome.findings[0].evidence_refs + requirement = AtomicGuideRequirement( + requirement_id="specialist_archive", + statement="Inspect the specialist archive before admission.", + disposition="supported_pre_submit" if supported else "pre_submit_capability_gap", + evidence_refs=refs, + ) + return outcome.model_copy( + update={ + "status": "draft_ready" if supported else "draft_ready_with_warnings", + "findings": ( + outcome.findings[0].model_copy( + update={ + "severity": "info" if supported else "warning", + "code": "guide.ready" if supported else "checker.capability_gap", + "message": ( + "Exact checker coverage is available." + if supported + else "Register and bind the required checker capability." + ), + } + ), + ), + "requirements": (requirement,), + "pre_submit_bindings": ( + PreSubmissionBindingProposal( + requirement_id=requirement.requirement_id, + capability_id="acme.safe_archive", + capability_version="v1.2.3", + stage="pre_submit", + ), + ) + if supported + else (), + "capability_suggestions": () + if supported + else ( + CapabilitySuggestion( + requirement_id=requirement.requirement_id, + stage="pre_submit", + title="Specialist archive checker", + rationale="The required immutable checker is not registered yet.", + evidence_refs=refs, + ), + ), + } + ) + + +async def _activation_inputs(factory, finalization, approval, actor, grant, values, policy): + """Approve the exact derived POST policy and return one activation command.""" + from app.core.hashing import canonical_json_hash + from app.modules.projects.api.guide_proposals import GuideProposalSelection + from app.modules.projects.api.post_policy import PostPolicyApproval + from app.modules.projects.api.post_policy import PostPolicyDerive + from tests.projects.guide_compilation.helpers import service_actor + from tests.projects.post_policy.pg_support import operate + from .pg_support import activation_command + + derived = await operate( + factory, + service_actor(values), + finalization.project_id, + None, + "derive", + PostPolicyDerive( + selection=GuideProposalSelection( + project_id=finalization.project_id, + guide_id=finalization.guide_id, + compilation_id=finalization.compilation_id, + ), + upstream_approval_operation_id=approval.operation_id, + upstream_approval_output_digest=canonical_json_hash(approval.model_dump(mode="json")), + ), + ) + approved = await operate( + factory, + actor, + finalization.project_id, + grant, + "approve", + PostPolicyApproval(target=derived.target, idempotency_key=uuid4()), + ) + return await activation_command(factory, approved, policy) + + async def test_complete_activation_and_exact_replay(clean_postgres_database): async with activation_case(clean_postgres_database) as ( factory, @@ -96,3 +192,89 @@ async def test_activation_default_authority_is_unavailable(clean_postgres_databa ) guide = await session.get(ProjectGuide, str(command.target.proposal.guide_id)) assert guide.status == "draft" and guide.activation_operation_id is None + + +async def test_checker_registration_requires_corrected_approval_before_activation( + clean_postgres_database, +): + """F-020 closes only after register, recompile, approve and exact activation.""" + from app.modules.projects.api.guide_proposals import ( + GuideProposalApproval, + GuideProposalCorrection, + ) + from tests.checkers.external.support import registry_spec + from tests.projects.guide_compilation.proposals.pg_support import ( + finalize_corrected_attempt, + read_package, + seed_selected_review_revision_inputs, + ) + from tests.projects.guide_compilation.proposals.test_postgresql import approve, correct + from .pg_support import publish_policy + from .source_fixtures import _register_external_checker_fixture, source_case + + gap, covered = _capability_outcome(supported=False), _capability_outcome(supported=True) + async with source_case( + clean_postgres_database, + compilation_outcome=gap, + ) as (values, factory, initial, actor, grant): + package = await read_package(factory, initial, actor, grant) + first = await approve( + factory, + initial, + actor, + grant, + GuideProposalApproval( + target=package.target, + acknowledged_warning_hashes=package.warning_hashes, + idempotency_key=uuid4(), + ), + ) + await _register_external_checker_fixture(factory, registry_spec("pre_submit")) + _, policy = await publish_policy(factory, initial.project_id) + await seed_selected_review_revision_inputs(factory, initial, actor) + stale = await _activation_inputs(factory, initial, first, actor, grant, values, policy) + async with factory() as session, session.begin(): + with pytest.raises(GuideProposalError, match="approval_blocked"): + await activation_service(session, actor, stale, grant).activate( + stale, actor=actor, request_id=uuid4() + ) + + correction = await correct( + factory, + initial, + actor, + grant, + GuideProposalCorrection( + target=package.target, + reason="Bind the registered checker to the required pre-admission stage.", + idempotency_key=uuid4(), + ), + ) + successor = await finalize_corrected_attempt( + factory, values, actor, correction, outcome=covered + ) + revised = await read_package(factory, successor, actor, grant) + second = await approve( + factory, + successor, + actor, + grant, + GuideProposalApproval( + target=revised.target, + expected_previous_approval_operation_id=first.operation_id, + expected_previous_approval_output_digest=revised.current_approval_output_digest, + idempotency_key=uuid4(), + ), + ) + assert second.pre_submit_bundle_hash != first.pre_submit_bundle_hash + command = await _activation_inputs(factory, successor, second, actor, grant, values, policy) + async with factory() as session, session.begin(): + receipt = await activation_service(session, actor, command, grant).activate( + command, actor=actor, request_id=uuid4() + ) + assert receipt.command.target.proposal.compilation_id == successor.compilation_id + async with factory() as session, session.begin(): + with pytest.raises(GuideProposalError, match="proposal_(stale|unavailable)"): + await activation_service(session, actor, stale, grant).activate( + stale, actor=actor, request_id=uuid4() + ) diff --git a/backend/tests/projects/guide_compilation/proposals/pg_support.py b/backend/tests/projects/guide_compilation/proposals/pg_support.py index 1a1729b47..13de3035f 100644 --- a/backend/tests/projects/guide_compilation/proposals/pg_support.py +++ b/backend/tests/projects/guide_compilation/proposals/pg_support.py @@ -227,7 +227,7 @@ async def read_package(factory, command, actor, grant_id): raise exc from exc.__context__ -async def request_corrected_attempt(factory, actor, correction): +async def request_corrected_attempt(factory, actor, correction, *, capabilities=None): """Enter the existing production human request port; no provider is invoked.""" from app.adapters.artifacts import guide_document_manifest_port from app.modules.authorization.guide_compilation import ( @@ -264,7 +264,7 @@ async def request_corrected_attempt(factory, actor, correction): ProjectGuideCompilationAuthorizationAdapter(kernel, prepared), request_inputs=CompilationRequestInputs( guide_document_manifest_port(session), - capability_projection(), + capabilities or capability_projection(), runtime_configuration(), ), ) @@ -273,7 +273,7 @@ async def request_corrected_attempt(factory, actor, correction): ) -async def finalize_corrected_attempt(factory, values, actor, correction): +async def finalize_corrected_attempt(factory, values, actor, correction, *, outcome=None): """Run a scripted result through actual execution, projections and finalization.""" from app.adapters.artifacts import guide_document_manifest_port from app.adapters.auth import ( @@ -294,12 +294,14 @@ async def finalize_corrected_attempt(factory, values, actor, correction): document_access, ) - await request_corrected_attempt(factory, actor, correction) + async with factory() as session, session.begin(): + capabilities = await external_checker_capability_projection(session) + await request_corrected_attempt(factory, actor, correction, capabilities=capabilities) async with factory() as session: setup = await session.get(ProjectSetupRun, str(correction.successor_setup_run_id)) runtime = ScriptedGuideRuntime() - async with factory() as session: - capabilities = await external_checker_capability_projection(session) + if outcome is not None: + runtime.outcome = outcome coordinator = project_guide_compilation_delivery_port( factory, material_factory=guide_document_manifest_port, From 0b9765d905637e63e83cd5664d5a5ffb447d34d3 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 00:20:59 +0100 Subject: [PATCH 135/283] [PILOT-04] prove selected checker end-to-end flow --- .../post_submit_materialization_helpers.py | 144 ++++++-- .../run_selected_end_to_end_probe.py | 340 ++++++++++++++++++ 2 files changed, 446 insertions(+), 38 deletions(-) create mode 100644 experiments/pilot04_external_checker_runtime/run_selected_end_to_end_probe.py diff --git a/backend/tests/post_submit_materialization_helpers.py b/backend/tests/post_submit_materialization_helpers.py index abd1aae29..07f806195 100644 --- a/backend/tests/post_submit_materialization_helpers.py +++ b/backend/tests/post_submit_materialization_helpers.py @@ -17,7 +17,10 @@ from app.modules.artifacts.models import SubmissionBundleAdmission from app.modules.artifacts.preparation import ArtifactPreparationService, ArtifactScratchManager from app.modules.artifacts.service import artifact_storage_namespace_spec -from app.modules.artifacts.submission_archive import SubmissionArchiveInspector, SubmissionArchiveLimits +from app.modules.artifacts.submission_archive import ( + SubmissionArchiveInspector, + SubmissionArchiveLimits, +) from app.modules.artifacts.submission_manifest import build_submission_manifest from app.modules.authorization.api import ActorIdentityFacts, ActorKind from app.modules.tasks.api import SubmissionCreationRequest @@ -61,6 +64,7 @@ def archive_with_modes(evidence_path, project_id): async def provision_material_services(factory, *, artifacts, checker): """Provision only the fixed identities present in the schema under test.""" from tests.checkers.execution.support import provision_post_submit_service + if artifacts: await _seed_services(factory) if checker: @@ -74,6 +78,7 @@ def _archive_facts(data): with zipfile.ZipFile(BytesIO(data)) as archive: files = {name: archive.read(name) for name in archive.namelist() if not name.endswith("/")} import hashlib + digest = "sha256:" + hashlib.sha256(data).hexdigest() return inspector, manifest, files, digest @@ -81,14 +86,20 @@ def _archive_facts(data): async def _write_current_submission(factory, context, request): async with factory() as session: return await compose_hidden_submission_creation_command( - session, context, request_id=new_record_id(), correlation_id=new_record_id(), + session, + context, + request_id=new_record_id(), + correlation_id=new_record_id(), ).create(request) async def _read_current_request(session, facts, created, data): from app.adapters.checkers import evaluation_coordinator + stored = await evaluation_coordinator(session).read_reserved_evaluation( - project_id=facts.project_id, task_id=facts.task_id, submission_id=created.submission_id, + project_id=facts.project_id, + task_id=facts.task_id, + submission_id=created.submission_id, request_id=created.evaluation_request_id, ) return stored.request @@ -98,8 +109,11 @@ async def _read_current_request(session, facts, created, data): async def material_fixture(tmp_path, database_url, **options): """Current canonical creation always commits its own exact initial request.""" async with _material_fixture( - tmp_path, database_url, write_submission=_write_current_submission, - read_request=_read_current_request, **options, + tmp_path, + database_url, + write_submission=_write_current_submission, + read_request=_read_current_request, + **options, ) as material: yield material @@ -118,7 +132,9 @@ async def _material_fixture( provision_checker=True, contribution_awards=(), human_review_required=True, + pre_submit_registry_spec=None, post_submit_registry_spec=None, + post_scratch_root=None, ): engine = create_async_engine(database_url) factory = async_sessionmaker(engine, expire_on_commit=False) @@ -126,11 +142,14 @@ async def _material_fixture( settings = storage_settings elif provider == "minio": from tests.test_s3_artifact_store import minio_settings - settings = minio_settings(private_prefix=f"material/{new_record_id()}").model_copy(update={ - **artifact_admission_limit_settings(1024 * 1024), - "artifact_scratch_root": tmp_path / "intake-scratch", - "artifact_scratch_minimum_free_bytes": 0, - }) + + settings = minio_settings(private_prefix=f"material/{new_record_id()}").model_copy( + update={ + **artifact_admission_limit_settings(1024 * 1024), + "artifact_scratch_root": tmp_path / "intake-scratch", + "artifact_scratch_minimum_free_bytes": 0, + } + ) else: settings = _settings( tmp_path, @@ -139,10 +158,18 @@ async def _material_fixture( ) bootstrap = create_artifact_store_bootstrap(settings) namespace = artifact_storage_namespace_spec(settings, bootstrap) - store = bootstrap.initialize_after_namespace_claim(ArtifactStoreNamespaceClaim( - bootstrap.identity, bootstrap.namespace_identity, namespace.namespace_fingerprint, - )) - manager = ArtifactScratchManager(root=tmp_path / "post-scratch", limits=scratch_limits if scratch_limits is not None else _limits()) + store = bootstrap.initialize_after_namespace_claim( + ArtifactStoreNamespaceClaim( + bootstrap.identity, + bootstrap.namespace_identity, + namespace.namespace_fingerprint, + ) + ) + scratch = post_scratch_root or tmp_path / "post-scratch" + manager = ArtifactScratchManager( + root=scratch, + limits=scratch_limits if scratch_limits is not None else _limits(), + ) try: plan, policy = await approved_selected_policy_fixture( factory, @@ -150,39 +177,63 @@ async def _material_fixture( guide_version="v1", contribution_awards=contribution_awards, human_review_required=human_review_required, + pre_submit_registry_spec=pre_submit_registry_spec, post_submit_registry_spec=post_submit_registry_spec, ) context = _context() - await provision_material_services(factory, artifacts=provision_services, checker=provision_checker) + await provision_material_services( + factory, artifacts=provision_services, checker=provision_checker + ) task_id, assignment_id = new_record_id(), new_record_id() async with factory.begin() as session: await _seed_human_actor(session, context) async with engine.begin() as connection: - params = dict(task=str(task_id), assignment=str(assignment_id), - project=str(plan.lineage.project_id), actor=str(context.actor_profile_id)) + params = dict( + task=str(task_id), + assignment=str(assignment_id), + project=str(plan.lineage.project_id), + actor=str(context.actor_profile_id), + ) await seed_started_task_for_artifact_test(connection, params) await install_submitter_grant(connection, params) data = archive_with_modes(policy["evidence_path"], plan.lineage.project_id) preparation_request = SubmissionBundlePreparationRequest( - actor=ActorIdentityFacts(context.actor_profile_id, context.identity_link_id, ActorKind.HUMAN), - request_id=context.request_id, correlation_id=context.correlation_id, - task_id=task_id, assignment_id=assignment_id, predecessor_submission_id=None, - idempotency_key=new_record_id(), summary="Completed the required project work and included evidence.", - contributor_attestation="I confirm no confidential client data, credentials, or copied source material is included in this submission; rights_confirmed. " + " ".join(policy["attestation_terms"]), - media_type="application/zip", byte_source=_bytes(data), + actor=ActorIdentityFacts( + context.actor_profile_id, context.identity_link_id, ActorKind.HUMAN + ), + request_id=context.request_id, + correlation_id=context.correlation_id, + task_id=task_id, + assignment_id=assignment_id, + predecessor_submission_id=None, + idempotency_key=new_record_id(), + summary="Completed the required project work and included evidence.", + contributor_attestation="I confirm no confidential client data, credentials, or copied source material is included in this submission; rights_confirmed. " + + " ".join(policy["attestation_terms"]), + media_type="application/zip", + byte_source=_bytes(data), + ) + admission_id = await _verified_admission( + factory, store, namespace, settings, context, preparation_request ) - admission_id = await _verified_admission(factory, store, namespace, settings, context, preparation_request) creation_request = SubmissionCreationRequest( - task_id=task_id, assignment_id=assignment_id, contributor_id=context.actor_profile_id, - predecessor_submission_id=None, admission_id=admission_id, + task_id=task_id, + assignment_id=assignment_id, + contributor_id=context.actor_profile_id, + predecessor_submission_id=None, + admission_id=admission_id, summary=preparation_request.summary, contributor_attestation=preparation_request.contributor_attestation, ) created = await write_submission(factory, context, creation_request) async with factory() as session: - facts = await submitted_bundle_port(session).read(SubmittedBundleRequest( - plan.lineage.project_id, task_id, created.submission_id, - )) + facts = await submitted_bundle_port(session).read( + SubmittedBundleRequest( + plan.lineage.project_id, + task_id, + created.submission_id, + ) + ) admission = await session.get(SubmissionBundleAdmission, str(admission_id)) replica_id = UUID(admission.verified_replica_id) request = await read_request(session, facts, created, data) @@ -190,16 +241,33 @@ async def _material_fixture( counted = CountedStore(store) preparation = ArtifactPreparationService(manager) service = post_submission_materialization( - sessions=factory, store=counted, namespace=namespace, - preparation=preparation, inspector=inspector, + sessions=factory, + store=counted, + namespace=namespace, + preparation=preparation, + inspector=inspector, + ) + yield SimpleNamespace( + replica_id=replica_id, + service=service, + factory=factory, + engine=engine, + request=request, + created=created, + facts=facts, + files=files, + data=data, + manifest=manifest, + actor_context=context, + creation_request=creation_request, + settings=settings, + store=counted, + namespace=namespace, + preparation=preparation, + manager=manager, + inspector=inspector, + scratch=scratch, ) - yield SimpleNamespace(replica_id=replica_id, service=service, factory=factory, engine=engine, request=request, - created=created, facts=facts, files=files, data=data, manifest=manifest, - actor_context=context, creation_request=creation_request, - settings=settings, - store=counted, namespace=namespace, preparation=preparation, - manager=manager, inspector=inspector, - scratch=tmp_path / "post-scratch") finally: manager.close() bootstrap.close() diff --git a/experiments/pilot04_external_checker_runtime/run_selected_end_to_end_probe.py b/experiments/pilot04_external_checker_runtime/run_selected_end_to_end_probe.py new file mode 100644 index 000000000..1817593cb --- /dev/null +++ b/experiments/pilot04_external_checker_runtime/run_selected_end_to_end_probe.py @@ -0,0 +1,340 @@ +"""Run selected PRE, atomic Submission and selected POST through one Rust service.""" + +from __future__ import annotations + +import argparse +import asyncio +import json +import os +from pathlib import Path +import subprocess +import tempfile +from io import BytesIO +from types import SimpleNamespace +from zipfile import ZipFile, ZipInfo + +from aiobotocore.config import AioConfig +from aiobotocore.session import AioSession +from sqlalchemy import func, select +from starlette.requests import Request + +from app.adapters.artifacts import ( + artifact_preparation_limits, + create_artifact_scratch_manager, + get_submission_bundle_preparation_command, +) +from app.adapters.checkers import external_checker_execution_factory +from app.core.identifiers import new_record_id +from app.modules.actors.api.service_identities import ServiceIdentity +from app.modules.artifacts.api import ( + SubmissionBundlePreparationCheckFailed, + SubmissionBundlePreparationRequest, +) +from app.modules.artifacts.authorization import ( + PreparedArtifactInternalAuthority, + PreparedSubmissionBundlePreparationAuthorization, +) +from app.modules.authorization.api import ActorIdentityFacts, ActorKind +from app.modules.checkers.api.external import ExternalCheckerRegistrySpec +from app.modules.checkers.models import CheckerRun +from app.modules.tasks.models import Submission, WorkstreamTask +from experiments.pilot04_external_checker_runtime.run_probe import _image_identity +from tests.artifact_store_helpers import artifact_admission_limit_settings +from tests.checkers.execution.support import live_executor, reserve +from tests.checkers.external.test_selected_post_submit import _post_spec +from tests.checkers.external.test_selected_pre_submit import _policy +from tests.archive_fixtures import byte_source +from tests.post_submit_materialization_helpers import material_fixture +from tests.tasks.lineage_fixtures import seed_started_task_for_artifact_test +from tests.test_s3_artifact_store import ( + MINIO_ACCESS_KEY, + MINIO_ENDPOINT, + MINIO_REGION, + MINIO_SECRET_KEY, + minio_settings, +) + + +def _locked_spec(phase: str, image: dict[str, str]) -> ExternalCheckerRegistrySpec: + source = _policy().entries[0].registry if phase == "pre_submit" else _post_spec() + values = source.model_dump( + mode="json", + exclude={ + "registry_entry_id", + "entry_digest", + "registration_operation_id", + "registered_by_actor_profile_id", + "authorization_decision_event_id", + "created_at", + }, + ) + values["image_digest"] = image["platform_manifest_digest"] + values["resources"] |= {"deadline_ms": 8_000, "maximum_output_bytes": 8_192} + return ExternalCheckerRegistrySpec.model_validate(values) + + +async def _bucket_client(): + session = AioSession() + session.set_credentials(MINIO_ACCESS_KEY, MINIO_SECRET_KEY) + return session.create_client( + "s3", + endpoint_url=MINIO_ENDPOINT, + region_name=MINIO_REGION, + config=AioConfig(s3={"addressing_style": "path"}), + ) + + +async def _delete_bucket(bucket: str) -> None: + async with await _bucket_client() as client: + values = await client.list_objects_v2(Bucket=bucket) + objects = [{"Key": item["Key"]} for item in values.get("Contents", ())] + if objects: + await client.delete_objects(Bucket=bucket, Delete={"Objects": objects}) + await client.delete_bucket(Bucket=bucket) + + +def _secret_archive(source: bytes) -> bytes: + """Preserve the valid packet while introducing one known private key.""" + output = BytesIO() + with ZipFile(BytesIO(source)) as existing, ZipFile(output, "w") as target: + for item in existing.infolist(): + value = existing.read(item) + if item.filename == "task.toml": + value += b"\n-----BEGIN OPENSSH PRIVATE KEY-----\nencoded\n" + copy = ZipInfo(item.filename, date_time=(1980, 1, 1, 0, 0, 0)) + copy.create_system, copy.external_attr = ( + item.create_system, + item.external_attr, + ) + target.writestr(copy, value) + return output.getvalue() + + +async def _prepare(fixture, settings, request): + """Enter the actual hidden PRE composition with no owner bypass.""" + http = Request( + { + "type": "http", + "headers": [], + "app": SimpleNamespace(state=SimpleNamespace(settings=settings)), + } + ) + async with fixture.factory() as session: + authority = PreparedArtifactInternalAuthority( + session, + service_identity=ServiceIdentity.ARTIFACT_PUT_RESOLVER, + request_id=new_record_id(), + correlation_id=new_record_id(), + ) + return await get_submission_bundle_preparation_command( + http, + session, + authority, + PreparedSubmissionBundlePreparationAuthorization( + session, fixture.actor_context + ), + ).prepare(request) + + +async def _prove_work_failure(fixture, settings) -> dict[str, object]: + """A default-check failure leaves a separate Task in progress.""" + task_id, assignment_id = new_record_id(), new_record_id() + params = { + "task": str(task_id), + "assignment": str(assignment_id), + "project": str(fixture.facts.project_id), + "actor": str(fixture.actor_context.actor_profile_id), + } + async with fixture.engine.begin() as connection: + await seed_started_task_for_artifact_test(connection, params) + request = SubmissionBundlePreparationRequest( + actor=ActorIdentityFacts( + fixture.actor_context.actor_profile_id, + fixture.actor_context.identity_link_id, + ActorKind.HUMAN, + ), + request_id=new_record_id(), + correlation_id=new_record_id(), + task_id=task_id, + assignment_id=assignment_id, + predecessor_submission_id=None, + idempotency_key=new_record_id(), + summary=fixture.creation_request.summary, + contributor_attestation=fixture.creation_request.contributor_attestation, + media_type="application/zip", + byte_source=byte_source(_secret_archive(fixture.data)), + ) + try: + await _prepare(fixture, settings, request) + except SubmissionBundlePreparationCheckFailed as error: + codes = tuple( + check.failure_code + for check in error.facts.workstream_default.checks + if check.failure_code is not None + ) + else: + raise RuntimeError("secret-bearing input unexpectedly passed selected PRE") + async with fixture.factory() as session: + task = await session.get(WorkstreamTask, str(task_id)) + submissions = await session.scalar(select(func.count()).select_from(Submission)) + if task.status != "in_progress" or submissions != 1: + raise RuntimeError("work finding created a Submission or advanced its Task") + return { + "task_id": str(task_id), + "failure_codes": codes, + "submission_count": submissions, + } + + +async def run( + *, database_url: str, image_reference: str, service_binary: Path, root: Path +) -> dict[str, object]: + """Prove actual image execution on both sides of atomic Submission creation.""" + image = _image_identity(image_reference) + bucket = "ws-p04-e2e-" + os.urandom(8).hex() + socket_root, scratch = root / "service", root / "scratch" + socket_root.mkdir(mode=0o700) + scratch.mkdir(mode=0o700) + socket_path = socket_root / "checker.sock" + settings = minio_settings( + private_prefix="selected-flow", + ).model_copy( + update={ + **artifact_admission_limit_settings(1024 * 1024), + "artifact_s3_bucket": bucket, + "artifact_scratch_root": scratch, + "artifact_scratch_minimum_free_bytes": 0, + "external_checker_service_socket": socket_path, + "external_checker_material_root": scratch, + "external_checker_service_timeout_seconds": 90.0, + } + ) + config = { + "socket_path": str(socket_path), + "material_root": str(scratch), + "docker_binary": "/usr/bin/docker", + "runtime": "runc", + "isolation_mode": "docker-dev", + "operating_system": image["operating_system"], + "architecture": image["architecture"], + "sandbox_uid": os.getuid(), + "sandbox_gid": os.getgid(), + "cache": [image], + } + config_path = socket_root / "service.json" + config_path.write_text(json.dumps(config, separators=(",", ":"))) + scratch_owner = create_artifact_scratch_manager(settings) + scratch_owner.close() + async with await _bucket_client() as client: + await client.create_bucket(Bucket=bucket) + service = subprocess.Popen( + [str(service_binary), str(config_path)], + stdout=subprocess.DEVNULL, + stderr=subprocess.PIPE, + text=True, + ) + try: + for _ in range(500): + if socket_path.exists(): + break + if service.poll() is not None: + raise RuntimeError("checker service exited before readiness") + await asyncio.sleep(0.02) + else: + raise RuntimeError("checker service socket did not become ready") + adapter = external_checker_execution_factory( + socket_path=socket_path, timeout_seconds=90.0 + ).create("unix_socket") + health = await adapter.health() + async with material_fixture( + root, + database_url, + storage_settings=settings, + pre_submit_registry_spec=_locked_spec("pre_submit", image), + post_submit_registry_spec=_locked_spec("post_submit", image), + post_scratch_root=scratch, + scratch_limits=artifact_preparation_limits(settings), + ) as fixture: + await reserve(fixture) + result = await live_executor( + fixture, selected_execution=adapter + ).evaluate_post_submission(fixture.request) + async with fixture.factory() as session: + task = await session.get(WorkstreamTask, str(fixture.facts.task_id)) + submission_count = await session.scalar( + select(func.count()).select_from(Submission) + ) + run_row = await session.get(CheckerRun, str(result.attempt_id)) + if ( + submission_count != 1 + or task.status != "evaluation_pending" + or result.outcome != "completed" + or result.execution is None + or len(result.execution.external_members) != 1 + or run_row.status != "completed" + ): + raise RuntimeError("selected flow did not retain its atomic boundaries") + member = result.execution.external_members[0] + if ( + member.result.verdict != "passed" + or member.isolation.platform_manifest_digest + != image["platform_manifest_digest"] + ): + raise RuntimeError("selected POST result or isolation differs") + workspaces = scratch / "workspaces" + workspace_cleanup = not workspaces.exists() or not any(workspaces.iterdir()) + if not workspace_cleanup: + raise RuntimeError("selected checker workspace cleanup is incomplete") + work_failure = await _prove_work_failure(fixture, settings) + return { + "image": image, + "health": { + "runtime": health.runtime, + "isolation_mode": health.isolation_mode, + }, + "submission_id": str(fixture.created.submission_id), + "evaluation_request_id": str(fixture.created.evaluation_request_id), + "attempt_id": str(result.attempt_id), + "post_result_digest": result.result_digest, + "post_member_result_digest": member.result.result_digest, + "task_status": task.status, + "submission_count": submission_count, + "workspace_cleanup": workspace_cleanup, + "work_failure": work_failure, + "minio_bucket": bucket, + } + finally: + service.terminate() + try: + service.wait(timeout=5) + except subprocess.TimeoutExpired: + service.kill() + service.wait(timeout=5) + await _delete_bucket(bucket) + + +def main() -> int: + parser = argparse.ArgumentParser() + parser.add_argument( + "--database-url", default=os.environ.get("WORKSTREAM_TEST_DATABASE_URL") + ) + parser.add_argument("--image-reference", required=True) + parser.add_argument("--service-binary", required=True, type=Path) + args = parser.parse_args() + if not args.database_url: + parser.error("--database-url or WORKSTREAM_TEST_DATABASE_URL is required") + with tempfile.TemporaryDirectory(prefix="ws-pilot04-selected-e2e-") as directory: + value = asyncio.run( + run( + database_url=args.database_url, + image_reference=args.image_reference, + service_binary=args.service_binary, + root=Path(directory), + ) + ) + print(json.dumps(value, sort_keys=True, separators=(",", ":"))) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) From 6e999e479e7d999dc5532c1efa18229e220d068b Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 00:44:06 +0100 Subject: [PATCH 136/283] [PILOT-04] prove recoverable checker infrastructure failure --- .../run_selected_end_to_end_probe.py | 271 ++++++++++++++++-- 1 file changed, 248 insertions(+), 23 deletions(-) diff --git a/experiments/pilot04_external_checker_runtime/run_selected_end_to_end_probe.py b/experiments/pilot04_external_checker_runtime/run_selected_end_to_end_probe.py index 1817593cb..1f37af6f6 100644 --- a/experiments/pilot04_external_checker_runtime/run_selected_end_to_end_probe.py +++ b/experiments/pilot04_external_checker_runtime/run_selected_end_to_end_probe.py @@ -11,6 +11,7 @@ import tempfile from io import BytesIO from types import SimpleNamespace +from uuid import UUID from zipfile import ZipFile, ZipInfo from aiobotocore.config import AioConfig @@ -24,20 +25,29 @@ get_submission_bundle_preparation_command, ) from app.adapters.checkers import external_checker_execution_factory +from app.api.deps.authorization import compose_hidden_submission_creation_command from app.core.identifiers import new_record_id from app.modules.actors.api.service_identities import ServiceIdentity from app.modules.artifacts.api import ( SubmissionBundlePreparationCheckFailed, + SubmissionBundlePreparationInfrastructureUnavailable, SubmissionBundlePreparationRequest, + SubmissionBundlePreparationStatus, ) +from app.modules.artifacts.models import ( + ArtifactVerificationJob, + SubmissionBundleAdmission, +) +from app.modules.artifacts.service import ArtifactStorageOrchestrator from app.modules.artifacts.authorization import ( PreparedArtifactInternalAuthority, PreparedSubmissionBundlePreparationAuthorization, ) from app.modules.authorization.api import ActorIdentityFacts, ActorKind from app.modules.checkers.api.external import ExternalCheckerRegistrySpec -from app.modules.checkers.models import CheckerRun -from app.modules.tasks.models import Submission, WorkstreamTask +from app.modules.checkers.models import CheckerRun, SelectedPreSubmitRun +from app.modules.tasks.api import SubmissionCreationRequest +from app.modules.tasks.models import Submission, SubmissionDispatch, WorkstreamTask from experiments.pilot04_external_checker_runtime.run_probe import _image_identity from tests.artifact_store_helpers import artifact_admission_limit_settings from tests.checkers.execution.support import live_executor, reserve @@ -69,7 +79,7 @@ def _locked_spec(phase: str, image: dict[str, str]) -> ExternalCheckerRegistrySp }, ) values["image_digest"] = image["platform_manifest_digest"] - values["resources"] |= {"deadline_ms": 8_000, "maximum_output_bytes": 8_192} + values["resources"] |= {"deadline_ms": 30_000, "maximum_output_bytes": 8_192} return ExternalCheckerRegistrySpec.model_validate(values) @@ -186,6 +196,228 @@ async def _prove_work_failure(fixture, settings) -> dict[str, object]: } +def _start_service(binary: Path, config_path: Path, socket_path: Path): + """Start only the private checker service and wait for its UDS endpoint.""" + socket_path.unlink(missing_ok=True) + return subprocess.Popen( + [str(binary), str(config_path)], + stdout=subprocess.DEVNULL, + stderr=subprocess.PIPE, + text=True, + ) + + +async def _wait_service(service, socket_path: Path) -> None: + for _ in range(500): + if socket_path.exists(): + return + if service.poll() is not None: + detail = service.stderr.read().strip() if service.stderr is not None else "" + raise RuntimeError( + f"checker service exited before readiness: {detail or 'no stderr'}" + ) + await asyncio.sleep(0.02) + raise RuntimeError("checker service socket did not become ready") + + +def _stop_service(service) -> None: + if service.poll() is not None: + return + service.terminate() + try: + service.wait(timeout=5) + except subprocess.TimeoutExpired: + service.kill() + service.wait(timeout=5) + + +def _request(fixture, task_id, assignment_id, data: bytes): + return SubmissionBundlePreparationRequest( + actor=ActorIdentityFacts( + fixture.actor_context.actor_profile_id, + fixture.actor_context.identity_link_id, + ActorKind.HUMAN, + ), + request_id=new_record_id(), + correlation_id=new_record_id(), + task_id=task_id, + assignment_id=assignment_id, + predecessor_submission_id=None, + idempotency_key=new_record_id(), + summary=fixture.creation_request.summary, + contributor_attestation=fixture.creation_request.contributor_attestation, + media_type="application/zip", + byte_source=byte_source(data), + ) + + +async def _verify_prepared(fixture, settings, prepared): + """Run the independent ART verifier for one freshly uploaded preparation.""" + async with fixture.factory() as session: + job_id = await session.scalar( + select(ArtifactVerificationJob.id).where( + ArtifactVerificationJob.originating_put_attempt_id + == str(prepared.put_attempt_id) + ) + ) + if job_id is None: + raise RuntimeError("fresh preparation did not enqueue verification") + await session.rollback() + verifier = PreparedArtifactInternalAuthority( + session, + service_identity=ServiceIdentity.ARTIFACT_VERIFIER, + request_id=new_record_id(), + correlation_id=new_record_id(), + ) + outcome = await ArtifactStorageOrchestrator( + session, fixture.store, fixture.namespace, settings, verifier + ).verify_object(UUID(job_id)) + if outcome != "verified": + raise RuntimeError("fresh preparation verification did not complete") + async with fixture.factory() as session: + admission = ( + await session.scalars( + select(SubmissionBundleAdmission).where( + SubmissionBundleAdmission.put_attempt_id + == str(prepared.put_attempt_id) + ) + ) + ).one() + if admission.status != "ready": + raise RuntimeError("fresh preparation admission is not ready") + return UUID(admission.id) + + +async def _prove_infrastructure_recovery( + fixture, settings, service_holder, service_binary, config_path, socket_path +): + """Retain infrastructure failure, then require a fresh successful upload.""" + task_id, assignment_id = new_record_id(), new_record_id() + params = { + "task": str(task_id), + "assignment": str(assignment_id), + "project": str(fixture.facts.project_id), + "actor": str(fixture.actor_context.actor_profile_id), + } + async with fixture.engine.begin() as connection: + await seed_started_task_for_artifact_test(connection, params) + _stop_service(service_holder[0]) + try: + await _prepare( + fixture, settings, _request(fixture, task_id, assignment_id, fixture.data) + ) + except SubmissionBundlePreparationInfrastructureUnavailable as error: + failure_code = str(error) + else: + raise RuntimeError("unavailable checker service did not fail preparation") + async with fixture.factory() as session: + task = await session.get(WorkstreamTask, str(task_id)) + before_submissions = await session.scalar( + select(func.count()).select_from(Submission) + ) + failed = ( + ( + await session.execute( + select(SelectedPreSubmitRun) + .where(SelectedPreSubmitRun.task_id == str(task_id)) + .order_by(SelectedPreSubmitRun.queued_at) + ) + ) + .scalars() + .all() + ) + if ( + task.status != "in_progress" + or before_submissions != 1 + or len(failed) != 1 + or failed[0].status != "infrastructure_failed" + ): + raise RuntimeError("infrastructure failure changed TASK or was not retained") + service = _start_service(service_binary, config_path, socket_path) + service_holder[0] = service + await _wait_service(service, socket_path) + recovered = await _prepare( + fixture, + settings, + _request(fixture, task_id, assignment_id, fixture.data), + ) + if recovered.replayed: + raise RuntimeError( + "fresh preparation did not recover infrastructure failure: " + f"status={recovered.submission_bundle_preparation_status}, " + f"admission={recovered.admission_id}, replayed={recovered.replayed}" + ) + if ( + recovered.submission_bundle_preparation_status + == SubmissionBundlePreparationStatus.STORED_PENDING_VERIFICATION + and recovered.admission_id is None + ): + admission_id = await _verify_prepared(fixture, settings, recovered) + elif ( + recovered.submission_bundle_preparation_status + == SubmissionBundlePreparationStatus.READY + and recovered.admission_id is not None + ): + admission_id = recovered.admission_id + else: + raise RuntimeError( + "fresh preparation returned an invalid durable state: " + f"status={recovered.submission_bundle_preparation_status}, " + f"admission={recovered.admission_id}" + ) + async with fixture.factory() as session: + created = await compose_hidden_submission_creation_command( + session, + fixture.actor_context, + request_id=new_record_id(), + correlation_id=new_record_id(), + ).create( + SubmissionCreationRequest( + task_id=task_id, + assignment_id=assignment_id, + contributor_id=fixture.actor_context.actor_profile_id, + predecessor_submission_id=None, + admission_id=admission_id, + summary=fixture.creation_request.summary, + contributor_attestation=fixture.creation_request.contributor_attestation, + ) + ) + async with fixture.factory() as session: + task = await session.get(WorkstreamTask, str(task_id)) + submission_count = await session.scalar( + select(func.count()).select_from(Submission) + ) + dispatch_count = await session.scalar( + select(func.count()).select_from(SubmissionDispatch) + ) + runs = ( + ( + await session.execute( + select(SelectedPreSubmitRun.status) + .where(SelectedPreSubmitRun.task_id == str(task_id)) + .order_by(SelectedPreSubmitRun.queued_at) + ) + ) + .scalars() + .all() + ) + if ( + task.status != "evaluation_pending" + or submission_count != 2 + or dispatch_count != 2 + or tuple(runs) != ("infrastructure_failed", "completed") + ): + raise RuntimeError("fresh recovery did not commit one atomic dispatch") + return { + "failure_code": failure_code, + "retained_run_statuses": runs, + "submission_id": str(created.submission_id), + "evaluation_request_id": str(created.evaluation_request_id), + "submission_count": submission_count, + "dispatch_count": dispatch_count, + } + + async def run( *, database_url: str, image_reference: str, service_binary: Path, root: Path ) -> dict[str, object]: @@ -227,21 +459,10 @@ async def run( scratch_owner.close() async with await _bucket_client() as client: await client.create_bucket(Bucket=bucket) - service = subprocess.Popen( - [str(service_binary), str(config_path)], - stdout=subprocess.DEVNULL, - stderr=subprocess.PIPE, - text=True, - ) + service = _start_service(service_binary, config_path, socket_path) + service_holder = [service] try: - for _ in range(500): - if socket_path.exists(): - break - if service.poll() is not None: - raise RuntimeError("checker service exited before readiness") - await asyncio.sleep(0.02) - else: - raise RuntimeError("checker service socket did not become ready") + await _wait_service(service, socket_path) adapter = external_checker_execution_factory( socket_path=socket_path, timeout_seconds=90.0 ).create("unix_socket") @@ -286,6 +507,14 @@ async def run( if not workspace_cleanup: raise RuntimeError("selected checker workspace cleanup is incomplete") work_failure = await _prove_work_failure(fixture, settings) + infrastructure_recovery = await _prove_infrastructure_recovery( + fixture, + settings, + service_holder, + service_binary, + config_path, + socket_path, + ) return { "image": image, "health": { @@ -301,15 +530,11 @@ async def run( "submission_count": submission_count, "workspace_cleanup": workspace_cleanup, "work_failure": work_failure, + "infrastructure_recovery": infrastructure_recovery, "minio_bucket": bucket, } finally: - service.terminate() - try: - service.wait(timeout=5) - except subprocess.TimeoutExpired: - service.kill() - service.wait(timeout=5) + _stop_service(service_holder[0]) await _delete_bucket(bucket) From 2dec7c3943d609671d710d35f946d1ca7010fca4 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 00:45:39 +0100 Subject: [PATCH 137/283] [PILOT-04] record end-to-end checker proof --- .../pilot04-workstream-default-checker.md | 68 ++++++++----------- 1 file changed, 28 insertions(+), 40 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 278cf8c9b..de7993a72 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -19,31 +19,15 @@ initial post-submit dispatch. Post-submit images produce evidence only. This branch contains the normalized external contract, immutable registry, long-lived Rust service and SDK, typed Unix-socket client, callback-scoped ART -grant, and the exact four-behavior Workstream default checker. The selected PRE -processor now runs the default before each locked external image over one -genuine prepared-ART callback, but its durable result and admission caller are -not selected yet. The admission binder now carries an unchanged byte/manifest -comparison into the default checker with exact predecessor and current locked -rules instead of treating that default behavior as an early ART rejection. -The selected result contract now has one canonical digest over the default, -ordered external results and observed isolation, plus a database-timed lease -and terminal latency body suitable for the durable owner. Its reservation -digest binds the contributor identity, TASK/assignment, genuine ART attempt -and prepared generation, approved policy/default, complete default input and -server-owned archive/manifest identity before the lease is issued. -The selected durable owner is now modeled separately from the retained legacy -evidence decoder: its UUIDv7 run identifier is the genuine PRE attempt identity, -so selection does not reserve through or foreign-key to the obsolete invocation -store. The coordinator takes TASK custody before CHECKERS state, issues a -database-timed generation lease, finalizes one terminal body, and mints a -process-local one-use admission capability only for a complete pass. Its -ordered work budget is derived from the default plus each locked image deadline -and service cleanup margin and must fit ART's configured custody deadline. -The selected execution workflow now prepares fixed-service authority before -TASK/CHECKERS locks, commits the database-timed lease before exposing material, -executes through one exact process-local ART capability with no transaction -open, then uses a distinct short root to authorize and finalize the exact result -or one closed recoverable infrastructure outcome. +grant, and the exact four-behavior Workstream default checker. ART verifies the +received ZIP and canonical manifest before the default and every locked PRE +image run over one genuine prepared-material capability. The selected durable +owner takes TASK custody before CHECKERS state, commits its generation lease +before execution, runs without a database transaction, and finalizes either the +exact result or one recoverable infrastructure outcome in a fresh short root. +Only a complete pass mints the one-use admission capability consumed by TASK's +existing atomic Submission, `evaluation_pending`, evaluation reservation and +outbox operation. Work findings retain bounded evidence without a Submission. Its closed AUTH contract now assigns those two phases to the dedicated selected PRE service principal and binds preparation, scope, the durable request and the exact execute/finalize fact digest without granting direct service access. @@ -66,7 +50,10 @@ tests have been removed; retained immutable evidence has only its bounded historical decoder. F-020 recovery now proves that registration alone cannot activate the retained warning-bearing generation and that only an exact registered binding in a corrected, linked approval can activate. The combined -public/native journey remains unfinished. +native journey now exercises real PostgreSQL 16, MinIO, the Rust service and the +digest-pinned image across pass, work-failure, infrastructure/restart/fresh +verification and POST evidence paths with database, object-store and workspace +cleanup. ## Bounded change @@ -177,27 +164,27 @@ intermediate-wait regression. - [x] F-020 recovery is proven by register -> recompile -> approve -> activate in one current generation; registration alone and wrong generation, stage, requirement, registry digest or stale approval remain blocked. -- [ ] ART verifies server receipt identity and a bounded safe manifest before +- [x] ART verifies server receipt identity and a bounded safe manifest before any project image reads material. -- [ ] The default checker runs exactly four blockers; absent summary and +- [x] The default checker runs exactly four blockers; absent summary and attestation remain warning-only. -- [ ] Every required pre image passes before admission consumption. Work +- [x] Every required pre image passes before admission consumption. Work findings create no Submission/dispatch and keep the task `in_progress`; infrastructure failures remain recoverable and consume no attempt. -- [ ] Passing preparation invokes the existing caller-owned atomic operation +- [x] Passing preparation invokes the existing caller-owned atomic operation and commits Submission, `evaluation_pending` and initial dispatch together. -- [ ] Required post images consume immutable Submission custody, persist +- [x] Required post images consume immutable Submission custody, persist normalized evidence and never decide acceptance. -- [ ] Timeout, cancellation, crash/restart, changed policy/material, +- [x] Timeout, cancellation, crash/restart, changed policy/material, cross-project access and duplicate delivery cannot create partial effects; latency and queue/execution lineage are retained, and restart requires fresh server-verified uploaded material rather than a reconstructed scratch handle. -- [ ] Retained old evidence remains readable without rewriting hashes; unresolved +- [x] Retained old evidence remains readable without rewriting hashes; unresolved old execution cannot cross into the new runtime and requires authorized policy transition. - [x] Both obsolete catalogues, implementations, callers and obsolete tests are removed without a fallback or parallel runtime. -- [ ] A real PostgreSQL 16, MinIO and Rust-service journey proves pass, work +- [x] A real PostgreSQL 16, MinIO and Rust-service journey proves pass, work failure, infrastructure/retry and post-dispatch paths with cleanup. ## Risk and review routing @@ -238,15 +225,16 @@ intermediate-wait regression. | Obsolete catalogue removal | Focused lane/architecture/ownership suite; recursive collection of every modified surviving test module; Ruff, module-boundary inventory and stale-import scan | 84 focused tests passed and 94 surviving tests collected. Ten obsolete executable catalogue/runner targets, their private-edge debt and tests are absent; exact ownership metadata admits only the selected owners and those retirements. | The stacked branch still has separately tracked structural-debt growth from earlier P02/P10/P04 source, so the repository-wide structural-debt gate is not claimed by this deletion checkpoint. | | F-020 recovery | `python3 /tmp/p04_selected_runner.py /tmp/pilot04-f020-native6 600 tests/projects/guide_activation/test_postgresql.py::test_checker_registration_requires_corrected_approval_before_activation`; focused external-policy tests and Ruff | PostgreSQL 16 PASS 1 with schema 0037 and database/role/MinIO cleanup complete, plus 6 pure compiler tests. A real Operator registration does not clear the existing warning generation; correction observes the current registry projection, a linked successor approval binds the exact row/digest, the successor activates, and the old generation remains refused. Wrong stage, requirement, identity and registry digest substitutions fail closed. | This proves the activation recovery gate, not the combined intake-to-POST journey. | | Retained admission migration shape | `pytest -q backend/tests/test_submission_bundle_admission.py backend/tests/checkers/external/test_selected_pre_submit_coordination.py backend/tests/checkers/external/test_selected_preparation_command.py backend/tests/test_artifact_architecture.py::test_checker_materialization_contract_has_one_canonical_consumer_owner`; focused Ruff | 62 passed; selected rows require complete new custody while every new column stays null on retained legacy rows, avoiding fabricated backfill or historical hash rewrites | Successor SQL and direct retained/selected row controls remain pending | -| Owner/caller trace | PROJECT approval/activation, ART preparation/admission, TASK composition and CHECKERS dispatch | Selected PRE uses durable reserve/lease/finalize roots around the genuine ART callback; a pass is consumed only by TASK's existing atomic Submission/evaluation reservation/outbox composition, while POST uses immutable Submission/ART custody | Final F-020 recovery, retained-history transition and combined native journey remain pending | -| End-to-end replacement | Real PostgreSQL/MinIO/Rust public and worker journey | Not run | Implementation incomplete | +| Owner/caller trace | PROJECT approval/activation, ART preparation/admission, TASK composition and CHECKERS dispatch | Selected PRE uses durable reserve/lease/finalize roots around the genuine ART callback; a pass is consumed only by TASK's existing atomic Submission/evaluation reservation/outbox composition, while POST uses immutable Submission/ART custody | Independent final integration review remains | +| Default behavior and warnings | `pytest -q backend/tests/checkers/default/test_contract.py backend/tests/checkers/default/test_execution.py backend/tests/checkers/external/test_selected_pre_submit.py -m 'not postgres_schema_contract'` | 30 passed. The manifest and executable behavior retain exactly four ordered blockers; empty summary and attestation produce warnings without changing eligibility. | Full required checks remain on the final reconciled head. | +| End-to-end replacement | `run_selected_end_to_end_probe.py` through the isolated runner, `/tmp/pilot04-selected-e2e10.log` and `.json`, using platform manifest `sha256:c664d8d85d6dfcded31710223c8d91441548e5445f0aa9b59d246fc464a129ef` | PASS on PostgreSQL 16/schema 0037 with database/role/MinIO/workspace cleanup complete. Real MinIO PRE and the Rust/runc image commit one Submission, `evaluation_pending` and dispatch, then actual Submission/ART POST evidence. A secret finding leaves a separate Task `in_progress` with no Submission. Service loss retains `implementation_unavailable`; restart uses a fresh upload and independent ART verification, records a completed successor generation and commits exactly one later Submission/dispatch. | This local proof uses explicit `runc`/`docker-dev`; hosted CI must exercise its configured runtime and the final reconciled head. | ## Reconciliation - Current-source reconciliation: implementation starts at PR538 head `7453a0d8c5664cfd486872a381899f3755393004`; final publication will reconcile actual merged `main` and intervening owners. -- Next usable boundary: full selected checker journey; no component-only merge. -- Remaining risks: exact durable external pre-attempt/result projection may - require a successor migration. Numbering and fingerprints resolve only - against the actual linear graph; no competing ordinal is reserved here. +- Next usable boundary: independent full-scope review and final required CI; + no component-only merge. +- Remaining risk: reconcile the final stacked migration and owner metadata with + actual `main`, then validate the complete required test union on that tree. From c47eb249c824152b84fbae79f7381f2992407572 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 01:12:17 +0100 Subject: [PATCH 138/283] [PILOT-04] Shrink full-flow structural debt --- .../app/modules/authorization/catalogue.py | 3 +- .../guide_compilation/approval_custody.py | 50 ++-- .../external/test_selected_pre_submit.py | 250 ++++++++++++++---- .../test_selected_preparation_command.py | 98 ++++--- .../post_submit_materialization_helpers.py | 181 ++++++++----- .../guide_activation/source_fixtures.py | 143 +++++----- backend/tests/retained_material_fixtures.py | 230 ++++++++++------ backend/tests/submission_capacity_fixtures.py | 7 +- .../tests/tasks/test_submission_lineage.py | 7 +- backend/tests/test_artifact_admission.py | 15 +- .../tests/test_submission_bundle_admission.py | 190 ++----------- 11 files changed, 667 insertions(+), 507 deletions(-) diff --git a/backend/app/modules/authorization/catalogue.py b/backend/app/modules/authorization/catalogue.py index 4607c0a84..861597482 100644 --- a/backend/app/modules/authorization/catalogue.py +++ b/backend/app/modules/authorization/catalogue.py @@ -874,8 +874,7 @@ def _index_actions(definitions: tuple[ActionDefinition, ...]) -> MappingProxyTyp ActionId.PROJECT_ROLE_GRANT_READ, ActionId.PROJECT_ROLE_GRANT_ISSUE, ActionId.PROJECT_ROLE_GRANT_REVOKE, - ActionId.PROJECT_CREATE, - ActionId.PROJECT_GUIDE_CREATE, + ActionId.PROJECT_CREATE, ActionId.PROJECT_GUIDE_CREATE, ActionId.PROJECT_GUIDE_UPDATE, ActionId.PROJECT_GUIDE_SOURCE_SNAPSHOT_CREATE, ActionId.PROJECT_GUIDE_COMPILATION_REQUEST, diff --git a/backend/app/modules/projects/guide_compilation/approval_custody.py b/backend/app/modules/projects/guide_compilation/approval_custody.py index 78eeeaf3f..b6d39cf59 100644 --- a/backend/app/modules/projects/guide_compilation/approval_custody.py +++ b/backend/app/modules/projects/guide_compilation/approval_custody.py @@ -87,29 +87,16 @@ async def load_approval_custody(session, policy_id: str | None) -> ApprovalCusto return ApprovalCustody(operation, reservation, effective, pre, successor) -def approved_projection_digest(view) -> str: - """Return the original digest only after proving the exact approved transition.""" - custody = view.approval_custody - policy = view.policy - if custody is None or policy is None: - raise ValueError("approval custody is unavailable") +def _approval_projection_matches( + view, custody, target, receipt, policy, external_plan_hash, external_pre_hash +) -> bool: + """Compare every immutable target, receipt, reservation and policy fact.""" operation, reservation, effective, pre = ( custody.operation, custody.reservation, custody.effective, custody.pre, ) - target = GuideProposalTarget.model_validate(operation.target_json) - receipt = GuideProposalApprovalReceipt.model_validate(operation.receipt_json) - external_plan_hash = external_pre_hash = None - if operation.effective_pre_submit_plan.get("schema_version") == ( - "external_checker_policies.v1" - ): - external_policies = validate_stored_external_checker_policies( - operation.effective_pre_submit_plan - ) - external_plan_hash = external_policies.policies_sha256 - external_pre_hash = external_policies.pre_submit.policy_sha256 if ( target.digest != operation.target_digest or target.compilation_id != view.compilation.id @@ -167,6 +154,35 @@ def approved_projection_digest(view) -> str: else canonical_json_hash(operation.effective_pre_submit_plan) ) != receipt.effective_pre_submit_plan_hash + ): + return False + return True + + +def approved_projection_digest(view) -> str: + """Return the original digest only after proving the exact approved transition.""" + custody = view.approval_custody + policy = view.policy + if custody is None or policy is None: + raise ValueError("approval custody is unavailable") + operation, effective, pre = ( + custody.operation, + custody.effective, + custody.pre, + ) + target = GuideProposalTarget.model_validate(operation.target_json) + receipt = GuideProposalApprovalReceipt.model_validate(operation.receipt_json) + external_plan_hash = external_pre_hash = None + if operation.effective_pre_submit_plan.get("schema_version") == ( + "external_checker_policies.v1" + ): + external_policies = validate_stored_external_checker_policies( + operation.effective_pre_submit_plan + ) + external_plan_hash = external_policies.policies_sha256 + external_pre_hash = external_policies.pre_submit.policy_sha256 + if not _approval_projection_matches( + view, custody, target, receipt, policy, external_plan_hash, external_pre_hash ): raise ValueError("approved proposal custody mismatch") lifecycle = (policy.lifecycle_status, effective.lifecycle_status, pre.lifecycle_status) diff --git a/backend/tests/checkers/external/test_selected_pre_submit.py b/backend/tests/checkers/external/test_selected_pre_submit.py index 92a62efec..57ab61a5a 100644 --- a/backend/tests/checkers/external/test_selected_pre_submit.py +++ b/backend/tests/checkers/external/test_selected_pre_submit.py @@ -10,7 +10,7 @@ from pathlib import Path from types import SimpleNamespace from typing import cast -from unittest.mock import AsyncMock +from unittest.mock import AsyncMock, Mock import zipfile import pytest @@ -44,6 +44,7 @@ ) from app.modules.checkers.api.materialization import SubmissionMaterialEntry from app.modules.checkers.api.selected_pre_submit import ( + SelectedPreSubmitAdmissionLineage, SelectedPreSubmitLeaseFacts, SelectedPreSubmitReservationFacts, SelectedPreSubmitTerminalFacts, @@ -61,6 +62,7 @@ bind_selected_pre_submit_admission, build_selected_pre_submit_reservation, ) +from app.modules.artifacts.submission_admission import SubmissionBundleAdmissionPublisher from app.modules.artifacts.submission_archive import ( SubmissionArchiveInspector, SubmissionArchiveLimits, @@ -99,6 +101,133 @@ def _archive(primary_bytes: bytes) -> bytes: return output.getvalue() +def _hex_sha(character: str) -> str: + return "sha256:" + character * 64 + + +def _selected_admission_reservation(): + manifest = {"schema_version": "submission_manifest.v1", "entries": []} + post_policy = {"schema_version": "external_post_submit_policy.v1", "entries": []} + post_policy_sha256 = canonical_json_hash(post_policy) + post_policy["policy_sha256"] = post_policy_sha256 + lineage = SelectedPreSubmitAdmissionLineage( + predecessor_submission_id=None, + predecessor_submission_version=None, + guide_id=new_record_id(), + guide_version="v2", + source_snapshot_id=new_record_id(), + source_snapshot_sha256=_hex_sha("1"), + locked_guide_sha256=_hex_sha("2"), + effective_policy_id=new_record_id(), + effective_policy_sha256=_hex_sha("3"), + pre_submit_policy_id=new_record_id(), + pre_submit_policy_sha256=_hex_sha("4"), + effective_plan_sha256=_hex_sha("5"), + rules_sha256=_hex_sha("8"), + external_checker_policies_sha256=_hex_sha("9"), + post_submit_policy_sha256=post_policy_sha256, + post_submit_policy_body=post_policy, + locked_policy_context_hash=_hex_sha("6"), + semantic_manifest_id=new_record_id(), + semantic_manifest_body=manifest, + packet_sha256=_hex_sha("7"), + storage_scheme="s3", + ) + selected = SelectedPreSubmitReservationFacts( + actor_profile_id=new_record_id(), + identity_link_id=new_record_id(), + project_id=new_record_id(), + task_id=new_record_id(), + assignment_id=new_record_id(), + attempt_id=new_record_id(), + idempotency_key=new_record_id(), + attempt_request_digest=_hex_sha("8"), + prepared_generation_id=new_record_id(), + policy_sha256=lineage.effective_plan_sha256, + default_behavior_sha256=WORKSTREAM_DEFAULT_BEHAVIOR_SHA256, + default_input_sha256=_hex_sha("9"), + archive_sha256=_hex_sha("a"), + archive_byte_count=25, + semantic_manifest_sha256=canonical_json_hash(manifest), + execution_budget_ms=120_000, + admission_lineage=lineage, + ) + return manifest, post_policy, selected + + +def _selected_admission_publisher_fixture(selected): + terminal = { + "request_digest": selected.request_digest, + "outcome": "completed", + "execution": {"eligible": True}, + } + attempt = SimpleNamespace( + id=str(new_record_id()), + producer_request_type="submission_bundle", + producer_ref=str(selected.actor_profile_id), + project_id=str(selected.project_id), + task_id=str(selected.task_id), + sha256=selected.archive_sha256, + byte_count=selected.archive_byte_count, + media_type="application/zip", + replica_id=str(new_record_id()), + receipt_id=str(new_record_id()), + ) + job = SimpleNamespace( + id=str(new_record_id()), + originating_put_attempt_id=attempt.id, + replica_id=attempt.replica_id, + execution_generation=2, + ) + intent = SimpleNamespace( + id=str(new_record_id()), + pre_submit_evidence_set_id=None, + selected_pre_submit_run_id=str(selected.attempt_id), + selected_request_json=selected.canonical_body(), + selected_request_digest=selected.request_digest, + selected_terminal_json=terminal, + selected_terminal_digest=canonical_json_hash(terminal), + ) + replica = SimpleNamespace( + id=attempt.replica_id, + content_id=str(new_record_id()), + verification_state="verified", + availability_state="available", + integrity_state="valid", + ) + content = SimpleNamespace( + id=replica.content_id, + sha256=attempt.sha256, + byte_count=attempt.byte_count, + ) + verification = SimpleNamespace( + id=str(new_record_id()), + verification_job_id=job.id, + execution_generation=job.execution_generation, + outcome="verified", + observed_sha256=attempt.sha256, + observed_byte_count=attempt.byte_count, + ) + session = SimpleNamespace( + scalar=AsyncMock( + side_effect=[ + job, + attempt, + intent, + None, + replica, + verification, + content, + SimpleNamespace(id=attempt.receipt_id), + datetime.now(UTC), + ] + ), + add=Mock(), + flush=AsyncMock(), + ) + return session, job, verification + + def _limits() -> ArtifactPreparationLimits: return ArtifactPreparationLimits( aggregate_reserved_bytes=2 * HARD_MAXIMUM_ARTIFACT_BYTES, @@ -295,9 +424,7 @@ async def execute(self, request, _grant): isolation=ExternalCheckerIsolationReceipt( repository="registry.example/workstream/checker", platform_manifest_digest=request.registry.image_digest, - platform_manifest_media_type=( - "application/vnd.oci.image.manifest.v1+json" - ), + platform_manifest_media_type=("application/vnd.oci.image.manifest.v1+json"), platform_manifest_byte_count=1024, operating_system="linux", architecture="amd64", @@ -310,6 +437,51 @@ async def execute(self, request, _grant): ) +def _assert_terminal_round_trip(identity, policy, default_input, material, result) -> None: + now = datetime.now(UTC) + reservation = SelectedPreSubmitReservationFacts( + actor_profile_id=new_record_id(), + identity_link_id=new_record_id(), + project_id=identity.project_id, + task_id=identity.task_id, + assignment_id=identity.assignment_id, + attempt_id=identity.attempt_id, + idempotency_key=new_record_id(), + attempt_request_digest=identity.attempt_request_digest, + prepared_generation_id=identity.prepared_generation_id, + policy_sha256=policy.policy_sha256, + default_behavior_sha256=WORKSTREAM_DEFAULT_BEHAVIOR_SHA256, + default_input_sha256=workstream_default_input_sha256(default_input), + archive_sha256=material.archive_sha256, + archive_byte_count=material.archive_byte_count, + semantic_manifest_sha256=material.semantic_manifest_sha256, + execution_budget_ms=120_000, + ) + lease = SelectedPreSubmitLeaseFacts( + reservation=reservation, + lease_id=new_record_id(), + lease_generation=1, + lease_expires_at=now + timedelta(minutes=2), + ) + terminal = SelectedPreSubmitTerminalFacts( + lease=lease, + outcome="completed", + execution=result, + infrastructure_failure_code=None, + queued_at=now, + started_at=now + timedelta(milliseconds=25), + completed_at=now + timedelta(milliseconds=75), + ) + assert terminal.canonical_body()["queue_latency_ms"] == 25 + assert terminal.canonical_body()["execution_latency_ms"] == 50 + assert terminal.canonical_body()["request_digest"] == reservation.request_digest + assert terminal.terminal_digest == canonical_json_hash(terminal.canonical_body()) + assert SelectedPreSubmitTerminalFacts.from_canonical_body(terminal.canonical_body()) == terminal + changed_terminal = terminal.canonical_body() | {"queue_latency_ms": 26} + with pytest.raises(ValueError, match="terminal facts"): + SelectedPreSubmitTerminalFacts.from_canonical_body(changed_terminal) + + @pytest.mark.asyncio @pytest.mark.parametrize("verdict,eligible", [("passed", True), ("failed", False)]) async def test_selected_pre_runs_default_then_locked_external_image( @@ -388,55 +560,33 @@ async def test_selected_pre_runs_default_then_locked_external_image( assert len(grants.requests) == len(execution.requests) == 1 assert grants.requests[0].request_digest == execution.requests[0].request_digest assert result.result_digest == canonical_json_hash(result.canonical_body()) - now = datetime.now(UTC) - reservation = SelectedPreSubmitReservationFacts( - actor_profile_id=new_record_id(), - identity_link_id=new_record_id(), - project_id=identity.project_id, - task_id=identity.task_id, - assignment_id=identity.assignment_id, - attempt_id=identity.attempt_id, - idempotency_key=new_record_id(), - attempt_request_digest=identity.attempt_request_digest, - prepared_generation_id=identity.prepared_generation_id, - policy_sha256=policy.policy_sha256, - default_behavior_sha256=WORKSTREAM_DEFAULT_BEHAVIOR_SHA256, - default_input_sha256=workstream_default_input_sha256(default_input), - archive_sha256=material.archive_sha256, - archive_byte_count=material.archive_byte_count, - semantic_manifest_sha256=material.semantic_manifest_sha256, - execution_budget_ms=120_000, - ) - lease = SelectedPreSubmitLeaseFacts( - reservation=reservation, - lease_id=new_record_id(), - lease_generation=1, - lease_expires_at=now + timedelta(minutes=2), - ) - terminal = SelectedPreSubmitTerminalFacts( - lease=lease, - outcome="completed", - execution=result, - infrastructure_failure_code=None, - queued_at=now, - started_at=now + timedelta(milliseconds=25), - completed_at=now + timedelta(milliseconds=75), - ) - assert terminal.canonical_body()["queue_latency_ms"] == 25 - assert terminal.canonical_body()["execution_latency_ms"] == 50 - assert terminal.canonical_body()["request_digest"] == reservation.request_digest - assert terminal.terminal_digest == canonical_json_hash(terminal.canonical_body()) - assert SelectedPreSubmitTerminalFacts.from_canonical_body( - terminal.canonical_body() - ) == terminal - changed_terminal = terminal.canonical_body() | {"queue_latency_ms": 26} - with pytest.raises(ValueError, match="terminal facts"): - SelectedPreSubmitTerminalFacts.from_canonical_body(changed_terminal) + _assert_terminal_round_trip(identity, policy, default_input, material, result) finally: await request.prepared_artifact.close() manager.close() +@pytest.mark.asyncio +async def test_selected_pre_terminal_publishes_self_contained_ready_admission() -> None: + manifest, post_policy, selected = _selected_admission_reservation() + session, job, verification = _selected_admission_publisher_fixture(selected) + + admission = await SubmissionBundleAdmissionPublisher(session).publish_verified( + verification_job_id=job.id, + verification_receipt_id=verification.id, + ) + + assert admission.pre_submit_evidence_set_id is None + assert admission.selected_pre_submit_run_id == str(selected.attempt_id) + assert admission.packet_sha256 == selected.admission_lineage.packet_sha256 + assert admission.semantic_manifest_body == manifest + assert ( + admission.selected_post_submit_policy_sha256 + == selected.admission_lineage.post_submit_policy_sha256 + ) + assert admission.selected_post_submit_policy_body == post_policy + + @pytest.mark.asyncio async def test_selected_pre_default_secret_blocker_precedes_external_image( tmp_path, @@ -605,9 +755,7 @@ async def test_selected_admission_binds_unchanged_work_to_current_task_rules( execution_budget_ms=120_000, ) assert reservation.admission_lineage is not None - assert reservation.admission_lineage.semantic_manifest_body == ( - request.manifest.as_dict() - ) + assert reservation.admission_lineage.semantic_manifest_body == (request.manifest.as_dict()) assert reservation.admission_lineage.packet_sha256 == request.packet.sha256 assert reservation.admission_lineage.predecessor_submission_id == ( predecessor.submission_id diff --git a/backend/tests/checkers/external/test_selected_preparation_command.py b/backend/tests/checkers/external/test_selected_preparation_command.py index 26a5f7bcd..4b4a24a7e 100644 --- a/backend/tests/checkers/external/test_selected_preparation_command.py +++ b/backend/tests/checkers/external/test_selected_preparation_command.py @@ -26,10 +26,7 @@ async def _root(): yield -@pytest.mark.asyncio -async def test_hidden_preparation_uses_selected_pre_before_durable_admission( - monkeypatch, -) -> None: +def _request_case(): actor = ActorIdentityFacts( actor_profile_id=new_record_id(), identity_link_id=new_record_id(), @@ -49,28 +46,23 @@ async def test_hidden_preparation_uses_selected_pre_before_durable_admission( media_type="application/zip", byte_source=SimpleNamespace(), ) - commitment = SimpleNamespace( - sha256="sha256:" + "1" * 64, - byte_count=100, - ) prepared = SimpleNamespace( generation_id=new_record_id(), - commitment=commitment, + commitment=SimpleNamespace(sha256="sha256:" + "1" * 64, byte_count=100), inspect=AsyncMock(return_value=object()), close=AsyncMock(), ) + return actor, request, prepared, attempt_id + + +def _runtime_case(prepared, attempt_id): policy = object() - selected = SimpleNamespace( - policy=policy, - default_input=object(), - change_gate=object(), - ) + selected = SimpleNamespace(policy=policy, default_input=object(), change_gate=object()) reservation = SimpleNamespace(attempt_id=attempt_id) - execution = SimpleNamespace(eligible=True) completion = SelectedPreSubmitCompletion( terminal=SimpleNamespace( outcome="completed", - execution=execution, + execution=SimpleNamespace(eligible=True), infrastructure_failure_code=None, ), capability=object(), @@ -85,9 +77,7 @@ async def test_hidden_preparation_uses_selected_pre_before_durable_admission( ) selected_execution = SimpleNamespace(execute=AsyncMock(return_value=completion)) durable = SimpleNamespace( - admit_in_transaction=AsyncMock( - return_value=(prepared, attempt_id, SimpleNamespace()) - ), + admit_in_transaction=AsyncMock(return_value=(prepared, attempt_id, SimpleNamespace())), publish_after_commit=AsyncMock( return_value=SubmissionBundleDurablePutResult( put_attempt_id=new_record_id(), @@ -110,16 +100,25 @@ async def test_hidden_preparation_uses_selected_pre_before_durable_admission( storage_scheme="s3", artifact_deadline_ms=120_000, ) + return SimpleNamespace( + runtime=runtime, + policy=policy, + selected=selected, + reservation=reservation, + completion=completion, + materialization=materialization, + coordinator=coordinator, + selected_execution=selected_execution, + durable=durable, + ) + +def _command(runtime, actor): @asynccontextmanager async def runtime_factory(): yield runtime - authority = SimpleNamespace( - preflight=AsyncMock(), - transaction=_root, - close=Mock(), - ) + authority = SimpleNamespace(preflight=AsyncMock(), transaction=_root, close=Mock()) command = PreparedSubmissionBundlePreparationCommand( session=SimpleNamespace(begin=_root), authority=authority, @@ -127,56 +126,69 @@ async def runtime_factory(): project_contexts=SimpleNamespace(), runtime_factory=runtime_factory, ) - task = SimpleNamespace(predecessor=None) project = SimpleNamespace( effective_policy_id=new_record_id(), pre_submit_policy_id=new_record_id(), external_checker_policies=SimpleNamespace(value="{}"), ) - command._lock_authorized_context = AsyncMock(return_value=(task, project)) + command._lock_authorized_context = AsyncMock( + return_value=(SimpleNamespace(predecessor=None), project) + ) command._load_predecessor = AsyncMock(return_value=None) command._load_predecessor_rules = AsyncMock(return_value=None) + return command + + +def _patch_selected_owners(monkeypatch, case): monkeypatch.setattr( owner, "LockedExternalCheckerPolicies", SimpleNamespace( - model_validate_json=Mock( - return_value=SimpleNamespace(pre_submit=policy) - ) + model_validate_json=Mock(return_value=SimpleNamespace(pre_submit=case.policy)) ), ) monkeypatch.setattr(owner, "build_submission_manifest", Mock(return_value=object())) monkeypatch.setattr( - owner, "bind_selected_pre_submit_admission", Mock(return_value=selected) + owner, "bind_selected_pre_submit_admission", Mock(return_value=case.selected) ) monkeypatch.setattr( - owner, "build_selected_pre_submit_reservation", Mock(return_value=reservation) + owner, + "build_selected_pre_submit_reservation", + Mock(return_value=case.reservation), ) monkeypatch.setattr( owner, "selected_pre_submit_attempt_request_digest", Mock(return_value="sha256:" + "3" * 64), ) - monkeypatch.setattr( - owner, "selected_pre_submit_execution_budget_ms", Mock(return_value=60_000) - ) + monkeypatch.setattr(owner, "selected_pre_submit_execution_budget_ms", Mock(return_value=60_000)) + + +@pytest.mark.asyncio +async def test_hidden_preparation_uses_selected_pre_before_durable_admission( + monkeypatch, +) -> None: + actor, request, prepared, attempt_id = _request_case() + case = _runtime_case(prepared, attempt_id) + command = _command(case.runtime, actor) + _patch_selected_owners(monkeypatch, case) result = await command.prepare(request) assert result.submission_bundle_preparation_status is ( SubmissionBundlePreparationStatus.PREPARED ) - materialization.prepare_selected_authorization.assert_awaited_once() - materialization.authorize_inspected.assert_awaited_once() - coordinator.read_current.assert_awaited_once_with(reservation) - coordinator.reserve.assert_awaited_once_with(reservation) - selected_execution.execute.assert_awaited_once() - admitted = durable.admit_in_transaction.await_args.args[0] + case.materialization.prepare_selected_authorization.assert_awaited_once() + case.materialization.authorize_inspected.assert_awaited_once() + case.coordinator.read_current.assert_awaited_once_with(case.reservation) + case.coordinator.reserve.assert_awaited_once_with(case.reservation) + case.selected_execution.execute.assert_awaited_once() + admitted = case.durable.admit_in_transaction.await_args.args[0] assert admitted.pass_capability is None - assert admitted.selected_completion is completion - durable.publish_after_commit.assert_awaited_once_with( + assert admitted.selected_completion is case.completion + case.durable.publish_after_commit.assert_awaited_once_with( prepared, attempt_id, - durable.admit_in_transaction.return_value[2], + case.durable.admit_in_transaction.return_value[2], selected_pre_submit_run_id=attempt_id, ) diff --git a/backend/tests/post_submit_materialization_helpers.py b/backend/tests/post_submit_materialization_helpers.py index 07f806195..0e996df14 100644 --- a/backend/tests/post_submit_materialization_helpers.py +++ b/backend/tests/post_submit_materialization_helpers.py @@ -118,26 +118,7 @@ async def material_fixture(tmp_path, database_url, **options): yield material -@asynccontextmanager -async def _material_fixture( - tmp_path, - database_url, - *, - write_submission, - read_request, - provider="local", - scratch_limits=None, - storage_settings=None, - provision_services=True, - provision_checker=True, - contribution_awards=(), - human_review_required=True, - pre_submit_registry_spec=None, - post_submit_registry_spec=None, - post_scratch_root=None, -): - engine = create_async_engine(database_url) - factory = async_sessionmaker(engine, expire_on_commit=False) +def _material_storage(tmp_path, provider, storage_settings, scratch_limits, post_scratch_root): if storage_settings is not None: settings = storage_settings elif provider == "minio": @@ -151,10 +132,11 @@ async def _material_fixture( } ) else: - settings = _settings( - tmp_path, - maximum_bytes=1024 * 1024, - external_checker=True, + settings = _settings(tmp_path, maximum_bytes=1024 * 1024).model_copy( + update={ + "external_checker_service_socket": tmp_path / "checker.sock", + "external_checker_material_root": tmp_path / "scratch", + } ) bootstrap = create_artifact_store_bootstrap(settings) namespace = artifact_storage_namespace_spec(settings, bootstrap) @@ -170,6 +152,94 @@ async def _material_fixture( root=scratch, limits=scratch_limits if scratch_limits is not None else _limits(), ) + return settings, bootstrap, namespace, store, scratch, manager + + +async def _create_material_submission( + factory, + engine, + plan, + policy, + store, + namespace, + settings, + write_submission, + *, + provision_services, + provision_checker, +): + context = _context() + await provision_material_services( + factory, artifacts=provision_services, checker=provision_checker + ) + task_id, assignment_id = new_record_id(), new_record_id() + async with factory.begin() as session: + await _seed_human_actor(session, context) + params = dict( + task=str(task_id), + assignment=str(assignment_id), + project=str(plan.lineage.project_id), + actor=str(context.actor_profile_id), + ) + async with engine.begin() as connection: + await seed_started_task_for_artifact_test(connection, params) + await install_submitter_grant(connection, params) + data = archive_with_modes(policy["evidence_path"], plan.lineage.project_id) + preparation_request = SubmissionBundlePreparationRequest( + actor=ActorIdentityFacts( + context.actor_profile_id, context.identity_link_id, ActorKind.HUMAN + ), + request_id=context.request_id, + correlation_id=context.correlation_id, + task_id=task_id, + assignment_id=assignment_id, + predecessor_submission_id=None, + idempotency_key=new_record_id(), + summary="Completed the required project work and included evidence.", + contributor_attestation="I confirm no confidential client data, credentials, or copied source material is included in this submission; rights_confirmed. " + + " ".join(policy["attestation_terms"]), + media_type="application/zip", + byte_source=_bytes(data), + ) + admission_id = await _verified_admission( + factory, store, namespace, settings, context, preparation_request + ) + creation_request = SubmissionCreationRequest( + task_id=task_id, + assignment_id=assignment_id, + contributor_id=context.actor_profile_id, + predecessor_submission_id=None, + admission_id=admission_id, + summary=preparation_request.summary, + contributor_attestation=preparation_request.contributor_attestation, + ) + created = await write_submission(factory, context, creation_request) + return context, task_id, data, admission_id, creation_request, created + + +@asynccontextmanager +async def _material_fixture( + tmp_path, + database_url, + *, + write_submission, + read_request, + provider="local", + scratch_limits=None, + storage_settings=None, + provision_services=True, + provision_checker=True, + contribution_awards=(), + human_review_required=True, + pre_submit_registry_spec=None, + post_submit_registry_spec=None, + post_scratch_root=None, +): + engine = create_async_engine(database_url) + factory = async_sessionmaker(engine, expire_on_commit=False) + settings, bootstrap, namespace, store, scratch, manager = _material_storage( + tmp_path, provider, storage_settings, scratch_limits, post_scratch_root + ) try: plan, policy = await approved_selected_policy_fixture( factory, @@ -180,52 +250,25 @@ async def _material_fixture( pre_submit_registry_spec=pre_submit_registry_spec, post_submit_registry_spec=post_submit_registry_spec, ) - context = _context() - await provision_material_services( - factory, artifacts=provision_services, checker=provision_checker - ) - task_id, assignment_id = new_record_id(), new_record_id() - async with factory.begin() as session: - await _seed_human_actor(session, context) - async with engine.begin() as connection: - params = dict( - task=str(task_id), - assignment=str(assignment_id), - project=str(plan.lineage.project_id), - actor=str(context.actor_profile_id), - ) - await seed_started_task_for_artifact_test(connection, params) - await install_submitter_grant(connection, params) - data = archive_with_modes(policy["evidence_path"], plan.lineage.project_id) - preparation_request = SubmissionBundlePreparationRequest( - actor=ActorIdentityFacts( - context.actor_profile_id, context.identity_link_id, ActorKind.HUMAN - ), - request_id=context.request_id, - correlation_id=context.correlation_id, - task_id=task_id, - assignment_id=assignment_id, - predecessor_submission_id=None, - idempotency_key=new_record_id(), - summary="Completed the required project work and included evidence.", - contributor_attestation="I confirm no confidential client data, credentials, or copied source material is included in this submission; rights_confirmed. " - + " ".join(policy["attestation_terms"]), - media_type="application/zip", - byte_source=_bytes(data), - ) - admission_id = await _verified_admission( - factory, store, namespace, settings, context, preparation_request - ) - creation_request = SubmissionCreationRequest( - task_id=task_id, - assignment_id=assignment_id, - contributor_id=context.actor_profile_id, - predecessor_submission_id=None, - admission_id=admission_id, - summary=preparation_request.summary, - contributor_attestation=preparation_request.contributor_attestation, + ( + context, + task_id, + data, + admission_id, + creation_request, + created, + ) = await _create_material_submission( + factory, + engine, + plan, + policy, + store, + namespace, + settings, + write_submission, + provision_services=provision_services, + provision_checker=provision_checker, ) - created = await write_submission(factory, context, creation_request) async with factory() as session: facts = await submitted_bundle_port(session).read( SubmittedBundleRequest( diff --git a/backend/tests/projects/guide_activation/source_fixtures.py b/backend/tests/projects/guide_activation/source_fixtures.py index de354768e..d357e4e43 100644 --- a/backend/tests/projects/guide_activation/source_fixtures.py +++ b/backend/tests/projects/guide_activation/source_fixtures.py @@ -36,18 +36,7 @@ from tests.projects.guide_compilation.proposals.pg_support import seed_review_actor -async def create_compiled_guide( - factory, - values, - actor, - *, - version="v1", - artifact_proposal=None, - pre_submit_registry_entry=None, - post_submit_registry_entry=None, - compilation_outcome=None, -): - """Create declarations with real AUTH, then execute/project/finalize scripted findings.""" +async def _create_guide_source(factory, values, actor, version): async with factory() as session, session.begin(): resolved = ResolvedActor( await session.get(ActorProfile, str(actor.actor_profile_id)), @@ -81,7 +70,76 @@ async def create_compiled_guide( ), ) setup = await session.get(ProjectSetupRun, str(created.response.setup.id)) - snapshot_id = setup.source_snapshot_id + return setup.source_snapshot_id + + +def _external_compilation_outcome(outcome, registry_entries, pre_entry, post_entry, refs): + if not registry_entries: + return outcome + from app.interfaces.project_agents import ( + AtomicGuideRequirement, + PostSubmissionBindingProposal, + PreSubmissionBindingProposal, + ) + + requirements, pre_bindings, post_bindings = [], [], [] + if pre_entry is not None: + requirements.append( + AtomicGuideRequirement( + requirement_id="project.archive_rules", + statement="Validate the submitted project archive rules.", + disposition="supported_pre_submit", + evidence_refs=refs, + ) + ) + pre_bindings.append( + PreSubmissionBindingProposal( + requirement_id="project.archive_rules", + capability_id=pre_entry.capability_id, + capability_version=pre_entry.capability_version, + stage="pre_submit", + ) + ) + if post_entry is not None: + requirements.append( + AtomicGuideRequirement( + requirement_id="project.post_evidence", + statement="Evaluate the submitted evidence package.", + disposition="supported_post_submit", + evidence_refs=refs, + ) + ) + post_bindings.append( + PostSubmissionBindingProposal( + requirement_id="project.post_evidence", + capability_id=post_entry.capability_id, + capability_version=post_entry.capability_version, + stage="post_submit", + parameters=(), + ) + ) + return outcome.model_copy( + update={ + "requirements": tuple(requirements), + "pre_submit_bindings": tuple(pre_bindings), + "post_submit_bindings": tuple(post_bindings), + } + ) + + +async def create_compiled_guide( + factory, + values, + actor, + *, + version="v1", + artifact_proposal=None, + pre_submit_registry_entry=None, + post_submit_registry_entry=None, + compilation_outcome=None, +): + """Create declarations with real AUTH, then execute/project/finalize scripted findings.""" + snapshot_id = await _create_guide_source(factory, values, actor, version) manifest = await create_committed_document_fixture(str(snapshot_id), sessions=factory) # Arrange the completed durable dispatch prerequisite; no broker is exercised here. async with factory() as session, session.begin(): @@ -130,58 +188,13 @@ async def create_compiled_guide( for field in ("findings", "requirements", "capability_suggestions") } ) - if registry_entries: - from app.interfaces.project_agents import ( - AtomicGuideRequirement, - PreSubmissionBindingProposal, - PostSubmissionBindingProposal, - ) - - requirements = [] - pre_bindings = [] - post_bindings = [] - if pre_submit_registry_entry is not None: - requirements.append( - AtomicGuideRequirement( - requirement_id="project.archive_rules", - statement="Validate the submitted project archive rules.", - disposition="supported_pre_submit", - evidence_refs=refs, - ) - ) - pre_bindings.append( - PreSubmissionBindingProposal( - requirement_id="project.archive_rules", - capability_id=pre_submit_registry_entry.capability_id, - capability_version=pre_submit_registry_entry.capability_version, - stage="pre_submit", - ) - ) - if post_submit_registry_entry is not None: - requirements.append( - AtomicGuideRequirement( - requirement_id="project.post_evidence", - statement="Evaluate the submitted evidence package.", - disposition="supported_post_submit", - evidence_refs=refs, - ) - ) - post_bindings.append( - PostSubmissionBindingProposal( - requirement_id="project.post_evidence", - capability_id=post_submit_registry_entry.capability_id, - capability_version=post_submit_registry_entry.capability_version, - stage="post_submit", - parameters=(), - ) - ) - outcome = outcome.model_copy( - update={ - "requirements": tuple(requirements), - "pre_submit_bindings": tuple(pre_bindings), - "post_submit_bindings": tuple(post_bindings), - } - ) + outcome = _external_compilation_outcome( + outcome, + registry_entries, + pre_submit_registry_entry, + post_submit_registry_entry, + refs, + ) url = factory.kw["bind"].url.render_as_string(hide_password=False) finalization = await compilation_and_projections( url, diff --git a/backend/tests/retained_material_fixtures.py b/backend/tests/retained_material_fixtures.py index e8f8ec432..8b161f610 100644 --- a/backend/tests/retained_material_fixtures.py +++ b/backend/tests/retained_material_fixtures.py @@ -20,7 +20,10 @@ ) from app.core.identifiers import new_record_id from app.interfaces.artifacts import ( - ArtifactObjectHead, ArtifactPutObservation, ArtifactPutResult, artifact_provider_object_ref, + ArtifactObjectHead, + ArtifactPutObservation, + ArtifactPutResult, + artifact_provider_object_ref, ) from app.interfaces.external_services import ExternalServiceAdapterIdentity from app.modules.artifacts.api import SubmissionBundlePreparationRequest @@ -28,15 +31,27 @@ PreparedPreSubmitMaterializationAuthorization, PreparedSubmissionBundlePreparationAuthorization, ) -from app.modules.artifacts.models import ArtifactStorageNamespace, ArtifactVerificationJob, SubmissionBundleAdmission +from app.modules.artifacts.models import ( + ArtifactStorageNamespace, + ArtifactVerificationJob, + SubmissionBundleAdmission, +) from app.modules.artifacts.preparation import ArtifactPreparationService, ArtifactScratchManager -from app.modules.artifacts.service import ArtifactAdmissionService, ArtifactStorageNamespaceSpec, ArtifactStorageOrchestrator +from app.modules.artifacts.service import ( + ArtifactAdmissionService, + ArtifactStorageNamespaceSpec, + ArtifactStorageOrchestrator, +) from app.modules.artifacts.submission_admission import ( - PreparedSubmissionBundlePreparationCommand, SubmissionBundleDurablePutService, + PreparedSubmissionBundlePreparationCommand, + SubmissionBundleDurablePutService, SubmissionBundlePreparationRuntime, ) from app.modules.artifacts.selected_pre_submit_execution import SelectedPreSubmitExecutionService -from app.modules.artifacts.submission_archive import SubmissionArchiveInspector, SubmissionArchiveLimits +from app.modules.artifacts.submission_archive import ( + SubmissionArchiveInspector, + SubmissionArchiveLimits, +) from app.modules.artifacts.submission_materialization import PreparedBundleMaterializationService from app.modules.authorization.api import ActorIdentityFacts, ActorKind from app.modules.actors.api import ServiceIdentity @@ -81,7 +96,7 @@ async def open(self, ref, byte_range=None): data = self.objects[ref] if byte_range is not None: end = None if byte_range.length is None else byte_range.offset + byte_range.length - data = data[byte_range.offset:end] + data = data[byte_range.offset : end] yield data async def head(self, ref): @@ -89,6 +104,104 @@ async def head(self, ref): return ArtifactObjectHead(ref, data is not None, len(data) if data is not None else None) +def _submission_request(task, assignment, link, packet, predecessor_id, policy): + content = BytesIO() + paths = {entry["path"] for entry in policy["required_artifacts"] if entry.get("required", True)} + paths.update( + entry.get("path") or "evidence/" + entry["key"] + for entry in policy["required_evidence"] + if entry.get("required", True) + ) + with ZipFile(content, "w") as archive: + for path in sorted(paths): + archive.writestr(path, f"{task.id}:{predecessor_id}:{packet.summary}\n") + context = _context(actor_profile_id=UUID(task.assigned_to), identity_link_id=UUID(link.id)) + request = SubmissionBundlePreparationRequest( + actor=ActorIdentityFacts( + context.actor_profile_id, context.identity_link_id, ActorKind.HUMAN + ), + request_id=context.request_id, + correlation_id=context.correlation_id, + task_id=UUID(task.id), + assignment_id=UUID(assignment.id), + predecessor_submission_id=UUID(predecessor_id) if predecessor_id else None, + idempotency_key=new_record_id(), + summary=packet.summary, + contributor_attestation=packet.worker_attestation, + media_type="application/zip", + byte_source=_bytes(content.getvalue()), + ) + return context, request + + +def _runtime_factory( + *, + session, + settings, + namespace, + authority, + materialization_authority, + preparation, + inspector, + materialization, + storage, + tasks, + projects, + coordinator, +): + @asynccontextmanager + async def runtime(): + try: + yield SubmissionBundlePreparationRuntime( + preparation=preparation, + inspector=inspector, + materialization=materialization, + durable_put=SubmissionBundleDurablePutService( + session=session, + admission=ArtifactAdmissionService(session, settings, namespace), + storage=storage, + authorization=authority, + task_contexts=tasks, + project_contexts=projects, + ), + selected_coordinator=coordinator, + selected_execution=SelectedPreSubmitExecutionService( + session=session, + coordinator=coordinator, + authority=selected_pre_submit_authority(session), + materialization=materialization, + ), + storage_scheme="s3", + artifact_deadline_ms=180_000, + ) + finally: + materialization_authority.close() + + return runtime + + +async def _verify_admission(factory, store, namespace, settings, result): + async with factory() as session: + job_id = await session.scalar( + select(ArtifactVerificationJob.id).where( + ArtifactVerificationJob.originating_put_attempt_id == str(result.put_attempt_id), + ) + ) + assert job_id is not None, result + await session.rollback() + orchestrator = ArtifactStorageOrchestrator( + session, store, namespace, settings, _AllowArtifactAuthority() + ) + assert await orchestrator.verify_object(UUID(job_id)) == "verified" + admission = await session.scalar( + select(SubmissionBundleAdmission).where( + SubmissionBundleAdmission.put_attempt_id == str(result.put_attempt_id), + ) + ) + assert admission.status == "ready" + return admission.id + + async def retained_admission( factory, task, @@ -105,31 +218,20 @@ async def retained_admission( async with factory() as session: persisted = await session.get(ArtifactStorageNamespace, "primary") namespace = ArtifactStorageNamespaceSpec( - persisted.backend, persisted.adapter, persisted.provider_profile, - persisted.namespace_descriptor, persisted.namespace_fingerprint, + persisted.backend, + persisted.adapter, + persisted.provider_profile, + persisted.namespace_descriptor, + persisted.namespace_fingerprint, ) - policy = (await session.get( - EffectiveProjectSubmissionArtifactPolicy, - task.locked_effective_project_submission_artifact_policy_id, - )).effective_policy - content = BytesIO() - paths = {entry["path"] for entry in policy["required_artifacts"] if entry.get("required", True)} - paths.update(entry.get("path") or "evidence/" + entry["key"] - for entry in policy["required_evidence"] if entry.get("required", True)) - with ZipFile(content, "w") as archive: - for path in sorted(paths): - archive.writestr(path, f"{task.id}:{predecessor_id}:{packet.summary}\n") + policy = ( + await session.get( + EffectiveProjectSubmissionArtifactPolicy, + task.locked_effective_project_submission_artifact_policy_id, + ) + ).effective_policy + context, request = _submission_request(task, assignment, link, packet, predecessor_id, policy) store = MemoryStore(namespace) - context = _context(actor_profile_id=UUID(task.assigned_to), identity_link_id=UUID(link.id)) - request = SubmissionBundlePreparationRequest( - actor=ActorIdentityFacts(context.actor_profile_id, context.identity_link_id, ActorKind.HUMAN), - request_id=context.request_id, correlation_id=context.correlation_id, - task_id=UUID(task.id), assignment_id=UUID(assignment.id), - predecessor_submission_id=UUID(predecessor_id) if predecessor_id else None, - idempotency_key=new_record_id(), summary=packet.summary, - contributor_attestation=packet.worker_attestation, - media_type="application/zip", byte_source=_bytes(content.getvalue()), - ) with TemporaryDirectory(prefix="retained-material-") as directory: settings = _settings(Path(directory), maximum_bytes=1024 * 1024) # This fixture traverses multiple real database transactions. Its scratch @@ -155,59 +257,35 @@ async def retained_admission( preparation=preparation, checker_execution=SelectedPreSubmitCheckerExecutionAdapter( archive_inspector=inspector, - external_execution=external_execution - or _ForbiddenExternalExecution(), + external_execution=external_execution or _ForbiddenExternalExecution(), ), storage_scheme="s3", ) - storage = ArtifactStorageOrchestrator(session, store, namespace, settings, _AllowArtifactAuthority()) + storage = ArtifactStorageOrchestrator( + session, store, namespace, settings, _AllowArtifactAuthority() + ) coordinator = selected_pre_submit_coordinator(session) - @asynccontextmanager - async def runtime(): - try: - yield SubmissionBundlePreparationRuntime( - preparation=preparation, - inspector=inspector, - materialization=materialization, - durable_put=SubmissionBundleDurablePutService( - session=session, - admission=ArtifactAdmissionService(session, settings, namespace), - storage=storage, - authorization=authority, - task_contexts=tasks, - project_contexts=projects, - ), - selected_coordinator=coordinator, - selected_execution=SelectedPreSubmitExecutionService( - session=session, - coordinator=coordinator, - authority=selected_pre_submit_authority(session), - materialization=materialization, - ), - storage_scheme="s3", - artifact_deadline_ms=180_000, - ) - finally: - materialization_authority.close() - result = await PreparedSubmissionBundlePreparationCommand( - session=session, authority=authority, task_contexts=tasks, - project_contexts=projects, runtime_factory=runtime, + session=session, + authority=authority, + task_contexts=tasks, + project_contexts=projects, + runtime_factory=_runtime_factory( + session=session, + settings=settings, + namespace=namespace, + authority=authority, + materialization_authority=materialization_authority, + preparation=preparation, + inspector=inspector, + materialization=materialization, + storage=storage, + tasks=tasks, + projects=projects, + coordinator=coordinator, + ), ).prepare(request) - async with factory() as session: - job_id = await session.scalar(select(ArtifactVerificationJob.id).where( - ArtifactVerificationJob.originating_put_attempt_id == str(result.put_attempt_id), - )) - assert job_id is not None, result - await session.rollback() - assert await ArtifactStorageOrchestrator( - session, store, namespace, settings, _AllowArtifactAuthority(), - ).verify_object(UUID(job_id)) == "verified" - admission = await session.scalar(select(SubmissionBundleAdmission).where( - SubmissionBundleAdmission.put_attempt_id == str(result.put_attempt_id), - )) - assert admission.status == "ready" - return admission.id + return await _verify_admission(factory, store, namespace, settings, result) finally: manager.close() diff --git a/backend/tests/submission_capacity_fixtures.py b/backend/tests/submission_capacity_fixtures.py index 152fb74cc..b256c8d5c 100644 --- a/backend/tests/submission_capacity_fixtures.py +++ b/backend/tests/submission_capacity_fixtures.py @@ -20,10 +20,9 @@ async def capacity_fixture(database_url, tmp_path): engine = create_async_engine(database_url) factory = async_sessionmaker(engine, expire_on_commit=False) - settings = _settings( - tmp_path, - maximum_bytes=1024 * 1024, - external_checker=True, + settings = _settings(tmp_path, maximum_bytes=1024 * 1024).model_copy( + update={"external_checker_service_socket": tmp_path / "checker.sock", + "external_checker_material_root": tmp_path / "scratch"} ) namespace = _namespace(settings) bootstrap, store = _local_store(settings, namespace) diff --git a/backend/tests/tasks/test_submission_lineage.py b/backend/tests/tasks/test_submission_lineage.py index f29c6e55a..4f108c102 100644 --- a/backend/tests/tasks/test_submission_lineage.py +++ b/backend/tests/tasks/test_submission_lineage.py @@ -43,10 +43,9 @@ async def _prepared_packet(isolated_database_env, tmp_path): engine = create_async_engine(isolated_database_env) factory = async_sessionmaker(engine, expire_on_commit=False) - settings = _settings( - tmp_path, - maximum_bytes=1024 * 1024, - external_checker=True, + settings = _settings(tmp_path, maximum_bytes=1024 * 1024).model_copy( + update={"external_checker_service_socket": tmp_path / "checker.sock", + "external_checker_material_root": tmp_path / "scratch"} ) namespace = _namespace(settings) bootstrap, store = _local_store(settings, namespace) diff --git a/backend/tests/test_artifact_admission.py b/backend/tests/test_artifact_admission.py index 9f9630c78..07ca8ab6b 100644 --- a/backend/tests/test_artifact_admission.py +++ b/backend/tests/test_artifact_admission.py @@ -166,15 +166,10 @@ def admission_database_env(isolated_database_env: str) -> Iterator[str]: yield isolated_database_env -def _settings( - tmp_path: Path, - *, - maximum_bytes: int = 1024, - external_checker: bool = False, -) -> Settings: +def _settings(tmp_path: Path, *, maximum_bytes: int = 1024) -> Settings: durable_root = tmp_path / "durable" durable_root.mkdir(mode=0o700, parents=True) - values = dict( + return Settings( _env_file=None, **artifact_admission_limit_settings(maximum_bytes), environment="test", @@ -183,12 +178,6 @@ def _settings( artifact_scratch_root=tmp_path / "scratch", artifact_scratch_minimum_free_bytes=0, ) - if external_checker: - values.update( - external_checker_service_socket=tmp_path / "checker.sock", - external_checker_material_root=tmp_path / "scratch", - ) - return Settings(**values) def _namespace(settings: Settings) -> ArtifactStorageNamespaceSpec: diff --git a/backend/tests/test_submission_bundle_admission.py b/backend/tests/test_submission_bundle_admission.py index 70dbdbc21..f8964a89d 100644 --- a/backend/tests/test_submission_bundle_admission.py +++ b/backend/tests/test_submission_bundle_admission.py @@ -7,7 +7,6 @@ from datetime import UTC, datetime from types import SimpleNamespace from unittest.mock import AsyncMock, Mock -from app.core.hashing import canonical_json_hash from app.core.identifiers import new_record_id import pytest @@ -64,11 +63,6 @@ from app.main import create_app from app.api.routes.artifact_submissions import router as submission_router from app.modules.artifacts.submission_admission import validate_submission_packet_headers -from app.modules.checkers.api.default_checker import WORKSTREAM_DEFAULT_BEHAVIOR_SHA256 -from app.modules.checkers.api.selected_pre_submit import ( - SelectedPreSubmitAdmissionLineage, - SelectedPreSubmitReservationFacts, -) def _actor() -> ActorIdentityFacts: @@ -137,7 +131,8 @@ async def test_actor_prelock_requires_a_root_transaction(active, nested) -> None authority = object.__new__(PreparedSubmissionBundlePreparationAuthorization) authority._session = SimpleNamespace( - in_transaction=lambda: active, in_nested_transaction=lambda: nested, + in_transaction=lambda: active, + in_nested_transaction=lambda: nested, ) authority._repository = SimpleNamespace(lock_request_actor=AsyncMock()) with pytest.raises(ArtifactAuthorityDeniedError): @@ -298,11 +293,7 @@ def test_submission_packet_headers_reject_non_ascii() -> None: SubmissionBundlePreparationRejected, match="submission_bundle_packet_header_encoding_invalid", ): - validate_submission_packet_headers( - "caf\N{LATIN SMALL LETTER E WITH ACUTE}", "ok" - ) - - + validate_submission_packet_headers("caf\N{LATIN SMALL LETTER E WITH ACUTE}", "ok") @asynccontextmanager @@ -388,6 +379,7 @@ async def invoke(*_args, **_kwargs): if name == denied_phase: raise denial return object() + return invoke authority = SimpleNamespace( @@ -395,12 +387,15 @@ async def invoke(*_args, **_kwargs): revalidate=AsyncMock(side_effect=phase("grant")), ) materialization = SimpleNamespace( - _storage_scheme="s3", authorize_inspected=AsyncMock(), + _storage_scheme="s3", + authorize_inspected=AsyncMock(), ) workflow = PreparedBundlePreSubmitEvidenceService( - session=SimpleNamespace(), materialization=materialization, + session=SimpleNamespace(), + materialization=materialization, preparation_authorization=authority, - task_contexts=SimpleNamespace(), project_contexts=SimpleNamespace(), + task_contexts=SimpleNamespace(), + project_contexts=SimpleNamespace(), ) evidence = SimpleNamespace( lock_task_context=AsyncMock(side_effect=phase("task")), @@ -413,18 +408,25 @@ async def invoke(*_args, **_kwargs): with pytest.raises(ArtifactAuthorityDeniedError) as caught: await workflow.reserve(object(), preparation_request=object()) assert caught.value is denial - assert events == (["task", "actor"] if denied_phase == "actor" - else ["task", "actor", "project", "grant"]) + assert events == ( + ["task", "actor"] if denied_phase == "actor" else ["task", "actor", "project", "grant"] + ) materialization.authorize_inspected.assert_not_awaited() workflow._attempts.reserve.assert_not_awaited() @pytest.mark.asyncio -@pytest.mark.parametrize("admission_status,expected_status", ( - ("ready", "ready"), ("stale", "stale"), ("consumed", "conflict"), -)) +@pytest.mark.parametrize( + "admission_status,expected_status", + ( + ("ready", "ready"), + ("stale", "stale"), + ("consumed", "conflict"), + ), +) async def test_existing_durable_preparation_projects_current_admission_state( - admission_status, expected_status, + admission_status, + expected_status, ) -> None: attempt_id = new_record_id() admission_id = new_record_id() @@ -454,9 +456,6 @@ async def test_existing_durable_preparation_projects_current_admission_state( ) - - - @pytest.mark.parametrize( "durable_status", ( @@ -502,6 +501,7 @@ def test_post_byte_locked_context_conflict_maps_to_public_race_code() -> None: assert isinstance(failure, SubmissionBundlePreparationRejected) assert str(failure) == "submission_bundle_preparation_context_changed" + def _capability(prepared, evidence_set_id): service = PreSubmitEvidenceService( SimpleNamespace(), @@ -599,7 +599,9 @@ async def test_verified_submission_lineage_publishes_one_ready_admission( observed_sha256=digest, observed_byte_count=25, ) - put_receipt = SimpleNamespace(id=str(new_record_id()) if observed_confirmation else attempt.receipt_id) + put_receipt = SimpleNamespace( + id=str(new_record_id()) if observed_confirmation else attempt.receipt_id + ) now = datetime.now(UTC) session = SimpleNamespace( scalar=AsyncMock( @@ -638,144 +640,6 @@ async def test_verified_submission_lineage_publishes_one_ready_admission( session.add.assert_called_once_with(admission) -@pytest.mark.asyncio -async def test_selected_pre_terminal_publishes_self_contained_ready_admission() -> None: - manifest = {"schema_version": "submission_manifest.v1", "entries": []} - post_policy = { - "schema_version": "external_post_submit_policy.v1", - "entries": [], - } - post_policy_sha256 = canonical_json_hash(post_policy) - post_policy["policy_sha256"] = post_policy_sha256 - lineage = SelectedPreSubmitAdmissionLineage( - predecessor_submission_id=None, - predecessor_submission_version=None, - guide_id=new_record_id(), - guide_version="v2", - source_snapshot_id=new_record_id(), - source_snapshot_sha256=_sha("1"), - locked_guide_sha256=_sha("2"), - effective_policy_id=new_record_id(), - effective_policy_sha256=_sha("3"), - pre_submit_policy_id=new_record_id(), - pre_submit_policy_sha256=_sha("4"), - effective_plan_sha256=_sha("5"), - rules_sha256=_sha("8"), - external_checker_policies_sha256=_sha("9"), - post_submit_policy_sha256=post_policy_sha256, - post_submit_policy_body=post_policy, - locked_policy_context_hash=_sha("6"), - semantic_manifest_id=new_record_id(), - semantic_manifest_body=manifest, - packet_sha256=_sha("7"), - storage_scheme="s3", - ) - selected = SelectedPreSubmitReservationFacts( - actor_profile_id=new_record_id(), - identity_link_id=new_record_id(), - project_id=new_record_id(), - task_id=new_record_id(), - assignment_id=new_record_id(), - attempt_id=new_record_id(), - idempotency_key=new_record_id(), - attempt_request_digest=_sha("8"), - prepared_generation_id=new_record_id(), - policy_sha256=lineage.effective_plan_sha256, - default_behavior_sha256=WORKSTREAM_DEFAULT_BEHAVIOR_SHA256, - default_input_sha256=_sha("9"), - archive_sha256=_sha("a"), - archive_byte_count=25, - semantic_manifest_sha256=canonical_json_hash(manifest), - execution_budget_ms=120_000, - admission_lineage=lineage, - ) - terminal = { - "request_digest": selected.request_digest, - "outcome": "completed", - "execution": {"eligible": True}, - } - attempt = SimpleNamespace( - id=str(new_record_id()), - producer_request_type="submission_bundle", - producer_ref=str(selected.actor_profile_id), - project_id=str(selected.project_id), - task_id=str(selected.task_id), - sha256=selected.archive_sha256, - byte_count=selected.archive_byte_count, - media_type="application/zip", - replica_id=str(new_record_id()), - receipt_id=str(new_record_id()), - ) - job = SimpleNamespace( - id=str(new_record_id()), - originating_put_attempt_id=attempt.id, - replica_id=attempt.replica_id, - execution_generation=2, - ) - intent = SimpleNamespace( - id=str(new_record_id()), - pre_submit_evidence_set_id=None, - selected_pre_submit_run_id=str(selected.attempt_id), - selected_request_json=selected.canonical_body(), - selected_request_digest=selected.request_digest, - selected_terminal_json=terminal, - selected_terminal_digest=canonical_json_hash(terminal), - ) - replica = SimpleNamespace( - id=attempt.replica_id, - content_id=str(new_record_id()), - verification_state="verified", - availability_state="available", - integrity_state="valid", - ) - content = SimpleNamespace( - id=replica.content_id, - sha256=attempt.sha256, - byte_count=attempt.byte_count, - ) - verification = SimpleNamespace( - id=str(new_record_id()), - verification_job_id=job.id, - execution_generation=job.execution_generation, - outcome="verified", - observed_sha256=attempt.sha256, - observed_byte_count=attempt.byte_count, - ) - receipt = SimpleNamespace(id=attempt.receipt_id) - session = SimpleNamespace( - scalar=AsyncMock( - side_effect=[ - job, - attempt, - intent, - None, - replica, - verification, - content, - receipt, - datetime.now(UTC), - ] - ), - add=Mock(), - flush=AsyncMock(), - ) - - admission = await SubmissionBundleAdmissionPublisher(session).publish_verified( - verification_job_id=job.id, - verification_receipt_id=verification.id, - ) - - assert admission.pre_submit_evidence_set_id is None - assert admission.selected_pre_submit_run_id == str(selected.attempt_id) - assert admission.packet_sha256 == lineage.packet_sha256 - assert admission.semantic_manifest_body == manifest - assert ( - admission.selected_post_submit_policy_sha256 - == lineage.post_submit_policy_sha256 - ) - assert admission.selected_post_submit_policy_body == post_policy - - @pytest.mark.asyncio async def test_observed_confirmed_write_receipt_is_supported() -> None: attempt = SimpleNamespace( From c43223b2b4a642f12e079f52bf1ba401d75ead97 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 07:02:45 +0100 Subject: [PATCH 139/283] [PILOT-10] Split native pagination regression into bounded checks --- .../pilot10-stable-contribution-pagination.md | 9 + .../contributions/exports/test_pagination.py | 284 ++++++++++-------- 2 files changed, 162 insertions(+), 131 deletions(-) diff --git a/.commitrail/changes/pilot10-stable-contribution-pagination.md b/.commitrail/changes/pilot10-stable-contribution-pagination.md index 4e427d1c0..035a01d30 100644 --- a/.commitrail/changes/pilot10-stable-contribution-pagination.md +++ b/.commitrail/changes/pilot10-stable-contribution-pagination.md @@ -109,3 +109,12 @@ Implementation still requires installed-schema proof. - Current-source reconciliation: started from main d47ee1e; reconciled main e31e1777 after PR #539 merged. - Next usable boundary: separate CLI export PR and the pilot closing drill. - Remaining risks: native membership mechanism and restore binding not yet frozen. + +## Pagination regression structure repair + +The native fixed-membership regression now delegates sealed-membership guards, +cursor custody and expiry/CSV checks to three same-module helpers. All 31 +assertions are AST-identical to the previously proven test, and operation order +is preserved. The test and each helper are below the 120-line structural limit. +Ruff, compilation and diff checks pass. This is a test-structure repair; the +previous native proof remains attributed to its exact composed head. diff --git a/backend/tests/contributions/exports/test_pagination.py b/backend/tests/contributions/exports/test_pagination.py index 384207950..43778abb7 100644 --- a/backend/tests/contributions/exports/test_pagination.py +++ b/backend/tests/contributions/exports/test_pagination.py @@ -75,139 +75,13 @@ async def before_project_lock(repository, project_id): task.cancel() await asyncio.gather(task, return_exceptions=True) assert first.status_code == 200, first.text - # The installed guards must protect the original selection even when a - # later real contribution now exists and would match the same query. - async with h.factory() as session: - membership = await session.scalar(select(ContributionExportMembership).where( - ContributionExportMembership.actor_profile_id == str(reader.id), - ContributionExportMembership.project_id == h.submitter_record.project_id, - ContributionExportMembership.page_size == 1, - ).order_by(ContributionExportMembership.exported_at.desc()).limit(1)) - assert membership is not None and membership.sealed and membership.member_count == 2 - export_id = membership.id - retained_facts = {table: await rows(session, table) for table in ( - "contribution_records", "compensation_awards", "final_acceptances", - )} - assert await session.scalar(select(func.count()).select_from(ContributionExportMember).where( - ContributionExportMember.export_id == export_id, - )) == 2 - for statement, parameters in ( - ("UPDATE contribution_export_memberships SET page_size=2 WHERE id=:export", {}), - ("DELETE FROM contribution_export_memberships WHERE id=:export", {}), - ("UPDATE contribution_export_members SET recorded_at=recorded_at + interval '1 second' " - "WHERE export_id=:export", {}), - ("DELETE FROM contribution_export_members WHERE export_id=:export", {}), - ("INSERT INTO contribution_export_members (export_id, contribution_id, recorded_at) " - "SELECT :export, id, created_at FROM contribution_records WHERE id=:late", - {"late": late_outcome.economic.contribution_record_id}), - ): - async with h.factory() as session: - with pytest.raises(IntegrityError) as rejected: - async with session.begin(): - await session.execute(text(statement), {"export": export_id} | parameters) - assert rejected.value.orig.sqlstate == "23514" - async with h.factory() as session: - assert await session.scalar(select(func.count()).select_from(ContributionExportMember).where( - ContributionExportMember.export_id == export_id, - )) == 2 - async with h.factory() as session: - await session.begin() - await session.execute(text( - "INSERT INTO contribution_export_memberships " - "(id, actor_profile_id, audience, project_id, output_format, page_size, " - "contribution_type, recorded_from, recorded_before, member_count, sealed, " - "query_digest, exported_at, expires_at) " - "SELECT :new, actor_profile_id, audience, project_id, output_format, page_size, " - "contribution_type, recorded_from, recorded_before, 3, false, " - "query_digest, exported_at, expires_at " - "FROM contribution_export_memberships WHERE id=:export" - ), {"new": new_record_id(), "export": export_id}) - with pytest.raises(IntegrityError) as unsealed: - await session.commit() - assert unsealed.value.orig.sqlstate == "23514" - await session.rollback() - cursor = first.json()["next_cursor"] - assert cursor is not None - for changed in ({"page_size": 2}, {"format": "csv"}, {"contribution_type": "completed_review"}): - invalid = await signed_access.client.get( - path, params={"page_size": 1, "cursor": cursor} | changed, headers=reader.headers, - ) - assert invalid.status_code == 422, invalid.text - assert invalid.json()["error"]["code"] == "contribution_export_invalid_cursor" - other = await signed_access.actor("other-membership-reader") - await signed_access.grant(admin_access.admin, other, role="project_manager", - project_id=h.submitter_record.project_id) - crossed = await signed_access.client.get( - path, params={"page_size": 1, "cursor": cursor}, headers=other.headers, - ) - assert crossed.status_code == 422, crossed.text - ungranted = await signed_access.actor("ungranted-membership-reader") - concealed = await signed_access.client.get( - path, params={"page_size": 1, "cursor": cursor}, headers=ungranted.headers, + export_id, retained_facts = await _assert_membership_guards(h, reader, late_outcome) + cursor, ids = await _assert_cursor_membership( + h, admin_access, reader, path, first, second_outcome, late_outcome, ) - assert concealed.status_code == 404, concealed.text - next_page = await signed_access.client.get( - path, params={"page_size": 1, "cursor": cursor}, headers=reader.headers, + await _assert_expired_cleanup_and_csv( + h, reader, path, signed_access, export_id, retained_facts, ids, late_outcome, ) - assert next_page.status_code == 200, next_page.text - assert next_page.json()["next_cursor"] is None - assert next_page.json()["exported_at"] == first.json()["exported_at"] - ids = [row["contribution_id"] for page in (first, next_page) for row in page.json()["items"]] - assert set(ids) == {str(h.submitter_record.id), str(second_outcome.economic.contribution_record_id)} - assert str(late_outcome.economic.contribution_record_id) not in ids - assert all(len(row["awards"]) == 2 for page in (first, next_page) for row in page.json()["items"]) - # Construct only private expiry metadata around the same real immutable - # facts; no economic row or clock is changed. The next public first page - # must remove this nonempty expired selection through its native cascade. - expired_id = new_record_id() - async with h.factory() as session, session.begin(): - await session.execute(text( - "INSERT INTO contribution_export_memberships " - "(id, actor_profile_id, audience, project_id, output_format, page_size, " - "contribution_type, recorded_from, recorded_before, member_count, sealed, " - "query_digest, exported_at, expires_at) " - "SELECT :new, actor_profile_id, audience, project_id, output_format, page_size, " - "contribution_type, recorded_from, recorded_before, 3, false, query_digest, " - "exported_at - interval '16 minutes', expires_at - interval '16 minutes' " - "FROM contribution_export_memberships WHERE id=:export" - ), {"new": expired_id, "export": export_id}) - await session.execute(text( - "INSERT INTO contribution_export_members (export_id, contribution_id, recorded_at) " - "SELECT :export, id, created_at FROM contribution_records WHERE project_id=:project" - ), {"export": expired_id, "project": h.submitter_record.project_id}) - await session.execute(text( - "UPDATE contribution_export_memberships SET sealed=true WHERE id=:export" - ), {"export": expired_id}) - fresh = await signed_access.client.get(path, headers=reader.headers) - assert fresh.status_code == 200 - async with h.factory() as session: - assert await session.get(ContributionExportMembership, expired_id) is None - assert {table: await rows(session, table) for table in retained_facts} == retained_facts - assert await session.scalar(select(func.count()).select_from(ContributionExportMember).where( - ContributionExportMember.export_id == expired_id, - )) == 0 - assert {row["contribution_id"] for row in fresh.json()["items"]} == set(ids) | { - str(late_outcome.economic.contribution_record_id), - } - csv_rows, csv_origin, csv_cursor = [], None, None - for page_number in range(3): - params = {"page_size": 1, "format": "csv"} - if csv_cursor is not None: - params["cursor"] = csv_cursor - csv_page = await signed_access.client.get(path, params=params, headers=reader.headers) - assert csv_page.status_code == 200, csv_page.text - if csv_origin is None: - csv_origin = csv_page.headers["X-Workstream-Exported-At"] - assert csv_page.headers["X-Workstream-Exported-At"] == csv_origin - csv_rows.extend(csv.DictReader(StringIO(csv_page.text, newline=""))) - csv_cursor = csv_page.headers.get("X-Workstream-Next-Cursor") - assert (csv_cursor is None) is (page_number == 2) - assert {row["contribution_id"] for row in csv_rows} == { - row["contribution_id"] for row in fresh.json()["items"] - } - assert len(csv_rows) == 6 - async with h.factory() as session: - assert await session.scalar(select(func.count()).select_from(ContributionExportMembership)) >= 2 revoked = await signed_access.client.post( f"/api/v1/admin-role-grants/{grant}/revoke", headers=admin_access.admin.headers | {"Idempotency-Key": str(new_record_id())}, @@ -218,3 +92,151 @@ async def before_project_lock(repository, project_id): path, params={"page_size": 1, "cursor": cursor}, headers=reader.headers, ) assert denied.status_code == 404, denied.text + + +async def _assert_membership_guards(h, reader, late_outcome): + """Protect sealed membership and refuse incomplete private exports.""" + # The installed guards must protect the original selection even when a + # later real contribution now exists and would match the same query. + async with h.factory() as session: + membership = await session.scalar(select(ContributionExportMembership).where( + ContributionExportMembership.actor_profile_id == str(reader.id), + ContributionExportMembership.project_id == h.submitter_record.project_id, + ContributionExportMembership.page_size == 1, + ).order_by(ContributionExportMembership.exported_at.desc()).limit(1)) + assert membership is not None and membership.sealed and membership.member_count == 2 + export_id = membership.id + retained_facts = {table: await rows(session, table) for table in ( + "contribution_records", "compensation_awards", "final_acceptances", + )} + assert await session.scalar(select(func.count()).select_from(ContributionExportMember).where( + ContributionExportMember.export_id == export_id, + )) == 2 + for statement, parameters in ( + ("UPDATE contribution_export_memberships SET page_size=2 WHERE id=:export", {}), + ("DELETE FROM contribution_export_memberships WHERE id=:export", {}), + ("UPDATE contribution_export_members SET recorded_at=recorded_at + interval '1 second' " + "WHERE export_id=:export", {}), + ("DELETE FROM contribution_export_members WHERE export_id=:export", {}), + ("INSERT INTO contribution_export_members (export_id, contribution_id, recorded_at) " + "SELECT :export, id, created_at FROM contribution_records WHERE id=:late", + {"late": late_outcome.economic.contribution_record_id}), + ): + async with h.factory() as session: + with pytest.raises(IntegrityError) as rejected: + async with session.begin(): + await session.execute(text(statement), {"export": export_id} | parameters) + assert rejected.value.orig.sqlstate == "23514" + async with h.factory() as session: + assert await session.scalar(select(func.count()).select_from(ContributionExportMember).where( + ContributionExportMember.export_id == export_id, + )) == 2 + async with h.factory() as session: + await session.begin() + await session.execute(text( + "INSERT INTO contribution_export_memberships " + "(id, actor_profile_id, audience, project_id, output_format, page_size, " + "contribution_type, recorded_from, recorded_before, member_count, sealed, " + "query_digest, exported_at, expires_at) " + "SELECT :new, actor_profile_id, audience, project_id, output_format, page_size, " + "contribution_type, recorded_from, recorded_before, 3, false, " + "query_digest, exported_at, expires_at " + "FROM contribution_export_memberships WHERE id=:export" + ), {"new": new_record_id(), "export": export_id}) + with pytest.raises(IntegrityError) as unsealed: + await session.commit() + assert unsealed.value.orig.sqlstate == "23514" + await session.rollback() + return export_id, retained_facts + + +async def _assert_cursor_membership(h, admin_access, reader, path, first, second_outcome, late_outcome): + """Bind continuations to query, authority and original visible records.""" + signed_access = admin_access.signed + cursor = first.json()["next_cursor"] + assert cursor is not None + for changed in ({"page_size": 2}, {"format": "csv"}, {"contribution_type": "completed_review"}): + invalid = await signed_access.client.get( + path, params={"page_size": 1, "cursor": cursor} | changed, headers=reader.headers, + ) + assert invalid.status_code == 422, invalid.text + assert invalid.json()["error"]["code"] == "contribution_export_invalid_cursor" + other = await signed_access.actor("other-membership-reader") + await signed_access.grant(admin_access.admin, other, role="project_manager", + project_id=h.submitter_record.project_id) + crossed = await signed_access.client.get( + path, params={"page_size": 1, "cursor": cursor}, headers=other.headers, + ) + assert crossed.status_code == 422, crossed.text + ungranted = await signed_access.actor("ungranted-membership-reader") + concealed = await signed_access.client.get( + path, params={"page_size": 1, "cursor": cursor}, headers=ungranted.headers, + ) + assert concealed.status_code == 404, concealed.text + next_page = await signed_access.client.get( + path, params={"page_size": 1, "cursor": cursor}, headers=reader.headers, + ) + assert next_page.status_code == 200, next_page.text + assert next_page.json()["next_cursor"] is None + assert next_page.json()["exported_at"] == first.json()["exported_at"] + ids = [row["contribution_id"] for page in (first, next_page) for row in page.json()["items"]] + assert set(ids) == {str(h.submitter_record.id), str(second_outcome.economic.contribution_record_id)} + assert str(late_outcome.economic.contribution_record_id) not in ids + assert all(len(row["awards"]) == 2 for page in (first, next_page) for row in page.json()["items"]) + return cursor, ids + + +async def _assert_expired_cleanup_and_csv(h, reader, path, signed_access, export_id, retained_facts, ids, late_outcome): + """Clean expired selections without changing facts and preserve CSV pages.""" + # Construct only private expiry metadata around the same real immutable + # facts; no economic row or clock is changed. The next public first page + # must remove this nonempty expired selection through its native cascade. + expired_id = new_record_id() + async with h.factory() as session, session.begin(): + await session.execute(text( + "INSERT INTO contribution_export_memberships " + "(id, actor_profile_id, audience, project_id, output_format, page_size, " + "contribution_type, recorded_from, recorded_before, member_count, sealed, " + "query_digest, exported_at, expires_at) " + "SELECT :new, actor_profile_id, audience, project_id, output_format, page_size, " + "contribution_type, recorded_from, recorded_before, 3, false, query_digest, " + "exported_at - interval '16 minutes', expires_at - interval '16 minutes' " + "FROM contribution_export_memberships WHERE id=:export" + ), {"new": expired_id, "export": export_id}) + await session.execute(text( + "INSERT INTO contribution_export_members (export_id, contribution_id, recorded_at) " + "SELECT :export, id, created_at FROM contribution_records WHERE project_id=:project" + ), {"export": expired_id, "project": h.submitter_record.project_id}) + await session.execute(text( + "UPDATE contribution_export_memberships SET sealed=true WHERE id=:export" + ), {"export": expired_id}) + fresh = await signed_access.client.get(path, headers=reader.headers) + assert fresh.status_code == 200 + async with h.factory() as session: + assert await session.get(ContributionExportMembership, expired_id) is None + assert {table: await rows(session, table) for table in retained_facts} == retained_facts + assert await session.scalar(select(func.count()).select_from(ContributionExportMember).where( + ContributionExportMember.export_id == expired_id, + )) == 0 + assert {row["contribution_id"] for row in fresh.json()["items"]} == set(ids) | { + str(late_outcome.economic.contribution_record_id), + } + csv_rows, csv_origin, csv_cursor = [], None, None + for page_number in range(3): + params = {"page_size": 1, "format": "csv"} + if csv_cursor is not None: + params["cursor"] = csv_cursor + csv_page = await signed_access.client.get(path, params=params, headers=reader.headers) + assert csv_page.status_code == 200, csv_page.text + if csv_origin is None: + csv_origin = csv_page.headers["X-Workstream-Exported-At"] + assert csv_page.headers["X-Workstream-Exported-At"] == csv_origin + csv_rows.extend(csv.DictReader(StringIO(csv_page.text, newline=""))) + csv_cursor = csv_page.headers.get("X-Workstream-Next-Cursor") + assert (csv_cursor is None) is (page_number == 2) + assert {row["contribution_id"] for row in csv_rows} == { + row["contribution_id"] for row in fresh.json()["items"] + } + assert len(csv_rows) == 6 + async with h.factory() as session: + assert await session.scalar(select(func.count()).select_from(ContributionExportMembership)) >= 2 From 8b45c9ce1ad269e8b64700d82a675c8d793fb4f5 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 08:15:46 +0100 Subject: [PATCH 140/283] [PILOT-04] Route production checker completion events --- .../pilot04-workstream-default-checker.md | 13 ++ backend/app/adapters/outbox/__init__.py | 16 +- .../tests/outbox/test_worker_postgresql.py | 34 ++-- .../evaluation_delivery/test_completion.py | 148 +++++++++++++++--- 4 files changed, 177 insertions(+), 34 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index de7993a72..bb254047b 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -238,3 +238,16 @@ intermediate-wait regression. no component-only merge. - Remaining risk: reconcile the final stacked migration and owner metadata with actual `main`, then validate the complete required test union on that tree. + +## Production completion repair + +Independent review found that the production outbox registry selected evaluation +requests but omitted the existing completion handler. The earlier real Rust/MinIO +probe called the executor directly and ended at `evaluation_pending`; it did not +prove worker completion routing. The registry now composes the canonical +completion handler. The new native production-registry test exercises request +delivery, emitted completion delivery, acknowledgment and duplicate refusal for +both human review and shared automatic acceptance with complete awards. Its +runtime result remains pending until the isolated PostgreSQL command completes. +Publication must remove the accidentally stacked PILOT-02/PILOT-10 source and +reconcile the selected-flow successor with the actual merged migration chain. diff --git a/backend/app/adapters/outbox/__init__.py b/backend/app/adapters/outbox/__init__.py index ad5fef55e..17ba420e3 100644 --- a/backend/app/adapters/outbox/__init__.py +++ b/backend/app/adapters/outbox/__init__.py @@ -34,16 +34,21 @@ def outbox_delivery( def production_outbox_delivery(session_factory): """Install exact assignment and selected evaluation handlers.""" from app.adapters.artifacts import worker_post_submission_materialization - from app.adapters.auth import outbox_dispatch_authorization, assignment_invalidation_authorization + from app.adapters.auth import ( + outbox_dispatch_authorization, + assignment_invalidation_authorization, + ) from app.adapters.tasks import ( TransactionalAssignmentInvalidationHandler, + evaluation_completion_handler, evaluation_request_handler, ) - from app.modules.checkers.api.execution import REQUEST_EVENT + from app.modules.checkers.api.execution import COMPLETION_EVENT, REQUEST_EVENT from app.modules.tasks.api.assignment_invalidation import ASSIGNMENT_INVALIDATION_EVENT return outbox_delivery( - session_factory, authorization_factory=outbox_dispatch_authorization, + session_factory, + authorization_factory=outbox_dispatch_authorization, registry=HandlerRegistry( [ ( @@ -65,6 +70,11 @@ def production_outbox_delivery(session_factory): ), ), ), + ( + COMPLETION_EVENT, + 1, + evaluation_completion_handler(sessions=session_factory), + ), ] ), options=DeliveryOptions(), diff --git a/backend/tests/outbox/test_worker_postgresql.py b/backend/tests/outbox/test_worker_postgresql.py index b8963c3ed..df9e822b7 100644 --- a/backend/tests/outbox/test_worker_postgresql.py +++ b/backend/tests/outbox/test_worker_postgresql.py @@ -189,7 +189,7 @@ def publish(*, args): async def test_production_registry_claims_only_registered_features(delivery_harness): from app.adapters.outbox import production_outbox_delivery - from app.modules.checkers.api.execution import REQUEST_EVENT + from app.modules.checkers.api.execution import COMPLETION_EVENT, REQUEST_EVENT h = delivery_harness event = await h.append() @@ -197,6 +197,7 @@ async def test_production_registry_claims_only_registered_features(delivery_harn assert production._registry.keys == ( ("TaskAssignmentAuthorityInvalidationRequested", 1), (REQUEST_EVENT, 1), + (COMPLETION_EVENT, 1), ) assert (await production.candidates()).items == () assert await production.deliver(event.event_id, h.project, "worker") is None @@ -257,9 +258,14 @@ async def stubborn(envelope): properties={"correlation_id": task_id}, body=((str(event.event_id), str(h.project)), {}, {}), ) - request = Request(message, app=worker.celery_app, task=task, decoded=True, - on_ack=lambda *args: acked.set(), - on_reject=lambda *args: rejected.append(args)) + request = Request( + message, + app=worker.celery_app, + task=task, + decoded=True, + on_ack=lambda *args: acked.set(), + on_reject=lambda *args: rejected.append(args), + ) result = request.execute_using_pool(pool) with pytest.raises(ExceptionWithTraceback) as timed_out: result.get(timeout=15) @@ -268,13 +274,21 @@ async def stubborn(envelope): assert rejected == [] # The pool owns waitpid/reaping. A competing join can observe stale # returncode metadata; the owned child sentinel proves actual exit. - assert wait([child.sentinel], timeout=5), "hard timeout must terminate the stuck worker process" + assert wait([child.sentinel], timeout=5), ( + "hard timeout must terminate the stuck worker process" + ) duplicate_id = str(new_record_id()) - duplicate = Request(Message( - headers={"id": duplicate_id, "task": task.name}, - properties={"correlation_id": duplicate_id}, body=message.body, - ), app=worker.celery_app, task=task, decoded=True, - on_reject=lambda *args: rejected.append(args)) + duplicate = Request( + Message( + headers={"id": duplicate_id, "task": task.name}, + properties={"correlation_id": duplicate_id}, + body=message.body, + ), + app=worker.celery_app, + task=task, + decoded=True, + on_reject=lambda *args: rejected.append(args), + ) failed, body, _ = duplicate.execute_using_pool(pool).get(timeout=15) assert not failed and ast.literal_eval(body) == {"status": "delivery_unavailable"} assert duplicate.worker_pid != child.pid diff --git a/backend/tests/tasks/evaluation_delivery/test_completion.py b/backend/tests/tasks/evaluation_delivery/test_completion.py index 33fa9e643..ab3dd0fa8 100644 --- a/backend/tests/tasks/evaluation_delivery/test_completion.py +++ b/backend/tests/tasks/evaluation_delivery/test_completion.py @@ -8,14 +8,18 @@ from app.adapters.auth import outbox_dispatch_authorization from app.adapters.outbox import outbox_delivery, production_outbox_delivery from app.adapters.tasks import evaluation_completion_handler -from app.modules.checkers.api.execution import COMPLETION_EVENT +from app.modules.checkers.api.execution import COMPLETION_EVENT, REQUEST_EVENT from app.modules.outbox.api import HandlerOutcome, FinalizationCause, DeliveryOptions from app.modules.outbox.registry import HandlerRegistry from app.modules.tasks.post_submit_routing.outcome import TaskPostSubmitOutcome from tests.authorization.post_submit_routing.support import provision_router from tests.tasks.post_submit_routing.test_source_preparation import routing_source -from tests.tasks.post_submit_routing.outcome_support import authorized_routing_source, outcome_snapshot -from .support import delivery_fixture, outcome +from tests.tasks.post_submit_routing.outcome_support import ( + authorized_routing_source, + outcome_snapshot, +) +from tests.post_submit_materialization_helpers import material_fixture +from .support import delivery_fixture, outcome, state async def completion_delivery(h, handler=None): @@ -23,20 +27,37 @@ async def completion_delivery(h, handler=None): await provision_router(h.factory) await delivery_fixture(h) return outbox_delivery( - h.factory, authorization_factory=outbox_dispatch_authorization, options=DeliveryOptions(), - registry=HandlerRegistry([(COMPLETION_EVENT, 1, handler or evaluation_completion_handler(sessions=h.factory))]), + h.factory, + authorization_factory=outbox_dispatch_authorization, + options=DeliveryOptions(), + registry=HandlerRegistry( + [(COMPLETION_EVENT, 1, handler or evaluation_completion_handler(sessions=h.factory))] + ), ) async def assert_committed(h, *, human, award_count): async with h.factory() as session: - assert await session.scalar(text("SELECT status FROM public.workstream_tasks WHERE id=:id"), - {"id": str(h.request.task_id)}) == ("review_pending" if human else "accepted") - for table, count in (("task_post_submit_routing_manifests", 1), ("final_acceptances", int(not human)), - ("contribution_records", int(not human)), ("compensation_awards", award_count), - ("reviews", 0)): + assert await session.scalar( + text("SELECT status FROM public.workstream_tasks WHERE id=:id"), + {"id": str(h.request.task_id)}, + ) == ("review_pending" if human else "accepted") + for table, count in ( + ("task_post_submit_routing_manifests", 1), + ("final_acceptances", int(not human)), + ("contribution_records", int(not human)), + ("compensation_awards", award_count), + ("reviews", 0), + ): assert await session.scalar(text(f"SELECT count(*) FROM public.{table}")) == count - assert await session.scalar(text("SELECT public.task_routing_outcome_complete(m) FROM public.task_post_submit_routing_manifests m")) is True + assert ( + await session.scalar( + text( + "SELECT public.task_routing_outcome_complete(m) FROM public.task_post_submit_routing_manifests m" + ) + ) + is True + ) async def commit_before_ack(h, monkeypatch, *, human, award_count): @@ -60,12 +81,19 @@ async def acknowledge(envelope): return result delivery = await completion_delivery(h, acknowledge) - running = asyncio.create_task(delivery.deliver(h.source["completion_event_id"], h.request.project_id, "completion")) + running = asyncio.create_task( + delivery.deliver(h.source["completion_event_id"], h.request.project_id, "completion") + ) try: await asyncio.wait_for(staged.wait(), 10) assert not running.done() async with h.factory() as session: - assert await session.scalar(text("SELECT count(*) FROM public.task_post_submit_routing_manifests")) == 0 + assert ( + await session.scalar( + text("SELECT count(*) FROM public.task_post_submit_routing_manifests") + ) + == 0 + ) assert await session.scalar(text("SELECT count(*) FROM public.final_acceptances")) == 0 release.set() receipt = await asyncio.wait_for(running, 10) @@ -78,7 +106,9 @@ async def acknowledge(envelope): await asyncio.gather(running, return_exceptions=True) -async def test_completion_handler_true_commits_before_ack_without_rev(tmp_path, isolated_database_env, monkeypatch): +async def test_completion_handler_true_commits_before_ack_without_rev( + tmp_path, isolated_database_env, monkeypatch +): from app.adapters.tasks.routing_acceptance import RoutingAcceptanceAdapter async def forbidden(*args, **kwargs): @@ -92,20 +122,33 @@ async def forbidden(*args, **kwargs): @pytest.mark.parametrize("awards", [(), ("money", "project_points")]) async def test_completion_handler_false_commits_acceptance_before_ack( - tmp_path, isolated_database_env, live_acceptance_lifecycle, monkeypatch, awards, + tmp_path, + isolated_database_env, + live_acceptance_lifecycle, + monkeypatch, + awards, ): - async with routing_source(tmp_path, isolated_database_env, human_review_required=False, contribution_awards=awards) as h: + async with routing_source( + tmp_path, isolated_database_env, human_review_required=False, contribution_awards=awards + ) as h: await commit_before_ack(h, monkeypatch, human=False, award_count=len(awards)) @pytest.mark.parametrize("human", [True, False]) -async def test_completion_handler_committed_replay_is_exact(tmp_path, isolated_database_env, live_acceptance_lifecycle, human): - async with authorized_routing_source(tmp_path, isolated_database_env, human_review_required=human) as h: +async def test_completion_handler_committed_replay_is_exact( + tmp_path, isolated_database_env, live_acceptance_lifecycle, human +): + async with authorized_routing_source( + tmp_path, isolated_database_env, human_review_required=human + ) as h: handler = evaluation_completion_handler(sessions=h.factory) assert await handler(h.envelope) is HandlerOutcome.ACKNOWLEDGE if not human: from tests.reviews.lifecycle.transition_support import command_for, transition - stopped = await transition(await command_for(live_acceptance_lifecycle.target.id, "draining")) + + stopped = await transition( + await command_for(live_acceptance_lifecycle.target.id, "draining") + ) assert stopped.generation == 3 async with h.factory() as session: saved = await outcome_snapshot(session) @@ -116,5 +159,68 @@ async def test_completion_handler_committed_replay_is_exact(tmp_path, isolated_d assert await handler(h.envelope) is HandlerOutcome.REJECT -def test_completion_handler_is_absent_from_production_registry(): - assert (COMPLETION_EVENT, 1) not in production_outbox_delivery(None)._registry.keys +def test_completion_handler_is_registered_in_production_registry(): + assert (COMPLETION_EVENT, 1) in production_outbox_delivery(None)._registry.keys + + +@pytest.mark.parametrize("human", [True, False]) +async def test_production_registry_delivers_request_then_completion_exactly_once( + tmp_path, + isolated_database_env, + live_acceptance_lifecycle, + monkeypatch, + human, +): + """Production registration must consume its own emitted completion event.""" + from app.adapters import artifacts as artifact_adapters + + awards = () if human else ("money", "project_points") + async with material_fixture( + tmp_path, + isolated_database_env, + human_review_required=human, + contribution_awards=awards, + ) as h: + await provision_router(h.factory) + await delivery_fixture(h) + monkeypatch.setattr( + artifact_adapters, + "worker_post_submission_materialization", + lambda *, sessions: h.service, + ) + delivery = production_outbox_delivery(h.factory) + assert delivery._registry.keys[-2:] == ( + (REQUEST_EVENT, 1), + (COMPLETION_EVENT, 1), + ) + + request_receipt = await delivery.deliver( + h.created.evaluation_event_id, + h.request.project_id, + "production-request", + ) + assert outcome(request_receipt)["delivery_state"] == "acknowledged" + completed = await state(h) + assert completed["run"]["status"] == "completed" + completion_event_id = completed["run"]["completion_event_id"] + assert completion_event_id is not None + + completion_receipt = await delivery.deliver( + completion_event_id, + h.request.project_id, + "production-completion", + ) + assert outcome(completion_receipt)["delivery_state"] == "acknowledged" + await assert_committed(h, human=human, award_count=len(awards)) + async with h.factory() as session: + snapshot = await outcome_snapshot(session) + assert ( + await delivery.deliver( + completion_event_id, + h.request.project_id, + "production-completion-replay", + ) + is None + ) + async with h.factory() as session: + assert await outcome_snapshot(session) == snapshot From 8e01fa7f5014682b0ed9bc02e5f34b48b94ababf Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 08:22:04 +0100 Subject: [PATCH 141/283] Revert "[PILOT-04] Reconcile ordered migration stack" This reverts commit 86b61120bc0f1799bd8a87dcf4f3fc77ea33c7d7, reversing changes made to f16f7d63a281a6942567e09e76683a7f8d4a26a6. --- .ci/behavior-ownership/partition.v1.json | 60 -- .../pilot02-atomic-json-draft-import.md | 495 -------------- .../changes/pilot02-bulk-transitions-cli.md | 358 ----------- .../pilot10-stable-contribution-pagination.md | 120 ---- README.md | 8 - backend/alembic/env.py | 3 - .../versions/0034_task_import_batches.py | 579 ----------------- .../versions/0035_task_batch_transitions.py | 486 -------------- .../0036_contribution_export_pages.py | 314 --------- backend/app/adapters/artifacts/__init__.py | 14 +- .../app/adapters/contributions/__init__.py | 6 +- backend/app/adapters/tasks/__init__.py | 47 -- backend/app/api/deps/authorization.py | 62 -- backend/app/api/deps/contribution_exports.py | 20 +- .../app/api/deps/task_batch_transitions.py | 25 - backend/app/api/routes/contributions.py | 29 +- backend/app/db/models.py | 4 - .../modules/artifacts/task_import_sources.py | 133 +--- backend/app/modules/audit/schemas.py | 5 +- .../artifact_project_authority.py | 14 +- .../app/modules/authorization/catalogue.py | 8 +- .../authorization/domain/action_groups.py | 3 - .../app/modules/authorization/domain/audit.py | 2 - .../authorization/domain/audit_targets.py | 5 +- .../authorization/domain/task_authority.py | 28 +- backend/app/modules/authorization/prepared.py | 9 +- backend/app/modules/authorization/runtime.py | 3 - .../authorization/task_authorization.py | 37 +- .../app/modules/contributions/api/records.py | 13 +- .../modules/contributions/records/cursors.py | 131 ---- .../modules/contributions/records/models.py | 57 +- .../contributions/records/read_facts.py | 15 +- .../contributions/records/read_repository.py | 129 +--- .../contributions/records/read_service.py | 19 +- .../tasks/api/task_batch_transition.py | 62 -- backend/app/modules/tasks/api/task_import.py | 121 +--- .../tasks/api/task_import_membership.py | 26 - .../app/modules/tasks/api/transition_audit.py | 2 +- .../app/modules/tasks/authorized_commands.py | 266 ++------ backend/app/modules/tasks/command_replay.py | 12 +- backend/app/modules/tasks/models.py | 179 +----- backend/app/modules/tasks/router.py | 59 +- backend/app/modules/tasks/schemas.py | 77 --- .../tasks/task_batch_transition/__init__.py | 1 - .../tasks/task_batch_transition/models.py | 165 ----- .../tasks/task_batch_transition_router.py | 69 -- .../modules/tasks/task_batch_transitions.py | 210 ------ .../app/modules/tasks/task_import_batches.py | 292 --------- .../modules/tasks/task_import_membership.py | 86 --- backend/scripts/behavior_ownership.py | 18 - backend/scripts/test_lane_catalogue.py | 11 +- .../tests/authorization/catalogue_fixtures.py | 4 - .../task_authority/test_audit_contract.py | 13 +- .../test_management_commands.py | 41 -- .../test_management_participants.py | 109 ---- backend/tests/authorization/test_catalogue.py | 4 +- backend/tests/conftest.py | 14 - .../contributions/exports/test_pagination.py | 242 ------- .../exports/test_source_reads.py | 4 +- .../contributions/test_export_cursors.py | 94 --- .../test_export_model_registry.py | 26 - .../contributions/test_export_projection.py | 58 +- .../test_task_batch_transition_contract.py | 136 ---- .../tasks/test_task_batch_transitions.py | 367 ----------- .../tasks/test_task_import_batch_bindings.py | 68 -- .../tasks/test_task_import_batch_contract.py | 69 -- .../tests/tasks/test_task_import_batches.py | 607 ------------------ backend/tests/test_alembic.py | 2 +- backend/tests/test_ci_lane_catalogue.py | 11 +- cli/README.md | 79 --- cli/internal/api/client.go | 10 +- cli/internal/api/task_import_batch.go | 305 --------- cli/internal/api/task_import_source.go | 123 ---- cli/internal/command/command.go | 1 - cli/internal/command/task_batch.go | 99 --- cli/internal/command/task_batch_commands.go | 106 --- cli/internal/command/task_batch_source.go | 92 --- cli/internal/taskimport/convert.go | 231 ------- cli/internal/taskimport/convert_test.go | 115 ---- cli/internal/taskimport/json.go | 155 ----- cli/internal/taskimport/json_test.go | 49 -- cli/tests/integration/test_http_boundary.py | 3 - .../test_task_batch_commands_http.py | 269 -------- cli/tests/integration/test_task_batch_csv.py | 102 --- .../test_task_batch_sources_http.py | 158 ----- .../authorization_activation_custody.md | 9 - docs/roadmap_status.md | 23 +- docs/spec_authorization_service.md | 9 - docs/spec_chunk_4_task_queue_assignment.md | 78 +-- docs/spec_contribution_compensation.md | 46 +- .../contracts/authorization_context_get.json | 322 +++++----- 91 files changed, 367 insertions(+), 8783 deletions(-) delete mode 100644 .commitrail/changes/pilot02-atomic-json-draft-import.md delete mode 100644 .commitrail/changes/pilot02-bulk-transitions-cli.md delete mode 100644 .commitrail/changes/pilot10-stable-contribution-pagination.md delete mode 100644 backend/alembic/versions/0034_task_import_batches.py delete mode 100644 backend/alembic/versions/0035_task_batch_transitions.py delete mode 100644 backend/alembic/versions/0036_contribution_export_pages.py delete mode 100644 backend/app/api/deps/task_batch_transitions.py delete mode 100644 backend/app/modules/contributions/records/cursors.py delete mode 100644 backend/app/modules/tasks/api/task_batch_transition.py delete mode 100644 backend/app/modules/tasks/api/task_import_membership.py delete mode 100644 backend/app/modules/tasks/task_batch_transition/__init__.py delete mode 100644 backend/app/modules/tasks/task_batch_transition/models.py delete mode 100644 backend/app/modules/tasks/task_batch_transition_router.py delete mode 100644 backend/app/modules/tasks/task_batch_transitions.py delete mode 100644 backend/app/modules/tasks/task_import_batches.py delete mode 100644 backend/app/modules/tasks/task_import_membership.py delete mode 100644 backend/tests/authorization/task_authority/test_management_participants.py delete mode 100644 backend/tests/contributions/exports/test_pagination.py delete mode 100644 backend/tests/contributions/test_export_cursors.py delete mode 100644 backend/tests/contributions/test_export_model_registry.py delete mode 100644 backend/tests/tasks/test_task_batch_transition_contract.py delete mode 100644 backend/tests/tasks/test_task_batch_transitions.py delete mode 100644 backend/tests/tasks/test_task_import_batch_bindings.py delete mode 100644 backend/tests/tasks/test_task_import_batch_contract.py delete mode 100644 backend/tests/tasks/test_task_import_batches.py delete mode 100644 cli/internal/api/task_import_batch.go delete mode 100644 cli/internal/api/task_import_source.go delete mode 100644 cli/internal/command/task_batch.go delete mode 100644 cli/internal/command/task_batch_commands.go delete mode 100644 cli/internal/command/task_batch_source.go delete mode 100644 cli/internal/taskimport/convert.go delete mode 100644 cli/internal/taskimport/convert_test.go delete mode 100644 cli/internal/taskimport/json.go delete mode 100644 cli/internal/taskimport/json_test.go delete mode 100644 cli/tests/integration/test_task_batch_commands_http.py delete mode 100644 cli/tests/integration/test_task_batch_csv.py delete mode 100644 cli/tests/integration/test_task_batch_sources_http.py diff --git a/.ci/behavior-ownership/partition.v1.json b/.ci/behavior-ownership/partition.v1.json index f851ad5bf..fcf78291a 100644 --- a/.ci/behavior-ownership/partition.v1.json +++ b/.ci/behavior-ownership/partition.v1.json @@ -116,10 +116,6 @@ "group": "shared", "target": "backend/app/api/deps/rate_controls.py" }, - { - "group": "lifecycle", - "target": "backend/app/api/deps/task_batch_transitions.py" - }, { "group": "shared", "target": "backend/app/api/router.py" @@ -404,14 +400,6 @@ "group": "artifacts", "target": "backend/app/modules/artifacts/schemas.py" }, - { - "group": "artifacts", - "target": "backend/app/modules/artifacts/selected_pre_submit_admission.py" - }, - { - "group": "artifacts", - "target": "backend/app/modules/artifacts/selected_pre_submit_execution.py" - }, { "group": "artifacts", "target": "backend/app/modules/artifacts/service.py" @@ -664,10 +652,6 @@ "group": "auth", "target": "backend/app/modules/authorization/domain/post_submit_routing.py" }, - { - "group": "auth", - "target": "backend/app/modules/authorization/domain/pre_submit.py" - }, { "group": "auth", "target": "backend/app/modules/authorization/domain/prepared_adapter_bindings.py" @@ -788,10 +772,6 @@ "group": "auth", "target": "backend/app/modules/authorization/post_submit_routing_authorization.py" }, - { - "group": "auth", - "target": "backend/app/modules/authorization/pre_submit_authorization.py" - }, { "group": "auth", "target": "backend/app/modules/authorization/pre_submit_materialization.py" @@ -908,10 +888,6 @@ "group": "artifacts", "target": "backend/app/modules/checkers/api/default_checker.py" }, - { - "group": "artifacts", - "target": "backend/app/modules/checkers/api/evaluation_contract.py" - }, { "group": "artifacts", "target": "backend/app/modules/checkers/api/execution.py" @@ -932,10 +908,6 @@ "group": "artifacts", "target": "backend/app/modules/checkers/api/history.py" }, - { - "group": "artifacts", - "target": "backend/app/modules/checkers/api/material.py" - }, { "group": "artifacts", "target": "backend/app/modules/checkers/api/materialization.py" @@ -1136,10 +1108,6 @@ "group": "lifecycle", "target": "backend/app/modules/contributions/records/csv.py" }, - { - "group": "lifecycle", - "target": "backend/app/modules/contributions/records/cursors.py" - }, { "group": "lifecycle", "target": "backend/app/modules/contributions/records/models.py" @@ -1660,10 +1628,6 @@ "group": "lifecycle", "target": "backend/app/modules/tasks/api/submitted_bundle.py" }, - { - "group": "lifecycle", - "target": "backend/app/modules/tasks/api/task_batch_transition.py" - }, { "group": "lifecycle", "target": "backend/app/modules/tasks/api/task_detail.py" @@ -1672,10 +1636,6 @@ "group": "lifecycle", "target": "backend/app/modules/tasks/api/task_import.py" }, - { - "group": "lifecycle", - "target": "backend/app/modules/tasks/api/task_import_membership.py" - }, { "group": "lifecycle", "target": "backend/app/modules/tasks/api/transition_audit.py" @@ -1780,26 +1740,6 @@ "group": "lifecycle", "target": "backend/app/modules/tasks/submitted_bundle.py" }, - { - "group": "lifecycle", - "target": "backend/app/modules/tasks/task_batch_transition/models.py" - }, - { - "group": "lifecycle", - "target": "backend/app/modules/tasks/task_batch_transition_router.py" - }, - { - "group": "lifecycle", - "target": "backend/app/modules/tasks/task_batch_transitions.py" - }, - { - "group": "lifecycle", - "target": "backend/app/modules/tasks/task_import_batches.py" - }, - { - "group": "lifecycle", - "target": "backend/app/modules/tasks/task_import_membership.py" - }, { "group": "auth", "target": "backend/app/schemas/auth.py" diff --git a/.commitrail/changes/pilot02-atomic-json-draft-import.md b/.commitrail/changes/pilot02-atomic-json-draft-import.md deleted file mode 100644 index cfe2939d2..000000000 --- a/.commitrail/changes/pilot02-atomic-json-draft-import.md +++ /dev/null @@ -1,495 +0,0 @@ -# PILOT-02B — Import one verified JSON source into DRAFT Tasks atomically - -- Initiative: `None` -- Durable disposition: `Planned` -- Intended merge outcome: A covered Project Manager imports one verified project-bound JSON source into one immutable batch and its DRAFT Tasks, with exact replay and complete rollback. - -## Intent - -Issue [489](https://github.com/Flow-Research/workstream/issues/489) requires a -real 200-row file to produce 200 DRAFT Tasks before separate screen and release. -PILOT-02A provides exact source custody but creates no Tasks. This chunk supplies -that missing JSON-to-DRAFT operation and a covered-manager batch-status read. -Issue #489 remains open after this chunk; batch transitions and CLI remain. - -## Current behavior - -The implementation incorporates merged source prerequisite PR520 on main -`d3c50e1500beffea684fe881cd0a2b3431e6ccb9`. Its parser in `tasks/api/task_import.py` -accepts one strict UTF-8 JSON document with 1..500 rows, required case-sensitive -external IDs, indexed duplicate errors and an 8 MiB ceiling. ART's -`api/task_import_source.py` and `task_import_sources.py` own project-bound -declaration, admission, fresh authority, verified reads and provider recovery. - -`tasks/authorized_commands.py` owns canonical create/screen/release and their -per-task AUTH/audit; each public command opens its own root transaction. -`command_replay.py` reserves one Task's actor/action/key namespace and requires -fresh authority before recovery. Its receipt cannot represent a whole batch. -`WorkstreamTask` has source fields, but no batch record or project/external-ID -unique constraint. Its existing `import_batch_id` is nullable string metadata; -it is not an authoritative native-UUID batch relationship. - -## Bounded change - -### Allowed - -- TASK: `api/task_import.py`, `api/transition_audit.py`, a cohesive `task_import_batches.py`, - `authorized_commands.py`, `command_replay.py`, `models.py`, `schemas.py`, - `repository.py` and `router.py`: typed import/status contracts, immutable batch - receipt and row membership, server provenance and reuse of canonical creation. -- Coordinated shared extraction: `task_import_membership.py` and its typed - `api/task_import_membership.py` are the single native original-response/member - validator used by import/status and the separate bulk owner. SCREEN/RELEASE - prepare/authorize/stage phases preserve the existing single-Task wrapper; - CREATE and source preparation remain unchanged. Retain the native participant - test in `tests/authorization/task_authority/test_management_participants.py` - and its exact shared-lane/owner inventory. -- ART: `task_import_sources.py` implements TASK’s bounded source-consumer - preparation/binding port over the existing verified source. ART already - depends on TASK’s canonical parser; the consumer contract remains in TASK - `api/task_import.py` to preserve the acyclic owner graph. Existing ART public - source/AUTH contracts remain intact. No second provider path, storage lifecycle - or inspector. -- Composition: existing `adapters/tasks/__init__.py`, - `adapters/artifacts/__init__.py`, `adapters/auth/__init__.py` and - `api/deps/authorization.py`: explicit owner ports and one transaction root. -- AUTH: exact batch import/status resource facts, preparation and closed - action/permission/resource classifications in the existing TASK authority - owner; reuse covered Project Manager grant evaluation and canonical denials. -- Focused TASK/ART/AUTH public-contract and native PostgreSQL/MinIO tests; - affected ownership/lane/inventory expectations and the selected MCP - `authorization_context_get` snapshot for additive ActionId parity; current TASK/ART/AUTH specs, - README and roadmap claims for this chunk only. -- AUDIT: the existing closed TaskCreated payload source-type classification in - `audit/schemas.py`; preserve every existing type and canonical event owner. -- One coordinated successor migration and its graph/reset/fingerprint consumers, - authored solely by the delegated migration owner after final schema handoff. - This planning work authors no migration and reserves no ordinal in advance. - -### Not allowed - -- PR520 source branch edits, batch screen/release, Task release/assignment, - contributor task creation, CLI/frontend, CSV ingestion, external adapters or - checker/runtime changes; no dependency on PILOT-04 execution. -- Changes to the normal screen/release guide locks, policy validation, - compensation selection, hidden completion/routing or false-guide readiness. -- Route-to-route calls, per-row commits/savepoint success, copied TASK transition - rules, direct product filesystem/provider access or invented byte receipts. -- Retained-row deletion, automatic repair/backfill of conflicts, unrestricted - AUTH strings, threshold/skip/runner weakening, deployment, merge or issue closure. - -## Design and decisions - -1. Public import selects a project and verified source with exactly one UUID - idempotency key; input supplies no Task state, creator, locked lineage or - server provenance. First import verifies actual provider bytes and parses - them before the TASK write root. Committed exact-file replay instead recovers - immutable IDs/facts from verified native original-source/receipt ancestry, - with fresh batch/source authority and no provider read or reinterpretation. - A different selected source needs its own actual verified receipt and the same - exact original byte identity/count; a client-claimed digest is insufficient. - Typed prepared facts bind source/project, exact SHA/count and actual - verification ancestry. Inside the write root, the ART participant validates - the immutable reference again without provider I/O or a separate commit. -2. TASK owns a UUIDv7 batch record, exact received-file commitment and ordered - row-to-Task membership. Project plus received-file identity governs exact-file - recovery; actor/action/key receipts distinguish retries from changed requests. - TASK row IDs use `new_record_id()` and are recovered from stored facts. - A source supplied by another covered manager conveys no inherited authority. -3. One root reserves the batch, acquires deterministic TASK/custody locks before - AUTH, and composes flush-only canonical create participants. Every new row - retains its own exact CREATE decision and normal `TaskCreated` audit. Batch, - all DRAFT Tasks, source binding, related receipts and successful evidence - commit together. Any row failure removes all these effects; canonical denied - evidence is retained through the correct AUTH owner after rollback. -4. Enforce case-sensitive `(project_id, external_task_id)` uniqueness in - PostgreSQL, including concurrent imports. Same external ID in another project - is allowed; an existing conflicting ID rejects the complete new batch with - indexed errors. Preserve exact source bytes rather than hashing reserialized - rows as the file identity. Imported provenance is server-stamped JSON custody; - a converted CSV is never described as original server-retained CSV. -5. Exact replay returns the original ordered Task IDs and immutable creation - facts with fresh covered-manager authority and no additional creation effects. - It cannot mutate Tasks that subsequently advanced. Existing single-Task - command replay/state-conflict behavior remains unchanged. Status reads are - project-scoped and conceal foreign or revoked access without source coordinates. -6. The inspected string `import_batch_id` is genuinely caller-supplied metadata: - retained public fixtures use `private-import-batch` and `ready-private-import`, - and the Go management contract accepts `batch`. It cannot be cast to an owned - UUID reference. The proposed handoff preserves that metadata unchanged and - gives the new ordered membership table the authoritative native batch/Task - relationship. Newly imported rows may expose the native batch UUID spelling - through that string metadata field. Batch APIs select the new UUID owner, - never arbitrary metadata; a manually supplied spelling creates no membership. - Existing management/contributor projection and concealment stay unchanged. - A duplicate project/external-ID preflight must stop with a diagnostic, without - deleting or rewriting retained Tasks. Affected review freezes this mapping, - exact replay AUTH facts and lock order before application coding. - -### Proposed schema and replay handoff for affected review - -- Batch: UUIDv7 ID, project UUID, original source UUID, exact SHA/count, - verified ART ancestry, row count, original actor/link and immutable creation - receipt/result. Unique received-file identity is project plus SHA/count. -- Ordered membership: native batch and Task UUIDs, project, zero-based row index, - external ID, normalized row digest and exact CREATE decision. Composite custody - binds each member to its batch/project and Task/project. Each Task has one - import membership; batch row indexes and project/external IDs are unique. -- Retry receipt: actor/action/UUID key namespace, exact project/source selector - request digest, original batch ID and immutable ordered result. A changed - selector under the same key conflicts even when the alternative source has - identical bytes. A new key for the same exact project/file recovers the - original batch after current authority and actual original custody checks. -- Fresh replay authorization binds the current caller to the stored batch/source - and manifest digest. It does not borrow the original actor, issue new CREATE - effects or pretend an advanced Task is DRAFT. Status can show current row - states separately from immutable creation facts. Existing single-Task command - state-conflict semantics remain intact. -- The ART binding participant validates actual immutable source/verification - rows in the caller's root; an application-created DTO supplies no authority. - The reviewed handoff must name the original source ID/operation identity, - put-attempt ID, artifact content/replica IDs, verification job ID/generation - and append-only verification receipt with its observed SHA/count. Exactly one - existing operation acknowledgement or confirmed observation receipt must bind - that same attempt and stored object ancestry. Reuse ART's existing native - admission/receipt custody pattern; do not copy it into TASK or accept a DTO as - proof. Initial import still uses the existing actual verified-byte read. - Committed recovery validates retained immutable ancestry through an ART-owned - participant and must not depend on the source read helper's current replica - availability/integrity flags, active namespace or provider access. Native - substitutions must fail without treating changed operational health as a new - import or reinterpreting original rows. - Direct SQL must reject foreign ancestry, partial closure and changed tuples. - Native FK representations follow each existing owner, including string-mapped - actor/audit UUIDs. The sole migration author receives the reviewed field/lock - contract against then-current main before allocating a linear successor. - -### Proposed public and row-mapping contract - -- POST `/projects/{project_id}/task-import-batches` accepts a closed - `{source_id: UUID}` body and the shared UUID idempotency header. Its import - action is `project.task.import`; proposed native resource facts use the - bounded `task_import_batch` classification with project/source identity. -- GET `/projects/{project_id}/task-import-batches/{batch_id}` uses - `project.task.import_batch.read`, returns only native membership, and separates - immutable original creation facts from current Task states. All responses are - bounded by the retained maximum 500 rows and keep document row order. -- The validated source's instruction fields map directly to canonical TaskCreate - fields. Server metadata stamps additive source type `json_import`, - `source_ref=task-import-source:`, the actual verified - `source_payload_hash`, and native batch UUID spelling in `import_batch_id`. - Select exactly `json_import` in the server-only ImportedTaskCreate subtype, - TaskTransitionFacts and the closed TaskCreated payload. Public manual-create - TaskCreate keeps its existing three source types; callers cannot select the - server-only import value through that route. The sole-author successor updates the current - lifecycle SQL custody validator to admit that same exact token; historical - baseline files stay unchanged. Normal manual/markdown/CSV entries remain. - Caller input cannot choose or relabel these atomic-import server stamps. - These labels add no authority; a manually stamped matching label remains - outside native membership. The server does not infer deadline, assignment, - guide locks, contribution terms or release state. -- Parser/mapping identity captures this exact field mapping and the published - `workstream.task_import.v1` document version. Source metadata labels are retained - as display values, never used as replay, project or authorization selectors. - Actual provider bytes are parsed only on first import; stored creation facts - and verified native receipts govern committed replay. - -### Concrete owner and schema preparation for review - -The next reviewed application boundary separates canonical Task creation into -three caller-root phases: prepare all retry/Task identities, consume the same -exact CREATE authority facts, then stage the existing Task/create event/receipt. -Normal public create remains the root-owning wrapper over those phases, with -its current advanced-state replay rejection unchanged. Batch replay recovers -its immutable creation responses and never routes through single-Task recovery. -No public route or per-row command transaction is invoked from the batch owner. - -The proposed native tables are `task_import_batches`, -`task_import_batch_members` and `task_import_batch_command_receipts`: - -- Batch reservation has UUIDv7 ID, project UUID, original command receipt UUID - (deferred circular closure), original source UUID and its - operation identity, exact source SHA/count, document schema and parser/mapping - identity, row count, retained optional metadata label, original actor/link, current batch creation decision and - original immutable ordered result. Project/SHA/count identifies one original - batch. A reservation may be incomplete only inside its caller root; a deferred - closure check rejects any committed pending header, missing or extra member, - incorrect row count or incomplete ordered result. -- Native ART ancestry stores source/attempt/content/replica IDs, verification - job/generation/receipt and exactly one operation/observation acknowledgement. - FKs plus owner validation bind each tuple to the same project/source bytes; - mutable replica health is not an original creation fact. -- Member has batch/project/Task IDs, bounded original row index, exact external - ID, normalized row digest, server-generated CREATE key, original Task command - receipt/decision IDs and closed original Task creation response. Task/project - and batch/project composite FKs close custody; unique Task membership, - batch/index and project/external-ID identities reject substitutions. Existing - arbitrary `import_batch_id` metadata never supplies these relationships. -- Batch command receipt has UUIDv7 ID, current actor/link, closed import action, UUID key, - exact request digest over project/selected-source IDs, selected verified - ancestry, original batch ID and closed immutable ordered result. Actor/action/ - key is unique. A changed selector conflicts after fresh authority; new-key - exact-file recovery creates only the current retry receipt/evidence. - -String-mapped owner UUID FKs use `Uuid(as_uuid=False)`; native UUID-typed receipt -IDs keep their existing representation. Reservation actor/project/source/Task -FK checks are deferred where they would otherwise acquire implicit locks before -explicit TASK/ART/AUTH preparation. SOURCE KEY SHARE is acquired explicitly -before AUTH and retained through commit. All three tables reject UPDATE/DELETE after committed -closure and reject statement-level TRUNCATE. Only the exact pending-to-committed -header/receipt completion may change staged fields; immutable identity and -ancestry never change. Members are append-only and committed headers cannot be -reopened or deleted. Native reset restores these guards through the canonical -owned reset helper, without leaving them disabled for product writes. The sole migration author reviews native -constraints, deferred closure and exact owner representations before DDL work; -these proposed names/columns are planning, not installed schema. - -### Concrete non-DDL schema handoff - -The ORM representations now declare these exact owner relationships for the -sole migration author’s affected review. They do not install any table or guard: - -- `task_import_batches`: native string-mapped UUIDv7 `id`, project and original - source UUIDs, unique original `creation_command_receipt_id`, exact SHA/count/ - JSON media, document/mapping versions, normalized-document `manifest_digest`, - retained nullable `metadata_label`, row count, original actor/link, original - batch ALLOW decision, pending/committed shape, original response and timestamps. - Project/SHA/count and ID/project are unique. The original command receipt FK - is deferred, closing the intentional header/receipt cycle at root commit. -- Both batch and retry receipt store native put-attempt/content/replica IDs, - verification job/generation/receipt, original source operation identity and - exactly one operation/observation acknowledgement UUID. Pending ancestry may - be NULL only inside the creating root; committed generation is explicitly - non-NULL and positive. Source/project/SHA/count/media uses the existing ART - composite custody FK, deferred until commit. Every other ART UUID FK uses its - owner’s string-mapped native UUID representation and is deferred. -- `task_import_batch_members`: native UUIDv7 ID, batch/project/Task UUIDs, - original index/external ID/normalized row digest, server-generated CREATE key, - original `TaskCommandReceipt` UUID (its existing Python UUID representation), - actual CREATE decision UUID, exact original Task response and timestamp. - Unique Task, batch/index, project/external-ID and CREATE receipt prevent - duplicated or substituted membership; Task/project and batch/project FKs - are deferred and bind actual native owners. -- `task_import_batch_command_receipts`: native UUIDv7 ID, current actor/link, - exact action `project.task.import`, UUID key, immutable selector request digest, - selected source/project/SHA/count/media and complete ART ancestry, original - batch ID, this invocation’s batch ALLOW decision, pending/committed result and - timestamps. Actor/action/key is unique; batch/project and actor/link custody - is deferred. New-key exact-file recovery creates only this receipt and fresh - authority evidence, with the original header/members/result unchanged. -- The header’s complete normalized-document digest is reconstructible from its - retained metadata label and ordered original Task instruction fields. It must - equal the original parsed document; native closure must also prove the exact - member count/indexes, original CREATE receipt/decision/action/actor/key/result, - truthful `json_import`/source-ref/hash/batch metadata and all ART ancestry. - Retry closure binds its fresh actor/link/decision and selected native source - while returning the original immutable ordered result. A pending header or - receipt cannot survive commit. All three tables reject DELETE/TRUNCATE and - committed UPDATE; only exact staged completion is admitted. -- Native TASK changes remain the approved global case-sensitive project/non-NULL - external-ID uniqueness with retained duplicate diagnostic preflight, difficulty - width 80 preserving values, and additive current lifecycle `json_import` - evidence. Current sensitive-audit constraints/guards must admit only the exact - batch resource/actions. Historical baseline SQL remains unchanged. Canonical - reset and graph/fingerprint/UUID inventories must retain every merged owner. - -Reservation order is retry namespace, exact-file header, all canonical Task -CREATE reservations, explicit sorted SOURCE KEY SHARE, then fresh batch/source/ -row AUTH and sorted external-ID writes. New batch FKs are deferred to avoid -implicit actor/source locks before this preparation. A separate provider-free -source read preflight authorizes before preparation outcomes are observable; -it commits no Task or batch effect. Each creation preparation is bound to its -original active SQLAlchemy root, preventing reuse after rollback/commit. The -sole author allocates a successor only after the lead names the actual merged -predecessor; source `0031` is merged, PR534 is reconciling to `0032`, and this -chunk reserves no ordinal. - -### Scope decisions and transaction preparation - -The lead confirmed the following issue489 boundaries during preparation: - -- Preserve all retained/manual `import_batch_id` strings. New imports may stamp - their native batch UUID spelling into metadata; native immutable membership - alone selects and authorizes the batch. Add a public control showing that a - manually supplied matching string never appears in the batch status response. -- Exact project/SHA/byte-count file replay returns original IDs and creation - facts after fresh batch/source Project Manager authority, even if Tasks have - advanced. Reused actor/action/key with a changed source selector conflicts; - a new key for the same exact file recovers the original batch. Actual verified - source ancestry and parser/schema identity are bound, not a client digest alone. -- Case-sensitive project/external-ID uniqueness covers every non-NULL Task - external ID, including normal create. Native preflight reports retained - duplicates without changing their data. NULL remains available for normal - Tasks without an external ID; arbitrary batch-label metadata gains no authority. - -The existing Task composite `(id, project_id)` uniqueness can bind native row -membership without rewriting Task IDs or their string-mapped UUID model type. -The new membership must bind the original external ID, row index, normalized -row digest, original CREATE decision and immutable creation response separately -from mutable current Task status. A batch closure invariant rejects committed -success with a missing, foreign or duplicated row. No committed pending batch -or partially created row set is an accepted intermediate product state. - -The creation refactor stays in the existing TASK owner: extract the current -create operation into one explicitly caller-owned participant, with the current -single-create public method remaining its transaction-owning wrapper. Batch -imports compose that participant; they do not invoke the public command in a -loop. Reserve all needed per-row replay identities before current AUTH locks, -then retain each row's real CREATE decision and `TaskCreated` evidence. Successful -batch closure and all row effects use one root; denial restaging follows the -specific AUTH instance that captured the original decision. Late-row failure -must remove every earlier successful creation effect in that root. - -The lead approved common AUTH-before-uniqueness ordering with sorted writes; -no additional global advisory fence or custody table is introduced. The exact -owner preparation and implicit-FK schedule still require affected schema review -and native discriminating proofs before any concurrency PASS: - -1. For first import, finish bounded ART provider verification and JSON parsing - before the TASK write root. Source read evidence belongs to that earlier - operation; no provider stream, scratch cleanup or I/O occurs while TASK - write locks wait. For committed exact-file replay, use stored immutable - batch/member results and actual native verified-source/receipt ancestry. - Do not depend on provider availability or parse old bytes again. If the - requested selector differs, validate its own completed verified receipt and - exact original SHA/count before recovering the original batch. -2. Within the root, reserve the batch/file retry identity and every per-row TASK - retry identity. Acquire existing Task/member custody needed by replay in - deterministic order before the first AUTH lock. Proposed new batch/row tuples - must not introduce foreign owner locks through premature FK writes. - The existing TaskCommandReceipt defers both actor and Task FKs until commit; - new pre-AUTH reservation rows must follow that owner pattern for actor, - project, source and not-yet-inserted Task references. An immediate actor FK - would let two same-actor imports retain KEY SHARE and deadlock while upgrading - to AUTH's actor FOR UPDATE. An immediate source FK before remaining TASK - reservations would silently invert TASK-before-ART custody. Native controls - must distinguish both implicit-FK hazards without weakening final custody. -3. Validate actual ART source/verification custody through its typed participant - after TASK custody and before fresh AUTH consumption. Read immutable tuples - with the weakest required lock; do not lock a mutable put attempt merely to - trust an application DTO. The source row is acquired FOR KEY SHARE here and - retained through commit: its existing upload/replay operation uses FOR UPDATE, - so postponing source FK custody until after AUTH could invert SOURCE/AUTH. - This compatible immutable-parent lock also satisfies deferred final custody - without reacquiring a conflicting source lock after actor authority. - Preserve existing TASK-before-CHECKERS/ART order. -4. Consume fresh current batch/source authority and exact per-row CREATE - authority through the shared TASK owner. After AUTH, insert external-ID-bearing - Tasks in deterministic project/UTF-8 external-ID order. Retain document row - indexes and immutable responses independently from insertion order. Stage - membership and evidence, close the batch and flush within the caller root. - No per-row TASK reservation or additional ART custody acquisition follows AUTH. - -Normal create already consumes fresh AUTH before inserting its Task. An import -that wrote the unique external key before AUTH could hold that key while a -normal create held the same actor's AUTH lock: the normal create would wait on -uniqueness while the import waited on AUTH. Shared AUTH-before-write ordering -prevents that inversion. Distinct actors retain independent AUTH custody; -deterministic multi-row writes prevent crossed-key index waits. Native controls -must observe intermediate waits for same-actor create/import and distinct-actor -imports whose documents list overlapping external IDs in reverse order, alongside -revocation and late-failure rollback. Native uniqueness also protects direct SQL; -AUTH custody and file replay do not depend on an invented global creation fence. - -Field mapping has one confirmed native-parity decision: -`TaskImportRow.difficulty` publishes an 80-character limit, whereas the current -`WorkstreamTask.difficulty` column is `varchar(50)` and `TaskCreate` has no length -validator. A valid retained source must not fail as an unexplained late database -error. The lead confirmed expanding that TASK display column to 80 in the -sole-author successor migration, preserving existing values and the published -source shape. Source intake is not narrowed and retained values are not rewritten. -Native 51/80-character controls and an indexed 81-character rejection must -discriminate the chosen boundary. No alteration is authored by this record. -The batch retains the actual `workstream.task_import.v1` document identity and -an explicit row-mapping/parser commitment, alongside verified bytes, so replay -never silently reinterprets retained rows under a later mapping. - -## Acceptance criteria - -- [ ] One real 200-row verified JSON source creates exactly 200 DRAFT Tasks under - one batch; every row has the correct source hash/reference, external ID, actor, - per-task AUTH decision and creation event. No locked screen/release lineage, - assignment or release effects are invented. -- [ ] Invalid or unverified input, one conflicting row, duplicate ID, foreign - source/project, missing authority and 501 rows yield indexed closed errors and - zero batch/Task creation effects. Existing separately committed source/read or - canonical denial evidence is distinguished from successful TASK effects. -- [ ] Exact same-key and exact-file retries recover original IDs with fresh - authority; changed bytes/key reuse conflicts; revoked replay fails. Source, - actor, receipt and row-membership substitutions fail closed. -- [ ] After successful import and Task advancement, provider unavailability - cannot prevent same-key or new-key exact-file recovery of original IDs/facts; - replay performs zero provider reads and emits no additional Task creation. - Revoked current authority still denies that recovery. A different verified - source with identical actual SHA/count recovers under a new key; a declaration - with only the claimed digest, foreign/missing receipt or different bytes never - recovers. Changing the selected source under the original key conflicts even - when both verified sources contain identical bytes. -- [ ] Native PostgreSQL proves identical concurrent import recovery, overlapping - external-ID conflicts, deterministic intermediate lock waits and complete - rollback after an injected late-row/audit/binding failure. -- [ ] Direct SQL rejects partial batch closure, foreign source/verification/Task - membership, changed original receipts and NULL/changed custody. For each of - batch/member/receipt tables, native direct-SQL UPDATE, DELETE and TRUNCATE - negatives retain all original facts. TaskCreated evidence uses the exact - `json_import` token and server provenance; malformed/caller-relabelled stamps - cannot produce a committed batch. Upgrade/reset - preserves every retained main and source fact on the sole linear schema. - -## Risk and review routing - -- Risk class: `L0` (multi-owner authority, immutable custody and atomic creation). -- Required reviewers: architecture/reuse for owner composition and native parity; - security for current actor/project/source/replay custody; QA/test delta for - observable rollback and discriminating native controls. The lead owns common - CI/collection/cleanup validation and independent SQL review. -- Human review focus: batch/file identity, retained provenance preflight, fresh - replay authority, per-task evidence, root atomicity and the SOURCE/TASK/AUTH - lock graph. Source storage is a prerequisite, not the import result. - -## Evidence - -| Claim | Command or proof | Result | Remaining uncertainty | -|---|---|---|---| -| Canonical creation participant | Exact `59d47a6c` isolated native execution of five retained CREATE, denial, rollback and receipt controls | 5 passed in 69.02 seconds; schema `0031_task_import_source`; owned database/role/MinIO cleanup complete | Proves preservation of normal creation; no atomic batch success claim | -| Source consumer and current CREATE participants | Exact `37d8705d` isolated execution of actual immutable-binding substitution/provider-health, public source, canonical denial, CREATE rollback and receipt controls | 10 passed in 120.95 seconds; runner exit 0, schema `0031_task_import_source`; owned database/role/MinIO cleanup complete | Raw `/tmp/pilot02-atomic-37d-source-create-corrected.log` and `.json`; validates existing owner integration, not installed batch schema | -| Shared SCREEN/RELEASE participant and membership extraction | Inspected sibling exact `4400568a` native replay; seven source/test files integrated as `96b1fb820` without its separate CLI record | 5 passed in 225.05 seconds; runner exit 0, schema `0031_task_import_source`; database/role cleanup complete | Raw `/tmp/pilot02-bulk-4400568-native.log` and `.json`; historical exact extraction proof, not a new batch-schema or public bulk success claim | -| Current owners and concrete gap | Inspect source port/parser, TASK create/replay/models and Issue 489 | Canonical caller-root phases, closed batch DTOs, model representations, ART immutable-binding participant and batch/root/AUTH composition are implemented | New table constraints and guards require sole-author DDL and native proof | -| Public import and atomic effects | Planned isolated runner: `pytest -q tests/tasks/test_task_import_batches.py` with real PostgreSQL 16/MinIO | Twenty-four native acceptance cases collect; not executed because batch schema is not installed | Actual 200-Task creation, immutable replay, late-stage rollback, direct SQL guards, exact original-authority revocation and intermediate-wait controls must pass after sole-author DDL | -| Schema, guards and complete integration | Sole-author native graph/reset/UUID proof, affected guards, complete hosted lanes and aggregate | Not run for this chunk | Exact frozen candidate, actual merge tree and cleanup required | - -## Review findings - -Independent schema/lock handoff review at exact `37d8705d` found no actionable -architecture/reuse/security issue in the non-DDL models, replay and preparation -graph. This qualified review does not prove native guards or public batch -success; those require the integrated migration and real end-to-end execution. -Scope preparation identifies the existing -per-command transaction and unbound string provenance as explicit handoff issues. -Affected independent planning review found two concrete missing integration -requirements: the closed TaskCreated JSON source token and complete batch/header/ -TRUNCATE immutability. This record now names all typed/audit/native token owners -and all-three-table UPDATE/DELETE/TRUNCATE controls. Complete batch/native proof remains unimplemented; schema contracts alone do -not prove installed custody or a public import result. - -## Reconciliation - -- Current-source reconciliation: this preparation branch incorporates source - prerequisite PR520 and merged main `e77c48b10`, - retaining its ten-lane CI, hidden materialization/completion/failure/feedback - owners and CLI approval/correction contracts. Before implementation, only - this planning record differed from the source candidate. Canonical Task creation now shares - caller-root phases with its normal public wrapper; atomic batch creation - still lacks installed schema/native proof. Model/API representations, - provider-free ART binding validation and public route composition are coded - on this isolated branch; no delivered import capability is claimed. No migration is - authored in this worktree. -- Next usable boundary: coordinate the reviewed batch/membership/receipt schema - and owner preparation/replay graph with the sole-author migration, then prove - the coded atomic JSON-to-DRAFT operation through public native acceptance cases. - No migration ordinal is allocated before the actual merged predecessor and - delegated migration queue are reconciled. Explicit batch screen/release and CLI - project/source/batch commands with client CSV conversion are implemented on a - separate coordinated lane; its public/native aggregate journey remains pending. -- Remaining risks: source prerequisite and current required CI/actual external - review remain separate; no deployed import capability or whole Issue 489 claim. diff --git a/.commitrail/changes/pilot02-bulk-transitions-cli.md b/.commitrail/changes/pilot02-bulk-transitions-cli.md deleted file mode 100644 index 866e5e050..000000000 --- a/.commitrail/changes/pilot02-bulk-transitions-cli.md +++ /dev/null @@ -1,358 +0,0 @@ -# PILOT-02C — Atomic batch screening/release and explicit CLI intake - -- Initiative: `None` -- Durable disposition: `Planned` -- Intended merge outcome: Covered Project Managers explicitly screen and release every immutable imported batch member atomically and use the public CLI for separate source/import/status/screen/release operations and local CSV conversion. - -## Intent - -Issue [489](https://github.com/Flow-Research/workstream/issues/489) requires -separate all-or-nothing screening and release after canonical JSON import. -PILOT-02A supplies ART source custody; PILOT-02B supplies immutable native batch -membership and canonical CREATE participation. Normal single-Task SCREEN/RELEASE -already own guide locks, validation, per-Task authority, audit and retry receipts. -Their current root transaction prevents composition across a complete batch. - -## Bounded change - -### Allowed - -- New TASK batch-transition owner and typed API contracts under - `backend/app/modules/tasks/task_batch_transitions.py` and - `backend/app/modules/tasks/api/task_batch_transition.py`; native membership - selection only. Extend exact existing SCREEN/RELEASE participants in - `authorized_commands.py` through prepare/authorize/stage phases. Coordinate - these regions with the atomic-import owner before edits. -- Aggregate custody is owned in `task_batch_transition/models.py`: exactly one - actor/action/key aggregate and its complete native member links. Lead review - approved compact ordered receipt projections and a scoped batch-write client - deadline, to be selected after native 200/500 measurements. No global transport - change or claimed measured ten-minute requirement is authorized. -- Explicit atomic-owner handoff permits the single native membership owner in - `task_import_membership.py`, its small `api/task_import_membership.py` error/row - facts, exact original-response wrapper replacement, and batch error import - updates in TASK router/import tests. A tiny `_locked_task` extraction shares - its unchanged AUTH prepare/consume/finally-close block through `_authorize_facts`. - CREATE methods/dataclass and source ancestry preparation remain untouched. -- Sole schema-owner handoff authorizes only the two aggregate model imports in - `backend/app/db/models.py`. The new model owner is relocated once to - `task_batch_transition/models.py` so canonical registration uses the existing - protected metadata-discovery exception, without an alias or new private debt. - A fresh-process canonical-only metadata/FK compiler check belongs in the - existing compact-contract test module. Migration, Alembic/env, fingerprints, - reset lists and schema-owner inventory remain with the sole migration author. -- New route/dependency modules and append-only composition of the typed batch - transition owner. Shared TASK `router.py`, `schemas.py`, model/receipt and AUTH - regions require an explicit owner handoff before edits. Existing per-Task - SCREEN/RELEASE actions and canonical denial handling remain mandatory. -- Atomic-owner-approved canonical custody hunks are the nullable - `TaskCommandReceipt.batch_transition_receipt_id` column/closed action constraint, - optional `command_replay.reserve` binding argument, and SCREEN/RELEASE - preparation/digest validation only. CREATE and other retained command digests - remain unchanged. New delivery is exactly `task_batch_transition_router.py`, - `api/deps/task_batch_transitions.py`, one TASK-router include and one TASK-adapter - factory. The new dependency composes inside the existing `get_task_commands` - yielding lifecycle; it neither duplicates AUTH denial handling nor creates an - alternate authority owner. -- New Go CLI `internal/taskimport/` conversion/validation, scoped - `internal/api/task_import*.go`, `internal/command/task_batch*.go`, and one - registration in `internal/command/command.go`; focused native Go/HTTP and - real public backend journey tests. Reuse existing HTTP client and output/error - conventions. Source admission, import, status, screen and release stay explicit. -- Lead-approved exact `cli/internal/api/client.go` PUT additions: classify PUT - alongside POST/PATCH at the three existing mutation checks and require the - canonical error envelope for POST/PUT. Disable automatic body replay and retain - uncertain-write reporting; no other shared-client changes are authorized. -- Exact CLI proof paths are new `cli/tests/integration/test_task_batch_csv.py` - and `test_task_batch_sources_http.py`, plus - `test_task_batch_commands_http.py`; the existing HTTP fixture receives one - PUT handler delegating to its unchanged exact-body POST capture. No retained - GET/PATCH/POST expectations or test guards are removed. -- Native participant lifetime/composition proof is owned in - `backend/tests/authorization/task_authority/test_management_participants.py`; - it extends the existing management proof using actual PostgreSQL and AUTH. -- Closed response proof is `tests/tasks/test_task_batch_transition_contract.py`; - actual public native journeys/rollback/revocation/wait proof is - `tests/tasks/test_task_batch_transitions.py`. These two modules require exact - TASK lane/inventory registration after coordinated atomic/current-main union. -- Exact metadata hunks are two TASK catalogue registrations and their unchanged - exact-set assertion in `backend/tests/test_ci_lane_catalogue.py`, plus five - explicit `PILOT_02C_BULK_TRANSITION_TARGETS` paths and additive partition - regeneration. Preserve all atomic/source and ten-lane entries, retained - assignments, protected-base custody and zero private-edge growth. -- Current-main reconciliation preserves both the atomic import and merged P10 - AUTH arms/action registries. Update the exact closed catalogue count and its - assertion to their 152-action union, preserving permissions and evaluators; - reconcile only the selected MCP authorization-context enum digest/provenance. - No bulk AUTH actions are introduced. -- Current TASK/AUTH/ART and CLI contracts, README, affected roadmap sections, - this record, and exact coordinated owner/lane/selected-contract metadata. -- Required schema/receipt changes only through the sole migration author after - the aggregate replay contract is reviewed and its exact DDL is handed off. - -### Not allowed - -No atomic-import/source owner rewrites, migration authorship or ordinal allocation, -arbitrary `Task.import_batch_id` membership, contributor creation, route calls, -per-row commits, alternate transition rules, skipped SCREENING, guide/activation -loosening, checker changes, external adapters, automatic write retries, provider -access, payouts, CI reductions, deployment, merge or issue-closing keywords. - -## Design and decisions - -Use native committed batch/member identities and preserve original row order in -responses. Lock all selected TASK/Assignment custody deterministically before -CHECKERS/project-policy or AUTH custody. Canonical single-Task operations and -bulk operations share the same flush-only participants and existing per-Task -receipts. One caller root authorizes every member and commits all lifecycle, -locked-guide, audit and receipt effects together. Aggregate exact-key custody -must bind the project, native batch, operation, reason and immutable membership; -its concrete receipt design is reviewed with the atomic owner before backend -composition. Replay reauthorizes the current covered PM and never reapplies -effects. Partial advanced state, crossed membership or any late failure refuses -the whole request. - -The lead confirmed canonical replay currentness on this assignment: every member -must still match the recorded SCREEN/RELEASE post-state, locked-context hash and -unassigned custody. A partly advanced or assigned batch conflicts atomically even -with unchanged input/key. Atomic-import replay's original DRAFT facts after -advancement remain a separate contract. CLI uncertain-write instructions retain -the same key/request, and warn that subsequent state changes can prevent replay. - -### Proposed aggregate custody for owner review - -The import/source command receipt cannot represent SCREEN/RELEASE, and the -canonical per-Task namespace admits only one Task per actor/action/key. A dedicated -`TaskBatchTransitionReceipt` plus append-only `TaskBatchTransitionMember` is -proposed; no new AUTH action or alternative Task writer is needed. The root's -receipt namespace is actor + existing SCREEN/RELEASE action + caller UUID key. -It binds exact project/native batch, reason request digest and original immutable -batch manifest. Successful member links bind every native import member in row -order to its canonical per-Task command receipt and consumed authority decision. -Per-Task keys are server-created random keys retained in those exact links; -callers never choose membership or per-row keys. - -Reservation and complete native membership preparation occur before any AUTH. -Prepare each canonical Task operation in UUID order (receipt, Task, assignment), -then consume all fresh per-Task authority, then stage shared canonical transitions. -Only after all succeed does the aggregate become committed with its exact ordered -response. Replay uses the retained per-Task links, freshly authorizes all members, -and runs canonical currentness recovery. Changed request and member/receipt drift -are conflicts after authority; no successful staging survives a late failure. -Direct-SQL guards must enforce exact closed action, complete membership, canonical -receipt/action/Task/actor/project equality, audit equality, original row order, -success response equality and immutable committed rows. Pending reservations -remain transaction-local, never a separately committed partial lifecycle. -Committed aggregate/member UPDATE and DELETE and statement-level TRUNCATE must -be refused. Deferred commit closure requires exactly the complete original native -member set/count; no subset, duplicate, substituted Task, action, actor, project, -decision, receipt or response is admitted. Reservation actor/Task/batch FKs must -defer premature AUTH/ART locks. The atomic owner independently reviewed this -namespace/closure design and found no shared-region blocker. - -Links alone could reuse earlier committed single-Task receipts and misrepresent -one aggregate root. The lead approved explicit nullable canonical receipt root -binding, subject to the atomic owner's exact model/replay handoff. Bulk receipts -bind `batch_transition_receipt_id` into their request digest; existing null -single-Task and CREATE request digests remain byte-compatible. Deferred closure -must require that exact binding and its canonical success/AUTH evidence, so a -historical standalone success cannot be enrolled after the fact. - -### Implemented aggregate checkpoint, migration pending - -The aggregate models, compact public DTO, native membership selection, reservation, -sorted all-Task preparation, fresh all-member AUTH, canonical staging and exact -ordered replay are implemented. Both public routes compose through the actual -canonical Task denial lifecycle. Successful AUTH, Task effects, member links and -both receipt layers share one root; the response is validated/serialized before -commit. Complete replay compares all native links and canonical root binding, -recovers each normal retained current-state receipt, and compares the complete -original compact response. An identity-link mismatch also rolls back the root. - -Pure compact-contract plus retained parser verification passed 41 cases. Ruff and -the protected module-boundary validator passed without exemptions or new private -edges. Native participant proof at the earlier exact clean extraction head -`4400568a484a8a3fdf1a428d3ef78e560c892c27` passed five cases in 225.05 seconds -through migration 0031 with cleanup complete; it proves the extraction only. -The newly written aggregate tests cover complete 200/500-member public journeys, -fresh-authorized exact replay, injected failure after the second actual canonical -write, changed-input/partial-advance rollback, real grant-revocation denial and an -observed native holder/waiter before concurrent same-key recovery. They have not -run because aggregate custody DDL is pending the sole migration author. No native -aggregate, native 200/500 timing, full CI, or readiness claim is made here. -The native module also carries two commit-closure controls after genuine -canonical stages: omitting the final initial member INSERT and leaving the root -pending. Both require a complete successful-effect rollback. Direct SQL controls -cover UPDATE/DELETE and TRUNCATE refusal for each committed aggregate table, -unchanged retained facts and fresh-authorized exact replay afterward. They are -written controls awaiting installed schema, not executed native evidence. - -Peer review of aggregate checkpoint `42900b036` found that the new dependency -projected immutable identity after the canonical Task dependency rolled back and -expired the resolved ORM actor/link. The repair projects the existing public -`ActorIdentityFacts` first, before that rollback; no row refresh, implicit read, -new authority owner or private actor import is introduced. The peer dependency-order/ORM-expiration discriminator uses actual FastAPI and -attached SQLAlchemy models without SQL, schema or AUTH execution. It proves the -composition defect and correction; native aggregate public proof remains pending. -The same peer review found missing/blank RELEASE input reached the native pending -receipt reason CHECK before normal validation. The repair uses the canonical -`TaskValidationError` reason requirement before opening/reserving the root, -retains the native CHECK, and adds public missing/blank negative controls asserting -unchanged aggregate, Task, lifecycle and successful authority facts. Valid inputs -still consume every member's fresh canonical AUTH. -The repaired pure compact/admission plus retained parser checks passed 44 cases -in 7.40 seconds; the protected module-boundary check also exited successfully. -The owned idle PostgreSQL container was stopped after the earlier native proof's -isolated DB/role cleanup, while aggregate DDL remains pending. - -Peer review also found the canonical model graph omitted the aggregate tables, -so the new canonical receipt FK could not resolve in a fresh process. The repair -registers both aggregate classes through the existing metadata-discovery owner -and relocates their unchanged bodies once to the protected `.models` shape. -The focused regression imports only `app.db.models` in a fresh interpreter, -resolves every canonical FK and compiles the canonical receipt and aggregate -tables with the PostgreSQL dialect. This is model-graph proof, not installed DDL -or native aggregate proof. -The focused compact/admission/model-graph module passed 15 cases in 7.98 seconds. -Removing only canonical registration makes the fresh-process check fail at the -missing aggregate table; registration was restored exactly. The protected -module-boundary validator passed without ledger changes or gate exemptions. - -CLI import/status/screen/release are implemented as separate exact typed calls. -Original/status responses are bounded to 16MiB, compact transitions to 2MiB, -with complete 1..500 ordered membership and strict original DRAFT/source custody. -Status validates original and current identities independently. The six new -built-CLI HTTP cases passed in 15.03 seconds, including complete 500-row output, -crossed/malformed/partial refusal, invalid selectors/keys producing zero requests, -canonical versus unrecognized denial, dropped connections and one-body/one-h2 -GOAWAY behavior. These are controlled HTTP fixtures, not native batch proof. -Go compilation, focused package tests and `go vet ./...` passed. The longer -deadline for batch writes has not been selected: it remains dependent on actual -native 200/500 timing, and existing transport semantics remain unchanged. - -No migration ordinal is allocated here. The sole author receives the final exact -models and constraints only after this custody design and shared regions are -reviewed. New tables are justified by the concrete aggregate/per-Task namespace -gap; no business snapshot or generic batch framework is proposed. - -Proposed public routes are POST project-scoped native batch `/screen` and -`/release`, with a bounded reason and caller UUID Idempotency-Key. Responses name -the exact project/batch/operation and 1..500 ordered Task results. Release requires -its normal nonblank reason and all locked prerequisites. - -CLI uses `project task-batch` with explicit project/source/batch selectors and -caller-owned keys. Local `convert-csv --input FILE --out FILE` creates bounded -UTF-8 canonical JSON without network or token access; output refuses existing -files. It handles CSV quoting, Unicode and semicolon-separated skill fields, -maps category to task_type and languages/tools to skill_tags, validates 1..500 -rows, required case-sensitive external IDs and document limits, and reports the -SHA/count of its exact output bytes. Those JSON bytes are the uploaded server -source; no original-CSV retention claim is made. -CSV headers accept canonical row names plus `source_id` for `external_task_id`, -`category` for `task_type`, and semicolon `languages`/`tools` appended after -`skill_tags`. Duplicate/unknown headers and simultaneous alias/canonical headers -are refused. Blank semicolon segments are omitted; other instruction text and -case-sensitive external IDs are preserved. One optional UTF-8 BOM is accepted. - -## Acceptance criteria - -- A real 200-row source/import followed by one SCREEN and one RELEASE produces - 200 READY Tasks with exact immutable membership, per-Task authority/audit and - the normal locked guide/policy fields. -- Invalid/missing prerequisite, unauthorized member, arbitrary metadata, - partial advanced state, changed key payload or late write failure leaves no - partial lifecycle, successful audit or receipt effects. -- Fresh-authority exact replay and actual PostgreSQL concurrent lock controls - preserve original identities, deterministic order and revocation refusal. -- CLI performs only explicitly requested writes, validates exact returned - selectors and bounded results, never automatically retries, and preserves - caller keys for manual unchanged-request recovery. -- CSV quoting/UTF-8/semicolon mapping and invalid/duplicate/501-row/oversized - cases are discriminated; output SHA/count equals uploaded JSON bytes. -- Required complete CI, independent AUTH/architecture/product/QA review and - current source documentation are reconciled at the final tested head. - -## Risk and review routing - -- Risk class: `L1`. -- Required reviewers: AUTH/security, architecture/reuse, product operations, - QA/test delta and affected documentation/CI ownership, coordinated by the lead. -- Human review focus: aggregate replay custody, shared participant parity, - locking/rollback and explicit CLI write semantics. - -## Evidence - -Inspection at atomic checkpoint `4a6d00fc8` identifies the reusable canonical -SCREEN/RELEASE root and the native `TaskImportBatchMember` custody. This branch -is reconciled onto the unmerged atomic candidate `91183adafec37e7ad7eda624ad3556d89dc54ce6`; -preserve its source/member/ten-lane metadata union and use only an explicitly -coordinated stacked draft before its human merge. Native schema/storage claims are -pending the sole-author migrations and actual isolated PostgreSQL/MinIO drills. -The offline converter is implemented with focused Go boundary checks and built -CLI/server-parser proof for quoting/Unicode, exact JSON commitment, no-clobber, -invalid CSV zero-output effects and 500/501 rows. This proof needs no token/API -configuration and makes no database or source-storage claim. Canonical -SCREEN/RELEASE extraction and the single native membership owner are implemented; -aggregate models/public composition are also implemented, with native aggregate -DDL and actual public proof still pending. -Source CLI uses separate existing declaration/upload/status routes and sends exact -original JSON bytes. Go tests/vet/tidy-diff and built CLI CSV/source boundary plus -retained HTTP/profile/project/guide declaration checks pass. The PUT transport -control removes only its write classification: the actual HTTP/2 peer then -receives two identical bodies on two connections and the client loses uncertain -write reporting. The correct implementation receives one body/connection and -reports uncertainty. Source was restored byte-exact after that control. - -The atomic owner explicitly handed off SCREEN/RELEASE phase extraction and the -native original/member validator at clean `4a6d00fc8`. CREATE preparation, -import/source ancestry and `_prepare_sources` remain with that owner. The shared -validator extraction must preserve label/manifest, ordered native Member/CREATE -receipt/response validation and advanced-state-independent original facts. Its -commit will be shared back with the atomic owner to avoid parallel validators. -Protected-base module-boundary validation and canonical import parser checks -pass. A native preflight proves retained single-Task SCREEN/RELEASE replay/guide -lock parity, successor-guide/currentness behavior, foreign-root participant -refusal, and two-Task late-failure rollback including actual successful AUTH -decisions. Its database/role cleanup is complete. The initial run used the dirty -extraction atop the CLI checkpoint; the later exact `4400568` five-case native -replay above supplies the qualified frozen extraction proof. -This uses existing schema through source0031 and canonical seeded project -prerequisites; it proves Task/AUTH transactions, not new batch DDL, provider bytes, -live setup inference or a complete 200-member public bulk journey. - -## Reconciliation - -Main `d47ee1e9917689b94fd9439c09dffaf88c6d3ec1` now contains P10's linear audit -migration 0033. This branch preserves its source and read contracts alongside the -atomic import candidate, including both exact AUTH audit-target arms and all -existing catalogue actions. Their approved union contains 152 ActionIds (116 -active and 36 planned, with permissions unchanged); its -closed count and exact assertion are updated together. The protected partition -now has 480 unique targets and the complete lane inventory has 532 modules, -preserving all incoming/atomic/bulk targets and the original protected base. -The selected MCP operation/components already equal the actual merged OpenAPI; -only the union digest and exact capture provenance are reconciled. Native atomic -and bulk migrations remain sequential sole-author work after 0033. -The focused reconciliation run passed the 46 exact CI-catalogue and 15 -compact/admission/canonical-graph cases; its only failure was the retained -114-active catalogue assertion. Updating that exact expectation to the union's -116 active actions made all seven catalogue cases pass in 6.18 seconds. -Protected module boundaries and scoped Ruff checks also passed. These are -source/model/contract checks, with installed bulk proof still pending. - -Before the main-d47 union, additive bulk metadata preserved every trusted -assignment and the existing protected base: 459 unique production targets -validated, with exactly five new bulk paths; that ten-lane inventory covered -523 test modules. Its exact -TASK owner assertion is extended by the two actual new proof modules; the focused -catalogue suite passes 46 cases in 7.79 seconds without weakening any gate. -Canonical TASK/CLI documentation distinguishes current-state transition replay -from original import replay and still marks native aggregate readiness pending. - -- Current-source reconciliation: Preserve the atomic owner's import/status and - source custody; shared-file regions require handoff before edits. -- Next usable boundary: Complete the separate explicit bulk/CLI journey under - issue 489; whole-issue completion requires every agreed acceptance criterion. -- Remaining risks: The implemented aggregate receipt/currentness contract still - needs sole-author native closure DDL, direct-SQL refusal, public rollback and - concurrency proof, and measured 200/500 journeys before readiness. diff --git a/.commitrail/changes/pilot10-stable-contribution-pagination.md b/.commitrail/changes/pilot10-stable-contribution-pagination.md deleted file mode 100644 index 035a01d30..000000000 --- a/.commitrail/changes/pilot10-stable-contribution-pagination.md +++ /dev/null @@ -1,120 +0,0 @@ -# PILOT-10B — Fixed-membership contribution export pages - -- Initiative: None -- Durable disposition: Planned -- Intended merge outcome: Existing authorized contribution exports traverse more than 1,000 records with signed, expiring cursors and fixed contribution membership. - -## Intent - -Finance, PMs and contributors must export their complete authorized contribution -selection without narrowing filters merely to stay under one response bound. - -## Current behavior - -PILOT-10A exposes JSON/CSV reads through the canonical CON projection and fresh -AUTH in a repeatable-read response transaction. The repository refuses selections -above 1,000 contributions. AUTH's existing signed timestamp/UUID keyset codec -protects other reads; it does not freeze export membership across transactions. - -## Bounded change - -### Allowed - -- CON API/read facts, repository, projection, owner-local export cursor codec and - record model; explicit CON composition and existing export REST dependencies/routes. -- Read indexes for existing CON actor/project ordering and private membership ordering. -- One sole-author native migration and corresponding schema/reset registration, - after coordination with the existing migration owner; no guessed revision. -- Focused contribution projection/cursor/native public-API regression tests, - affected public schema capture, additive CI ownership and current export docs. - -### Not allowed - -- Economic recognition, award definitions, policy custody, acceptance/routing, - fulfillment, new roles/actions, weakening authority or immutable source evidence. -- Importing AUTH-private codec code into CON; parallel old/new export readers; - native migration authored by anyone except the coordinated migration owner. -- Automatic mutation retry, removed CI checks, deployment or merge. - -## Design and decisions - -Extend the existing read operation with bounded page_size and cursor. Each page -retains its complete awards and fresh canonical authority through serialization -and commit. Sign actor, audience, project, normalized filters, format, page size, -original membership snapshot and last timestamp/UUID boundary with the existing -configured pagination secret. Expire cursors after 15 minutes and reject invalid -or cross-query continuation without disclosing facts. JSON exposes next_cursor; -CSV uses X-Workstream-Next-Cursor and X-Workstream-Exported-At headers. - -Native membership uses two CON-private expiring tables: a header bound to actor, -normalized query and a 15-minute export instant, and immutable contribution IDs -with their recorded-time ordering keys. First-page membership capture uses the -same fresh-authorized repeatable-read transaction as canonical projection. -The complete selection is bounded at 100,000 contributions; each page at 1,000. -Headers are sealed before commit; member additions after sealing are refused. -Expired headers/members alone may be removed, in batches of at most 100 during -reads; retained contribution and award records are never changed or deleted. - -A timestamp/UUID watermark does not exclude late commits. Native xid8 snapshot -filtering would also require provenance metadata on economic rows, cutover rules -and cluster/restore identity handling. Focused peer design review selected the -explicit membership list because ordinary native FK-backed data preserves the -selection through restart and logical restore without that extra subsystem. -CLI is a separate bounded PR. - -## Acceptance criteria - -- [ ] Multi-page traversal returns each originally visible selected contribution - once, in timestamp/UUID order, with its complete exact award set. -- [ ] Delayed commits, later/backdated inserts and savepoints do not change membership. -- [ ] Retained data remains readable; new metadata cannot be forged or mutated. -- [ ] Forged/expired/cross-actor/query cursors fail; revoked authority conceals every page. -- [ ] JSON and CSV share identical page membership and stable exported_at. - -## Risk and review routing - -- Risk class: L1 -- Required reviewers: architecture, security, QA, test_delta, documentation. -- Human review focus: native visibility/restore semantics, fresh authority and exact evidence. - -## Evidence - -| Claim | Command or proof | Result | Remaining uncertainty | -|---|---|---|---| -| Current implementation | Inspect canonical CON read and AUTH keyset owner | Existing read extended; peer selected expiring native membership | Installed native implementation pending | -| Membership/authority | Real PostgreSQL installed-schema public reads, delayed commit and revocation controls | Planned | No native runtime claim yet | -| Cursor/projection validation | Focused cursor, exact projection, CSV and canonical-only model discovery | 68 pass; independent scope/expiry mutants fail intended assertions | No native membership claim | -| Required repository checks | CI lane catalogue and behavior ownership tests; Ruff; changed Markdown links | 203 pass after additive registration repair; lint and links pass | Full hosted/native proof pending; no readiness claim | - -## Review findings - -Focused peer plan review selected private expiring membership over cluster-local -transaction-ID coupling. Source review reproduced missing canonical-only model -registration in a fresh process. Membership declarations now live in CON's -existing registered records/models.py; the separate declaration module was -removed, with a fresh-process regression preserving native FK compilation. -Prepared public regression now includes direct installed-guard checks for sealed -append, header/member mutation, premature deletion, deferred unsealed commit, -and public cleanup of a nonempty expired private selection. -These collect successfully but are not runtime proof until the native migration -is installed. First composed native run at 97e8b1cd installed 0036 and passed direct guard -assertions, then reproduced invalid-cursor reclassification (503 instead of 422). -Database, role and MinIO cleanup all passed. Preserve InvalidContributionCursor -through the projection service; an owner-port regression checks propagation -without loading award evidence. Full native rerun remains required. -Implementation still requires installed-schema proof. - -## Reconciliation - -- Current-source reconciliation: started from main d47ee1e; reconciled main e31e1777 after PR #539 merged. -- Next usable boundary: separate CLI export PR and the pilot closing drill. -- Remaining risks: native membership mechanism and restore binding not yet frozen. - -## Pagination regression structure repair - -The native fixed-membership regression now delegates sealed-membership guards, -cursor custody and expiry/CSV checks to three same-module helpers. All 31 -assertions are AST-identical to the previously proven test, and operation order -is preserved. The test and each helper are below the 120-line structural limit. -Ruff, compilation and diff checks pass. This is a test-structure repair; the -previous native proof remains attributed to its exact composed head. diff --git a/README.md b/README.md index 870f5d325..6f7695b0e 100644 --- a/README.md +++ b/README.md @@ -221,14 +221,6 @@ composition remain before public intake and the first real end-to-end drill. Active work stays on that first contribution path. Live human review/revision, reviewer participation and fulfillment delivery follow separately. -Current human contributors can read their own contribution evidence at -`GET /api/v1/actors/me/contributions`; covering Project Managers and exact-project -Finance Authorities can export it at -`GET /api/v1/projects/{project_id}/contributions/export`. JSON and CSV share -complete exact award facts and signed, 15-minute fixed-membership pagination. -Use the returned cursor with unchanged filters, format and page size; authorization -is checked on every page. See the [contribution evidence contract](docs/spec_contribution_compensation.md#bounded-contribution-evidence-reads) -for limits and continuation details. These are earned facts, not proof of payment. Contribution evidence remains the input for a separately implemented future reputation projection. Frontend product work follows stable and tested backend contracts for the surface it consumes. diff --git a/backend/alembic/env.py b/backend/alembic/env.py index 6421cdf4b..615105ada 100644 --- a/backend/alembic/env.py +++ b/backend/alembic/env.py @@ -87,9 +87,6 @@ def do_run_migrations(connection: Connection) -> None: ("0031_task_import_source",), ("0032_checker_remediation",), ("0033_contribution_reads",), - ("0034_task_import_batches",), - ("0035_task_batch_transitions",), - ("0036_contribution_export_pages",), (_CURRENT_HEAD_REVISION,), ): raise RuntimeError(_RECREATE_GUIDANCE) diff --git a/backend/alembic/versions/0034_task_import_batches.py b/backend/alembic/versions/0034_task_import_batches.py deleted file mode 100644 index e810bed69..000000000 --- a/backend/alembic/versions/0034_task_import_batches.py +++ /dev/null @@ -1,579 +0,0 @@ -"""Install atomic JSON-to-DRAFT Task import custody.""" - -from alembic import op -import sqlalchemy as sa -from sqlalchemy.dialects import postgresql - - -revision = "0034_task_import_batches" -down_revision = "0033_contribution_reads" -branch_labels = None -depends_on = None - - -_TABLES = ( - "task_import_batches", - "task_import_batch_members", - "task_import_batch_command_receipts", -) - - -def _definition(table: str, name: str) -> str: - return op.get_bind().execute(sa.text( - "select pg_catalog.pg_get_constraintdef(oid) from pg_catalog.pg_constraint " - "where conrelid=cast(:table as regclass) and conname=:name" - ), {"table": f"public.{table}", "name": name}).scalar_one() - - -def _replace_constraint(table: str, name: str, definition: str) -> None: - op.execute(f"alter table public.{table} drop constraint {name}") - op.execute(f"alter table public.{table} add constraint {name} {definition}") - - -def _replace_function(signature: str, old: str, new: str) -> None: - body = op.get_bind().execute(sa.text( - "select pg_catalog.pg_get_functiondef(cast(:signature as regprocedure))" - ), {"signature": signature}).scalar_one() - if body.count(old) != 1: - raise RuntimeError(f"atomic task import function shape changed: {signature}") - op.execute(body.replace(old, new)) - - -def _extend_audit_contract() -> None: - name = "ck_audit_events_authorization_action_evidence" - definition = _definition("audit_events", name) - anchor = ( - "(((action_id)::text = 'project.task.create'::text) AND " - "((permission_id)::text = 'project.task.manage'::text))" - ) - additions = " OR ".join( - "(((action_id)::text = " - f"'{action}'::text) AND ((permission_id)::text = 'project.task.manage'::text))" - for action in ("project.task.import", "project.task.import_batch.read") - ) - if definition.count(anchor) != 2 or "project.task.import_batch.read" in definition: - raise RuntimeError("atomic task import audit action constraint shape changed") - _replace_constraint("audit_events", name, definition.replace(anchor, anchor + " OR " + additions)) - - name = "ck_audit_events_authority_privacy_bounds" - definition = _definition("audit_events", name) - if "'task_import_batch'::character varying" in definition: - raise RuntimeError("atomic task import audit target constraint already changed") - resource_start = definition.index("resource_type IS NULL") - target_start = definition.index("target_ref_kind IS NULL") - addition = "('task_import_batch'::character varying)::text, " - for start in sorted((resource_start, target_start), reverse=True): - index = definition.index("ARRAY[", start) + len("ARRAY[") - definition = definition[:index] + addition + definition[index:] - _replace_constraint("audit_events", name, definition) - - -def _alter_tasks() -> None: - duplicate = op.get_bind().execute(sa.text( - "select project_id, external_task_id, count(*) from public.workstream_tasks " - "where external_task_id is not null group by project_id, external_task_id " - "having count(*) > 1 order by project_id, external_task_id limit 1" - )).first() - if duplicate is not None: - raise RuntimeError( - "cannot install atomic task import uniqueness with retained duplicate " - f"project/external_task_id facts: {duplicate[0]}/{duplicate[1]}" - ) - op.alter_column( - "workstream_tasks", "difficulty", schema="public", - existing_type=sa.String(50), type_=sa.String(80), existing_nullable=True, - ) - op.create_unique_constraint( - "uq_workstream_tasks_project_external_id", - "workstream_tasks", ["project_id", "external_task_id"], schema="public", - ) - _replace_function( - "public.guard_task_management_audit()", - "payload->>'source_type' in ('manual','markdown_import','csv_import')", - "payload->>'source_type' in ('manual','markdown_import','csv_import','json_import')", - ) - - -def _create_tables() -> None: - op.create_table( - "task_import_batches", - sa.Column("id", sa.Uuid(), nullable=False), - sa.Column("project_id", sa.Uuid(), nullable=False), - sa.Column("source_id", sa.Uuid(), nullable=False), - sa.Column("creation_command_receipt_id", sa.Uuid(), nullable=False), - sa.Column("sha256", sa.String(71), nullable=False), - sa.Column("byte_count", sa.BigInteger(), nullable=False), - sa.Column("media_type", sa.String(255), nullable=False), - sa.Column("schema_version", sa.String(80), nullable=False), - sa.Column("mapping_version", sa.String(80), nullable=False), - sa.Column("manifest_digest", sa.String(71), nullable=False), - sa.Column("row_count", sa.Integer(), nullable=False), - sa.Column("metadata_label", sa.String(255), nullable=True), - sa.Column("actor_profile_id", sa.Uuid(), nullable=False), - sa.Column("identity_link_id", sa.Uuid(), nullable=False), - sa.Column("authorization_decision_id", sa.Uuid(), nullable=True), - sa.Column("status", sa.String(16), nullable=False), - sa.Column("response", postgresql.JSONB(), nullable=True), - sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.text("now()"), nullable=False), - sa.Column("committed_at", sa.DateTime(timezone=True), nullable=True), - sa.Column("source_operation_identity", sa.String(71), nullable=False), - sa.Column("put_attempt_id", sa.Uuid(), nullable=True), - sa.Column("content_id", sa.Uuid(), nullable=True), - sa.Column("replica_id", sa.Uuid(), nullable=True), - sa.Column("verification_job_id", sa.Uuid(), nullable=True), - sa.Column("verification_generation", sa.BigInteger(), nullable=True), - sa.Column("verification_receipt_id", sa.Uuid(), nullable=True), - sa.Column("operation_receipt_id", sa.Uuid(), nullable=True), - sa.Column("observation_receipt_id", sa.Uuid(), nullable=True), - sa.PrimaryKeyConstraint("id", name="pk_task_import_batches"), - sa.UniqueConstraint("project_id", "sha256", "byte_count", name="uq_task_import_batch_file"), - sa.UniqueConstraint("id", "project_id", name="uq_task_import_batch_project"), - sa.UniqueConstraint("creation_command_receipt_id", name="uq_task_import_batch_creation_command"), - sa.ForeignKeyConstraint(["project_id"], ["public.projects.id"], ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), - sa.ForeignKeyConstraint(["actor_profile_id"], ["public.actor_profiles.id"], ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), - sa.ForeignKeyConstraint(["identity_link_id", "actor_profile_id"], ["public.actor_identity_links.id", "public.actor_identity_links.actor_profile_id"], name="fk_task_import_batch_actor_link", ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), - sa.ForeignKeyConstraint(["authorization_decision_id"], ["public.audit_events.id"], ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), - sa.ForeignKeyConstraint(["source_id", "project_id", "sha256", "byte_count", "media_type"], ["public.artifact_task_import_sources.id", "public.artifact_task_import_sources.project_id", "public.artifact_task_import_sources.sha256", "public.artifact_task_import_sources.byte_count", "public.artifact_task_import_sources.media_type"], name="fk_task_import_batch_source", ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), - sa.ForeignKeyConstraint(["put_attempt_id"], ["public.artifact_put_attempts.id"], ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), - sa.ForeignKeyConstraint(["content_id"], ["public.artifact_contents.id"], ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), - sa.ForeignKeyConstraint(["replica_id"], ["public.artifact_replicas.id"], ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), - sa.ForeignKeyConstraint(["verification_job_id"], ["public.artifact_verification_jobs.id"], ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), - sa.ForeignKeyConstraint(["verification_receipt_id"], ["public.artifact_verification_receipts.id"], ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), - sa.ForeignKeyConstraint(["operation_receipt_id"], ["public.artifact_operation_receipts.id"], ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), - sa.ForeignKeyConstraint(["observation_receipt_id"], ["public.artifact_put_observation_receipts.id"], ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), - sa.CheckConstraint("(get_byte(uuid_send(id),6)>>4)=7 and (get_byte(uuid_send(id),8)&192)=128", name="ck_task_import_batches_id_uuid7"), - sa.CheckConstraint("sha256 ~ '^sha256:[0-9a-f]{64}$'", name="ck_task_import_batches_source_hash"), - sa.CheckConstraint("source_operation_identity ~ '^sha256:[0-9a-f]{64}$'", name="ck_task_import_batches_source_operation"), - sa.CheckConstraint("manifest_digest ~ '^sha256:[0-9a-f]{64}$'", name="ck_task_import_batches_manifest_hash"), - sa.CheckConstraint("byte_count between 1 and 8388608 and row_count between 1 and 500", name="ck_task_import_batches_bounds"), - sa.CheckConstraint("media_type='application/json' and schema_version='workstream.task_import.v1' and mapping_version='workstream.task_import.draft_mapping.v1'", name="ck_task_import_batches_format"), - sa.CheckConstraint("(status='pending' and response is null and authorization_decision_id is null and committed_at is null) or (status='committed' and response is not null and jsonb_typeof(response::jsonb)='object' and authorization_decision_id is not null and committed_at is not null and put_attempt_id is not null and content_id is not null and replica_id is not null and verification_job_id is not null and verification_generation is not null and verification_generation>0 and verification_receipt_id is not null and ((operation_receipt_id is not null and observation_receipt_id is null) or (operation_receipt_id is null and observation_receipt_id is not null)))", name="ck_task_import_batches_state_shape"), - schema="public", - ) - op.create_table( - "task_import_batch_command_receipts", - sa.Column("id", sa.Uuid(), nullable=False), - sa.Column("actor_profile_id", sa.Uuid(), nullable=False), - sa.Column("identity_link_id", sa.Uuid(), nullable=False), - sa.Column("action_id", sa.String(160), nullable=False), - sa.Column("idempotency_key", sa.Uuid(), nullable=False), - sa.Column("request_digest", sa.String(71), nullable=False), - sa.Column("project_id", sa.Uuid(), nullable=False), - sa.Column("source_id", sa.Uuid(), nullable=False), - sa.Column("sha256", sa.String(71), nullable=False), - sa.Column("byte_count", sa.BigInteger(), nullable=False), - sa.Column("media_type", sa.String(255), nullable=False), - sa.Column("batch_id", sa.Uuid(), nullable=True), - sa.Column("authorization_decision_id", sa.Uuid(), nullable=True), - sa.Column("status", sa.String(16), nullable=False), - sa.Column("response", postgresql.JSONB(), nullable=True), - sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.text("now()"), nullable=False), - sa.Column("committed_at", sa.DateTime(timezone=True), nullable=True), - sa.Column("source_operation_identity", sa.String(71), nullable=False), - sa.Column("put_attempt_id", sa.Uuid(), nullable=True), - sa.Column("content_id", sa.Uuid(), nullable=True), - sa.Column("replica_id", sa.Uuid(), nullable=True), - sa.Column("verification_job_id", sa.Uuid(), nullable=True), - sa.Column("verification_generation", sa.BigInteger(), nullable=True), - sa.Column("verification_receipt_id", sa.Uuid(), nullable=True), - sa.Column("operation_receipt_id", sa.Uuid(), nullable=True), - sa.Column("observation_receipt_id", sa.Uuid(), nullable=True), - sa.PrimaryKeyConstraint("id", name="pk_task_import_batch_command_receipts"), - sa.UniqueConstraint("actor_profile_id", "action_id", "idempotency_key", name="uq_task_import_command_namespace"), - sa.ForeignKeyConstraint(["project_id"], ["public.projects.id"], ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), - sa.ForeignKeyConstraint(["actor_profile_id"], ["public.actor_profiles.id"], ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), - sa.ForeignKeyConstraint(["identity_link_id", "actor_profile_id"], ["public.actor_identity_links.id", "public.actor_identity_links.actor_profile_id"], name="fk_task_import_command_actor_link", ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), - sa.ForeignKeyConstraint(["authorization_decision_id"], ["public.audit_events.id"], ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), - sa.ForeignKeyConstraint(["source_id", "project_id", "sha256", "byte_count", "media_type"], ["public.artifact_task_import_sources.id", "public.artifact_task_import_sources.project_id", "public.artifact_task_import_sources.sha256", "public.artifact_task_import_sources.byte_count", "public.artifact_task_import_sources.media_type"], name="fk_task_import_command_source", ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), - sa.ForeignKeyConstraint(["put_attempt_id"], ["public.artifact_put_attempts.id"], ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), - sa.ForeignKeyConstraint(["content_id"], ["public.artifact_contents.id"], ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), - sa.ForeignKeyConstraint(["replica_id"], ["public.artifact_replicas.id"], ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), - sa.ForeignKeyConstraint(["verification_job_id"], ["public.artifact_verification_jobs.id"], ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), - sa.ForeignKeyConstraint(["verification_receipt_id"], ["public.artifact_verification_receipts.id"], ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), - sa.ForeignKeyConstraint(["operation_receipt_id"], ["public.artifact_operation_receipts.id"], ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), - sa.ForeignKeyConstraint(["observation_receipt_id"], ["public.artifact_put_observation_receipts.id"], ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), - sa.CheckConstraint("(get_byte(uuid_send(id),6)>>4)=7 and (get_byte(uuid_send(id),8)&192)=128", name="ck_task_import_batch_command_receipts_id_uuid7"), - sa.CheckConstraint("action_id='project.task.import'", name="ck_task_import_batch_command_receipts_action"), - sa.CheckConstraint("request_digest ~ '^sha256:[0-9a-f]{64}$'", name="ck_task_import_batch_command_receipts_request_hash"), - sa.CheckConstraint("sha256 ~ '^sha256:[0-9a-f]{64}$' and source_operation_identity ~ '^sha256:[0-9a-f]{64}$'", name="ck_task_import_batch_command_receipts_source_hash"), - sa.CheckConstraint("byte_count between 1 and 8388608 and media_type='application/json'", name="ck_task_import_batch_command_receipts_bounds"), - sa.CheckConstraint("(status='pending' and response is null and authorization_decision_id is null and committed_at is null) or (status='committed' and batch_id is not null and response is not null and jsonb_typeof(response::jsonb)='object' and authorization_decision_id is not null and committed_at is not null and put_attempt_id is not null and content_id is not null and replica_id is not null and verification_job_id is not null and verification_generation is not null and verification_generation>0 and verification_receipt_id is not null and ((operation_receipt_id is not null and observation_receipt_id is null) or (operation_receipt_id is null and observation_receipt_id is not null)))", name="ck_task_import_batch_command_receipts_state_shape"), - schema="public", - ) - op.create_foreign_key( - "fk_task_import_batch_creation_command", "task_import_batches", - "task_import_batch_command_receipts", ["creation_command_receipt_id"], ["id"], - source_schema="public", referent_schema="public", ondelete="RESTRICT", - deferrable=True, initially="DEFERRED", - ) - op.create_foreign_key( - "fk_task_import_command_batch", "task_import_batch_command_receipts", - "task_import_batches", ["batch_id", "project_id"], ["id", "project_id"], - source_schema="public", referent_schema="public", ondelete="RESTRICT", - deferrable=True, initially="DEFERRED", - ) - op.create_table( - "task_import_batch_members", - sa.Column("id", sa.Uuid(), nullable=False), - sa.Column("batch_id", sa.Uuid(), nullable=False), - sa.Column("project_id", sa.Uuid(), nullable=False), - sa.Column("task_id", sa.Uuid(), nullable=False), - sa.Column("row_index", sa.Integer(), nullable=False), - sa.Column("external_task_id", sa.String(200), nullable=False), - sa.Column("row_digest", sa.String(71), nullable=False), - sa.Column("create_idempotency_key", sa.Uuid(), nullable=False), - sa.Column("task_command_receipt_id", sa.Uuid(), nullable=False), - sa.Column("authorization_decision_id", sa.Uuid(), nullable=False), - sa.Column("response", postgresql.JSONB(), nullable=False), - sa.Column("created_at", sa.DateTime(timezone=True), server_default=sa.text("now()"), nullable=False), - sa.PrimaryKeyConstraint("id", name="pk_task_import_batch_members"), - sa.UniqueConstraint("task_id", name="uq_task_import_member_task"), - sa.UniqueConstraint("batch_id", "row_index", name="uq_task_import_member_row"), - sa.UniqueConstraint("project_id", "external_task_id", name="uq_task_import_member_external_id"), - sa.UniqueConstraint("task_command_receipt_id", name="uq_task_import_member_creation"), - sa.ForeignKeyConstraint(["batch_id", "project_id"], ["public.task_import_batches.id", "public.task_import_batches.project_id"], name="fk_task_import_member_batch", ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), - sa.ForeignKeyConstraint(["task_id", "project_id"], ["public.workstream_tasks.id", "public.workstream_tasks.project_id"], name="fk_task_import_member_task", ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), - sa.ForeignKeyConstraint(["task_command_receipt_id"], ["public.task_command_receipts.id"], ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), - sa.ForeignKeyConstraint(["authorization_decision_id"], ["public.audit_events.id"], ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), - sa.CheckConstraint("(get_byte(uuid_send(id),6)>>4)=7 and (get_byte(uuid_send(id),8)&192)=128", name="ck_task_import_batch_members_id_uuid7"), - sa.CheckConstraint("row_index between 0 and 499", name="ck_task_import_batch_members_row_index"), - sa.CheckConstraint("row_digest ~ '^sha256:[0-9a-f]{64}$'", name="ck_task_import_batch_members_row_hash"), - sa.CheckConstraint("jsonb_typeof(response::jsonb)='object'", name="ck_task_import_batch_members_response_shape"), - schema="public", - ) - - -def _create_custody_functions() -> None: - op.execute(r""" -create function public.task_import_binding_valid( - expected_source_id uuid, expected_project_id uuid, expected_sha256 text, - expected_byte_count bigint, expected_operation_identity text, - expected_put_attempt_id uuid, expected_content_id uuid, expected_replica_id uuid, - expected_verification_job_id uuid, expected_verification_generation bigint, - expected_verification_receipt_id uuid, expected_operation_receipt_id uuid, - expected_observation_receipt_id uuid -) returns boolean language sql stable set search_path=pg_catalog,public,pg_temp as $$ - select exists( - select 1 from public.artifact_task_import_sources s - join public.artifact_put_attempts a on a.id=expected_put_attempt_id and a.task_import_source_id=s.id - join public.artifact_replicas r on r.id=expected_replica_id and r.id=a.replica_id - join public.artifact_contents c on c.id=expected_content_id and c.id=r.content_id - join public.artifact_verification_jobs j on j.id=expected_verification_job_id - and j.originating_put_attempt_id=a.id and j.replica_id=r.id - join public.artifact_verification_receipts v on v.id=expected_verification_receipt_id - and v.verification_job_id=j.id and v.outcome='verified' - where s.id=expected_source_id and s.project_id=expected_project_id and s.sha256=expected_sha256 - and s.byte_count=expected_byte_count and s.operation_identity=expected_operation_identity - and a.producer_request_type='task_import_source' and a.logical_role='task_import_source' - and a.project_id=s.project_id and a.sha256=s.sha256 and a.byte_count=s.byte_count - and a.media_type=s.media_type and c.sha256=s.sha256 and c.byte_count=s.byte_count - and r.storage_namespace_id=a.storage_namespace_id - and r.namespace_fingerprint=a.namespace_fingerprint - and v.execution_generation=expected_verification_generation - and v.observed_sha256=s.sha256 and v.observed_byte_count=s.byte_count - and ((expected_operation_receipt_id is not null and expected_observation_receipt_id is null and exists( - select 1 from public.artifact_operation_receipts o where o.id=expected_operation_receipt_id - and o.put_attempt_id=a.id and o.replica_id=r.id and o.request_digest=a.request_digest - and o.provider_object_ref=r.provider_object_ref and o.logical_role='task_import_source' - and o.outcome='stored_pending_verification')) or - (expected_operation_receipt_id is null and expected_observation_receipt_id is not null and exists( - select 1 from public.artifact_put_observation_receipts o where o.id=expected_observation_receipt_id - and o.put_attempt_id=a.id and o.outcome='observed_confirmed' - and o.observed_sha256=s.sha256 and o.expected_sha256=s.sha256 - and o.observed_byte_count=s.byte_count and o.expected_byte_count=s.byte_count))) - ) -$$ -""") - op.execute(r""" -create function public.task_import_binding_digest( - expected_source_id uuid, expected_project_id uuid, expected_sha256 text, - expected_byte_count bigint, expected_operation_identity text, - expected_put_attempt_id uuid, expected_content_id uuid, expected_replica_id uuid, - expected_verification_job_id uuid, expected_verification_generation bigint, - expected_verification_receipt_id uuid, expected_operation_receipt_id uuid, - expected_observation_receipt_id uuid -) returns text language sql immutable set search_path=pg_catalog,public,pg_temp as $$ - select public.external_checker_registry_digest(pg_catalog.jsonb_build_object( - 'source_id',expected_source_id,'project_id',expected_project_id,'sha256',expected_sha256, - 'byte_count',expected_byte_count,'operation_identity',expected_operation_identity, - 'put_attempt_id',expected_put_attempt_id,'content_id',expected_content_id, - 'replica_id',expected_replica_id,'verification_job_id',expected_verification_job_id, - 'verification_generation',expected_verification_generation, - 'verification_receipt_id',expected_verification_receipt_id, - 'operation_receipt_id',expected_operation_receipt_id, - 'observation_receipt_id',expected_observation_receipt_id)) -$$ -""") - op.execute(r""" -create function public.task_import_authority_valid( - expected_decision_id uuid, expected_action text, expected_batch_id uuid, - expected_project_id uuid, expected_source_id uuid, expected_actor_id uuid, - expected_link_id uuid, expected_sha256 text, expected_byte_count bigint, - expected_row_count integer, expected_manifest_digest text, - expected_source_binding_digest text, expected_idempotency_key uuid, - expected_request_digest text -) returns boolean language sql stable set search_path=pg_catalog,public,pg_temp as $$ - select exists(select 1 from public.audit_events a where a.id=expected_decision_id - and a.event_domain='authority' and a.event_type='SensitiveAuthorizationAllowed' - and a.actor_ref_kind='actor_profile' and a.actor_id=expected_actor_id::text - and a.project_id=expected_project_id and a.action_id=expected_action - and a.permission_id='project.task.manage' - and a.resource_type='task_import_batch' and a.resource_id=expected_batch_id::text - and a.target_ref_kind='task_import_batch' and a.target_ref_id=expected_batch_id::text - and a.denial_code is null and a.after_facts::jsonb=pg_catalog.jsonb_build_object( - 'allowed',true,'resource_context_digest',public.external_checker_registry_digest( - pg_catalog.jsonb_build_object('resource_context',pg_catalog.jsonb_build_object( - 'resource_type','task_import_batch','resource_id',expected_batch_id, - 'scope_project_id',expected_project_id,'source_id',expected_source_id, - 'actor_profile_id',expected_actor_id,'identity_link_id',expected_link_id, - 'sha256',expected_sha256,'byte_count',expected_byte_count, - 'row_count',expected_row_count,'manifest_digest',expected_manifest_digest, - 'source_binding_digest',expected_source_binding_digest, - 'idempotency_key',expected_idempotency_key,'request_digest',expected_request_digest))))) -$$ -""") - op.execute(r""" -create function public.validate_task_import_batch_custody(target uuid) returns void -language plpgsql set search_path=pg_catalog,public,pg_temp as $$ -declare b public.task_import_batches%rowtype; cmd public.task_import_batch_command_receipts%rowtype; - members integer; manifest jsonb; binding_digest text; -begin - select * into b from public.task_import_batches where id=target; - if not found then return; end if; - if b.status<>'committed' then raise exception 'task import batch cannot remain pending' using errcode='23514'; end if; - select * into cmd from public.task_import_batch_command_receipts where id=b.creation_command_receipt_id; - binding_digest:=public.task_import_binding_digest(b.source_id,b.project_id,b.sha256,b.byte_count, - b.source_operation_identity,b.put_attempt_id,b.content_id,b.replica_id,b.verification_job_id, - b.verification_generation,b.verification_receipt_id,b.operation_receipt_id,b.observation_receipt_id); - if not public.task_import_binding_valid(b.source_id,b.project_id,b.sha256,b.byte_count, - b.source_operation_identity,b.put_attempt_id,b.content_id,b.replica_id,b.verification_job_id, - b.verification_generation,b.verification_receipt_id,b.operation_receipt_id,b.observation_receipt_id) - or cmd.id is null or cmd.batch_id is distinct from b.id or cmd.project_id is distinct from b.project_id - or cmd.actor_profile_id is distinct from b.actor_profile_id or cmd.identity_link_id is distinct from b.identity_link_id - or cmd.source_id is distinct from b.source_id or cmd.response::jsonb is distinct from b.response::jsonb - or not public.task_import_authority_valid(b.authorization_decision_id,'project.task.import',b.id,b.project_id, - b.source_id,b.actor_profile_id,b.identity_link_id,b.sha256,b.byte_count,b.row_count,b.manifest_digest, - binding_digest,cmd.idempotency_key,cmd.request_digest) then - raise exception 'task import batch original custody invalid' using errcode='23514'; - end if; - select count(*) into members from public.task_import_batch_members m where m.batch_id=b.id; - if members<>b.row_count or exists( - select 1 from generate_series(0,b.row_count-1) i where not exists( - select 1 from public.task_import_batch_members m where m.batch_id=b.id and m.row_index=i)) then - raise exception 'task import batch membership incomplete' using errcode='23514'; - end if; - if b.response::jsonb->>'batch_id' is distinct from b.id::text - or b.response::jsonb->>'project_id' is distinct from b.project_id::text - or b.response::jsonb->>'source_id' is distinct from b.source_id::text - or b.response::jsonb->>'sha256' is distinct from b.sha256 - or (b.response::jsonb->>'byte_count')::bigint is distinct from b.byte_count - or (b.response::jsonb->>'row_count')::integer is distinct from b.row_count - or b.response::jsonb->>'schema_version' is distinct from b.schema_version - or b.response::jsonb->>'mapping_version' is distinct from b.mapping_version - or b.response::jsonb->'label' is distinct from coalesce(to_jsonb(b.metadata_label),'null'::jsonb) - or pg_catalog.jsonb_array_length(b.response::jsonb->'tasks')<>b.row_count then - raise exception 'task import batch response custody invalid' using errcode='23514'; - end if; - if exists(select 1 from public.task_import_batch_members m - join public.workstream_tasks t on t.id=m.task_id and t.project_id=m.project_id - join public.task_command_receipts r on r.id=m.task_command_receipt_id - where m.batch_id=b.id and ( - m.project_id is distinct from b.project_id or m.external_task_id is distinct from t.external_task_id - or t.source_type<>'json_import' or t.source_ref is distinct from 'task-import-source:'||b.source_id::text - or t.source_payload_hash is distinct from b.sha256 or t.import_batch_id is distinct from b.id::text - or t.created_by is distinct from b.actor_profile_id::text - or r.status<>'committed' or r.action_id<>'project.task.create' or r.task_id is distinct from m.task_id - or r.actor_profile_id is distinct from b.actor_profile_id or r.idempotency_key is distinct from m.create_idempotency_key - or r.response is distinct from m.response or m.response::jsonb is distinct from b.response::jsonb->'tasks'->m.row_index - or m.response::jsonb->>'id' is distinct from m.task_id::text - or m.response::jsonb->>'project_id' is distinct from b.project_id::text - or m.response::jsonb->>'external_task_id' is distinct from m.external_task_id - or m.response::jsonb->>'source_type'<>'json_import' - or m.response::jsonb->>'source_ref' is distinct from 'task-import-source:'||b.source_id::text - or m.response::jsonb->>'source_payload_hash' is distinct from b.sha256 - or m.response::jsonb->>'import_batch_id' is distinct from b.id::text - or m.response::jsonb->>'created_by' is distinct from b.actor_profile_id::text - or not exists(select 1 from public.audit_events e where e.id=m.authorization_decision_id - and e.event_domain='authority' and e.event_type='SensitiveAuthorizationAllowed' - and e.action_id='project.task.create' and e.permission_id='project.task.manage' - and e.actor_id=b.actor_profile_id::text and e.project_id=b.project_id) - or not exists(select 1 from public.audit_events e where e.event_type='TaskCreated' - and e.entity_id=m.task_id and e.event_payload::jsonb#>>'{references,authorization_decision_id}'=m.authorization_decision_id::text) - )) then raise exception 'task import batch member custody invalid' using errcode='23514'; end if; - select pg_catalog.jsonb_build_object( - 'schema_version',b.schema_version,'metadata',pg_catalog.jsonb_build_object('label',b.metadata_label), - 'tasks',pg_catalog.jsonb_agg(pg_catalog.jsonb_build_object( - 'external_task_id',m.response::jsonb->'external_task_id','title',m.response::jsonb->'title', - 'description',m.response::jsonb->'description','task_type',m.response::jsonb->'task_type', - 'difficulty',m.response::jsonb->'difficulty','skill_tags',m.response::jsonb->'skill_tags', - 'estimated_time_minutes',m.response::jsonb->'estimated_time_minutes', - 'acceptance_criteria',m.response::jsonb->'acceptance_criteria', - 'rejection_criteria',m.response::jsonb->'rejection_criteria') order by m.row_index)) into manifest - from public.task_import_batch_members m where m.batch_id=b.id; - if public.external_checker_registry_digest(manifest) is distinct from b.manifest_digest - or exists(select 1 from public.task_import_batch_members m where m.batch_id=b.id and - m.row_digest is distinct from public.external_checker_registry_digest(pg_catalog.jsonb_build_object( - 'external_task_id',m.response::jsonb->'external_task_id','title',m.response::jsonb->'title', - 'description',m.response::jsonb->'description','task_type',m.response::jsonb->'task_type', - 'difficulty',m.response::jsonb->'difficulty','skill_tags',m.response::jsonb->'skill_tags', - 'estimated_time_minutes',m.response::jsonb->'estimated_time_minutes', - 'acceptance_criteria',m.response::jsonb->'acceptance_criteria', - 'rejection_criteria',m.response::jsonb->'rejection_criteria'))) then - raise exception 'task import batch manifest custody invalid' using errcode='23514'; - end if; -end -$$ -""") - op.execute(r""" -create function public.validate_task_import_command_custody(target uuid) returns void -language plpgsql set search_path=pg_catalog,public,pg_temp as $$ -declare c public.task_import_batch_command_receipts%rowtype; b public.task_import_batches%rowtype; binding_digest text; -begin - select * into c from public.task_import_batch_command_receipts where id=target; - if not found then return; end if; - if c.status<>'committed' then raise exception 'task import command cannot remain pending' using errcode='23514'; end if; - select * into b from public.task_import_batches where id=c.batch_id; - binding_digest:=public.task_import_binding_digest(c.source_id,c.project_id,c.sha256,c.byte_count, - c.source_operation_identity,c.put_attempt_id,c.content_id,c.replica_id,c.verification_job_id, - c.verification_generation,c.verification_receipt_id,c.operation_receipt_id,c.observation_receipt_id); - if b.id is null or c.response::jsonb is distinct from b.response::jsonb - or c.sha256 is distinct from b.sha256 or c.byte_count is distinct from b.byte_count - or not public.task_import_binding_valid(c.source_id,c.project_id,c.sha256,c.byte_count, - c.source_operation_identity,c.put_attempt_id,c.content_id,c.replica_id,c.verification_job_id, - c.verification_generation,c.verification_receipt_id,c.operation_receipt_id,c.observation_receipt_id) - or not public.task_import_authority_valid(c.authorization_decision_id,'project.task.import',b.id,c.project_id, - c.source_id,c.actor_profile_id,c.identity_link_id,c.sha256,c.byte_count,b.row_count,b.manifest_digest, - binding_digest,c.idempotency_key,c.request_digest) then - raise exception 'task import command custody invalid' using errcode='23514'; - end if; -end -$$ -""") - - -def _create_guards() -> None: - op.execute(r""" -create function public.guard_task_import_batch_mutation() returns trigger -language plpgsql set search_path=pg_catalog,public,pg_temp as $$ -begin - if tg_op='UPDATE' and old.status='pending' and new.status='committed' - and row(new.id,new.project_id,new.source_id,new.creation_command_receipt_id,new.sha256,new.byte_count, - new.media_type,new.schema_version,new.mapping_version,new.manifest_digest,new.row_count,new.metadata_label, - new.actor_profile_id,new.identity_link_id,new.created_at,new.source_operation_identity) - is not distinct from row(old.id,old.project_id,old.source_id,old.creation_command_receipt_id,old.sha256,old.byte_count, - old.media_type,old.schema_version,old.mapping_version,old.manifest_digest,old.row_count,old.metadata_label, - old.actor_profile_id,old.identity_link_id,old.created_at,old.source_operation_identity) then return new; end if; - raise exception 'task import batch custody is immutable' using errcode='55000'; -end -$$ -""") - op.execute(r""" -create function public.guard_task_import_command_mutation() returns trigger -language plpgsql set search_path=pg_catalog,public,pg_temp as $$ -begin - if tg_op='UPDATE' and old.status='pending' and new.status='committed' - and row(new.id,new.actor_profile_id,new.identity_link_id,new.action_id,new.idempotency_key,new.request_digest, - new.project_id,new.source_id,new.sha256,new.byte_count,new.media_type,new.created_at,new.source_operation_identity) - is not distinct from row(old.id,old.actor_profile_id,old.identity_link_id,old.action_id,old.idempotency_key,old.request_digest, - old.project_id,old.source_id,old.sha256,old.byte_count,old.media_type,old.created_at,old.source_operation_identity) then return new; end if; - raise exception 'task import command custody is immutable' using errcode='55000'; -end -$$ -""") - op.execute(r""" -create function public.reject_task_import_member_mutation() returns trigger -language plpgsql set search_path=pg_catalog,public,pg_temp as $$ begin - raise exception 'task import member custody is immutable' using errcode='55000'; end $$ -""") - op.execute(r""" -create function public.reject_task_import_truncate() returns trigger -language plpgsql set search_path=pg_catalog,public,pg_temp as $$ begin - raise exception 'task import custody cannot be truncated' using errcode='55000'; end $$ -""") - op.execute("create trigger task_import_batches_immutable before update or delete on public.task_import_batches for each row execute function public.guard_task_import_batch_mutation()") - op.execute("create trigger task_import_batch_commands_immutable before update or delete on public.task_import_batch_command_receipts for each row execute function public.guard_task_import_command_mutation()") - op.execute("create trigger task_import_batch_members_immutable before update or delete on public.task_import_batch_members for each row execute function public.reject_task_import_member_mutation()") - for table in _TABLES: - op.execute(f"create trigger {table}_no_truncate before truncate on public.{table} for each statement execute function public.reject_task_import_truncate()") - op.execute("create constraint trigger task_import_batch_custody after insert or update on public.task_import_batches deferrable initially deferred for each row execute function public.trigger_validate_task_import_batch()") - op.execute("create constraint trigger task_import_command_custody after insert or update on public.task_import_batch_command_receipts deferrable initially deferred for each row execute function public.trigger_validate_task_import_command()") - op.execute("create constraint trigger task_import_member_custody after insert or update on public.task_import_batch_members deferrable initially deferred for each row execute function public.trigger_validate_task_import_member()") - - -def _create_trigger_wrappers() -> None: - op.execute(r""" -create function public.trigger_validate_task_import_batch() returns trigger -language plpgsql set search_path=pg_catalog,public,pg_temp as $$ -declare final_status text; -begin - select status into final_status from public.task_import_batches where id=new.id; - if not found or final_status<>'committed' then - raise exception 'task import batch cannot remain pending' using errcode='23514'; - end if; - if new.status='committed' then - perform public.validate_task_import_batch_custody(new.id); - end if; - return new; -end $$ -""") - op.execute(r""" -create function public.trigger_validate_task_import_command() returns trigger -language plpgsql set search_path=pg_catalog,public,pg_temp as $$ -declare final_status text; -begin - select status into final_status from public.task_import_batch_command_receipts where id=new.id; - if not found or final_status<>'committed' then - raise exception 'task import command cannot remain pending' using errcode='23514'; - end if; - if new.status='committed' then - perform public.validate_task_import_command_custody(new.id); - end if; - return new; -end $$ -""") - op.execute(r""" -create function public.trigger_validate_task_import_member() returns trigger -language plpgsql set search_path=pg_catalog,public,pg_temp as $$ -declare parent_status text; parent_xid xid; -begin - select status,xmin into parent_status,parent_xid - from public.task_import_batches where id=new.batch_id; - if not found or parent_status<>'committed' - or parent_xid<>pg_catalog.pg_current_xact_id()::xid then - raise exception 'task import member must be committed with its batch root' using errcode='23514'; - end if; - return new; -end $$ -""") - - -def upgrade() -> None: - """Install exact batch, member, replay, ART and AUTH closure.""" - op.execute("set local search_path=pg_catalog,public,pg_temp") - op.execute( - "lock table public.audit_events, public.workstream_tasks, public.task_command_receipts, " - "public.artifact_task_import_sources in access exclusive mode" - ) - _extend_audit_contract() - _alter_tasks() - _create_tables() - _create_custody_functions() - _create_trigger_wrappers() - _create_guards() - - -def downgrade() -> None: - """Refuse removal of retained native import custody.""" - op.execute("set local search_path=pg_catalog,public,pg_temp") - op.execute( - "lock table public.task_import_batches, public.task_import_batch_members, " - "public.task_import_batch_command_receipts in access exclusive mode" - ) - retained = op.get_bind().execute(sa.text( - "select exists(select 1 from public.task_import_batches) or " - "exists(select 1 from public.task_import_batch_members) or " - "exists(select 1 from public.task_import_batch_command_receipts)" - )).scalar_one() - if retained: - raise RuntimeError("cannot downgrade atomic task import with retained custody") - raise RuntimeError("Workstream v0.1 migrations cannot be downgraded; recreate the database") diff --git a/backend/alembic/versions/0035_task_batch_transitions.py b/backend/alembic/versions/0035_task_batch_transitions.py deleted file mode 100644 index 00552aba0..000000000 --- a/backend/alembic/versions/0035_task_batch_transitions.py +++ /dev/null @@ -1,486 +0,0 @@ -"""Install immutable aggregate custody for complete native batch transitions.""" - -from alembic import op -import sqlalchemy as sa -from sqlalchemy.dialects import postgresql - - -revision = "0035_task_batch_transitions" -down_revision = "0034_task_import_batches" -branch_labels = None -depends_on = None - - -_TABLES = ("task_batch_transition_receipts", "task_batch_transition_members") - - -def _replace_function(signature: str, old: str, new: str) -> None: - body = ( - op.get_bind() - .execute( - sa.text("select pg_catalog.pg_get_functiondef(cast(:signature as regprocedure))"), - {"signature": signature}, - ) - .scalar_one() - ) - if body.count(old) != 1: - raise RuntimeError(f"bulk transition predecessor function shape changed: {signature}") - op.execute(body.replace(old, new)) - - -def _create_tables() -> None: - op.create_table( - "task_batch_transition_receipts", - sa.Column("id", sa.Uuid(), nullable=False), - sa.Column("actor_profile_id", sa.Uuid(), nullable=False), - sa.Column("identity_link_id", sa.Uuid(), nullable=False), - sa.Column("action_id", sa.String(160), nullable=False), - sa.Column("idempotency_key", sa.Uuid(), nullable=False), - sa.Column("request_digest", sa.String(71), nullable=False), - sa.Column("reason", sa.Text(), nullable=True), - sa.Column("project_id", sa.Uuid(), nullable=False), - sa.Column("batch_id", sa.Uuid(), nullable=False), - sa.Column("manifest_digest", sa.String(71), nullable=False), - sa.Column("membership_digest", sa.String(71), nullable=False), - sa.Column("row_count", sa.Integer(), nullable=False), - sa.Column("status", sa.String(16), nullable=False), - sa.Column("response", postgresql.JSONB(none_as_null=True), nullable=True), - sa.Column( - "created_at", - sa.DateTime(timezone=True), - server_default=sa.text("now()"), - nullable=False, - ), - sa.Column("committed_at", sa.DateTime(timezone=True), nullable=True), - sa.PrimaryKeyConstraint("id"), - sa.ForeignKeyConstraint( - ["actor_profile_id"], - ["public.actor_profiles.id"], - ondelete="RESTRICT", - deferrable=True, - initially="DEFERRED", - ), - sa.ForeignKeyConstraint( - ["identity_link_id", "actor_profile_id"], - ["public.actor_identity_links.id", "public.actor_identity_links.actor_profile_id"], - name="fk_task_batch_transition_actor_link", - ondelete="RESTRICT", - deferrable=True, - initially="DEFERRED", - ), - sa.ForeignKeyConstraint( - ["batch_id", "project_id"], - ["public.task_import_batches.id", "public.task_import_batches.project_id"], - name="fk_task_batch_transition_batch", - ondelete="RESTRICT", - deferrable=True, - initially="DEFERRED", - ), - sa.UniqueConstraint( - "actor_profile_id", - "action_id", - "idempotency_key", - name="uq_task_batch_transition_namespace", - ), - sa.UniqueConstraint("id", "project_id", "batch_id", name="uq_task_batch_transition_parent"), - sa.CheckConstraint( - "(get_byte(uuid_send(id),6)>>4)=7 and (get_byte(uuid_send(id),8)&192)=128", - name="ck_task_batch_transition_receipts_id_uuid7", - ), - sa.CheckConstraint( - "action_id in ('project.task.screen','project.task.release')", - name="ck_task_batch_transition_receipts_action", - ), - sa.CheckConstraint( - "request_digest ~ '^sha256:[0-9a-f]{64}$' and manifest_digest ~ '^sha256:[0-9a-f]{64}$' and membership_digest ~ '^sha256:[0-9a-f]{64}$'", - name="ck_task_batch_transition_receipts_digests", - ), - sa.CheckConstraint( - "row_count between 1 and 500", name="ck_task_batch_transition_receipts_bounds" - ), - sa.CheckConstraint( - "reason is null or length(reason)<=4000", - name="ck_task_batch_transition_receipts_reason_bounds", - ), - sa.CheckConstraint( - "action_id<>'project.task.release' or (reason is not null and length(btrim(reason))>0)", - name="ck_task_batch_transition_receipts_release_reason", - ), - sa.CheckConstraint( - "(status='pending' and response is null and committed_at is null) or (status='committed' and response is not null and jsonb_typeof(response)='object' and committed_at is not null)", - name="ck_task_batch_transition_receipts_state_shape", - ), - schema="public", - ) - op.create_table( - "task_batch_transition_members", - sa.Column("id", sa.Uuid(), nullable=False), - sa.Column("transition_receipt_id", sa.Uuid(), nullable=False), - sa.Column("project_id", sa.Uuid(), nullable=False), - sa.Column("batch_id", sa.Uuid(), nullable=False), - sa.Column("native_member_id", sa.Uuid(), nullable=False), - sa.Column("task_id", sa.Uuid(), nullable=False), - sa.Column("row_index", sa.Integer(), nullable=False), - sa.Column("task_idempotency_key", sa.Uuid(), nullable=False), - sa.Column("task_command_receipt_id", sa.Uuid(), nullable=False), - sa.Column("authorization_decision_id", sa.Uuid(), nullable=False), - sa.Column( - "created_at", - sa.DateTime(timezone=True), - server_default=sa.text("now()"), - nullable=False, - ), - sa.PrimaryKeyConstraint("id"), - sa.ForeignKeyConstraint( - ["transition_receipt_id", "project_id", "batch_id"], - [ - "public.task_batch_transition_receipts.id", - "public.task_batch_transition_receipts.project_id", - "public.task_batch_transition_receipts.batch_id", - ], - name="fk_task_batch_transition_member_parent", - ondelete="RESTRICT", - deferrable=True, - initially="DEFERRED", - ), - sa.ForeignKeyConstraint( - ["native_member_id"], - ["public.task_import_batch_members.id"], - ondelete="RESTRICT", - deferrable=True, - initially="DEFERRED", - ), - sa.ForeignKeyConstraint( - ["task_id", "project_id"], - ["public.workstream_tasks.id", "public.workstream_tasks.project_id"], - name="fk_task_batch_transition_member_task", - ondelete="RESTRICT", - deferrable=True, - initially="DEFERRED", - ), - sa.ForeignKeyConstraint( - ["task_command_receipt_id"], - ["public.task_command_receipts.id"], - ondelete="RESTRICT", - deferrable=True, - initially="DEFERRED", - ), - sa.ForeignKeyConstraint( - ["authorization_decision_id"], - ["public.audit_events.id"], - ondelete="RESTRICT", - deferrable=True, - initially="DEFERRED", - ), - sa.UniqueConstraint( - "transition_receipt_id", "row_index", name="uq_task_batch_transition_member_row" - ), - sa.UniqueConstraint( - "transition_receipt_id", - "native_member_id", - name="uq_task_batch_transition_member_native", - ), - sa.UniqueConstraint( - "transition_receipt_id", "task_id", name="uq_task_batch_transition_member_task" - ), - sa.UniqueConstraint( - "task_command_receipt_id", name="uq_task_batch_transition_member_command" - ), - sa.CheckConstraint( - "(get_byte(uuid_send(id),6)>>4)=7 and (get_byte(uuid_send(id),8)&192)=128", - name="ck_task_batch_transition_members_id_uuid7", - ), - sa.CheckConstraint( - "row_index between 0 and 499", name="ck_task_batch_transition_members_row_index" - ), - schema="public", - ) - - -def _alter_command_receipts() -> None: - op.add_column( - "task_command_receipts", - sa.Column("batch_transition_receipt_id", sa.Uuid(), nullable=True), - schema="public", - ) - op.create_foreign_key( - "fk_task_command_batch_transition", - "task_command_receipts", - "task_batch_transition_receipts", - ["batch_transition_receipt_id"], - ["id"], - source_schema="public", - referent_schema="public", - ondelete="RESTRICT", - deferrable=True, - initially="DEFERRED", - ) - op.create_check_constraint( - "ck_task_command_receipts_task_command_batch_transition_action", - "task_command_receipts", - "batch_transition_receipt_id is null or action_id in ('project.task.screen','project.task.release')", - schema="public", - ) - op.create_index( - "ix_task_command_receipts_batch_transition_receipt_id", - "task_command_receipts", - ["batch_transition_receipt_id"], - schema="public", - ) - _replace_function( - "public.protect_task_command_receipt()", - "NEW.request_digest, NEW.task_id, NEW.created_at)", - "NEW.request_digest, NEW.batch_transition_receipt_id, NEW.task_id, NEW.created_at)", - ) - _replace_function( - "public.protect_task_command_receipt()", - "OLD.request_digest, OLD.task_id, OLD.created_at)", - "OLD.request_digest, OLD.batch_transition_receipt_id, OLD.task_id, OLD.created_at)", - ) - - -def _create_custody() -> None: - op.execute(r""" -create function public.validate_task_batch_transition_custody(p_receipt_id uuid) returns boolean -language plpgsql set search_path=pg_catalog,public,pg_temp as $$ -declare b public.task_batch_transition_receipts%rowtype; expected_membership text; - expected_request text; expected_response jsonb; expected_event text; -begin - select * into b from public.task_batch_transition_receipts where id=p_receipt_id; - if not found then return false; end if; - if b.status<>'committed' or b.response is null or b.committed_at is null then return false; end if; - if not exists(select 1 from public.task_import_batches source where source.id=b.batch_id - and source.project_id=b.project_id and source.status='committed' - and source.manifest_digest=b.manifest_digest and source.row_count=b.row_count) then return false; end if; - - select public.external_checker_registry_digest(jsonb_build_object('members',coalesce(jsonb_agg( - jsonb_build_object('member_id',n.id::text,'task_id',n.task_id::text,'row_index',n.row_index, - 'external_task_id',n.external_task_id,'row_digest',n.row_digest, - 'create_idempotency_key',n.create_idempotency_key::text, - 'task_command_receipt_id',n.task_command_receipt_id::text, - 'authorization_decision_id',n.authorization_decision_id::text) - order by n.row_index),'[]'::jsonb))) into expected_membership - from public.task_import_batch_members n where n.batch_id=b.batch_id; - expected_request := public.external_checker_registry_digest(jsonb_build_object( - 'project_id',b.project_id::text,'batch_id',b.batch_id::text, - 'operation',b.action_id,'reason',to_jsonb(b.reason))); - if b.membership_digest<>expected_membership or b.request_digest<>expected_request then return false; end if; - - if (select count(*) from public.task_import_batch_members where batch_id=b.batch_id)<>b.row_count - or (select count(*) from public.task_batch_transition_members where transition_receipt_id=b.id)<>b.row_count - or (select count(*) from public.task_command_receipts - where batch_transition_receipt_id=b.id)<>b.row_count - or exists(select 1 from public.task_import_batch_members n - left join public.task_batch_transition_members m - on m.transition_receipt_id=b.id and m.native_member_id=n.id - where n.batch_id=b.batch_id and (m.id is null or m.project_id<>n.project_id - or m.batch_id<>n.batch_id or m.task_id<>n.task_id or m.row_index<>n.row_index)) - or exists(select 1 from public.task_batch_transition_members m - left join public.task_import_batch_members n on n.id=m.native_member_id - where m.transition_receipt_id=b.id and (n.id is null or n.batch_id<>b.batch_id)) then return false; end if; - if exists(select 1 from public.task_command_receipts c - left join public.task_batch_transition_members m - on m.transition_receipt_id=b.id and m.task_command_receipt_id=c.id - where c.batch_transition_receipt_id=b.id and m.id is null) then return false; end if; - - expected_event := case b.action_id when 'project.task.screen' then 'TaskScreened' else 'TaskReleased' end; - if exists(select 1 from public.task_batch_transition_members m - join public.task_import_batch_members n on n.id=m.native_member_id - left join public.task_command_receipts c on c.id=m.task_command_receipt_id - left join public.audit_events d on d.id=m.authorization_decision_id - where m.transition_receipt_id=b.id and ( - m.project_id<>b.project_id or m.batch_id<>b.batch_id or m.task_id<>n.task_id - or m.row_index<>n.row_index or m.task_idempotency_key<>c.idempotency_key - or c.id is null or c.batch_transition_receipt_id is distinct from b.id or c.task_id<>m.task_id - or c.actor_profile_id::text<>b.actor_profile_id::text or c.action_id<>b.action_id - or c.status<>'committed' or c.response is null or c.locked_context_hash is null - or c.request_digest<>public.external_checker_registry_digest(jsonb_build_object( - 'task_id',m.task_id::text,'reason',to_jsonb(b.reason), - 'batch_transition_receipt_id',b.id::text)) - or c.response::jsonb->>'id' is distinct from m.task_id::text - or c.response::jsonb->>'project_id' is distinct from b.project_id::text - or c.response::jsonb->>'status' is distinct from case b.action_id - when 'project.task.screen' then 'screening' else 'ready' end - or nullif(c.response::jsonb->>'locked_guide_version','') is null - or not coalesce((c.response::jsonb->>'locked_contribution_policy_version_id') - ~ '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$',false) - or d.id is null or d.event_domain is distinct from 'authority' - or d.event_type is distinct from 'SensitiveAuthorizationAllowed' - or d.action_id is distinct from b.action_id - or d.permission_id is distinct from 'project.task.manage' - or d.actor_id is distinct from b.actor_profile_id::text - or d.project_id is distinct from b.project_id - or d.resource_type is distinct from 'project' - or d.resource_id is distinct from b.project_id::text or d.denial_code is not null - or d.after_facts::jsonb is distinct from jsonb_build_object('allowed',true,'resource_context_digest',d.after_facts::jsonb->'resource_context_digest') - or not coalesce((d.after_facts::jsonb->>'resource_context_digest') - ~ '^sha256:[0-9a-f]{64}$',false) - or not exists(select 1 from public.audit_events e where e.entity_id=m.task_id - and e.event_type=expected_event and e.actor_id=b.actor_profile_id::text - and e.event_payload::jsonb#>>'{references,project_id}'=b.project_id::text - and e.event_payload::jsonb#>>'{references,task_id}'=m.task_id::text - and e.event_payload::jsonb#>>'{references,authorization_decision_id}'=m.authorization_decision_id::text - and e.event_payload::jsonb#>>'{manager_authority_facts,resource_id}'=m.task_id::text - and e.event_payload::jsonb#>>'{manager_authority_facts,scope_project_id}'=b.project_id::text - and e.event_payload::jsonb#>>'{manager_authority_facts,idempotency_key}'=c.idempotency_key::text - and e.event_payload::jsonb#>>'{manager_authority_facts,request_digest}'=c.request_digest - and e.event_payload::jsonb#>>'{manager_authority_facts,identity_link_id}'=b.identity_link_id::text - and e.event_payload::jsonb#>>'{manager_authority_facts,task_status}'= - case b.action_id when 'project.task.screen' then 'draft' else 'screening' end - and coalesce((e.event_payload::jsonb#>>'{manager_authority_facts,locked_context_hash}') - ~ '^sha256:[0-9a-f]{64}$',false) - and (b.action_id='project.task.screen' or - e.event_payload::jsonb#>>'{manager_authority_facts,locked_context_hash}'=c.locked_context_hash) - and public.external_checker_registry_digest(jsonb_build_object( - 'resource_context',jsonb_strip_nulls( - e.event_payload::jsonb->'manager_authority_facts'))) - =d.after_facts::jsonb->>'resource_context_digest' - and e.event_payload::jsonb->>'authorization_resource_digest' - =d.after_facts::jsonb->>'resource_context_digest' - and e.event_payload::jsonb->>'locked_guide_version'=c.response::jsonb->>'locked_guide_version' - and e.event_payload::jsonb->>'locked_contribution_policy_version_id' - =c.response::jsonb->>'locked_contribution_policy_version_id') - )) then return false; end if; - - select jsonb_build_object('project_id',b.project_id::text,'batch_id',b.batch_id::text, - 'operation',case b.action_id when 'project.task.screen' then 'screen' else 'release' end, - 'row_count',b.row_count,'tasks',coalesce(jsonb_agg(jsonb_build_object( - 'task_id',m.task_id::text,'row_index',m.row_index,'status',c.response::jsonb->>'status', - 'locked_guide_version',c.response::jsonb->>'locked_guide_version', - 'locked_contribution_policy_version_id',c.response::jsonb->>'locked_contribution_policy_version_id', - 'locked_context_hash',c.locked_context_hash) order by m.row_index),'[]'::jsonb)) - into expected_response - from public.task_batch_transition_members m - join public.task_command_receipts c on c.id=m.task_command_receipt_id - where m.transition_receipt_id=b.id; - return b.response=expected_response; -exception when others then return false; -end $$ -""") - op.execute(r""" -create function public.trigger_validate_task_batch_transition() returns trigger -language plpgsql set search_path=pg_catalog,public,pg_temp as $$ -declare final_status text; -begin - select status into final_status from public.task_batch_transition_receipts where id=new.id; - if not found or final_status<>'committed' then - raise exception 'task batch transition cannot remain pending' using errcode='23514'; - end if; - if new.status='committed' - and not public.validate_task_batch_transition_custody(new.id) then - raise exception 'task batch transition custody mismatch' using errcode='23514'; - end if; return new; end $$ -""") - op.execute(r""" -create function public.trigger_validate_task_batch_transition_member() returns trigger -language plpgsql set search_path=pg_catalog,public,pg_temp as $$ -declare parent_status text; parent_xid xid; -begin - select status,xmin into parent_status,parent_xid - from public.task_batch_transition_receipts where id=new.transition_receipt_id; - if not found or parent_status<>'committed' - or parent_xid<>pg_catalog.pg_current_xact_id()::xid then - raise exception 'task batch transition member must be committed with its root' using errcode='23514'; - end if; - return new; -end $$ -""") - op.execute(r""" -create function public.trigger_validate_task_batch_command_root() returns trigger -language plpgsql set search_path=pg_catalog,public,pg_temp as $$ -declare parent_status text; parent_xid xid; -begin - if new.batch_transition_receipt_id is null then return new; end if; - select status,xmin into parent_status,parent_xid - from public.task_batch_transition_receipts where id=new.batch_transition_receipt_id; - if not found or parent_status<>'committed' - or parent_xid<>pg_catalog.pg_current_xact_id()::xid then - raise exception 'task batch transition command must be committed with its root' using errcode='23514'; - end if; - return new; -end $$ -""") - op.execute( - "create constraint trigger task_batch_transition_custody after insert or update on public.task_batch_transition_receipts deferrable initially deferred for each row execute function public.trigger_validate_task_batch_transition()" - ) - op.execute( - "create constraint trigger task_batch_transition_member_custody after insert or update on public.task_batch_transition_members deferrable initially deferred for each row execute function public.trigger_validate_task_batch_transition_member()" - ) - op.execute( - "create constraint trigger task_batch_transition_command_custody after insert or update of batch_transition_receipt_id,status,response,locked_context_hash on public.task_command_receipts deferrable initially deferred for each row execute function public.trigger_validate_task_batch_command_root()" - ) - - -def _create_guards() -> None: - op.execute(r""" -create function public.guard_task_batch_transition_receipt() returns trigger -language plpgsql set search_path=pg_catalog,public,pg_temp as $$ begin - if tg_op='TRUNCATE' then raise exception 'task batch transition receipts cannot be truncated' using errcode='55000'; end if; - if tg_op='DELETE' then raise exception 'task batch transition receipts are immutable' using errcode='55000'; end if; - if new is not distinct from old then return new; end if; - if old.status<>'pending' or new.status<>'committed' - or row(new.id,new.actor_profile_id,new.identity_link_id,new.action_id,new.idempotency_key, - new.request_digest,new.reason,new.project_id,new.batch_id,new.manifest_digest, - new.membership_digest,new.row_count,new.created_at) - is distinct from - row(old.id,old.actor_profile_id,old.identity_link_id,old.action_id,old.idempotency_key, - old.request_digest,old.reason,old.project_id,old.batch_id,old.manifest_digest, - old.membership_digest,old.row_count,old.created_at) - or old.response is not null or old.committed_at is not null - or new.response is null or new.committed_at is null then - raise exception 'task batch transition receipt is immutable' using errcode='23514'; - end if; return new; end $$ -""") - op.execute(r""" -create function public.reject_task_batch_transition_member_mutation() returns trigger -language plpgsql set search_path=pg_catalog,public,pg_temp as $$ begin - raise exception 'task batch transition members are immutable' using errcode='55000'; end $$ -""") - op.execute( - "create trigger task_batch_transition_receipt_immutable before update or delete on public.task_batch_transition_receipts for each row execute function public.guard_task_batch_transition_receipt()" - ) - op.execute( - "create trigger task_batch_transition_receipt_no_truncate before truncate on public.task_batch_transition_receipts for each statement execute function public.guard_task_batch_transition_receipt()" - ) - op.execute( - "create trigger task_batch_transition_member_immutable before update or delete on public.task_batch_transition_members for each row execute function public.reject_task_batch_transition_member_mutation()" - ) - op.execute( - "create trigger task_batch_transition_member_no_truncate before truncate on public.task_batch_transition_members for each statement execute function public.reject_task_batch_transition_member_mutation()" - ) - - -def upgrade() -> None: - """Install exact aggregate-to-member-to-command transition custody.""" - op.execute("set local search_path=pg_catalog,public,pg_temp") - op.execute( - "lock table public.task_command_receipts, public.task_import_batches, " - "public.task_import_batch_members, public.audit_events in access exclusive mode" - ) - _create_tables() - _alter_command_receipts() - _create_custody() - _create_guards() - - -def downgrade() -> None: - """Refuse removal of retained aggregate transition custody.""" - op.execute("set local search_path=pg_catalog,public,pg_temp") - op.execute( - "lock table public.task_batch_transition_receipts, public.task_batch_transition_members, " - "public.task_command_receipts in access exclusive mode" - ) - retained = ( - op.get_bind() - .execute( - sa.text( - "select exists(select 1 from public.task_batch_transition_receipts) or " - "exists(select 1 from public.task_batch_transition_members) or " - "exists(select 1 from public.task_command_receipts where batch_transition_receipt_id is not null)" - ) - ) - .scalar_one() - ) - if retained: - raise RuntimeError("cannot downgrade batch transitions with retained custody") - raise RuntimeError("Workstream v0.1 migrations cannot be downgraded; recreate the database") diff --git a/backend/alembic/versions/0036_contribution_export_pages.py b/backend/alembic/versions/0036_contribution_export_pages.py deleted file mode 100644 index 090ae20f4..000000000 --- a/backend/alembic/versions/0036_contribution_export_pages.py +++ /dev/null @@ -1,314 +0,0 @@ -"""Install private fixed-membership contribution export custody.""" - -from alembic import op - -revision = "0036_contribution_export_pages" -down_revision = "0035_task_batch_transitions" -branch_labels = None -depends_on = None - - -def upgrade() -> None: - op.execute(""" -CREATE INDEX ix_contribution_records_self_export -ON public.contribution_records (contributor_id, created_at, id) -""") - op.execute(""" -CREATE INDEX ix_contribution_records_project_export -ON public.contribution_records (project_id, created_at, id) -""") - op.execute(""" -CREATE TABLE public.contribution_export_memberships ( - id UUID NOT NULL, - actor_profile_id UUID NOT NULL, - audience VARCHAR(16) NOT NULL, - project_id UUID, - output_format VARCHAR(4) NOT NULL, - page_size INTEGER NOT NULL, - contribution_type VARCHAR(32), - recorded_from TIMESTAMP WITH TIME ZONE, - recorded_before TIMESTAMP WITH TIME ZONE, - member_count INTEGER NOT NULL, - sealed BOOLEAN NOT NULL, - query_digest VARCHAR(71) NOT NULL, - exported_at TIMESTAMP WITH TIME ZONE NOT NULL, - expires_at TIMESTAMP WITH TIME ZONE NOT NULL, - CONSTRAINT pk_contribution_export_memberships PRIMARY KEY (id), - CONSTRAINT ck_contribution_export_memberships_id_uuid7 - CHECK ((get_byte(uuid_send(id), 6) >> 4) = 7 - AND (get_byte(uuid_send(id), 8) & 192) = 128), - CONSTRAINT ck_contribution_export_memberships_query_digest - CHECK (query_digest ~ '^sha256:[0-9a-f]{64}$'), - CONSTRAINT ck_contribution_export_memberships_expiry - CHECK (expires_at = exported_at + interval '15 minutes'), - CONSTRAINT ck_contribution_export_memberships_member_count - CHECK (member_count BETWEEN 0 AND 100000), - CONSTRAINT ck_contribution_export_memberships_audience - CHECK (audience IN ('self','project') - AND (audience <> 'project' OR project_id IS NOT NULL)), - CONSTRAINT ck_contribution_export_memberships_output_format - CHECK (output_format IN ('json','csv')), - CONSTRAINT ck_contribution_export_memberships_page_size - CHECK (page_size BETWEEN 1 AND 1000), - CONSTRAINT ck_contribution_export_memberships_contribution_type - CHECK (contribution_type IS NULL - OR contribution_type IN ('accepted_submission','completed_review')), - CONSTRAINT ck_contribution_export_memberships_recorded_interval - CHECK (recorded_from IS NULL OR recorded_before IS NULL - OR recorded_from < recorded_before), - CONSTRAINT fk_contribution_export_memberships_actor_profile_id_act_4609 - FOREIGN KEY(actor_profile_id) REFERENCES public.actor_profiles (id) - ON DELETE RESTRICT, - CONSTRAINT fk_contribution_export_memberships_project_id_projects - FOREIGN KEY(project_id) REFERENCES public.projects (id) - ON DELETE RESTRICT -) -""") - op.execute(""" -CREATE INDEX ix_contribution_export_memberships_expires_at -ON public.contribution_export_memberships (expires_at) -""") - op.execute(""" -CREATE TABLE public.contribution_export_members ( - export_id UUID NOT NULL, - contribution_id UUID NOT NULL, - recorded_at TIMESTAMP WITH TIME ZONE NOT NULL, - CONSTRAINT pk_contribution_export_members - PRIMARY KEY (export_id, contribution_id), - CONSTRAINT fk_contribution_export_members_export_id_contribution_e_3433 - FOREIGN KEY(export_id) REFERENCES public.contribution_export_memberships (id) - ON DELETE CASCADE, - CONSTRAINT fk_contribution_export_members_contribution_id_contribu_5e22 - FOREIGN KEY(contribution_id) REFERENCES public.contribution_records (id) - ON DELETE RESTRICT -) -""") - op.execute(""" -CREATE INDEX ix_contribution_export_members_order -ON public.contribution_export_members (export_id, recorded_at, contribution_id) -""") - op.execute(""" -CREATE FUNCTION public.guard_contribution_export_member() RETURNS trigger -LANGUAGE plpgsql SET search_path=pg_catalog,public,pg_temp AS $$ -DECLARE - export_row public.contribution_export_memberships%ROWTYPE; - contribution_row public.contribution_records%ROWTYPE; -BEGIN - SELECT * INTO export_row - FROM public.contribution_export_memberships - WHERE id=NEW.export_id FOR UPDATE; - IF NOT FOUND OR export_row.sealed THEN - RAISE EXCEPTION 'contribution export membership is not capturing' - USING ERRCODE='23514'; - END IF; - - SELECT * INTO contribution_row - FROM public.contribution_records WHERE id=NEW.contribution_id; - IF NOT FOUND - OR NEW.recorded_at IS DISTINCT FROM contribution_row.created_at - OR (export_row.audience='self' - AND contribution_row.contributor_id IS DISTINCT FROM export_row.actor_profile_id) - OR (export_row.project_id IS NOT NULL - AND contribution_row.project_id IS DISTINCT FROM export_row.project_id) - OR (export_row.contribution_type IS NOT NULL - AND contribution_row.contribution_type IS DISTINCT FROM export_row.contribution_type) - OR (export_row.recorded_from IS NOT NULL - AND contribution_row.created_at < export_row.recorded_from) - OR (export_row.recorded_before IS NOT NULL - AND contribution_row.created_at >= export_row.recorded_before) - THEN - RAISE EXCEPTION 'contribution export member does not match the sealed query' - USING ERRCODE='23514'; - END IF; - RETURN NEW; -END $$ -""") - op.execute(""" -CREATE TRIGGER contribution_export_member_custody -BEFORE INSERT ON public.contribution_export_members -FOR EACH ROW EXECUTE FUNCTION public.guard_contribution_export_member() -""") - op.execute(""" -CREATE FUNCTION public.guard_contribution_export_membership_insert() RETURNS trigger -LANGUAGE plpgsql SET search_path=pg_catalog,public,pg_temp AS $$ -BEGIN - IF NEW.sealed THEN - RAISE EXCEPTION 'contribution export membership must begin unsealed' - USING ERRCODE='23514'; - END IF; - RETURN NEW; -END $$ -""") - op.execute(""" -CREATE TRIGGER contribution_export_membership_insert -BEFORE INSERT ON public.contribution_export_memberships -FOR EACH ROW EXECUTE FUNCTION public.guard_contribution_export_membership_insert() -""") - op.execute(""" -CREATE FUNCTION public.guard_contribution_export_membership_update() RETURNS trigger -LANGUAGE plpgsql SET search_path=pg_catalog,public,pg_temp AS $$ -BEGIN - IF OLD.sealed OR NOT NEW.sealed - OR NEW.id IS DISTINCT FROM OLD.id - OR NEW.actor_profile_id IS DISTINCT FROM OLD.actor_profile_id - OR NEW.audience IS DISTINCT FROM OLD.audience - OR NEW.project_id IS DISTINCT FROM OLD.project_id - OR NEW.output_format IS DISTINCT FROM OLD.output_format - OR NEW.page_size IS DISTINCT FROM OLD.page_size - OR NEW.contribution_type IS DISTINCT FROM OLD.contribution_type - OR NEW.recorded_from IS DISTINCT FROM OLD.recorded_from - OR NEW.recorded_before IS DISTINCT FROM OLD.recorded_before - OR NEW.member_count IS DISTINCT FROM OLD.member_count - OR NEW.query_digest IS DISTINCT FROM OLD.query_digest - OR NEW.exported_at IS DISTINCT FROM OLD.exported_at - OR NEW.expires_at IS DISTINCT FROM OLD.expires_at - THEN - RAISE EXCEPTION 'contribution export membership facts are immutable' - USING ERRCODE='23514'; - END IF; - RETURN NEW; -END $$ -""") - op.execute(""" -CREATE TRIGGER contribution_export_membership_update -BEFORE UPDATE ON public.contribution_export_memberships -FOR EACH ROW EXECUTE FUNCTION public.guard_contribution_export_membership_update() -""") - op.execute(""" -CREATE FUNCTION public.guard_contribution_export_membership_delete() RETURNS trigger -LANGUAGE plpgsql SET search_path=pg_catalog,public,pg_temp AS $$ -BEGIN - IF OLD.expires_at > pg_catalog.clock_timestamp() THEN - RAISE EXCEPTION 'active contribution export membership cannot be deleted' - USING ERRCODE='23514'; - END IF; - RETURN OLD; -END $$ -""") - op.execute(""" -CREATE TRIGGER contribution_export_membership_delete -BEFORE DELETE ON public.contribution_export_memberships -FOR EACH ROW EXECUTE FUNCTION public.guard_contribution_export_membership_delete() -""") - op.execute(""" -CREATE FUNCTION public.guard_contribution_export_member_mutation() RETURNS trigger -LANGUAGE plpgsql SET search_path=pg_catalog,public,pg_temp AS $$ -DECLARE - expiry timestamptz; -BEGIN - IF TG_OP='UPDATE' THEN - RAISE EXCEPTION 'contribution export members are immutable' - USING ERRCODE='23514'; - END IF; - SELECT expires_at INTO expiry - FROM public.contribution_export_memberships WHERE id=OLD.export_id; - IF pg_catalog.pg_trigger_depth() <= 1 OR expiry IS NOT NULL THEN - RAISE EXCEPTION 'contribution export members can be deleted only with an expired parent' - USING ERRCODE='23514'; - END IF; - RETURN OLD; -END $$ -""") - op.execute(""" -CREATE TRIGGER contribution_export_member_mutation -BEFORE UPDATE OR DELETE ON public.contribution_export_members -FOR EACH ROW EXECUTE FUNCTION public.guard_contribution_export_member_mutation() -""") - op.execute(""" -CREATE FUNCTION public.validate_contribution_export_membership(export_uuid uuid) RETURNS void -LANGUAGE plpgsql SET search_path=pg_catalog,public,pg_temp AS $$ -DECLARE - export_row public.contribution_export_memberships%ROWTYPE; - stored_count bigint; - selected_count bigint; -BEGIN - SELECT * INTO export_row - FROM public.contribution_export_memberships WHERE id=export_uuid; - IF NOT FOUND THEN - RETURN; - END IF; - IF NOT export_row.sealed THEN - RAISE EXCEPTION 'contribution export membership must be sealed before commit' - USING ERRCODE='23514'; - END IF; - - SELECT count(*) INTO stored_count - FROM public.contribution_export_members WHERE export_id=export_uuid; - SELECT count(*) INTO selected_count - FROM public.contribution_records c - WHERE (export_row.audience<>'self' OR c.contributor_id=export_row.actor_profile_id) - AND (export_row.project_id IS NULL OR c.project_id=export_row.project_id) - AND (export_row.contribution_type IS NULL - OR c.contribution_type=export_row.contribution_type) - AND (export_row.recorded_from IS NULL OR c.created_at>=export_row.recorded_from) - AND (export_row.recorded_before IS NULL OR c.created_at'self' OR c.contributor_id=export_row.actor_profile_id) - AND (export_row.project_id IS NULL OR c.project_id=export_row.project_id) - AND (export_row.contribution_type IS NULL - OR c.contribution_type=export_row.contribution_type) - AND (export_row.recorded_from IS NULL OR c.created_at>=export_row.recorded_from) - AND (export_row.recorded_before IS NULL OR c.created_at None: - connection = op.get_bind() - retained = connection.exec_driver_sql( - "SELECT EXISTS (SELECT 1 FROM public.contribution_export_memberships) " - "OR EXISTS (SELECT 1 FROM public.contribution_export_members)" - ).scalar_one() - if retained: - raise RuntimeError( - "0036_contribution_export_pages cannot be downgraded while retained " - "contribution export custody exists" - ) - raise RuntimeError( - "Workstream v0.1 migrations cannot be downgraded; recreate the database" - ) diff --git a/backend/app/adapters/artifacts/__init__.py b/backend/app/adapters/artifacts/__init__.py index ebec6160a..b665ab0ff 100644 --- a/backend/app/adapters/artifacts/__init__.py +++ b/backend/app/adapters/artifacts/__init__.py @@ -623,20 +623,18 @@ async def get_task_import_source_commands( session: Annotated[AsyncSession, Depends(get_db_session)], context: Annotated[object, Depends(get_artifact_authorization_context)], ) -> TaskImportSourceCommandPort: - """Capture actor facts, then compose the same source owner for public commands.""" - await session.rollback() - return task_import_source_commands(session, settings=request.app.state.settings, context=context) - - -def task_import_source_commands(session: AsyncSession, *, settings, context): - """Compose source reads/bindings and lazy provider runtime through one owner path.""" + """Compose exact source commands in ART's registered owner root.""" from app.adapters.auth import task_import_source_authorization from app.modules.artifacts.service import ( ArtifactAdmissionService, ArtifactStorageOrchestrator, artifact_storage_namespace_spec, ) from app.modules.artifacts.task_import_sources import ArtifactTaskImportSourceCommands, TaskImportSourceRuntime - request_id, correlation_id = context.request_id, context.correlation_id + settings = request.app.state.settings + request_id, correlation_id = (UUID(value) for value in request_ids(request)) + # Identity provisioning is committed by its owner. As in TASK commands, + # discard the resolver's read-only refresh before ART owns each root. + await session.rollback() @asynccontextmanager async def runtime(): diff --git a/backend/app/adapters/contributions/__init__.py b/backend/app/adapters/contributions/__init__.py index f762d358d..63dd33462 100644 --- a/backend/app/adapters/contributions/__init__.py +++ b/backend/app/adapters/contributions/__init__.py @@ -72,21 +72,17 @@ def submitter_contribution_participant(session, fence): def contribution_export_service( session: AsyncSession, *, authorization: ContributionReadAuthorizationPort, - cursor_secret: bytes | None, ) -> ContributionExportPort: """Compose one mandatory authorized evidence projection on the caller's snapshot.""" from app.adapters.actors import contribution_actor_label_port from app.adapters.compensation import contribution_award_read_port from app.adapters.reviews import final_acceptance_read_port from app.adapters.tasks import contribution_task_evidence_port - from app.modules.contributions.records.cursors import ContributionCursorCodec from app.modules.contributions.records.read_repository import ContributionReadRepository from app.modules.contributions.records.read_service import ContributionReadService return ContributionReadService( - authorization=authorization, records=ContributionReadRepository( - session, cursor_codec=None if cursor_secret is None else ContributionCursorCodec(cursor_secret), - ), + authorization=authorization, records=ContributionReadRepository(session), awards=contribution_award_read_port(session), acceptances=final_acceptance_read_port(session), tasks=contribution_task_evidence_port(session), actors=contribution_actor_label_port(session), ) diff --git a/backend/app/adapters/tasks/__init__.py b/backend/app/adapters/tasks/__init__.py index 492a1542f..a7a1db822 100644 --- a/backend/app/adapters/tasks/__init__.py +++ b/backend/app/adapters/tasks/__init__.py @@ -165,35 +165,6 @@ def task_commands( ) -def task_import_batch_commands( - session: AsyncSession, - *, - authorization, - audit: TaskTransitionAuditPort, - actor_profile_id: UUID, - identity_link_id: UUID, - settings: Settings, - source, -): - """Compose the batch root from canonical TASK commands and one ART source owner.""" - from app.modules.tasks.task_import_batches import TaskImportBatchCommands - - return TaskImportBatchCommands( - session, - actor_profile_id=actor_profile_id, - identity_link_id=identity_link_id, - authorization=authorization, - tasks=task_commands( - session, - authorization=authorization, - audit=audit, - actor_profile_id=actor_profile_id, - settings=settings, - ), - source=source, - ) - - def contributor_task_repository(session: AsyncSession) -> TaskRepository: """Compose contributor reads with CON's bounded locked-terms public port.""" from app.adapters.contributions import locked_compensation_terms_port @@ -201,24 +172,6 @@ def contributor_task_repository(session: AsyncSession) -> TaskRepository: return TaskRepository(session, compensation_terms=locked_compensation_terms_port(session)) -def task_batch_transition_commands( - session: AsyncSession, - *, - tasks: AuthorizedTaskCommands, - actor_profile_id: UUID, - identity_link_id: UUID, -): - """Bind the batch root to the same canonical Task authority and participants.""" - from app.modules.tasks.task_batch_transitions import TaskBatchTransitionCommands - - return TaskBatchTransitionCommands( - session, - tasks=tasks, - actor_profile_id=actor_profile_id, - identity_link_id=identity_link_id, - ) - - def task_submission_context_port(session: AsyncSession) -> TaskSubmissionContextPort: """Bind the public TASK submission-context port to its repository.""" return TaskRepository(session) diff --git a/backend/app/api/deps/authorization.py b/backend/app/api/deps/authorization.py index 9fd13e374..36eee14ad 100644 --- a/backend/app/api/deps/authorization.py +++ b/backend/app/api/deps/authorization.py @@ -114,68 +114,6 @@ async def get_authorization_actor( return await resolve_authorization_actor(request, result, session, rate_control) -async def get_task_import_batch_commands( - request: Request, - resolved: Annotated[ResolvedActor, Depends(get_authorization_actor)], - session: Annotated[AsyncSession, Depends(get_db_session)], -) -> AsyncIterator[object]: - """Compose one root and restage denials only through their actual issuing owner.""" - from app.adapters.artifacts import task_import_source_commands - from app.adapters.audit import task_transition_audit - from app.adapters.auth import task_authorization - from app.adapters.tasks import task_import_batch_commands - from app.modules.artifacts.api.task_import_source import TaskImportSourceAuthorityDenied, TaskImportSourceError - from app.modules.tasks.api import TaskAuthorityDenied - from app.modules.tasks.api.task_import import TaskImportBatchAuthorityDenied - - request_id, correlation_id = (UUID(value) for value in request_ids(request)) - context = _authorization_context(resolved, request_id, correlation_id) - await session.rollback() - authority = task_authorization(session, context) - source = task_import_source_commands(session, settings=request.app.state.settings, context=context) - try: - yield task_import_batch_commands( - session, settings=request.app.state.settings, authorization=authority, - audit=task_transition_audit(session), actor_profile_id=context.actor_profile_id, - identity_link_id=context.identity_link_id, source=source, - ) - except (TaskAuthorityDenied, TaskImportBatchAuthorityDenied, TaskImportSourceAuthorityDenied) as exc: - await session.rollback() - try: - if isinstance(exc, TaskImportSourceAuthorityDenied): - await source.restage_denial(exc) - else: - await authority.restage_denial(exc) - await session.commit() - except (AuthorizationEvidenceUnavailable, SQLAlchemyError) as evidence_error: - await session.rollback() - raise StructuredHTTPException( - status_code=503, detail="Task import authority unavailable", error_code="task_import_authority_unavailable", - error_message="Task import authority unavailable", retryable=True, - ) from evidence_error - concealed = request.method == "GET" - raise StructuredHTTPException( - status_code=404 if concealed else 403, - detail="Task import batch not found" if concealed else "Task import authority denied", - error_code="task_import_batch_not_found" if concealed else "permission_not_granted", - error_message="Task import batch not found" if concealed else "Task import authority denied", - ) from exc - except TaskImportSourceError as exc: - raise StructuredHTTPException( - status_code=exc.status_code, detail=exc.code, error_code=exc.code, - error_message=exc.code.replace("_", " "), retryable=exc.status_code == 503, - ) from exc - except (AuthorizationEvidenceUnavailable, SQLAlchemyError) as exc: - await session.rollback() - raise StructuredHTTPException( - status_code=503, detail="Task import authority unavailable", error_code="task_import_authority_unavailable", - error_message="Task import authority unavailable", retryable=True, - ) from exc - finally: - if session.in_transaction(): - await session.rollback() - - async def get_task_commands( request: Request, resolved: Annotated[ResolvedActor, Depends(get_authorization_actor)], diff --git a/backend/app/api/deps/contribution_exports.py b/backend/app/api/deps/contribution_exports.py index 4d747a546..5fc671bf7 100644 --- a/backend/app/api/deps/contribution_exports.py +++ b/backend/app/api/deps/contribution_exports.py @@ -16,11 +16,10 @@ _authorization_context, get_authorization_actor, get_authorization_actor_identity, ) from app.core.api_controls import StructuredHTTPException, request_ids -from app.core.config import decode_pagination_cursor_hmac_secret from app.db.session import get_db_session from app.modules.contributions.api.records import ( ContributionExportPort, ContributionExportResponse, ContributionExportTooLarge, - ContributionExportUnavailable, ContributionReadDenied, ContributionReadRequest, InvalidContributionCursor, + ContributionExportUnavailable, ContributionReadDenied, ContributionReadRequest, ) @@ -37,7 +36,7 @@ def contribution_export_http_error(status: int) -> StructuredHTTPException: """Conceal denied scopes and keep limits/storage errors free of owner facts.""" code, message = { 404: ("contribution_export_not_found", "Contribution evidence unavailable"), - 422: ("contribution_export_too_large", "Contribution export exceeds 100000 records; narrow the filters"), + 422: ("contribution_export_too_large", "Contribution export exceeds 1000 records; narrow the filters"), 503: ("contribution_export_unavailable", "Contribution export unavailable"), }[status] return StructuredHTTPException(status_code=status, detail=code, error_code=code, @@ -54,18 +53,12 @@ async def get_contribution_export_request( context = _authorization_context(resolved, request_id, correlation_id) actor = await get_authorization_actor_identity(resolved) await session.rollback() - secret = request.app.state.settings.pagination_cursor_hmac_secret - cursor_secret = None if secret is None else decode_pagination_cursor_hmac_secret(secret) try: yield ContributionExportRequest(session, contribution_export_service( - session, authorization=contribution_read_authorization(session, context), cursor_secret=cursor_secret, + session, authorization=contribution_read_authorization(session, context), ), actor.actor_profile_id) except ContributionReadDenied as exc: raise contribution_export_http_error(404) from exc - except InvalidContributionCursor as exc: - raise StructuredHTTPException(status_code=422, detail="contribution_export_invalid_cursor", - error_code="contribution_export_invalid_cursor", - error_message="Invalid contribution export cursor") from exc except ContributionExportTooLarge as exc: raise contribution_export_http_error(422) from exc except (ContributionExportUnavailable, SQLAlchemyError, ValidationError, TypeError) as exc: @@ -104,11 +97,8 @@ async def contribution_export_response( raise if selected.output_format == "csv": body = contribution_export_csv(projection) - headers = {"Content-Disposition": 'attachment; filename="contributions.csv"', - "X-Workstream-Exported-At": projection.exported_at.isoformat()} - if projection.next_cursor is not None: - headers["X-Workstream-Next-Cursor"] = projection.next_cursor - response = Response(body, media_type="text/csv; charset=utf-8", headers=headers) + response = Response(body, media_type="text/csv; charset=utf-8", + headers={"Content-Disposition": 'attachment; filename="contributions.csv"'}) else: body = projection.model_dump_json().encode("utf-8") ContributionExportResponse.model_validate_json(body) diff --git a/backend/app/api/deps/task_batch_transitions.py b/backend/app/api/deps/task_batch_transitions.py deleted file mode 100644 index 0556ca300..000000000 --- a/backend/app/api/deps/task_batch_transitions.py +++ /dev/null @@ -1,25 +0,0 @@ -"""Compose a batch root inside the existing canonical Task denial lifecycle.""" - -from typing import Annotated - -from fastapi import Depends -from sqlalchemy.ext.asyncio import AsyncSession - -from app.api.deps.authorization import get_authorization_actor_identity, get_task_commands -from app.db.session import get_db_session -from app.modules.authorization.api import ActorIdentityFacts -from app.modules.tasks.api.task_batch_transition import TaskBatchTransitionPort - - -async def get_task_batch_transition_commands( - identity: Annotated[ActorIdentityFacts, Depends(get_authorization_actor_identity)], - tasks: Annotated[object, Depends(get_task_commands)], - session: Annotated[AsyncSession, Depends(get_db_session)], -) -> TaskBatchTransitionPort: - """Reuse the actual issuing AUTH owner for rollback and denial-only restaging.""" - from app.adapters.tasks import task_batch_transition_commands - - return task_batch_transition_commands( - session, tasks=tasks, actor_profile_id=identity.actor_profile_id, - identity_link_id=identity.identity_link_id, - ) diff --git a/backend/app/api/routes/contributions.py b/backend/app/api/routes/contributions.py index cdda6b785..89f80ef26 100644 --- a/backend/app/api/routes/contributions.py +++ b/backend/app/api/routes/contributions.py @@ -3,7 +3,7 @@ from typing import Annotated, Literal from uuid import UUID -from fastapi import APIRouter, Depends, Query +from fastapi import APIRouter, Depends from pydantic import AwareDatetime, ValidationError from app.api.deps.contribution_exports import ( @@ -14,25 +14,16 @@ router = APIRouter(tags=["contributions"]) _ERRORS = {status: {"model": ApiErrorResponse} for status in (404, 422, 503)} -_CSV = {"200": { - "content": {"text/csv": {"schema": {"type": "string"}}}, - "headers": { - "X-Workstream-Exported-At": {"description": "CSV original export instant, identical on every page", - "schema": {"type": "string", "format": "date-time"}}, - "X-Workstream-Next-Cursor": {"description": "CSV continuation; absent on the final page", - "schema": {"type": "string", "maxLength": 4096}}, - }, -}} +_CSV = {"200": {"content": {"text/csv": {"schema": {"type": "string"}}}}} -def _selected(context, audience, project_id, output_format, contribution_type, recorded_from, recorded_before, - page_size, cursor): +def _selected(context, audience, project_id, output_format, contribution_type, recorded_from, recorded_before): """Bind self actor on the server and reject inverted/naive recorded-time filters.""" try: return ContributionReadRequest( audience=audience, actor_profile_id=context.actor_profile_id, project_id=project_id, output_format=output_format, contribution_type=contribution_type, - recorded_from=recorded_from, recorded_before=recorded_before, page_size=page_size, cursor=cursor, + recorded_from=recorded_from, recorded_before=recorded_before, ) except ValidationError as exc: raise StructuredHTTPException(status_code=422, detail="contribution_export_invalid", @@ -47,13 +38,10 @@ async def read_own_contributions( project_id: UUID | None = None, format: Literal["json", "csv"] = "json", contribution_type: Literal["accepted_submission", "completed_review"] | None = None, recorded_from: AwareDatetime | None = None, recorded_before: AwareDatetime | None = None, - page_size: Annotated[int, Query(ge=1, le=1000)] = 100, - cursor: Annotated[str | None, Query(min_length=1, max_length=4096, - pattern=r"^[A-Za-z0-9_-]+$")] = None, ): - """Return one authorized page of a fixed own-contribution selection.""" + """Return all selected own records, refusing over 1000 instead of truncating.""" return await contribution_export_response(context, _selected( - context, "self", project_id, format, contribution_type, recorded_from, recorded_before, page_size, cursor, + context, "self", project_id, format, contribution_type, recorded_from, recorded_before, )) @@ -65,11 +53,8 @@ async def export_project_contributions( format: Literal["json", "csv"] = "json", contribution_type: Literal["accepted_submission", "completed_review"] | None = None, recorded_from: AwareDatetime | None = None, recorded_before: AwareDatetime | None = None, - page_size: Annotated[int, Query(ge=1, le=1000)] = 100, - cursor: Annotated[str | None, Query(min_length=1, max_length=4096, - pattern=r"^[A-Za-z0-9_-]+$")] = None, ): """Export one project for covering PM or exact-project Finance authority.""" return await contribution_export_response(context, _selected( - context, "project", project_id, format, contribution_type, recorded_from, recorded_before, page_size, cursor, + context, "project", project_id, format, contribution_type, recorded_from, recorded_before, )) diff --git a/backend/app/db/models.py b/backend/app/db/models.py index cf4c8b078..f438ad840 100644 --- a/backend/app/db/models.py +++ b/backend/app/db/models.py @@ -88,10 +88,6 @@ TaskAssignment, WorkstreamTask, ) -from app.modules.tasks.task_batch_transition.models import ( # noqa: F401 - TaskBatchTransitionMember, - TaskBatchTransitionReceipt, -) from app.modules.tasks.post_submit_routing.models import ( # noqa: F401 TaskPostSubmitRoutingManifest, TaskRoutingRequest, diff --git a/backend/app/modules/artifacts/task_import_sources.py b/backend/app/modules/artifacts/task_import_sources.py index 6c14a064a..77c1ea88e 100644 --- a/backend/app/modules/artifacts/task_import_sources.py +++ b/backend/app/modules/artifacts/task_import_sources.py @@ -30,9 +30,7 @@ ArtifactAdmissionError, ArtifactAdmissionConflictError, ArtifactAdmissionCapacityError, validate_artifact_replica_execution_namespace, ) -from app.modules.tasks.api.task_import import ( - parse_task_import, TASK_IMPORT_MAXIMUM_BYTES, TaskImportSourceCommitment, VerifiedTaskImportSourceBinding, -) +from app.modules.tasks.api.task_import import parse_task_import, TASK_IMPORT_MAXIMUM_BYTES class _TaskImportInspector: @@ -198,149 +196,48 @@ async def upload(self, project_id: UUID, source_id: UUID, byte_source: AsyncIter await prepared.close() return await self.status(project_id, source_id) - async def _verified_ancestry( - self, source: ArtifactTaskImportSource, - expected: VerifiedTaskImportSourceBinding | None = None, - *, require_operational: bool = False, - ) -> tuple[VerifiedTaskImportSourceBinding, ArtifactReplica]: - """Validate append-only byte receipts independently of current provider health.""" - query = (select( + async def _verified_replica(self, source: ArtifactTaskImportSource) -> ArtifactReplica: + row = (await self._session.execute(select( ArtifactPutAttempt, ArtifactReplica, ArtifactContent, ArtifactVerificationJob, ArtifactVerificationReceipt, ).join(ArtifactReplica, ArtifactReplica.id == ArtifactPutAttempt.replica_id) .join(ArtifactContent, ArtifactContent.id == ArtifactReplica.content_id) .join(ArtifactVerificationJob, ArtifactVerificationJob.originating_put_attempt_id == ArtifactPutAttempt.id) - .join(ArtifactVerificationReceipt, ArtifactVerificationReceipt.verification_job_id == ArtifactVerificationJob.id) - .where(ArtifactPutAttempt.task_import_source_id == source.id, ArtifactVerificationReceipt.outcome == "verified")) - if require_operational: - query = query.where( - ArtifactVerificationJob.status == "verified", - ArtifactVerificationReceipt.execution_generation == ArtifactVerificationJob.execution_generation, - ).order_by(ArtifactVerificationJob.created_at.desc(), ArtifactVerificationJob.id.desc()).limit(1) - elif expected is not None: - query = query.where(ArtifactVerificationReceipt.id == str(expected.verification_receipt_id)) - else: - query = query.order_by(ArtifactVerificationReceipt.created_at.desc(), ArtifactVerificationReceipt.id.desc()).limit(1) - row = (await self._session.execute(query)).one_or_none() + .join(ArtifactVerificationReceipt, (ArtifactVerificationReceipt.verification_job_id == ArtifactVerificationJob.id) + & (ArtifactVerificationReceipt.execution_generation == ArtifactVerificationJob.execution_generation)) + .where(ArtifactPutAttempt.task_import_source_id == source.id, ArtifactVerificationJob.status == "verified") + .order_by(ArtifactVerificationJob.created_at.desc(), ArtifactVerificationJob.id.desc()).limit(1))).one_or_none() if row is None: raise TaskImportSourceError("task_import_source_unverified", 409) attempt, replica, content, job, receipt = row if (attempt.producer_request_type != "task_import_source" or attempt.project_id != source.project_id - or (require_operational and attempt.status != "object_confirmed") - or attempt.logical_role != "task_import_source" + or attempt.logical_role != "task_import_source" or attempt.status != "object_confirmed" or (attempt.sha256, attempt.byte_count, attempt.media_type) != (source.sha256, source.byte_count, source.media_type) or (content.sha256, content.byte_count) != (source.sha256, source.byte_count) - or job.replica_id != replica.id + or job.replica_id != replica.id or job.execution_generation != receipt.execution_generation or receipt.verification_job_id != job.id or receipt.outcome != "verified" or (receipt.observed_sha256, receipt.observed_byte_count) != (source.sha256, source.byte_count) + or (replica.verification_state, replica.availability_state, replica.integrity_state) != ("verified", "available", "valid") or (replica.storage_namespace_id, replica.namespace_fingerprint) != (attempt.storage_namespace_id, attempt.namespace_fingerprint)): raise TaskImportSourceError("task_import_source_custody_invalid", 409) - operation_id = attempt.receipt_id if expected is None else ( - str(expected.operation_receipt_id) if expected.operation_receipt_id is not None else None - ) - observation_id = None - if operation_id is not None: + if attempt.receipt_id is not None: acknowledged = await self._session.scalar(select(ArtifactOperationReceipt.id).where( - ArtifactOperationReceipt.id == operation_id, ArtifactOperationReceipt.put_attempt_id == attempt.id, + ArtifactOperationReceipt.id == attempt.receipt_id, ArtifactOperationReceipt.put_attempt_id == attempt.id, ArtifactOperationReceipt.replica_id == replica.id, ArtifactOperationReceipt.request_digest == attempt.request_digest, ArtifactOperationReceipt.provider_object_ref == replica.provider_object_ref, ArtifactOperationReceipt.logical_role == "task_import_source", ArtifactOperationReceipt.outcome == "stored_pending_verification", )) else: - query = select(ArtifactPutObservationReceipt.id).where( + acknowledged = await self._session.scalar(select(ArtifactPutObservationReceipt.id).where( ArtifactPutObservationReceipt.put_attempt_id == attempt.id, + ArtifactPutObservationReceipt.execution_generation == attempt.execution_generation, ArtifactPutObservationReceipt.outcome == "observed_confirmed", ArtifactPutObservationReceipt.observed_sha256 == source.sha256, ArtifactPutObservationReceipt.expected_sha256 == source.sha256, ArtifactPutObservationReceipt.observed_byte_count == source.byte_count, ArtifactPutObservationReceipt.expected_byte_count == source.byte_count, - ) - if require_operational: - query = query.where(ArtifactPutObservationReceipt.execution_generation == attempt.execution_generation) - elif expected is not None: - query = query.where(ArtifactPutObservationReceipt.id == str(expected.observation_receipt_id)) - else: - query = query.order_by(ArtifactPutObservationReceipt.execution_generation.desc(), - ArtifactPutObservationReceipt.id.desc()).limit(1) - acknowledged = await self._session.scalar(query) - observation_id = acknowledged + )) if acknowledged is None: raise TaskImportSourceError("task_import_source_custody_invalid", 409) - binding = VerifiedTaskImportSourceBinding( - source_id=UUID(source.id), project_id=UUID(source.project_id), sha256=source.sha256, - byte_count=source.byte_count, operation_identity=source.operation_identity, - put_attempt_id=UUID(attempt.id), content_id=UUID(content.id), replica_id=UUID(replica.id), - verification_job_id=UUID(job.id), verification_generation=receipt.execution_generation, - verification_receipt_id=UUID(receipt.id), - operation_receipt_id=UUID(operation_id) if operation_id is not None else None, - observation_receipt_id=UUID(observation_id) if observation_id is not None else None, - ) - if expected is not None and binding != expected: - raise TaskImportSourceError("task_import_source_custody_invalid", 409) - return binding, replica - - async def source_commitment(self, project_id: UUID, source_id: UUID) -> TaskImportSourceCommitment: - """Read the actual declaration for preparation; this supplies no authority.""" - if not self._session.in_transaction(): - raise RuntimeError("source commitment requires a caller transaction") - source = await self._session.scalar(select(ArtifactTaskImportSource).where( - ArtifactTaskImportSource.id == str(source_id), ArtifactTaskImportSource.project_id == str(project_id), - ).execution_options(populate_existing=True)) - if source is None: - raise TaskImportSourceError("task_import_source_not_found", 404) - return self._commitment(source) - - @staticmethod - def _commitment(source: ArtifactTaskImportSource) -> TaskImportSourceCommitment: - return TaskImportSourceCommitment(UUID(source.id), UUID(source.project_id), source.sha256, - source.byte_count, source.operation_identity) - - async def authorize_commitment(self, facts: TaskImportSourceCommitment) -> UUID: - """Fence the actual declaration and authorize a provider-free preparation read.""" - if not self._session.in_transaction(): - raise RuntimeError("source authorization requires a caller transaction") - source = await self._session.scalar(select(ArtifactTaskImportSource).where( - ArtifactTaskImportSource.id == str(facts.source_id), - ArtifactTaskImportSource.project_id == str(facts.project_id), - ).with_for_update(read=True, key_share=True).execution_options(populate_existing=True)) - if source is None: - raise TaskImportSourceError("task_import_source_not_found", 404) - current = self._commitment(source) - if current != facts: - raise TaskImportSourceError("task_import_source_custody_invalid", 409) - return await self._authorization.authorize(TaskImportSourceAction.READ, self._facts(source)) - - async def prepare_binding( - self, project_id: UUID, source_id: UUID, - expected: VerifiedTaskImportSourceBinding | None = None, - ) -> VerifiedTaskImportSourceBinding: - """Retain SOURCE KEY SHARE before AUTH in the caller-owned transaction.""" - if not self._session.in_transaction(): - raise RuntimeError("source binding requires a caller transaction") - source = await self._session.scalar(select(ArtifactTaskImportSource).where( - ArtifactTaskImportSource.id == str(source_id), ArtifactTaskImportSource.project_id == str(project_id), - ).with_for_update(read=True, key_share=True).execution_options(populate_existing=True)) - if source is None: - raise TaskImportSourceError("task_import_source_not_found", 404) - binding, _ = await self._verified_ancestry(source, expected) - return binding - - async def authorize_binding(self, binding: VerifiedTaskImportSourceBinding) -> UUID: - """Revalidate prepared ancestry and consume fresh current-actor source READ.""" - await self.prepare_binding(binding.project_id, binding.source_id, binding) - source = await self._session.get(ArtifactTaskImportSource, str(binding.source_id)) - return await self._authorization.authorize(TaskImportSourceAction.READ, self._facts(source)) - - async def restage_denial(self, error: TaskImportSourceAuthorityDenied) -> None: - """Delegate caller-root denial custody to the source instance that captured it.""" - await self._authorization.restage_denial(error) - - async def _verified_replica(self, source: ArtifactTaskImportSource) -> ArtifactReplica: - """Apply current operational health checks only to an actual provider read.""" - _, replica = await self._verified_ancestry(source, require_operational=True) - if (replica.verification_state, replica.availability_state, replica.integrity_state) != ( - "verified", "available", "valid", - ): - raise TaskImportSourceError("task_import_source_custody_invalid", 409) return replica @asynccontextmanager diff --git a/backend/app/modules/audit/schemas.py b/backend/app/modules/audit/schemas.py index afa9be2b7..2602256b5 100644 --- a/backend/app/modules/audit/schemas.py +++ b/backend/app/modules/audit/schemas.py @@ -41,7 +41,7 @@ project_guide_compilation_attempt project_guide_sufficiency_projection project_submission_artifact_policy_projection project_guide_setup_finalization project_guide_compilation_review_package project_guide_compilation_correction - project_post_submit_checker_policy_mutation external_checker_registry_entry task_import_source task_import_batch""".split() + project_post_submit_checker_policy_mutation external_checker_registry_entry task_import_source""".split() ) _UUID_TARGET_KINDS = frozenset( { @@ -53,7 +53,6 @@ "project_role_grant", "external_checker_registry_entry", "task_import_source", - "task_import_batch", } ) _TARGET_REF_KINDS = _UUID_TARGET_KINDS | {"project"} @@ -368,7 +367,7 @@ class LifecycleAuditEventInput(BaseModel): event_type: LifecycleAuditEventType actor_id: UUID reason: LifecycleAuditReason - source_type: Literal["manual", "markdown_import", "csv_import", "json_import"] | None = None + source_type: Literal["manual", "markdown_import", "csv_import"] | None = None locked_lineage: dict[str, object] | None = None task_reason: Annotated[str, Field(min_length=1, max_length=1000)] | None = None from_status: Annotated[str, Field(pattern=r"^[a-z][a-z0-9_]{0,29}$")] | None = None diff --git a/backend/app/modules/authorization/artifact_project_authority.py b/backend/app/modules/authorization/artifact_project_authority.py index e3f67199d..a120d2c85 100644 --- a/backend/app/modules/authorization/artifact_project_authority.py +++ b/backend/app/modules/authorization/artifact_project_authority.py @@ -7,7 +7,7 @@ from app.modules.authorization.catalogue import ActionAvailability, ActionId from app.modules.authorization.schemas import AdminRole from app.modules.authorization.domain.task_authority import ( - TASK_ACTIONS, TASK_IMPORT_BATCH_ACTIONS, TASK_PROJECT_ROLE_READ_ACTIONS, TASK_SUBMITTER_ACTIONS, + TASK_ACTIONS, TASK_PROJECT_ROLE_READ_ACTIONS, TASK_SUBMITTER_ACTIONS, evaluate_task_authority, ) from app.modules.authorization.runtime import ( @@ -24,7 +24,7 @@ PROJECT_SUBMITTER_ACTIONS = TASK_SUBMITTER_ACTIONS | { ActionId.ARTIFACT_SUBMISSION_BUNDLE_PREPARE, ActionId.SUBMISSION_CREATE, } -PROJECT_AUTHORITY_ACTIONS = TASK_ACTIONS | TASK_IMPORT_BATCH_ACTIONS | PROJECT_SUBMITTER_ACTIONS | { +PROJECT_AUTHORITY_ACTIONS = TASK_ACTIONS | PROJECT_SUBMITTER_ACTIONS | { ActionId.ARTIFACT_GUIDE_SOURCE_INGEST, ActionId.ARTIFACT_TASK_IMPORT_SOURCE_DECLARE, ActionId.ARTIFACT_TASK_IMPORT_SOURCE_UPLOAD, @@ -52,7 +52,7 @@ async def lock_project_authority(repository, context, scope, action, locked_cont ActionId.OPERATIONS_TASK_START_OVERRIDE, ActionId.OPERATIONS_TASK_LOCKED_CONTEXT_READ, }, allowed_roles={ - **{action: frozenset({AdminRole.PROJECT_MANAGER}) for action in TASK_IMPORT_SOURCE_ACTIONS | TASK_IMPORT_BATCH_ACTIONS}, + **{action: frozenset({AdminRole.PROJECT_MANAGER}) for action in TASK_IMPORT_SOURCE_ACTIONS}, ActionId.PROJECT_TASK_LOCKED_CONTEXT_READ: frozenset({AdminRole.PROJECT_MANAGER}), ActionId.OPERATIONS_TASK_LOCKED_CONTEXT_READ: frozenset({AdminRole.OPERATOR}), ActionId.AUDIT_TASK_LOCKED_CONTEXT_READ: frozenset({AdminRole.AUDIT_AUTHORITY}), @@ -90,15 +90,13 @@ def evaluate_project_authority(action, context, authority, resource, lifecycle_d """Keep each resource guard distinct while sharing the closed dispatch boundary.""" if action.action_id in TASK_ACTIONS: return evaluate_task_authority(action, context, authority, resource, lifecycle_denial) - if action.action_id in TASK_IMPORT_SOURCE_ACTIONS | TASK_IMPORT_BATCH_ACTIONS: - from app.modules.authorization.runtime import TaskImportSourceResourceContext, TaskImportBatchResourceContext - expected_resource = (TaskImportBatchResourceContext if action.action_id in TASK_IMPORT_BATCH_ACTIONS - else TaskImportSourceResourceContext) + if action.action_id in TASK_IMPORT_SOURCE_ACTIONS: + from app.modules.authorization.runtime import TaskImportSourceResourceContext denial = lifecycle_denial if denial is None and action.availability is not ActionAvailability.ACTIVE: denial = AuthorizationDenialCode.ACTION_UNAVAILABLE if denial is None and ( - type(resource) is not expected_resource + type(resource) is not TaskImportSourceResourceContext or resource.scope_project_id != authority.scope_project_id or resource.actor_profile_id != context.actor_profile_id or resource.identity_link_id != context.identity_link_id diff --git a/backend/app/modules/authorization/catalogue.py b/backend/app/modules/authorization/catalogue.py index 861597482..7d512f85a 100644 --- a/backend/app/modules/authorization/catalogue.py +++ b/backend/app/modules/authorization/catalogue.py @@ -111,8 +111,6 @@ class ActionId(StrEnum): PROJECT_TASK_QUEUE_READ = "project.task.queue.read" OPERATIONS_TASK_QUEUE_READ = "operations.task.queue.read" PROJECT_TASK_CREATE = "project.task.create" - PROJECT_TASK_IMPORT = "project.task.import" - PROJECT_TASK_IMPORT_BATCH_READ = "project.task.import_batch.read" PROJECT_TASK_SCREEN = "project.task.screen" PROJECT_TASK_RELEASE = "project.task.release" TASK_CLAIM = "task.claim" @@ -299,7 +297,6 @@ class ActionOwner(StrEnum): TASK_PROJECT_GRANT = "task-project-grant-authorization" PILOT_13 = "PILOT-13" PILOT_02A = "PILOT-02A" - PILOT_02B = "PILOT-02B" PILOT_04 = "PILOT-04" PILOT_10 = "PILOT-10" @@ -572,8 +569,6 @@ def _active( _active(ActionId.PROJECT_TASK_QUEUE_READ, PermissionId.PROJECT_TASK_MANAGE, ActionOwner.ARCH_03C4), _active(ActionId.OPERATIONS_TASK_QUEUE_READ, PermissionId.OPERATIONS_STATUS_READ, ActionOwner.ARCH_03C4), _active(ActionId.PROJECT_TASK_CREATE, PermissionId.PROJECT_TASK_MANAGE, ActionOwner.ARCH_03C3), - _active(ActionId.PROJECT_TASK_IMPORT, PermissionId.PROJECT_TASK_MANAGE, ActionOwner.PILOT_02B), - _active(ActionId.PROJECT_TASK_IMPORT_BATCH_READ, PermissionId.PROJECT_TASK_MANAGE, ActionOwner.PILOT_02B), _active(ActionId.ARTIFACT_TASK_IMPORT_SOURCE_DECLARE, PermissionId.PROJECT_TASK_MANAGE, ActionOwner.PILOT_02A), _active(ActionId.ARTIFACT_TASK_IMPORT_SOURCE_UPLOAD, PermissionId.PROJECT_TASK_MANAGE, ActionOwner.PILOT_02A), _active(ActionId.ARTIFACT_TASK_IMPORT_SOURCE_READ, PermissionId.PROJECT_TASK_MANAGE, ActionOwner.PILOT_02A), @@ -787,7 +782,7 @@ def _active( def _require_catalogue_counts() -> None: """Keep the closed action inventory and permission boundary exact.""" - if len(PERMISSION_IDS) != 80 or len(ACTION_IDS) != 154: + if len(PERMISSION_IDS) != 80 or len(ACTION_IDS) != 152: raise RuntimeError("authorization catalogue count mismatch") if len(HISTORICAL_PERMISSION_IDS) != 49 or len(NEW_PERMISSION_IDS) != 31: raise RuntimeError("authorization permission boundary mismatch") @@ -925,7 +920,6 @@ def _index_actions(definitions: tuple[ActionDefinition, ...]) -> MappingProxyTyp ActionId.TASK_GUIDE_READ, ActionId.PROJECT_TASK_WORK_CONTEXT_READ, ActionId.OPERATIONS_TASK_START_OVERRIDE, ActionId.PROJECT_TASK_CREATE, ActionId.PROJECT_TASK_SCREEN, ActionId.PROJECT_TASK_RELEASE, - ActionId.PROJECT_TASK_IMPORT, ActionId.PROJECT_TASK_IMPORT_BATCH_READ, ActionId.ARTIFACT_TASK_IMPORT_SOURCE_DECLARE, ActionId.ARTIFACT_TASK_IMPORT_SOURCE_UPLOAD, ActionId.ARTIFACT_TASK_IMPORT_SOURCE_READ, ActionId.TASK_QUEUE_READ, ActionId.PROJECT_TASK_QUEUE_READ, ActionId.OPERATIONS_TASK_QUEUE_READ, diff --git a/backend/app/modules/authorization/domain/action_groups.py b/backend/app/modules/authorization/domain/action_groups.py index e14417799..a8ad94f8f 100644 --- a/backend/app/modules/authorization/domain/action_groups.py +++ b/backend/app/modules/authorization/domain/action_groups.py @@ -1,7 +1,6 @@ """Exact shared kernel action classifications; these sets grant no authority.""" from app.modules.authorization.catalogue import GUIDE_PROPOSAL_ACTION_IDS, POST_POLICY_HUMAN_ACTION_IDS, POST_POLICY_MUTATION_ACTION_IDS -from app.modules.authorization.domain.task_authority import TASK_IMPORT_BATCH_ACTIONS, TaskImportBatchResourceContext from app.modules.authorization.catalogue import ActionId from app.modules.authorization.domain import adapter_bindings, contribution_policies from app.modules.authorization.runtime import PROJECT_SUBMISSION_POLICY_TARGET_KIND_BY_ACTION @@ -41,7 +40,6 @@ { ActionId.CONTRIBUTION_READ_SELF, ActionId.CONTRIBUTION_READ_PROJECT, ActionId.ARTIFACT_GUIDE_SOURCE_INGEST, - *TASK_IMPORT_BATCH_ACTIONS, ActionId.ARTIFACT_TASK_IMPORT_SOURCE_DECLARE, ActionId.ARTIFACT_TASK_IMPORT_SOURCE_UPLOAD, ActionId.ARTIFACT_TASK_IMPORT_SOURCE_READ, @@ -75,7 +73,6 @@ def supports_prepared_denial(action_id: ActionId, resource_context: object) -> b ) or (action_id in TASK_ACTIONS and isinstance(resource_context, TaskAuthorityResourceContext)) - or (action_id in TASK_IMPORT_BATCH_ACTIONS and type(resource_context) is TaskImportBatchResourceContext) or ( action_id in {ActionId.ARTIFACT_TASK_IMPORT_SOURCE_DECLARE, ActionId.ARTIFACT_TASK_IMPORT_SOURCE_UPLOAD, ActionId.ARTIFACT_TASK_IMPORT_SOURCE_READ} diff --git a/backend/app/modules/authorization/domain/audit.py b/backend/app/modules/authorization/domain/audit.py index 6742374fb..1b956804d 100644 --- a/backend/app/modules/authorization/domain/audit.py +++ b/backend/app/modules/authorization/domain/audit.py @@ -44,7 +44,6 @@ "contribution_policy", "external_checker_registry_entry", "task_import_source", - "task_import_batch", ) @@ -109,7 +108,6 @@ "contribution_policy", "external_checker_registry_entry", "task_import_source", - "task_import_batch", ] diff --git a/backend/app/modules/authorization/domain/audit_targets.py b/backend/app/modules/authorization/domain/audit_targets.py index 5078453a1..54cea9783 100644 --- a/backend/app/modules/authorization/domain/audit_targets.py +++ b/backend/app/modules/authorization/domain/audit_targets.py @@ -15,7 +15,7 @@ GUIDE_BOUND_PROJECT_MANAGER_ACTIONS, SUBMISSION_POLICY_MUTATIONS, ) from app.modules.authorization.domain.project_create import ProjectCreateResourceContext -from app.modules.authorization.domain.task_authority import TaskAuthorityResourceContext, TaskImportBatchResourceContext +from app.modules.authorization.domain.task_authority import TaskAuthorityResourceContext from app.modules.authorization.domain.task_queues import QueueReadResourceContext from app.modules.authorization.domain.submission_history import HistoryReadResourceContext @@ -55,9 +55,6 @@ def project_authority_audit_target( if type(resource) is ReviewLifecycleActivationContract: return None, resource.resource_type, str(resource.resource_id), "joint_lifecycle_control", str(resource.resource_id) - if type(resource) is TaskImportBatchResourceContext: - return (str(resource.scope_project_id), resource.resource_type, str(resource.resource_id), - resource.resource_type, str(resource.resource_id)) if type(resource) is ContributionProjectReadResourceContext: if matched_scope_project_id != resource.scope_project_id: return None diff --git a/backend/app/modules/authorization/domain/task_authority.py b/backend/app/modules/authorization/domain/task_authority.py index 58fefc80f..a1c81e4fb 100644 --- a/backend/app/modules/authorization/domain/task_authority.py +++ b/backend/app/modules/authorization/domain/task_authority.py @@ -33,7 +33,6 @@ TASK_MANAGER_ACTIONS = frozenset({ ActionId.PROJECT_TASK_CREATE, ActionId.PROJECT_TASK_SCREEN, ActionId.PROJECT_TASK_RELEASE, }) -TASK_IMPORT_BATCH_ACTIONS = frozenset({ActionId.PROJECT_TASK_IMPORT, ActionId.PROJECT_TASK_IMPORT_BATCH_READ}) TASK_ACTIONS = TASK_PROJECT_ROLE_ACTIONS | TASK_MANAGER_ACTIONS | TASK_MANAGER_READ_ACTIONS | TASK_LOCKED_CONTEXT_READ_ACTIONS | { ActionId.OPERATIONS_TASK_START_OVERRIDE, ActionId.AUDIT_TASK_EVIDENCE_READ, @@ -61,36 +60,15 @@ class TaskAuthorityResourceContext(BaseModel): replay_command_id: UUID | None = None -class TaskImportBatchResourceContext(BaseModel): - """Exact native batch, selected byte ancestry and original manifest under fresh PM authority.""" - - model_config = ConfigDict(extra="forbid", frozen=True, strict=True) - - resource_type: Literal["task_import_batch"] = "task_import_batch" - resource_id: UUID - scope_project_id: UUID - source_id: UUID - actor_profile_id: UUID - identity_link_id: UUID - sha256: str = Field(pattern=r"^sha256:[0-9a-f]{64}$") - byte_count: int = Field(ge=1, le=8388608) - row_count: int = Field(ge=1, le=500) - manifest_digest: str = Field(pattern=r"^sha256:[0-9a-f]{64}$") - source_binding_digest: str = Field(pattern=r"^sha256:[0-9a-f]{64}$") - idempotency_key: UUID - request_digest: str = Field(pattern=r"^sha256:[0-9a-f]{64}$") - - def parse_task_authority_binding( action: ActionId, request: Mapping[str, object], invalid_error: type[Exception], idempotency_key: UUID, -) -> TaskAuthorityResourceContext | TaskImportBatchResourceContext | None: +) -> TaskAuthorityResourceContext | None: """Keep the complete task commitment typed and immutable through consumption.""" - if action not in TASK_ACTIONS | TASK_IMPORT_BATCH_ACTIONS: + if action not in TASK_ACTIONS: return None try: - model = TaskImportBatchResourceContext if action in TASK_IMPORT_BATCH_ACTIONS else TaskAuthorityResourceContext - resource = model.model_validate_json(json.dumps(dict(request))) + resource = TaskAuthorityResourceContext.model_validate_json(json.dumps(dict(request))) if resource.idempotency_key is not None and resource.idempotency_key != idempotency_key: raise ValueError("task key differs from prepared binding") return resource diff --git a/backend/app/modules/authorization/prepared.py b/backend/app/modules/authorization/prepared.py index 495d3a485..6a8e67bd3 100644 --- a/backend/app/modules/authorization/prepared.py +++ b/backend/app/modules/authorization/prepared.py @@ -120,7 +120,7 @@ SubmissionBundlePreparationResourceContext, ) from app.modules.authorization.domain.task_authority import ( - TASK_ACTIONS, TASK_IMPORT_BATCH_ACTIONS, TaskAuthorityResourceContext, TaskImportBatchResourceContext, parse_task_authority_binding, + TASK_ACTIONS, TaskAuthorityResourceContext, parse_task_authority_binding, ) from app.modules.authorization.domain.post_submit_routing import ( ROUTE, PostSubmitRoutingResourceContext, post_submit_routing_prepare_matches, @@ -203,7 +203,7 @@ class _PreparedAuthorizationBinding: post_submit_prepare_context: dict | None = None pre_submit_prepare_context: dict | None = None routing_request: TaskRoutingRequestFacts | None = None - task_authority_context: TaskAuthorityResourceContext | TaskImportBatchResourceContext | None = None + task_authority_context: TaskAuthorityResourceContext | None = None lifecycle_command: LifecycleTransitionCommand | None = None project_create_operation_id: UUID | None = None project_create_project_id: UUID | None = None @@ -664,8 +664,8 @@ async def consume( """Consume one exact capability before evaluating and evidencing final facts.""" issuance = self._live_issuance(handle) self._validate_consumption(issuance, expected_action_id, caller_input, final_resource_context) - if expected_action_id in TASK_ACTIONS | TASK_IMPORT_BATCH_ACTIONS and ( - not isinstance(final_resource_context, (TaskAuthorityResourceContext, TaskImportBatchResourceContext)) + if expected_action_id in TASK_ACTIONS and ( + not isinstance(final_resource_context, TaskAuthorityResourceContext) or issuance.binding.task_authority_context != final_resource_context ): raise PreparedAuthorizationHandleInvalid("invalid prepared authorization handle") @@ -974,7 +974,6 @@ def _scope_from_resource( or GUIDE_PROPOSAL_RESOURCE_BY_ACTION.get(action_id) or COMPILATION_RESOURCE_BY_ACTION.get(action_id) or (TaskAuthorityResourceContext if action_id in TASK_ACTIONS else None) - or (TaskImportBatchResourceContext if action_id in TASK_IMPORT_BATCH_ACTIONS else None) or (TaskImportSourceResourceContext if action_id in TASK_IMPORT_SOURCE_ACTIONS else None) ) if action_id in CONTRIBUTION_POLICY_MUTATION_ACTIONS and isinstance(resource, ContributionPolicyMutationResourceContext): diff --git a/backend/app/modules/authorization/runtime.py b/backend/app/modules/authorization/runtime.py index de31a7598..34a3862f7 100644 --- a/backend/app/modules/authorization/runtime.py +++ b/backend/app/modules/authorization/runtime.py @@ -49,8 +49,6 @@ from app.modules.authorization.schemas import AdminRole, AdminScope, ProjectRole from app.modules.authorization.submission_preparation import SubmissionBundlePreparationPreflightResourceContext, SubmissionBundlePreparationResourceContext from app.modules.authorization.submission_consumption import SubmissionBindingResourceContext, SubmissionCreationResourceContext -from app.modules.authorization.domain.task_authority import TaskImportBatchResourceContext as TaskImportBatchResourceContext - _STRICT_FROZEN = ConfigDict(extra="forbid", frozen=True, strict=True) PROJECT_DIAGNOSTIC_TARGET_KIND_BY_ACTION = { ActionId.PROJECT_SETUP_RUN_READ: "setup_run", @@ -1094,7 +1092,6 @@ class PreSubmitCheckerInputResourceContext(PreSubmitCheckerInputPreparationConte | ProjectRoleGrantRevokeResourceContext | GuideSourceIngestResourceContext | TaskImportSourceResourceContext - | TaskImportBatchResourceContext | ArtifactPutAttemptResourceContext | ArtifactVerificationJobResourceContext | ArtifactPendingWorkResourceContext diff --git a/backend/app/modules/authorization/task_authorization.py b/backend/app/modules/authorization/task_authorization.py index e98db703e..26d5d2121 100644 --- a/backend/app/modules/authorization/task_authorization.py +++ b/backend/app/modules/authorization/task_authorization.py @@ -1,16 +1,11 @@ """AUTH-owned adapter for exact prepared task operations.""" -from uuid import UUID - from sqlalchemy.ext.asyncio import AsyncSession from app.modules.tasks.api import TaskAuthorityDenied, TaskAuthorityFacts from app.modules.tasks.api.authorization import TaskAuthorityDecision -from app.modules.tasks.api.task_import import ( - TaskImportBatchAction, TaskImportBatchAuthorityDenied, TaskImportBatchAuthorityFacts, -) from app.modules.authorization.catalogue import ActionId -from app.modules.authorization.domain.task_authority import TaskAuthorityResourceContext, TaskImportBatchResourceContext +from app.modules.authorization.domain.task_authority import TaskAuthorityResourceContext from app.modules.authorization.kernel import AuthorizationService from app.modules.authorization.prepared import PreparedAuthorizationHandle, PreparedAuthorizationService from app.modules.authorization.repository import AdminAuthorizationRepository @@ -121,35 +116,7 @@ def close(self, handle: object) -> None: if isinstance(handle, _TaskPrepared): handle.service.close() - async def authorize(self, action: TaskImportBatchAction, facts: TaskImportBatchAuthorityFacts) -> UUID: - """Bind the native batch/file result to current covered-manager authority.""" - if type(facts) is not TaskImportBatchAuthorityFacts or facts.actor_profile_id != self._context.actor_profile_id: - raise TaskImportBatchAuthorityDenied("task import authority denied") - resource = TaskImportBatchResourceContext( - resource_id=facts.batch_id, scope_project_id=facts.project_id, source_id=facts.source_id, - actor_profile_id=facts.actor_profile_id, identity_link_id=self._context.identity_link_id, - sha256=facts.sha256, byte_count=facts.byte_count, row_count=facts.row_count, - manifest_digest=facts.manifest_digest, source_binding_digest=facts.source_binding_digest, - idempotency_key=facts.idempotency_key, request_digest=facts.request_digest, - ) - service = PreparedAuthorizationService(self._session, self._context, self._kernel, self._repository) - caller_input = PreparedAuthorizationInput(idempotency_key=facts.idempotency_key, - request_value=resource.model_dump(mode="json")) - try: - try: - handle = await service.prepare(ActionId(action.value), caller_input, PreparedAuthorityScope( - kind=PreparedAuthorityScopeKind.PROJECT, project_id=facts.project_id, - )) - except PreparedAuthorizationUnsupported as exc: - await service.deny_unsupported(ActionId(action.value), caller_input, resource, exc) - raise - return (await service.consume(handle, ActionId(action.value), caller_input, resource)).decision_id - except AuthorizationDenied as exc: - raise TaskImportBatchAuthorityDenied("task import authority denied") from exc - finally: - service.close() - - async def restage_denial(self, error: TaskAuthorityDenied | TaskImportBatchAuthorityDenied) -> bool: + async def restage_denial(self, error: TaskAuthorityDenied) -> bool: """Reuse the issuing kernel's exact pending evidence after rollback.""" if isinstance(error.__cause__, AuthorizationDenied): await self._kernel.restage_denial(error.__cause__.decision) diff --git a/backend/app/modules/contributions/api/records.py b/backend/app/modules/contributions/api/records.py index 5650ce1b5..cc45be3d3 100644 --- a/backend/app/modules/contributions/api/records.py +++ b/backend/app/modules/contributions/api/records.py @@ -16,12 +16,8 @@ class ContributionExportUnavailable(RuntimeError): """Canonical evidence or exact current read authority cannot be established.""" -class InvalidContributionCursor(ValueError): - """Signed continuation is malformed, expired or belongs to another query.""" - - class ContributionExportTooLarge(ValueError): - """The complete selection exceeds the membership bound; no partial export is valid.""" + """The complete selection exceeds the fixed limit; no partial export is valid.""" class ContributionReadDenied(RuntimeError): @@ -39,8 +35,6 @@ class ContributionReadRequest(BaseModel): contribution_type: ContributionType | None = None recorded_from: AwareDatetime | None = None recorded_before: AwareDatetime | None = None - page_size: int = Field(default=100, ge=1, le=MAX_EXPORT_CONTRIBUTIONS) - cursor: str | None = Field(default=None, min_length=1, max_length=4096, pattern=r"^[A-Za-z0-9_-]+$") @field_validator("recorded_from", "recorded_before") @classmethod @@ -138,16 +132,15 @@ def validate_source_and_awards(self) -> Self: class ContributionExportResponse(BaseModel): - """One bounded fixed-membership page from a fresh authorized read transaction.""" + """The complete bounded selection from one repeatable-read request transaction.""" model_config = _STRICT exported_at: AwareDatetime - next_cursor: str | None = Field(default=None, min_length=1, max_length=4096, pattern=r"^[A-Za-z0-9_-]+$") items: tuple[ContributionRecordView, ...] = Field(max_length=MAX_EXPORT_CONTRIBUTIONS) @model_validator(mode="after") def validate_unique_order(self) -> Self: - """Stable key order is required for traversal and conveys no business commit order.""" + """Stable display order does not claim a cursor or business commit order.""" keys = [(item.recorded_at, item.contribution_id) for item in self.items] if keys != sorted(keys) or len({item.contribution_id for item in self.items}) != len(keys): raise ValueError("contribution export order or identity differs") diff --git a/backend/app/modules/contributions/records/cursors.py b/backend/app/modules/contributions/records/cursors.py deleted file mode 100644 index 92cfb6cde..000000000 --- a/backend/app/modules/contributions/records/cursors.py +++ /dev/null @@ -1,131 +0,0 @@ -"""CON-owned signed continuation of one expiring contribution membership export.""" - -import base64 -import binascii -from dataclasses import dataclass -from datetime import UTC, datetime -import hashlib -import hmac -import json -import re -from uuid import UUID - -from app.core.hashing import canonical_json_hash -from app.modules.contributions.api.records import ContributionReadRequest, InvalidContributionCursor - -MAX_CURSOR_BYTES = 4096 -_CURSOR = re.compile(r"^[A-Za-z0-9_-]+$") -_FIELDS = {"v", "q", "export", "at", "expires", "last_at", "last_id"} - - -@dataclass(frozen=True) -class ContributionCursor: - """Verified scope and position; current read authority is still mandatory.""" - - export_id: UUID - exported_at: datetime - expires_at: datetime - last_recorded_at: datetime - last_contribution_id: UUID - - -def contribution_query_digest(request: ContributionReadRequest) -> str: - """Bind normalized actor, audience, filters, format and page size, excluding position.""" - return canonical_json_hash({ - "domain": "contribution-export-membership-v1", - "query": request.model_dump(mode="json", exclude={"cursor"}), - }) - - -def _json(value) -> bytes: - return json.dumps(value, sort_keys=True, separators=(",", ":"), - ensure_ascii=True, allow_nan=False).encode("ascii") - - -def _encode(value: bytes) -> str: - return base64.urlsafe_b64encode(value).decode("ascii").rstrip("=") - - -def _decode(value: str) -> bytes: - if not isinstance(value, str) or not value or len(value) > MAX_CURSOR_BYTES or not _CURSOR.fullmatch(value): - raise InvalidContributionCursor("Invalid contribution export cursor") - decoded = base64.b64decode(value + "=" * (-len(value) % 4), altchars=b"-_", validate=True) - if _encode(decoded) != value: - raise InvalidContributionCursor("Invalid contribution export cursor") - return decoded - - -def _unique(pairs): - result = {} - for key, value in pairs: - if key in result: - raise InvalidContributionCursor("Invalid contribution export cursor") - result[key] = value - return result - - -def _time(value: datetime) -> str: - if value.tzinfo is None or value.utcoffset() is None: - raise ValueError("Export cursor requires aware timestamps") - return value.astimezone(UTC).isoformat(timespec="microseconds").replace("+00:00", "Z") - - -def _parse_time(value: str) -> datetime: - if not isinstance(value, str) or not value.endswith("Z"): - raise InvalidContributionCursor("Invalid contribution export cursor") - parsed = datetime.fromisoformat(value[:-1] + "+00:00") - if _time(parsed) != value: - raise InvalidContributionCursor("Invalid contribution export cursor") - return parsed - - -def _uuid(value: str) -> UUID: - parsed = UUID(value) - if str(parsed) != value: - raise InvalidContributionCursor("Invalid contribution export cursor") - return parsed - - -class ContributionCursorCodec: - """Use the existing configured pagination HMAC secret with a distinct domain.""" - - def __init__(self, secret: bytes) -> None: - if len(secret) != 32: - raise ValueError("Invalid pagination cursor HMAC secret") - self._secret = bytes(secret) - - def encode(self, state: ContributionCursor, *, query_digest: str) -> str: - """Emit canonical bounded signed state; no bearer credential is embedded.""" - payload = {"v": 1, "q": query_digest, "export": str(state.export_id), - "at": _time(state.exported_at), "expires": _time(state.expires_at), - "last_at": _time(state.last_recorded_at), "last_id": str(state.last_contribution_id)} - signature = hmac.new(self._secret, _json(payload), hashlib.sha256).digest() - token = _encode(_json({"p": payload, "s": _encode(signature)})) - if len(token) > MAX_CURSOR_BYTES: - raise ValueError("Export cursor exceeds its bound") - return token - - def decode(self, value: str, *, query_digest: str, now: datetime) -> ContributionCursor: - """Verify all signed fields before any membership lookup; reject expiry exactly.""" - try: - envelope = json.loads(_decode(value), object_pairs_hook=_unique) - if not isinstance(envelope, dict) or set(envelope) != {"p", "s"}: - raise ValueError() - payload = envelope["p"] - if not isinstance(payload, dict) or set(payload) != _FIELDS or type(payload["v"]) is not int or payload["v"] != 1: - raise ValueError() - expected = hmac.new(self._secret, _json(payload), hashlib.sha256).digest() - if not hmac.compare_digest(expected, _decode(envelope["s"])) or not hmac.compare_digest(payload["q"], query_digest): - raise ValueError() - state = ContributionCursor( - export_id=_uuid(payload["export"]), exported_at=_parse_time(payload["at"]), - expires_at=_parse_time(payload["expires"]), last_recorded_at=_parse_time(payload["last_at"]), - last_contribution_id=_uuid(payload["last_id"]), - ) - if not state.exported_at <= now < state.expires_at or ( - state.expires_at - state.exported_at - ).total_seconds() != 900: - raise ValueError() - return state - except (ValueError, TypeError, KeyError, UnicodeError, binascii.Error, OverflowError): - raise InvalidContributionCursor("Invalid contribution export cursor") from None diff --git a/backend/app/modules/contributions/records/models.py b/backend/app/modules/contributions/records/models.py index c1dfcb180..51cbd2a23 100644 --- a/backend/app/modules/contributions/records/models.py +++ b/backend/app/modules/contributions/records/models.py @@ -3,7 +3,7 @@ from datetime import datetime from uuid import UUID -from sqlalchemy import Boolean, CheckConstraint, DateTime, ForeignKey, Index, Integer, String, UniqueConstraint, Uuid, text +from sqlalchemy import CheckConstraint, DateTime, ForeignKey, String, UniqueConstraint, Uuid, text from sqlalchemy.orm import Mapped, mapped_column from app.db.base import Base @@ -30,8 +30,6 @@ class ContributionRecord(Base): CheckConstraint("artifact_hash ~ '^sha256:[0-9a-f]{64}$'", name="artifact_hash"), UniqueConstraint("source_review_id"), UniqueConstraint("source_final_acceptance_id"), - Index("ix_contribution_records_self_export", "contributor_id", "created_at", "id"), - Index("ix_contribution_records_project_export", "project_id", "created_at", "id"), ) id: Mapped[UUID] = mapped_column(Uuid(), primary_key=True) @@ -67,56 +65,3 @@ class ContributionRecord(Base): created_at: Mapped[datetime] = mapped_column( DateTime(timezone=True), nullable=False, server_default=text("clock_timestamp()") ) - - -class ContributionExportMembership(Base): - """One bounded export selection; it grants no authority on later reads.""" - - __tablename__ = "contribution_export_memberships" - __table_args__ = ( - CheckConstraint("(get_byte(uuid_send(id), 6) >> 4) = 7 and (get_byte(uuid_send(id), 8) & 192) = 128", - name="id_uuid7"), - CheckConstraint("query_digest ~ '^sha256:[0-9a-f]{64}$'", name="query_digest"), - CheckConstraint("expires_at = exported_at + interval '15 minutes'", name="expiry"), - CheckConstraint("member_count between 0 and 100000", name="member_count"), - CheckConstraint("audience in ('self','project') and (audience != 'project' or project_id is not null)", - name="audience"), - CheckConstraint("output_format in ('json','csv')", name="output_format"), - CheckConstraint("page_size between 1 and 1000", name="page_size"), - CheckConstraint("contribution_type is null or contribution_type in ('accepted_submission','completed_review')", - name="contribution_type"), - CheckConstraint("recorded_from is null or recorded_before is null or recorded_from < recorded_before", - name="recorded_interval"), - ) - id: Mapped[UUID] = mapped_column(Uuid(), primary_key=True) - actor_profile_id: Mapped[str] = mapped_column( - Uuid(as_uuid=False), ForeignKey("actor_profiles.id", ondelete="RESTRICT"), nullable=False, - ) - audience: Mapped[str] = mapped_column(String(16), nullable=False) - project_id: Mapped[str | None] = mapped_column( - Uuid(as_uuid=False), ForeignKey("projects.id", ondelete="RESTRICT"), - ) - output_format: Mapped[str] = mapped_column(String(4), nullable=False) - page_size: Mapped[int] = mapped_column(Integer, nullable=False) - contribution_type: Mapped[str | None] = mapped_column(String(32)) - recorded_from: Mapped[datetime | None] = mapped_column(DateTime(timezone=True)) - recorded_before: Mapped[datetime | None] = mapped_column(DateTime(timezone=True)) - member_count: Mapped[int] = mapped_column(Integer, nullable=False) - sealed: Mapped[bool] = mapped_column(Boolean, nullable=False) - query_digest: Mapped[str] = mapped_column(String(71), nullable=False) - exported_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False) - expires_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False, index=True) - - -class ContributionExportMember(Base): - """Immutable originally visible identity and its source ordering timestamp.""" - - __tablename__ = "contribution_export_members" - __table_args__ = (Index("ix_contribution_export_members_order", "export_id", "recorded_at", "contribution_id"),) - export_id: Mapped[UUID] = mapped_column( - Uuid(), ForeignKey("contribution_export_memberships.id", ondelete="CASCADE"), primary_key=True, - ) - contribution_id: Mapped[UUID] = mapped_column( - Uuid(), ForeignKey("contribution_records.id", ondelete="RESTRICT"), primary_key=True, - ) - recorded_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False) diff --git a/backend/app/modules/contributions/records/read_facts.py b/backend/app/modules/contributions/records/read_facts.py index 4a3f13bca..0e240ea15 100644 --- a/backend/app/modules/contributions/records/read_facts.py +++ b/backend/app/modules/contributions/records/read_facts.py @@ -44,18 +44,9 @@ def validate_frozen_set(self) -> Self: return self -class ContributionReadPage(BaseModel): - """One complete page with its original export instant and verified continuation.""" - - model_config = _STRICT - records: tuple[ContributionReadFacts, ...] = Field(max_length=1000) - exported_at: AwareDatetime - next_cursor: str | None = None - - class ContributionReadRepositoryPort(Protocol): - """Load a bounded page from one fixed selection; never silently truncate.""" + """Load at most the complete fixed-limit set; never silently truncate.""" - async def read(self, request: ContributionReadRequest) -> ContributionReadPage: - """Pre-filter before membership capture and load only the selected page.""" + async def read(self, request: ContributionReadRequest) -> tuple[ContributionReadFacts, ...]: + """Pre-filter audience/project/date/type before the over-limit probe.""" ... diff --git a/backend/app/modules/contributions/records/read_repository.py b/backend/app/modules/contributions/records/read_repository.py index 7e82d17c3..f10280a1c 100644 --- a/backend/app/modules/contributions/records/read_repository.py +++ b/backend/app/modules/contributions/records/read_repository.py @@ -1,13 +1,12 @@ """Canonical contribution/rule projection, pre-filtered before any response bound.""" -from datetime import timedelta from uuid import UUID -from sqlalchemy import and_, delete, func, insert, literal, select, tuple_ +from sqlalchemy import and_, select from sqlalchemy.ext.asyncio import AsyncSession from app.modules.contributions.api.records import ( - InvalidContributionCursor, + MAX_EXPORT_CONTRIBUTIONS, ContributionExportTooLarge, ContributionExportUnavailable, ContributionReadRequest, @@ -16,96 +15,19 @@ ContributionAwardDefinition, ContributionPolicyVersion, ContributionRule, ) from app.modules.contributions.records.models import ContributionRecord -from app.core.identifiers import new_record_id -from app.modules.contributions.records.cursors import ContributionCursor, ContributionCursorCodec, contribution_query_digest -from app.modules.contributions.records.models import ContributionExportMember, ContributionExportMembership -from app.modules.contributions.records.read_facts import ContributionReadFacts, ContributionReadPage, FrozenContributionAward +from app.modules.contributions.records.read_facts import ContributionReadFacts, FrozenContributionAward class ContributionReadRepository: """Read immutable facts and frozen terms in the caller's authorized snapshot.""" - def __init__(self, session: AsyncSession, *, cursor_codec: ContributionCursorCodec | None) -> None: + def __init__(self, session: AsyncSession) -> None: """Share transaction ownership; no economic insert/update or commit is exposed.""" self._session = session - self._cursor_codec = cursor_codec - @staticmethod - def _selection(query, request): - """Share original selection with membership capture and canonical page loading.""" - if request.audience == "self": - query = query.where(ContributionRecord.contributor_id == str(request.actor_profile_id)) - if request.project_id is not None: - query = query.where(ContributionRecord.project_id == str(request.project_id)) - if request.contribution_type is not None: - query = query.where(ContributionRecord.contribution_type == request.contribution_type) - if request.recorded_from is not None: - query = query.where(ContributionRecord.created_at >= request.recorded_from) - if request.recorded_before is not None: - query = query.where(ContributionRecord.created_at < request.recorded_before) - return query - - async def _membership(self, request): - """Capture once or prove the signed, sealed original selection after fresh AUTH.""" - now = await self._session.scalar(select(func.clock_timestamp())) - digest = contribution_query_digest(request) - position = None - if request.cursor is not None: - if self._cursor_codec is None: - raise ContributionExportUnavailable("Contribution export pagination unavailable") - position = self._cursor_codec.decode(request.cursor, query_digest=digest, now=now) - header = await self._session.scalar(select(ContributionExportMembership).where( - ContributionExportMembership.id == position.export_id, - ).with_for_update(read=True, key_share=True)) - if header is None or not header.sealed or ( - header.actor_profile_id, header.query_digest, header.exported_at, header.expires_at, - header.audience, header.project_id, header.output_format, header.page_size, - header.contribution_type, header.recorded_from, header.recorded_before, - ) != (str(request.actor_profile_id), digest, position.exported_at, position.expires_at, - request.audience, None if request.project_id is None else str(request.project_id), - request.output_format, request.page_size, request.contribution_type, - request.recorded_from, request.recorded_before): - raise InvalidContributionCursor("Invalid contribution export cursor") - return header, position - selected = self._selection(select(ContributionRecord.id, ContributionRecord.created_at), request) - count = await self._session.scalar(select(func.count()).select_from(selected.limit(100001).subquery())) - if count > 100000: - raise ContributionExportTooLarge("Contribution export exceeds 100000 records; narrow the filters") - if count > request.page_size and self._cursor_codec is None: - raise ContributionExportUnavailable("Contribution export pagination unavailable") - # Private expired membership only. Current page headers are protected by - # key-share locks; economic records are never targets of this cleanup. - expired = select(ContributionExportMembership.id).where( - ContributionExportMembership.expires_at <= now, - ).order_by(ContributionExportMembership.expires_at, ContributionExportMembership.id).limit(100) - expired_ids = tuple(await self._session.scalars(expired.with_for_update(skip_locked=True))) - if expired_ids: - await self._session.execute(delete(ContributionExportMembership).where( - ContributionExportMembership.id.in_(expired_ids), - )) - header = ContributionExportMembership( - id=new_record_id(), actor_profile_id=str(request.actor_profile_id), query_digest=digest, - exported_at=now, expires_at=now + timedelta(minutes=15), member_count=count, sealed=False, - audience=request.audience, project_id=None if request.project_id is None else str(request.project_id), - output_format=request.output_format, page_size=request.page_size, - contribution_type=request.contribution_type, recorded_from=request.recorded_from, - recorded_before=request.recorded_before, - ) - self._session.add(header) - await self._session.flush() - capture = self._selection(select(literal(header.id), ContributionRecord.id, - ContributionRecord.created_at), request) - await self._session.execute(insert(ContributionExportMember).from_select( - ["export_id", "contribution_id", "recorded_at"], capture, - )) - header.sealed = True - await self._session.flush() - return header, position - - async def read(self, request: ContributionReadRequest) -> ContributionReadPage: - """Read complete award definitions for a bounded original-membership page.""" + async def read(self, request: ContributionReadRequest) -> tuple[ContributionReadFacts, ...]: + """Probe one excess contribution before loading its complete definition sets.""" request = ContributionReadRequest.model_validate(request) - header, position = await self._membership(request) query = select(ContributionRecord, ContributionPolicyVersion.version_number, ContributionRule.id, ContributionRule.compensation_mode).outerjoin( ContributionPolicyVersion, @@ -116,27 +38,23 @@ async def read(self, request: ContributionReadRequest) -> ContributionReadPage: ContributionRule.project_id == ContributionRecord.project_id, ContributionRule.contribution_type == ContributionRecord.contribution_type, )) - query = self._selection(query, request).join(ContributionExportMember, and_( - ContributionExportMember.contribution_id == ContributionRecord.id, - ContributionExportMember.recorded_at == ContributionRecord.created_at, - ContributionExportMember.export_id == header.id, - )) - if position is not None: - query = query.where(tuple_(ContributionRecord.created_at, ContributionRecord.id) > - tuple_(position.last_recorded_at, position.last_contribution_id)) + if request.audience == "self": + query = query.where(ContributionRecord.contributor_id == str(request.actor_profile_id)) + if request.project_id is not None: + query = query.where(ContributionRecord.project_id == str(request.project_id)) + if request.contribution_type is not None: + query = query.where(ContributionRecord.contribution_type == request.contribution_type) + if request.recorded_from is not None: + query = query.where(ContributionRecord.created_at >= request.recorded_from) + if request.recorded_before is not None: + query = query.where(ContributionRecord.created_at < request.recorded_before) rows = (await self._session.execute(query.order_by( ContributionRecord.created_at, ContributionRecord.id, - ).limit(request.page_size + 1))).all() - more = len(rows) > request.page_size - rows = rows[:request.page_size] - next_cursor = None - if more: - last = rows[-1][0] - next_cursor = self._cursor_codec.encode(ContributionCursor( - header.id, header.exported_at, header.expires_at, last.created_at, last.id, - ), query_digest=header.query_digest) + ).limit(MAX_EXPORT_CONTRIBUTIONS + 1))).all() + if len(rows) > MAX_EXPORT_CONTRIBUTIONS: + raise ContributionExportTooLarge("Contribution export exceeds 1000 records; narrow the filters") if not rows: - return ContributionReadPage(records=(), exported_at=header.exported_at, next_cursor=None) + return () if any(version is None or rule is None or mode is None for _, version, rule, mode in rows): raise ContributionExportUnavailable("Contribution evidence unavailable") rule_ids = {rule for _, _, rule, _ in rows} @@ -149,11 +67,8 @@ async def read(self, request: ContributionReadRequest) -> ContributionReadPage: id=definition.id, instrument=definition.instrument_type, unit=definition.unit_code, quantity=definition.quantity, )) - return ContributionReadPage( - records=tuple(self._facts(row, version, mode, tuple(by_rule[rule])) - for row, version, rule, mode in rows), - exported_at=header.exported_at, next_cursor=next_cursor, - ) + return tuple(self._facts(row, version, mode, tuple(by_rule[rule])) + for row, version, rule, mode in rows) @staticmethod def _facts(row, version, mode, definitions) -> ContributionReadFacts: diff --git a/backend/app/modules/contributions/records/read_service.py b/backend/app/modules/contributions/records/read_service.py index 127fb6d27..5de02b519 100644 --- a/backend/app/modules/contributions/records/read_service.py +++ b/backend/app/modules/contributions/records/read_service.py @@ -1,5 +1,7 @@ """One authorized canonical evidence projection shared by JSON and CSV.""" +from datetime import UTC, datetime + from pydantic import ValidationError from app.modules.actors.api.contribution_labels import ( @@ -8,8 +10,9 @@ from app.modules.compensation.api.award_reads import ContributionAwardReadPort from app.modules.compensation.api.awards import CompensationAwardFacts from app.modules.contributions.api.records import ( + MAX_EXPORT_CONTRIBUTIONS, ContributionAwardView, ContributionExportResponse, ContributionExportTooLarge, - ContributionExportUnavailable, InvalidContributionCursor, + ContributionExportUnavailable, ContributionReadAuthorizationPort, ContributionReadRequest, ContributionRecordView, ) @@ -18,7 +21,7 @@ ContributionTaskSourceFacts, ContributionTaskSourceReadPort, ) from app.modules.contributions.records.read_facts import ( - ContributionReadFacts, ContributionReadPage, ContributionReadRepositoryPort, + ContributionReadFacts, ContributionReadRepositoryPort, ) @@ -53,10 +56,10 @@ async def read(self, request: ContributionReadRequest) -> ContributionExportResp request = ContributionReadRequest.model_validate(request) await self._authorization.authorize(request) try: - page = ContributionReadPage.model_validate(await self._records.read(request)) - records = tuple(ContributionReadFacts.model_validate(row) for row in page.records) - if len(records) > request.page_size: - raise ContributionExportUnavailable("Contribution page exceeds its authorized bound") + records = tuple(ContributionReadFacts.model_validate(row) + for row in await self._records.read(request)) + if len(records) > MAX_EXPORT_CONTRIBUTIONS: + raise ContributionExportTooLarge("Contribution export exceeds 1000 records; narrow the filters") for record in records: self._require_selected(record, request) record_ids = {record.id for record in records} @@ -93,8 +96,8 @@ async def read(self, request: ContributionReadRequest) -> ContributionExportResp actors[record.contributor_id], acceptances.get((record.project_id, record.source_final_acceptance_id)), ) for record in records) - return ContributionExportResponse(exported_at=page.exported_at, items=items, next_cursor=page.next_cursor) - except (ContributionExportTooLarge, InvalidContributionCursor): + return ContributionExportResponse(exported_at=datetime.now(UTC), items=items) + except ContributionExportTooLarge: raise except (ValidationError, ValueError, TypeError) as exc: raise ContributionExportUnavailable("Contribution evidence unavailable") from exc diff --git a/backend/app/modules/tasks/api/task_batch_transition.py b/backend/app/modules/tasks/api/task_batch_transition.py deleted file mode 100644 index 221ae46ea..000000000 --- a/backend/app/modules/tasks/api/task_batch_transition.py +++ /dev/null @@ -1,62 +0,0 @@ -"""Closed batch transition requests and compact canonical receipt projections.""" - -from typing import Literal, Protocol -from uuid import UUID - -from pydantic import BaseModel, ConfigDict, Field, model_validator - - -class TaskBatchTransitionRequest(BaseModel): - """One normal transition reason; membership comes only from the native batch.""" - - model_config = ConfigDict(extra="forbid", frozen=True) - - reason: str | None = Field(default=None, max_length=4000) - - -class TaskBatchTransitionResult(BaseModel): - """Ordered canonical success facts without repeating Task instructions.""" - - model_config = ConfigDict(extra="forbid", frozen=True) - - task_id: UUID - row_index: int = Field(ge=0, le=499) - status: Literal["screening", "ready"] - locked_guide_version: str = Field(min_length=1, max_length=100) - locked_contribution_policy_version_id: UUID - locked_context_hash: str = Field(pattern=r"^sha256:[0-9a-f]{64}$") - - -class TaskBatchTransitionResponse(BaseModel): - """The complete original ordered result, recoverable only while all Tasks match.""" - - model_config = ConfigDict(extra="forbid", frozen=True) - - project_id: UUID - batch_id: UUID - operation: Literal["screen", "release"] - row_count: int = Field(ge=1, le=500) - tasks: tuple[TaskBatchTransitionResult, ...] = Field(min_length=1, max_length=500) - - @model_validator(mode="after") - def complete_order(self): - """Refuse partial, duplicated or incorrectly ordered public membership.""" - status = "screening" if self.operation == "screen" else "ready" - if (len(self.tasks) != self.row_count - or len({task.task_id for task in self.tasks}) != self.row_count - or any(task.row_index != index or task.status != status - for index, task in enumerate(self.tasks))): - raise ValueError("task batch transition membership is invalid") - return self - - -class TaskBatchTransitionPort(Protocol): - """Own one complete transition root; no caller may supply individual members.""" - - async def screen( - self, project_id: UUID, batch_id: UUID, reason: str | None, *, idempotency_key: UUID, - ) -> TaskBatchTransitionResponse: ... - - async def release( - self, project_id: UUID, batch_id: UUID, reason: str | None, *, idempotency_key: UUID, - ) -> TaskBatchTransitionResponse: ... diff --git a/backend/app/modules/tasks/api/task_import.py b/backend/app/modules/tasks/api/task_import.py index edf720e5a..e74c44c51 100644 --- a/backend/app/modules/tasks/api/task_import.py +++ b/backend/app/modules/tasks/api/task_import.py @@ -3,131 +3,14 @@ import hashlib import json import unicodedata -from collections.abc import AsyncIterator -from contextlib import AbstractAsyncContextManager from dataclasses import dataclass -from enum import StrEnum -from typing import Annotated, Literal, Protocol -from uuid import UUID +from typing import Annotated, Literal -from pydantic import BaseModel, ConfigDict, Field, ValidationError, field_validator, model_validator +from pydantic import BaseModel, ConfigDict, Field, ValidationError, field_validator from pydantic_core import PydanticCustomError TASK_IMPORT_MAXIMUM_BYTES = 8 * 1024 * 1024 -TASK_IMPORT_MAPPING_VERSION = "workstream.task_import.draft_mapping.v1" - - -class TaskImportBatchAction(StrEnum): - """Covered-manager import and membership status, separate from Task transitions.""" - - IMPORT = "project.task.import" - READ = "project.task.import_batch.read" - - -class TaskImportBatchAuthorityDenied(RuntimeError): - """The exact native batch operation lacks current covered-manager authority.""" - - -@dataclass(frozen=True, slots=True) -class TaskImportBatchAuthorityFacts: - """Caller and exact native file/result identities consumed by the AUTH owner.""" - - batch_id: UUID - project_id: UUID - source_id: UUID - actor_profile_id: UUID - sha256: str - byte_count: int - row_count: int - manifest_digest: str - source_binding_digest: str - idempotency_key: UUID - request_digest: str - - -class TaskImportBatchAuthorizationPort(Protocol): - """Consume exact prepared authority and retain its original denial after rollback.""" - - async def authorize(self, action: TaskImportBatchAction, facts: TaskImportBatchAuthorityFacts) -> UUID: - """Return the fresh canonical decision for the current batch caller.""" - ... - - async def restage_denial(self, error: TaskImportBatchAuthorityDenied) -> None: - """Commit canonical denied evidence only through the instance that captured it.""" - ... - - -@dataclass(frozen=True, slots=True) -class TaskImportSourceCommitment: - """Actual native declaration selected by ART; it supplies no authority.""" - - source_id: UUID - project_id: UUID - sha256: str - byte_count: int - operation_identity: str - - -class VerifiedTaskImportSourceBinding(BaseModel): - """Immutable native byte ancestry; the ART participant revalidates every reference.""" - - model_config = ConfigDict(extra="forbid", strict=True, frozen=True) - - source_id: UUID - project_id: UUID - sha256: str = Field(pattern=r"^sha256:[0-9a-f]{64}$") - byte_count: int = Field(ge=1, le=8388608) - operation_identity: str = Field(pattern=r"^sha256:[0-9a-f]{64}$") - put_attempt_id: UUID - content_id: UUID - replica_id: UUID - verification_job_id: UUID - verification_generation: int = Field(ge=1) - verification_receipt_id: UUID - operation_receipt_id: UUID | None - observation_receipt_id: UUID | None - - @model_validator(mode="after") - def exact_acknowledgement(self): - """Require precisely one retained operation or observation acknowledgement.""" - if (self.operation_receipt_id is None) == (self.observation_receipt_id is None): - raise ValueError("verified source requires exactly one acknowledgement") - return self - - -class TaskImportSourceByteRead(Protocol): - """A bounded, already-verified byte stream scoped to the owning read context.""" - - @property - def stream(self) -> AsyncIterator[bytes]: ... - - -class TaskImportSourceConsumerPort(Protocol): - """TASK's required source capability, implemented only by the existing ART owner.""" - - async def source_commitment(self, project_id: UUID, source_id: UUID) -> TaskImportSourceCommitment: - """Read actual immutable preparation facts without granting authority.""" - ... - - async def authorize_commitment(self, facts: TaskImportSourceCommitment) -> UUID: - """Check fresh actual source authority before exposing preparation outcomes.""" - ... - - async def prepare_binding( - self, project_id: UUID, source_id: UUID, - expected: VerifiedTaskImportSourceBinding | None = None, - ) -> VerifiedTaskImportSourceBinding: - """Retain SOURCE KEY SHARE and validate native receipts before caller AUTH.""" - ... - - async def authorize_binding(self, binding: VerifiedTaskImportSourceBinding) -> UUID: - """Revalidate prepared custody and authorize the current caller freshly.""" - ... - - def open(self, project_id: UUID, source_id: UUID) -> AbstractAsyncContextManager[TaskImportSourceByteRead]: - """Verify actual provider bytes before yielding the bounded source stream.""" - ... class TaskImportRow(BaseModel): diff --git a/backend/app/modules/tasks/api/task_import_membership.py b/backend/app/modules/tasks/api/task_import_membership.py deleted file mode 100644 index 1a1d593f5..000000000 --- a/backend/app/modules/tasks/api/task_import_membership.py +++ /dev/null @@ -1,26 +0,0 @@ -"""Native immutable import membership; these facts never grant Task authority.""" - -from dataclasses import dataclass -from uuid import UUID - - -class TaskImportBatchError(RuntimeError): - """A controlled batch outcome with bounded document-row diagnostics.""" - - def __init__(self, code: str, status_code: int, row_indexes: tuple[int, ...] = ()): - self.code, self.status_code, self.row_indexes = code, status_code, row_indexes - super().__init__(code) - - -@dataclass(frozen=True, slots=True) -class TaskImportMemberIdentity: - """One actual ordered native row and its original canonical CREATE custody.""" - - member_id: UUID - task_id: UUID - row_index: int - external_task_id: str - row_digest: str - create_idempotency_key: UUID - task_command_receipt_id: UUID - authorization_decision_id: UUID diff --git a/backend/app/modules/tasks/api/transition_audit.py b/backend/app/modules/tasks/api/transition_audit.py index 4380f68a0..a6ab5ac6e 100644 --- a/backend/app/modules/tasks/api/transition_audit.py +++ b/backend/app/modules/tasks/api/transition_audit.py @@ -44,7 +44,7 @@ class TaskTransitionFacts: from_status: str | None to_status: str reason: str | None - source_type: Literal["manual", "markdown_import", "csv_import", "json_import"] | None = None + source_type: Literal["manual", "markdown_import", "csv_import"] | None = None locked_lineage: TaskPolicyLineage | None = None authority: TaskAuthorityDecision | None = None diff --git a/backend/app/modules/tasks/authorized_commands.py b/backend/app/modules/tasks/authorized_commands.py index 08c43bec8..7ae1680c6 100644 --- a/backend/app/modules/tasks/authorized_commands.py +++ b/backend/app/modules/tasks/authorized_commands.py @@ -3,7 +3,7 @@ import json from collections.abc import AsyncIterator from contextlib import AsyncExitStack, asynccontextmanager -from dataclasses import dataclass, replace +from dataclasses import replace from datetime import UTC, datetime from uuid import UUID from app.core.identifiers import new_record_id @@ -12,7 +12,7 @@ from sqlalchemy import func from sqlalchemy.exc import IntegrityError -from sqlalchemy.ext.asyncio import AsyncSession, AsyncSessionTransaction +from sqlalchemy.ext.asyncio import AsyncSession from app.modules.contributions.api import LockedCompensationTermsPort from app.core.hashing import canonical_json_hash @@ -32,7 +32,7 @@ from app.modules.tasks.api.transition_audit import TaskPolicyLineage, TaskTransitionAuditPort, TaskTransitionFacts from app.modules.tasks.api.audit_evidence import AuditTaskEvidenceRequest, AuditTaskEvidencePage, TaskEvidenceInvalid from app.modules.tasks.models import TaskAssignment, TaskCommandReceipt, WorkstreamTask -from app.modules.tasks.command_replay import TaskCommandReplay, TaskReplayConflict +from app.modules.tasks.command_replay import TaskCommandReplay from app.modules.tasks.repository import TaskRepository from app.modules.tasks.schemas import ( ContributorTaskLifecycle, ContributorTaskWorkContext, ManagementTaskWorkContext, @@ -40,7 +40,6 @@ ManagementTaskLockedContext, OperationalTaskLockedContext, AuditTaskLockedContext, AssignmentResponse, TaskCreate, - ImportedTaskCreate, TaskResponse, TaskWithAssignmentResponse, ) @@ -56,37 +55,6 @@ ) -@dataclass(frozen=True, slots=True) -class TaskCreationPreparation: - """Caller-root reservation and immutable values prepared before AUTH locks.""" - - project_id: UUID - task_id: UUID - payload_json: str - receipt: TaskCommandReceipt - request_digest: str - reserved: bool - current: WorkstreamTask | None - facts: TaskAuthorityFacts - transaction: AsyncSessionTransaction - - -@dataclass(frozen=True, slots=True) -class TaskTransitionPreparation: - """TASK/assignment custody and exact current facts retained in one caller root.""" - - task: WorkstreamTask - assignment: TaskAssignment | None - operation: TaskAuthorityOperation - reason: str | None - receipt: TaskCommandReceipt - request_digest: str - reserved: bool - facts: TaskAuthorityFacts - transaction: AsyncSessionTransaction - batch_transition_receipt_id: UUID | None = None - - class AuthorizedTaskCommands: """TASK owns state and assignment; AUTH owns permission and current grants.""" @@ -160,91 +128,45 @@ async def _locked_task( if request_digest is not None: facts = replace(facts, request_digest=request_digest, replay_command_id=self._replay.manager_replay(receipt, operation, task_id, self._actor_id, idempotency_key) if receipt else None) - decision = await self._authorize_facts(facts) - return task, assignment, decision - - async def _authorize_facts(self, facts: TaskAuthorityFacts) -> TaskAuthorityDecision: handle = await self._authorization.prepare(facts) try: - return await self._authorization.consume(handle, facts) + decision_id = await self._authorization.consume(handle, facts) + return task, assignment, decision_id finally: self._authorization.close(handle) async def create_task(self, project_id: UUID, payload: TaskCreate, *, idempotency_key: UUID) -> TaskResponse: - """Own the single-create root over the same preparation/AUTH/staging phases.""" - async with self._session.begin(): - prepared = await self.prepare_creation(project_id, payload, idempotency_key=idempotency_key) - decision = await self.authorize_creation(prepared) - return await self.stage_creation(prepared, decision) - - async def prepare_creation( - self, project_id: UUID, payload: TaskCreate | ImportedTaskCreate, *, idempotency_key: UUID, - ) -> TaskCreationPreparation: - """Reserve and acquire any existing TASK custody before the caller takes AUTH.""" - if not self._session.in_transaction(): - raise RuntimeError("task creation preparation requires the caller transaction") + """Authorize the exact proposed task before creating it in the same transaction.""" operation = TaskAuthorityOperation.CREATE - receipt, digest, reserved = await self._replay.reserve( - self._actor_id, operation, idempotency_key, new_record_id(), None, - request_value={"project_id": str(project_id), "payload": payload.model_dump(mode="json")}, - ) - current = await self._repo.get_task(receipt.task_id, for_update=True) if not reserved else None - proposed = WorkstreamTask(id=receipt.task_id, project_id=str(project_id), status="draft", - created_by=str(self._actor_id), **payload.model_dump()) - facts = replace( - self._facts(proposed, None, operation, None, idempotency_key), request_digest=digest, - replay_command_id=self._replay.manager_replay( - receipt, operation, UUID(proposed.id), self._actor_id, idempotency_key, - ), - ) - return TaskCreationPreparation(project_id, UUID(proposed.id), payload.model_dump_json(), - receipt, digest, reserved, current, facts, self._session.get_transaction()) - - async def authorize_creation(self, prepared: TaskCreationPreparation) -> TaskAuthorityDecision: - """Consume exact current per-Task authority after all caller preparation locks.""" - if (self._session.get_transaction() is not prepared.transaction or not prepared.transaction.is_active - or prepared.facts.actor_profile_id != self._actor_id): - raise RuntimeError("task creation authority requires its original caller transaction") - handle = await self._authorization.prepare(prepared.facts) - try: - return await self._authorization.consume(handle, prepared.facts) - finally: - self._authorization.close(handle) - - async def stage_creation( - self, prepared: TaskCreationPreparation, decision: TaskAuthorityDecision, - ) -> TaskResponse: - """Stage canonical creation/evidence/receipt without opening or committing a root.""" - if (self._session.get_transaction() is not prepared.transaction or not prepared.transaction.is_active - or prepared.facts.actor_profile_id != self._actor_id): - raise RuntimeError("task creation staging requires its original caller transaction") - payload = TypeAdapter(TaskCreate | ImportedTaskCreate).validate_json(prepared.payload_json) - digest = canonical_json_hash({"project_id": str(prepared.project_id), "payload": payload.model_dump(mode="json")}) - if digest != prepared.request_digest or prepared.receipt.task_id != str(prepared.task_id): - raise TaskValidationError("task creation preparation changed") - project = await self._contexts._project_contexts.read_project_display(prepared.project_id) - if project is None or project.id != prepared.project_id: - raise TaskProjectNotReady("project not found") - task = prepared.current if prepared.current is not None else WorkstreamTask( - id=str(prepared.task_id), project_id=str(prepared.project_id), status="draft", - created_by=str(self._actor_id), **payload.model_dump(), - ) - facts = self._facts(task, None, TaskAuthorityOperation.CREATE, None) - replayed = self._replay.recover( - prepared.receipt, prepared.request_digest, facts, task, None, reserved=prepared.reserved, - ) - if replayed is not None: - return replayed - try: + async with self._session.begin(): + receipt, digest, reserved = await self._replay.reserve( + self._actor_id, operation, idempotency_key, new_record_id(), None, + request_value={"project_id": str(project_id), "payload": payload.model_dump(mode="json")}, + ) + # A duplicate may address an existing task: keep TASK before AUTH. + current = await self._repo.get_task(receipt.task_id, for_update=True) if not reserved else None + proposed = WorkstreamTask(id=receipt.task_id, project_id=str(project_id), status="draft", + created_by=str(self._actor_id), **payload.model_dump()) + facts = replace(self._facts(proposed, None, operation, None, idempotency_key), + request_digest=digest, replay_command_id=self._replay.manager_replay(receipt, operation, UUID(proposed.id), self._actor_id, idempotency_key)) + handle = await self._authorization.prepare(facts) + try: + decision_id = await self._authorization.consume(handle, facts) + finally: + self._authorization.close(handle) + project = await self._contexts._project_contexts.read_project_display(project_id) + if project is None or project.id != project_id: + raise TaskProjectNotReady("project not found") + task = current if current is not None else proposed + replayed = self._replay.recover(receipt, digest, self._facts(task, None, operation, None), + task, None, reserved=reserved) + if replayed is not None: + return replayed task = await self._repo.add_task(task) - except IntegrityError as exc: - if integrity_constraint_name(exc) == "uq_workstream_tasks_project_external_id": - raise TaskReplayConflict("external_task_id_conflict") from exc - raise - await self._record_management(task, TaskAuthorityOperation.CREATE, decision, None, None) - response = self._contexts.task_response_for_authority(task, can_manage=True) - self._replay.complete(prepared.receipt, None, self._facts(task, None, TaskAuthorityOperation.CREATE, None), response) - await self._session.flush() + await self._record_management(task, operation, decision_id, None, None) + response = self._contexts.task_response_for_authority(task, can_manage=True) + self._replay.complete(receipt, None, self._facts(task, None, operation, None), response) + await self._session.flush() return response async def screen(self, task_id: UUID, reason: str | None, *, idempotency_key: UUID) -> TaskResponse: @@ -257,97 +179,35 @@ async def _manage_transition( self, task_id: UUID, operation: TaskAuthorityOperation, reason: str | None, key: UUID, ) -> TaskResponse: async with self._session.begin(): - prepared = await self.prepare_transition(task_id, operation, reason, idempotency_key=key) - decision = await self.authorize_transition(prepared) - response = await self.stage_transition(prepared, decision) - return response - - async def prepare_transition( - self, task_id: UUID, operation: TaskAuthorityOperation, reason: str | None, - *, idempotency_key: UUID, project_id: UUID | None = None, - batch_transition_receipt_id: UUID | None = None, - ) -> TaskTransitionPreparation: - """Reserve canonical retry custody and lock TASK before the caller takes AUTH.""" - if operation not in {TaskAuthorityOperation.SCREEN, TaskAuthorityOperation.RELEASE}: - raise ValueError("task transition participant supports SCREEN/RELEASE only") - transaction = self._session.get_transaction() - if transaction is None or not transaction.is_active: - raise RuntimeError("task transition preparation requires the caller transaction") - receipt, digest, reserved = await self._replay.reserve( - self._actor_id, operation, idempotency_key, task_id, reason, - batch_transition_receipt_id=batch_transition_receipt_id, - ) - task = (await self._repo.lock_project_task(project_id, task_id) if project_id is not None - else await self._repo.get_task(str(task_id), for_update=True)) - if task is None: - raise TaskNotFound("task not found") - assignment = await self._repo.get_active_assignment(task.id, for_update=True) - facts = replace( - self._facts(task, assignment, operation, reason, idempotency_key), request_digest=digest, - replay_command_id=self._replay.manager_replay(receipt, operation, task_id, self._actor_id, idempotency_key), - ) - return TaskTransitionPreparation(task, assignment, operation, reason, receipt, digest, - reserved, facts, transaction, batch_transition_receipt_id) - - def _validate_transition_preparation(self, prepared: TaskTransitionPreparation) -> None: - if (self._session.get_transaction() is not prepared.transaction or not prepared.transaction.is_active - or prepared.facts.actor_profile_id != self._actor_id): - raise RuntimeError("task transition requires its original caller transaction") - current = replace( - self._facts(prepared.task, prepared.assignment, prepared.operation, prepared.reason, - prepared.facts.idempotency_key), request_digest=prepared.request_digest, - replay_command_id=self._replay.manager_replay( - prepared.receipt, prepared.operation, UUID(prepared.task.id), self._actor_id, - prepared.facts.idempotency_key, - ), - ) - values = {"task_id": prepared.task.id, "reason": prepared.reason} - if prepared.batch_transition_receipt_id is not None: - values["batch_transition_receipt_id"] = str(prepared.batch_transition_receipt_id) - if (current != prepared.facts - or prepared.receipt.batch_transition_receipt_id != prepared.batch_transition_receipt_id - or prepared.request_digest != canonical_json_hash(values)): - raise TaskValidationError("task transition preparation changed") - - async def authorize_transition(self, prepared: TaskTransitionPreparation) -> TaskAuthorityDecision: - """Consume fresh exact per-Task authority after all caller preparation locks.""" - self._validate_transition_preparation(prepared) - return await self._authorize_facts(prepared.facts) - - async def stage_transition( - self, prepared: TaskTransitionPreparation, decision: TaskAuthorityDecision, - ) -> TaskResponse: - """Flush the normal transition, guide locks, audit and receipt in the caller root.""" - self._validate_transition_preparation(prepared) - task, assignment, operation, reason = (prepared.task, prepared.assignment, - prepared.operation, prepared.reason) - replayed = self._replay.recover( - prepared.receipt, prepared.request_digest, self._facts(task, assignment, operation, reason), - task, assignment, reserved=prepared.reserved, - ) - if replayed is not None: - return replayed - before = task.status - target = "screening" if operation is TaskAuthorityOperation.SCREEN else "ready" - self._contexts._ensure_transition_allowed(before, target) - if operation is TaskAuthorityOperation.SCREEN: - context = await self._contexts._load_active_policy_context(task.project_id) - self._contexts._validate_task_contract_fields(task) - self._contexts._stamp_locked_context(task, context) - else: - if not reason or not reason.strip(): - raise TaskValidationError("release decision reason is required") - self._contexts._ensure_locked_context(task) - context = await self._contexts._load_locked_task_context(task) - self._contexts._validate_installed_plans(context.facts) - task.status = target - await self._session.flush() - await self._record_management(task, operation, decision, before, reason) - await self._session.flush() - await self._session.refresh(task) - response = self._contexts.task_response_for_authority(task, can_manage=True) - self._replay.complete(prepared.receipt, None, self._facts(task, None, operation, reason), response) - await self._session.flush() + receipt, digest, reserved = await self._replay.reserve(self._actor_id, operation, key, task_id, reason) + task, assignment, decision_id = await self._locked_task( + task_id, operation, reason, idempotency_key=key, receipt=receipt, request_digest=digest, + ) + replayed = self._replay.recover(receipt, digest, self._facts(task, assignment, operation, reason), + task, assignment, reserved=reserved) + if replayed is not None: + return replayed + before = task.status + target = "screening" if operation is TaskAuthorityOperation.SCREEN else "ready" + self._contexts._ensure_transition_allowed(before, target) + if operation is TaskAuthorityOperation.SCREEN: + context = await self._contexts._load_active_policy_context(task.project_id) + self._contexts._validate_task_contract_fields(task) + self._contexts._stamp_locked_context(task, context) + else: + if not reason or not reason.strip(): + raise TaskValidationError("release decision reason is required") + self._contexts._ensure_locked_context(task) + context = await self._contexts._load_locked_task_context(task) + self._contexts._validate_installed_plans(context.facts) + task.status = target + await self._session.flush() + await self._record_management(task, operation, decision_id, before, reason) + await self._session.flush() + await self._session.refresh(task) + response = self._contexts.task_response_for_authority(task, can_manage=True) + self._replay.complete(receipt, None, self._facts(task, None, operation, reason), response) + await self._session.flush() return response async def _record_management( diff --git a/backend/app/modules/tasks/command_replay.py b/backend/app/modules/tasks/command_replay.py index a2b5c46a3..c8dee2265 100644 --- a/backend/app/modules/tasks/command_replay.py +++ b/backend/app/modules/tasks/command_replay.py @@ -34,25 +34,15 @@ def __init__(self, session: AsyncSession): async def reserve( self, actor_id: UUID, operation: TaskAuthorityOperation, key: UUID, task_id: UUID, reason: str | None, *, request_value: dict | None = None, - batch_transition_receipt_id: UUID | None = None, ) -> tuple[TaskCommandReceipt, str, bool]: if not isinstance(key, UUID): raise ValueError("task command requires an idempotency UUID") - if batch_transition_receipt_id is not None and ( - operation not in {TaskAuthorityOperation.SCREEN, TaskAuthorityOperation.RELEASE} - or request_value is not None or not isinstance(batch_transition_receipt_id, UUID) - ): - raise ValueError("batch receipt binding requires a canonical SCREEN/RELEASE participant") - values = request_value if request_value is not None else {"task_id": str(task_id), "reason": reason} - if batch_transition_receipt_id is not None: - values = {**values, "batch_transition_receipt_id": str(batch_transition_receipt_id)} - digest = canonical_json_hash(values) + digest = canonical_json_hash(request_value if request_value is not None else {"task_id": str(task_id), "reason": reason}) inserted_id = new_record_id() receipt_id = await self._session.scalar( insert(TaskCommandReceipt).values( id=inserted_id, actor_profile_id=str(actor_id), action_id=operation.value, idempotency_key=key, request_digest=digest, task_id=str(task_id), status="pending", - batch_transition_receipt_id=batch_transition_receipt_id, ).on_conflict_do_update( index_elements=[TaskCommandReceipt.actor_profile_id, TaskCommandReceipt.action_id, TaskCommandReceipt.idempotency_key], diff --git a/backend/app/modules/tasks/models.py b/backend/app/modules/tasks/models.py index df2605dbe..12ba81481 100644 --- a/backend/app/modules/tasks/models.py +++ b/backend/app/modules/tasks/models.py @@ -7,7 +7,6 @@ from sqlalchemy import ( Boolean, - BigInteger, CheckConstraint, DateTime, ForeignKey, @@ -46,8 +45,6 @@ class TaskCommandReceipt(Base): name="task_command_action", ), CheckConstraint("request_digest ~ '^sha256:[0-9a-f]{64}$'", name="task_command_request_digest"), - CheckConstraint("batch_transition_receipt_id is null or action_id in ('project.task.screen','project.task.release')", - name="task_command_batch_transition_action"), CheckConstraint( "(status='pending' and assignment_id is null and contributor_id is null " "and locked_context_hash is null and response is null and committed_at is null) or " @@ -76,12 +73,6 @@ class TaskCommandReceipt(Base): action_id: Mapped[str] = mapped_column(String(160)) idempotency_key: Mapped[UUID] = mapped_column(Uuid()) request_digest: Mapped[str] = mapped_column(String(71)) - # Existing single-Task/CREATE receipts remain null. Bulk participation is - # immutable receipt provenance, never an AUTH selector or a mutable Task flag. - batch_transition_receipt_id: Mapped[UUID | None] = mapped_column(ForeignKey( - "task_batch_transition_receipts.id", name="fk_task_command_batch_transition", - ondelete="RESTRICT", deferrable=True, initially="DEFERRED", - )) # Defer TASK custody until after reservation and proposed-task insertion. task_id: Mapped[str] = mapped_column(ForeignKey( "workstream_tasks.id", name="fk_task_command_task", deferrable=True, initially="DEFERRED", @@ -209,7 +200,6 @@ class WorkstreamTask(Base): ), UniqueConstraint("id", "locked_guide_version", name="uq_workstream_tasks_id_locked_guide"), UniqueConstraint("id", "project_id", name="uq_workstream_tasks_id_project"), - UniqueConstraint("project_id", "external_task_id", name="uq_workstream_tasks_project_external_id"), UniqueConstraint( "id", "locked_post_submit_checker_policy_id", @@ -313,7 +303,7 @@ class WorkstreamTask(Base): title: Mapped[str] = mapped_column(String(300), nullable=False) description: Mapped[str] = mapped_column(Text, nullable=False) task_type: Mapped[str | None] = mapped_column(String(100)) - difficulty: Mapped[str | None] = mapped_column(String(80)) + difficulty: Mapped[str | None] = mapped_column(String(50)) skill_tags: Mapped[list[str]] = mapped_column(JSON, nullable=False, default=list) estimated_time_minutes: Mapped[int | None] = mapped_column(Integer) status: Mapped[str] = mapped_column(String(30), nullable=False, default="draft", index=True) @@ -778,170 +768,3 @@ def result(self): name: UUID(str(getattr(self, name))) if name.endswith("_id") else getattr(self, name) for name in SubmissionCreationResult.__dataclass_fields__ }) - - -class TaskImportBatch(Base): - """One exact received JSON file and its immutable ordered creation result.""" - - __tablename__ = "task_import_batches" - __table_args__ = ( - CheckConstraint("(get_byte(uuid_send(id), 6) >> 4) = 7 and (get_byte(uuid_send(id), 8) & 192) = 128", name="id_uuid7"), - UniqueConstraint("project_id", "sha256", "byte_count", name="uq_task_import_batch_file"), - UniqueConstraint("id", "project_id", name="uq_task_import_batch_project"), - UniqueConstraint("creation_command_receipt_id", name="uq_task_import_batch_creation_command"), - ForeignKeyConstraint( - ["source_id", "project_id", "sha256", "byte_count", "media_type"], - ["artifact_task_import_sources.id", "artifact_task_import_sources.project_id", - "artifact_task_import_sources.sha256", "artifact_task_import_sources.byte_count", - "artifact_task_import_sources.media_type"], - name="fk_task_import_batch_source", ondelete="RESTRICT", deferrable=True, initially="DEFERRED", - ), - ForeignKeyConstraint( - ["identity_link_id", "actor_profile_id"], - ["actor_identity_links.id", "actor_identity_links.actor_profile_id"], - name="fk_task_import_batch_actor_link", ondelete="RESTRICT", deferrable=True, initially="DEFERRED", - ), - CheckConstraint("sha256 ~ '^sha256:[0-9a-f]{64}$'", name="source_hash"), - CheckConstraint("source_operation_identity ~ '^sha256:[0-9a-f]{64}$'", name="source_operation"), - CheckConstraint("manifest_digest ~ '^sha256:[0-9a-f]{64}$'", name="manifest_hash"), - CheckConstraint("byte_count between 1 and 8388608 and row_count between 1 and 500", name="bounds"), - CheckConstraint("media_type='application/json' and schema_version='workstream.task_import.v1' " - "and mapping_version='workstream.task_import.draft_mapping.v1'", name="format"), - CheckConstraint( - "(status='pending' and response is null and authorization_decision_id is null and committed_at is null) or " - "(status='committed' and response is not null and jsonb_typeof(response)='object' " - "and authorization_decision_id is not null and committed_at is not null " - "and put_attempt_id is not null and content_id is not null and replica_id is not null " - "and verification_job_id is not null and verification_generation is not null " - "and verification_generation>0 and verification_receipt_id is not null " - "and ((operation_receipt_id is not null and observation_receipt_id is null) " - "or (operation_receipt_id is null and observation_receipt_id is not null)))", name="state_shape", - ), - ) - - id: Mapped[str] = mapped_column(Uuid(as_uuid=False), primary_key=True) - project_id: Mapped[str] = mapped_column(ForeignKey("projects.id", ondelete="RESTRICT", deferrable=True, initially="DEFERRED")) - source_id: Mapped[str] = mapped_column(Uuid(as_uuid=False)) - creation_command_receipt_id: Mapped[str] = mapped_column(ForeignKey( - "task_import_batch_command_receipts.id", ondelete="RESTRICT", deferrable=True, initially="DEFERRED", - )) - sha256: Mapped[str] = mapped_column(String(71)) - byte_count: Mapped[int] = mapped_column(BigInteger) - media_type: Mapped[str] = mapped_column(String(255), default="application/json") - schema_version: Mapped[str] = mapped_column(String(80)) - mapping_version: Mapped[str] = mapped_column(String(80)) - manifest_digest: Mapped[str] = mapped_column(String(71)) - row_count: Mapped[int] = mapped_column(Integer) - metadata_label: Mapped[str | None] = mapped_column(String(255)) - actor_profile_id: Mapped[str] = mapped_column(ForeignKey("actor_profiles.id", ondelete="RESTRICT", deferrable=True, initially="DEFERRED")) - identity_link_id: Mapped[str] = mapped_column(Uuid(as_uuid=False)) - authorization_decision_id: Mapped[str | None] = mapped_column(ForeignKey("audit_events.id", ondelete="RESTRICT", deferrable=True, initially="DEFERRED")) - status: Mapped[str] = mapped_column(String(16), default="pending") - response: Mapped[dict | None] = mapped_column(JSONB(none_as_null=True)) - created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now()) - committed_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True)) - source_operation_identity: Mapped[str] = mapped_column(String(71)) - put_attempt_id: Mapped[str | None] = mapped_column(ForeignKey("artifact_put_attempts.id", ondelete="RESTRICT", deferrable=True, initially="DEFERRED")) - content_id: Mapped[str | None] = mapped_column(ForeignKey("artifact_contents.id", ondelete="RESTRICT", deferrable=True, initially="DEFERRED")) - replica_id: Mapped[str | None] = mapped_column(ForeignKey("artifact_replicas.id", ondelete="RESTRICT", deferrable=True, initially="DEFERRED")) - verification_job_id: Mapped[str | None] = mapped_column(ForeignKey("artifact_verification_jobs.id", ondelete="RESTRICT", deferrable=True, initially="DEFERRED")) - verification_generation: Mapped[int | None] = mapped_column(BigInteger) - verification_receipt_id: Mapped[str | None] = mapped_column(ForeignKey("artifact_verification_receipts.id", ondelete="RESTRICT", deferrable=True, initially="DEFERRED")) - operation_receipt_id: Mapped[str | None] = mapped_column(ForeignKey("artifact_operation_receipts.id", ondelete="RESTRICT", deferrable=True, initially="DEFERRED")) - observation_receipt_id: Mapped[str | None] = mapped_column(ForeignKey("artifact_put_observation_receipts.id", ondelete="RESTRICT", deferrable=True, initially="DEFERRED")) - - -class TaskImportBatchMember(Base): - """Append-only document row bound to its canonical Task creation receipt.""" - - __tablename__ = "task_import_batch_members" - __table_args__ = ( - CheckConstraint("(get_byte(uuid_send(id), 6) >> 4) = 7 and (get_byte(uuid_send(id), 8) & 192) = 128", name="id_uuid7"), - UniqueConstraint("task_id", name="uq_task_import_member_task"), - UniqueConstraint("batch_id", "row_index", name="uq_task_import_member_row"), - UniqueConstraint("project_id", "external_task_id", name="uq_task_import_member_external_id"), - UniqueConstraint("task_command_receipt_id", name="uq_task_import_member_creation"), - ForeignKeyConstraint(["batch_id", "project_id"], ["task_import_batches.id", "task_import_batches.project_id"], - name="fk_task_import_member_batch", ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), - ForeignKeyConstraint(["task_id", "project_id"], ["workstream_tasks.id", "workstream_tasks.project_id"], - name="fk_task_import_member_task", ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), - CheckConstraint("row_index between 0 and 499", name="row_index"), - CheckConstraint("row_digest ~ '^sha256:[0-9a-f]{64}$'", name="row_hash"), - CheckConstraint("jsonb_typeof(response)='object'", name="response_shape"), - ) - - id: Mapped[str] = mapped_column(Uuid(as_uuid=False), primary_key=True) - batch_id: Mapped[str] = mapped_column(Uuid(as_uuid=False)) - project_id: Mapped[str] = mapped_column(Uuid(as_uuid=False)) - task_id: Mapped[str] = mapped_column(Uuid(as_uuid=False)) - row_index: Mapped[int] = mapped_column(Integer) - external_task_id: Mapped[str] = mapped_column(String(200)) - row_digest: Mapped[str] = mapped_column(String(71)) - create_idempotency_key: Mapped[UUID] = mapped_column(Uuid()) - task_command_receipt_id: Mapped[UUID] = mapped_column(ForeignKey("task_command_receipts.id", ondelete="RESTRICT", deferrable=True, initially="DEFERRED")) - authorization_decision_id: Mapped[str] = mapped_column(ForeignKey("audit_events.id", ondelete="RESTRICT", deferrable=True, initially="DEFERRED")) - response: Mapped[dict] = mapped_column(JSONB) - created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now()) - - -class TaskImportBatchCommandReceipt(Base): - """Actor/action/key retry custody with independently verified selected-source ancestry.""" - - __tablename__ = "task_import_batch_command_receipts" - __table_args__ = ( - CheckConstraint("(get_byte(uuid_send(id), 6) >> 4) = 7 and (get_byte(uuid_send(id), 8) & 192) = 128", name="id_uuid7"), - UniqueConstraint("actor_profile_id", "action_id", "idempotency_key", name="uq_task_import_command_namespace"), - ForeignKeyConstraint(["batch_id", "project_id"], ["task_import_batches.id", "task_import_batches.project_id"], - name="fk_task_import_command_batch", ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), - ForeignKeyConstraint(["identity_link_id", "actor_profile_id"], - ["actor_identity_links.id", "actor_identity_links.actor_profile_id"], - name="fk_task_import_command_actor_link", ondelete="RESTRICT", deferrable=True, initially="DEFERRED"), - ForeignKeyConstraint( - ["source_id", "project_id", "sha256", "byte_count", "media_type"], - ["artifact_task_import_sources.id", "artifact_task_import_sources.project_id", - "artifact_task_import_sources.sha256", "artifact_task_import_sources.byte_count", - "artifact_task_import_sources.media_type"], - name="fk_task_import_command_source", ondelete="RESTRICT", deferrable=True, initially="DEFERRED", - ), - CheckConstraint("action_id='project.task.import'", name="action"), - CheckConstraint("request_digest ~ '^sha256:[0-9a-f]{64}$'", name="request_hash"), - CheckConstraint("sha256 ~ '^sha256:[0-9a-f]{64}$' and source_operation_identity ~ '^sha256:[0-9a-f]{64}$'", name="source_hash"), - CheckConstraint("byte_count between 1 and 8388608 and media_type='application/json'", name="bounds"), - CheckConstraint( - "(status='pending' and response is null and authorization_decision_id is null and committed_at is null) or " - "(status='committed' and batch_id is not null and response is not null and jsonb_typeof(response)='object' " - "and authorization_decision_id is not null and committed_at is not null " - "and put_attempt_id is not null and content_id is not null and replica_id is not null " - "and verification_job_id is not null and verification_generation is not null " - "and verification_generation>0 and verification_receipt_id is not null " - "and ((operation_receipt_id is not null and observation_receipt_id is null) " - "or (operation_receipt_id is null and observation_receipt_id is not null)))", name="state_shape", - ), - ) - - id: Mapped[str] = mapped_column(Uuid(as_uuid=False), primary_key=True) - actor_profile_id: Mapped[str] = mapped_column(ForeignKey("actor_profiles.id", ondelete="RESTRICT", deferrable=True, initially="DEFERRED")) - identity_link_id: Mapped[str] = mapped_column(Uuid(as_uuid=False)) - action_id: Mapped[str] = mapped_column(String(160)) - idempotency_key: Mapped[UUID] = mapped_column(Uuid()) - request_digest: Mapped[str] = mapped_column(String(71)) - project_id: Mapped[str] = mapped_column(ForeignKey("projects.id", ondelete="RESTRICT", deferrable=True, initially="DEFERRED")) - source_id: Mapped[str] = mapped_column(Uuid(as_uuid=False)) - sha256: Mapped[str] = mapped_column(String(71)) - byte_count: Mapped[int] = mapped_column(BigInteger) - media_type: Mapped[str] = mapped_column(String(255), default="application/json") - batch_id: Mapped[str | None] = mapped_column(Uuid(as_uuid=False)) - authorization_decision_id: Mapped[str | None] = mapped_column(ForeignKey("audit_events.id", ondelete="RESTRICT", deferrable=True, initially="DEFERRED")) - status: Mapped[str] = mapped_column(String(16), default="pending") - response: Mapped[dict | None] = mapped_column(JSONB(none_as_null=True)) - created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now()) - committed_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True)) - source_operation_identity: Mapped[str] = mapped_column(String(71)) - put_attempt_id: Mapped[str | None] = mapped_column(ForeignKey("artifact_put_attempts.id", ondelete="RESTRICT", deferrable=True, initially="DEFERRED")) - content_id: Mapped[str | None] = mapped_column(ForeignKey("artifact_contents.id", ondelete="RESTRICT", deferrable=True, initially="DEFERRED")) - replica_id: Mapped[str | None] = mapped_column(ForeignKey("artifact_replicas.id", ondelete="RESTRICT", deferrable=True, initially="DEFERRED")) - verification_job_id: Mapped[str | None] = mapped_column(ForeignKey("artifact_verification_jobs.id", ondelete="RESTRICT", deferrable=True, initially="DEFERRED")) - verification_generation: Mapped[int | None] = mapped_column(BigInteger) - verification_receipt_id: Mapped[str | None] = mapped_column(ForeignKey("artifact_verification_receipts.id", ondelete="RESTRICT", deferrable=True, initially="DEFERRED")) - operation_receipt_id: Mapped[str | None] = mapped_column(ForeignKey("artifact_operation_receipts.id", ondelete="RESTRICT", deferrable=True, initially="DEFERRED")) - observation_receipt_id: Mapped[str | None] = mapped_column(ForeignKey("artifact_put_observation_receipts.id", ondelete="RESTRICT", deferrable=True, initially="DEFERRED")) diff --git a/backend/app/modules/tasks/router.py b/backend/app/modules/tasks/router.py index 39fab6c4e..e526fafcc 100644 --- a/backend/app/modules/tasks/router.py +++ b/backend/app/modules/tasks/router.py @@ -6,9 +6,8 @@ from collections.abc import AsyncIterator from datetime import datetime from uuid import UUID -from app.api.deps.authorization import get_task_commands, get_task_import_batch_commands, enforce_human_authorization_read +from app.api.deps.authorization import get_task_commands, enforce_human_authorization_read from app.modules.tasks.queue_router import router as queue_router -from app.modules.tasks.task_batch_transition_router import router as batch_transition_router from app.modules.tasks.authorized_commands import AuthorizedTaskCommands from app.modules.tasks.api import TaskAuthorityOperation, ContributorTaskDetail, ManagementTaskDetail from typing import Annotated @@ -28,12 +27,6 @@ TaskWithAssignmentResponse, ) from app.modules.tasks.service import TaskProjectNotReady, TaskServiceError, TaskNotFound -from app.modules.tasks.task_import_batches import TaskImportBatchCommands -from app.modules.tasks.api.task_import_membership import TaskImportBatchError -from app.modules.tasks.api.task_import import TaskImportBatchAction -from app.modules.tasks.schemas import TaskImportBatchRequest, TaskImportBatchResponse, TaskImportBatchStatus -from app.interfaces.artifacts import ArtifactStoreError -from pydantic import ValidationError from app.modules.tasks.api.audit_evidence import AuditTaskEvidenceRequest, AuditTaskEvidencePage, TaskEvidenceCursor from app.api.deps.history import HistoryReadOperation, get_history_reads @@ -47,7 +40,6 @@ router = APIRouter(tags=["tasks"]) # Static queue routes precede the project-scoped task UUID route. router.include_router(queue_router) -router.include_router(batch_transition_router) TASK_IDEMPOTENCY_PARAMETER = { "name": "Idempotency-Key", "in": "header", "required": True, @@ -61,55 +53,6 @@ def require_task_command_key(request: Request) -> UUID: return parse_idempotency_key(values[0] if len(values) == 1 else "") -def task_import_error(exc: Exception) -> StructuredHTTPException: - """Expose bounded parser/row failures and safe storage outcomes without coordinates.""" - details = None - if isinstance(exc, TaskImportBatchError): - code, status_code = exc.code, exc.status_code - if isinstance(exc, TaskImportBatchError) and exc.row_indexes: - details = [{"loc": ["tasks", index, "external_task_id"], "type": "external_task_id_conflict"} - for index in exc.row_indexes] - elif isinstance(exc, (ValidationError, ValueError)): - code, status_code = "task_import_json_invalid", 422 - if isinstance(exc, ValidationError): - details = [{"loc": list(error["loc"]), "type": error["type"], "msg": error["msg"]} - for error in exc.errors(include_input=False, include_context=False, include_url=False)] - else: - code, status_code = "task_import_source_unavailable", 503 - return StructuredHTTPException(status_code=status_code, detail=details or code, - error_code=code, error_message=code.replace("_", " "), retryable=status_code == 503) - - -@router.post("/projects/{project_id}/task-import-batches", response_model=TaskImportBatchResponse, status_code=201, - openapi_extra={"x-workstream-action-id": TaskImportBatchAction.IMPORT.value, - "parameters": [TASK_IDEMPOTENCY_PARAMETER]}) -async def import_task_batch( - project_id: UUID, payload: TaskImportBatchRequest, - key: Annotated[UUID, Depends(require_task_command_key)], - commands: Annotated[TaskImportBatchCommands, Depends(get_task_import_batch_commands)], -) -> TaskImportBatchResponse: - """Import every JSON row into DRAFT or recover the original immutable result.""" - try: - return await commands.import_source(project_id, payload.source_id, idempotency_key=key) - except (TaskImportBatchError, ArtifactStoreError, ValidationError, ValueError) as exc: - raise task_import_error(exc) from exc - - -@router.get("/projects/{project_id}/task-import-batches/{batch_id}", response_model=TaskImportBatchStatus, - dependencies=[Depends(enforce_human_authorization_read)], - openapi_extra={"x-workstream-action-id": TaskImportBatchAction.READ.value}) -async def read_task_batch( - request: Request, project_id: UUID, batch_id: UUID, - commands: Annotated[TaskImportBatchCommands, Depends(get_task_import_batch_commands)], -) -> TaskImportBatchStatus: - """Read native membership and current states under fresh covered-manager authority.""" - from app.core.api_controls import request_ids - try: - return await commands.status(project_id, batch_id, request_id=UUID(request_ids(request)[0])) - except TaskImportBatchError as exc: - raise task_import_error(exc) from exc - - CANONICAL_ERROR_OBJECT_SCHEMA = {"$ref": "#/components/schemas/ApiError"} diff --git a/backend/app/modules/tasks/schemas.py b/backend/app/modules/tasks/schemas.py index b284f79c6..97141aac3 100644 --- a/backend/app/modules/tasks/schemas.py +++ b/backend/app/modules/tasks/schemas.py @@ -153,13 +153,6 @@ class TaskCreate(BaseModel): deadline_at: datetime | None = None -class ImportedTaskCreate(TaskCreate): - """Server-stamped JSON creation values; not a public manual-create request.""" - - model_config = ConfigDict(extra="forbid", frozen=True) - source_type: Literal["json_import"] = "json_import" - - class TaskTransitionRequest(BaseModel): """Optional request body for task lifecycle transitions.""" @@ -259,76 +252,6 @@ class TaskResponse(BaseModel): updated_at: datetime -class TaskImportBatchRequest(BaseModel): - """Select one native verified source; all Task provenance is server-stamped.""" - - model_config = ConfigDict(extra="forbid", frozen=True) - - source_id: UUID - - -class TaskImportBatchResponse(BaseModel): - """Immutable original ordered creation facts, also returned after Tasks advance.""" - - model_config = ConfigDict(extra="forbid", frozen=True) - - batch_id: UUID - project_id: UUID - source_id: UUID - sha256: str = Field(pattern=r"^sha256:[0-9a-f]{64}$") - byte_count: int = Field(ge=1, le=8388608) - schema_version: Literal["workstream.task_import.v1"] - mapping_version: Literal["workstream.task_import.draft_mapping.v1"] - label: str | None = Field(default=None, min_length=1, max_length=255) - row_count: int = Field(ge=1, le=500) - created_at: datetime - tasks: tuple[TaskResponse, ...] = Field(min_length=1, max_length=500) - - @model_validator(mode="after") - def original_creation_custody(self): - """Reject foreign, duplicate or relabelled original Task creation responses.""" - if len(self.tasks) != self.row_count or len({task.id for task in self.tasks}) != self.row_count: - raise ValueError("batch creation result has invalid membership") - external_ids = {task.external_task_id for task in self.tasks} - if None in external_ids or len(external_ids) != self.row_count: - raise ValueError("batch creation result has invalid external IDs") - for task in self.tasks: - if (task.project_id != str(self.project_id) or task.status != "draft" - or task.source_type != "json_import" - or task.source_ref != f"task-import-source:{self.source_id}" - or task.source_payload_hash != self.sha256 or task.import_batch_id != str(self.batch_id)): - raise ValueError("batch creation result differs from original custody") - return self - - -class TaskImportBatchCurrentTask(BaseModel): - """Current lifecycle state selected solely by immutable native membership.""" - - model_config = ConfigDict(extra="forbid", frozen=True) - - task_id: UUID - row_index: int = Field(ge=0, le=499) - status: str = Field(pattern=r"^[a-z][a-z0-9_]{0,29}$") - - -class TaskImportBatchStatus(BaseModel): - """Separate original creation facts from the current member lifecycle states.""" - - model_config = ConfigDict(extra="forbid", frozen=True) - - creation: TaskImportBatchResponse - current_tasks: tuple[TaskImportBatchCurrentTask, ...] = Field(min_length=1, max_length=500) - - @model_validator(mode="after") - def exact_current_membership(self): - """Keep the current projection in the same original document row order.""" - if (len(self.current_tasks) != self.creation.row_count - or any(row.row_index != index or str(row.task_id) != self.creation.tasks[index].id - for index, row in enumerate(self.current_tasks))): - raise ValueError("current Task projection differs from native membership") - return self - - class RequiredArtifactRequirement(BaseModel): """Contributor-facing required artifact rule from the locked effective policy.""" diff --git a/backend/app/modules/tasks/task_batch_transition/__init__.py b/backend/app/modules/tasks/task_batch_transition/__init__.py deleted file mode 100644 index 3d50d38a5..000000000 --- a/backend/app/modules/tasks/task_batch_transition/__init__.py +++ /dev/null @@ -1 +0,0 @@ -"""TASK-owned aggregate transition custody.""" diff --git a/backend/app/modules/tasks/task_batch_transition/models.py b/backend/app/modules/tasks/task_batch_transition/models.py deleted file mode 100644 index cc0057b2a..000000000 --- a/backend/app/modules/tasks/task_batch_transition/models.py +++ /dev/null @@ -1,165 +0,0 @@ -"""TASK-owned aggregate success custody over canonical per-Task command receipts.""" - -from datetime import datetime -from uuid import UUID - -from sqlalchemy import ( - CheckConstraint, - DateTime, - ForeignKey, - ForeignKeyConstraint, - Integer, - String, - Text, - UniqueConstraint, - Uuid, -) -from sqlalchemy.dialects.postgresql import JSONB -from sqlalchemy.orm import Mapped, mapped_column -from sqlalchemy.sql import func - -from app.db.base import Base - - -class TaskBatchTransitionReceipt(Base): - """One actor/action/key root, committed only with every native batch member.""" - - __tablename__ = "task_batch_transition_receipts" - __table_args__ = ( - CheckConstraint( - "(get_byte(uuid_send(id), 6) >> 4) = 7 and (get_byte(uuid_send(id), 8) & 192) = 128", - name="id_uuid7", - ), - UniqueConstraint( - "actor_profile_id", - "action_id", - "idempotency_key", - name="uq_task_batch_transition_namespace", - ), - UniqueConstraint("id", "project_id", "batch_id", name="uq_task_batch_transition_parent"), - ForeignKeyConstraint( - ["batch_id", "project_id"], - ["task_import_batches.id", "task_import_batches.project_id"], - name="fk_task_batch_transition_batch", - ondelete="RESTRICT", - deferrable=True, - initially="DEFERRED", - ), - ForeignKeyConstraint( - ["identity_link_id", "actor_profile_id"], - ["actor_identity_links.id", "actor_identity_links.actor_profile_id"], - name="fk_task_batch_transition_actor_link", - ondelete="RESTRICT", - deferrable=True, - initially="DEFERRED", - ), - CheckConstraint( - "action_id in ('project.task.screen','project.task.release')", name="action" - ), - CheckConstraint( - "request_digest ~ '^sha256:[0-9a-f]{64}$' and manifest_digest ~ '^sha256:[0-9a-f]{64}$' " - "and membership_digest ~ '^sha256:[0-9a-f]{64}$'", - name="digests", - ), - CheckConstraint("row_count between 1 and 500", name="bounds"), - CheckConstraint("reason is null or length(reason)<=4000", name="reason_bounds"), - CheckConstraint( - "action_id<>'project.task.release' or (reason is not null and length(btrim(reason))>0)", - name="release_reason", - ), - CheckConstraint( - "(status='pending' and response is null and committed_at is null) or " - "(status='committed' and response is not null and jsonb_typeof(response)='object' " - "and committed_at is not null)", - name="state_shape", - ), - ) - - id: Mapped[UUID] = mapped_column(Uuid(), primary_key=True) - actor_profile_id: Mapped[str] = mapped_column( - ForeignKey("actor_profiles.id", ondelete="RESTRICT", deferrable=True, initially="DEFERRED") - ) - identity_link_id: Mapped[str] = mapped_column(Uuid(as_uuid=False)) - action_id: Mapped[str] = mapped_column(String(160)) - idempotency_key: Mapped[UUID] = mapped_column(Uuid()) - request_digest: Mapped[str] = mapped_column(String(71)) - reason: Mapped[str | None] = mapped_column(Text) - project_id: Mapped[str] = mapped_column(Uuid(as_uuid=False)) - batch_id: Mapped[str] = mapped_column(Uuid(as_uuid=False)) - manifest_digest: Mapped[str] = mapped_column(String(71)) - membership_digest: Mapped[str] = mapped_column(String(71)) - row_count: Mapped[int] = mapped_column(Integer) - status: Mapped[str] = mapped_column(String(16), default="pending") - response: Mapped[dict | None] = mapped_column(JSONB(none_as_null=True)) - created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now()) - committed_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True)) - - -class TaskBatchTransitionMember(Base): - """Immutable original row linked to its root-bound canonical success and AUTH.""" - - __tablename__ = "task_batch_transition_members" - __table_args__ = ( - CheckConstraint( - "(get_byte(uuid_send(id), 6) >> 4) = 7 and (get_byte(uuid_send(id), 8) & 192) = 128", - name="id_uuid7", - ), - UniqueConstraint( - "transition_receipt_id", "row_index", name="uq_task_batch_transition_member_row" - ), - UniqueConstraint( - "transition_receipt_id", - "native_member_id", - name="uq_task_batch_transition_member_native", - ), - UniqueConstraint( - "transition_receipt_id", "task_id", name="uq_task_batch_transition_member_task" - ), - UniqueConstraint("task_command_receipt_id", name="uq_task_batch_transition_member_command"), - ForeignKeyConstraint( - ["transition_receipt_id", "project_id", "batch_id"], - [ - "task_batch_transition_receipts.id", - "task_batch_transition_receipts.project_id", - "task_batch_transition_receipts.batch_id", - ], - name="fk_task_batch_transition_member_parent", - ondelete="RESTRICT", - deferrable=True, - initially="DEFERRED", - ), - ForeignKeyConstraint( - ["task_id", "project_id"], - ["workstream_tasks.id", "workstream_tasks.project_id"], - name="fk_task_batch_transition_member_task", - ondelete="RESTRICT", - deferrable=True, - initially="DEFERRED", - ), - CheckConstraint("row_index between 0 and 499", name="row_index"), - ) - - id: Mapped[UUID] = mapped_column(Uuid(), primary_key=True) - transition_receipt_id: Mapped[UUID] = mapped_column(Uuid()) - project_id: Mapped[str] = mapped_column(Uuid(as_uuid=False)) - batch_id: Mapped[str] = mapped_column(Uuid(as_uuid=False)) - native_member_id: Mapped[str] = mapped_column( - ForeignKey( - "task_import_batch_members.id", - ondelete="RESTRICT", - deferrable=True, - initially="DEFERRED", - ) - ) - task_id: Mapped[str] = mapped_column(Uuid(as_uuid=False)) - row_index: Mapped[int] = mapped_column(Integer) - task_idempotency_key: Mapped[UUID] = mapped_column(Uuid()) - task_command_receipt_id: Mapped[UUID] = mapped_column( - ForeignKey( - "task_command_receipts.id", ondelete="RESTRICT", deferrable=True, initially="DEFERRED" - ) - ) - authorization_decision_id: Mapped[str] = mapped_column( - ForeignKey("audit_events.id", ondelete="RESTRICT", deferrable=True, initially="DEFERRED") - ) - created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), server_default=func.now()) diff --git a/backend/app/modules/tasks/task_batch_transition_router.py b/backend/app/modules/tasks/task_batch_transition_router.py deleted file mode 100644 index b42b37cc5..000000000 --- a/backend/app/modules/tasks/task_batch_transition_router.py +++ /dev/null @@ -1,69 +0,0 @@ -"""Explicit project-scoped all-member SCREEN and RELEASE delivery.""" - -from typing import Annotated -from uuid import UUID - -from fastapi import APIRouter, Depends, Request - -from app.api.deps.task_batch_transitions import get_task_batch_transition_commands -from app.core.api_controls import StructuredHTTPException, parse_idempotency_key -from app.modules.tasks.api.authorization import TaskAuthorityOperation -from app.modules.tasks.api.task_batch_transition import ( - TaskBatchTransitionPort, TaskBatchTransitionRequest, TaskBatchTransitionResponse, -) -from app.modules.tasks.api.task_import_membership import TaskImportBatchError -from app.modules.tasks.service import TaskServiceError - -router = APIRouter(tags=["tasks"]) -_KEY_PARAMETER = {"name": "Idempotency-Key", "in": "header", "required": True, - "schema": {"type": "string", "format": "uuid"}} - - -def require_batch_transition_key(request: Request) -> UUID: - """Require one exact caller retry UUID before resolving a mutating actor.""" - values = request.headers.getlist("Idempotency-Key") - return parse_idempotency_key(values[0] if len(values) == 1 else "") - - -def _error(exc: TaskImportBatchError | TaskServiceError) -> StructuredHTTPException: - code = getattr(exc, "code", None) or "task_batch_transition_invalid" - return StructuredHTTPException( - status_code=exc.status_code, detail=str(exc), error_code=code, - error_message=str(exc), retryable=getattr(exc, "retryable", False), - ) - - -@router.post( - "/projects/{project_id}/task-import-batches/{batch_id}/screen", - response_model=TaskBatchTransitionResponse, - openapi_extra={"x-workstream-action-id": TaskAuthorityOperation.SCREEN.value, - "parameters": [_KEY_PARAMETER]}, -) -async def screen_task_batch( - project_id: UUID, batch_id: UUID, payload: TaskBatchTransitionRequest, - key: Annotated[UUID, Depends(require_batch_transition_key)], - commands: Annotated[TaskBatchTransitionPort, Depends(get_task_batch_transition_commands)], -) -> TaskBatchTransitionResponse: - """Screen the complete native batch or recover its still-current exact result.""" - try: - return await commands.screen(project_id, batch_id, payload.reason, idempotency_key=key) - except (TaskImportBatchError, TaskServiceError) as exc: - raise _error(exc) from exc - - -@router.post( - "/projects/{project_id}/task-import-batches/{batch_id}/release", - response_model=TaskBatchTransitionResponse, - openapi_extra={"x-workstream-action-id": TaskAuthorityOperation.RELEASE.value, - "parameters": [_KEY_PARAMETER]}, -) -async def release_task_batch( - project_id: UUID, batch_id: UUID, payload: TaskBatchTransitionRequest, - key: Annotated[UUID, Depends(require_batch_transition_key)], - commands: Annotated[TaskBatchTransitionPort, Depends(get_task_batch_transition_commands)], -) -> TaskBatchTransitionResponse: - """Release all members with normal reason and locked prerequisites, or none.""" - try: - return await commands.release(project_id, batch_id, payload.reason, idempotency_key=key) - except (TaskImportBatchError, TaskServiceError) as exc: - raise _error(exc) from exc diff --git a/backend/app/modules/tasks/task_batch_transitions.py b/backend/app/modules/tasks/task_batch_transitions.py deleted file mode 100644 index 66668e2d6..000000000 --- a/backend/app/modules/tasks/task_batch_transitions.py +++ /dev/null @@ -1,210 +0,0 @@ -"""One caller-root SCREEN/RELEASE over complete immutable native batch membership.""" - -from dataclasses import dataclass -from datetime import UTC, datetime -from uuid import UUID, uuid4 - -from sqlalchemy import select -from sqlalchemy.dialects.postgresql import insert -from sqlalchemy.ext.asyncio import AsyncSession - -from app.core.hashing import canonical_json_hash -from app.core.identifiers import new_record_id -from app.modules.tasks.api.authorization import TaskAuthorityDecision, TaskAuthorityOperation -from app.modules.tasks.api.task_batch_transition import ( - TaskBatchTransitionRequest, TaskBatchTransitionResponse, TaskBatchTransitionResult, -) -from app.modules.tasks.api.task_import_membership import TaskImportBatchError, TaskImportMemberIdentity -from app.modules.tasks.authorized_commands import AuthorizedTaskCommands, TaskTransitionPreparation -from app.modules.tasks.command_replay import TaskReplayConflict -from app.modules.tasks.schemas import TaskResponse -from app.modules.tasks.service import TaskValidationError -from app.modules.tasks.task_batch_transition.models import TaskBatchTransitionMember, TaskBatchTransitionReceipt -from app.modules.tasks.task_import_membership import TaskImportMembership, TaskImportMembershipSnapshot - - -@dataclass(frozen=True, slots=True) -class _PreparedMember: - native: TaskImportMemberIdentity - task: TaskTransitionPreparation - retained: TaskBatchTransitionMember | None - - -def _membership_digest(snapshot: TaskImportMembershipSnapshot) -> str: - """Seal the actual ordered native member and original CREATE identities.""" - return canonical_json_hash({"members": [{ - "member_id": str(row.member_id), "task_id": str(row.task_id), "row_index": row.row_index, - "external_task_id": row.external_task_id, "row_digest": row.row_digest, - "create_idempotency_key": str(row.create_idempotency_key), - "task_command_receipt_id": str(row.task_command_receipt_id), - "authorization_decision_id": str(row.authorization_decision_id), - } for row in snapshot.members]}) - - -class TaskBatchTransitionCommands: - """Compose canonical participants; never infer membership from a mutable Task.""" - - def __init__( - self, session: AsyncSession, *, actor_profile_id: UUID, identity_link_id: UUID, - tasks: AuthorizedTaskCommands, - ) -> None: - self._session, self._actor_id, self._link_id = session, actor_profile_id, identity_link_id - self._tasks = tasks - self._membership = TaskImportMembership(session) - - async def screen( - self, project_id: UUID, batch_id: UUID, reason: str | None, *, idempotency_key: UUID, - ) -> TaskBatchTransitionResponse: - """Screen every native member, preserving the normal guide-locking owner.""" - return await self._transition(project_id, batch_id, TaskAuthorityOperation.SCREEN, reason, idempotency_key) - - async def release( - self, project_id: UUID, batch_id: UUID, reason: str | None, *, idempotency_key: UUID, - ) -> TaskBatchTransitionResponse: - """Release every native member with its normal reason and locked prerequisites.""" - return await self._transition(project_id, batch_id, TaskAuthorityOperation.RELEASE, reason, idempotency_key) - - async def _reserve( - self, snapshot: TaskImportMembershipSnapshot, operation: TaskAuthorityOperation, - reason: str | None, key: UUID, digest: str, - ) -> tuple[TaskBatchTransitionReceipt, bool]: - """Serialize the caller namespace without updating an immutable success row.""" - identifier = new_record_id() - await self._session.execute(insert(TaskBatchTransitionReceipt).values( - id=identifier, actor_profile_id=str(self._actor_id), identity_link_id=str(self._link_id), - action_id=operation.value, idempotency_key=key, request_digest=digest, reason=reason, - project_id=str(snapshot.creation.project_id), batch_id=str(snapshot.creation.batch_id), - manifest_digest=snapshot.manifest_digest, membership_digest=_membership_digest(snapshot), - row_count=len(snapshot.members), status="pending", - ).on_conflict_do_nothing(constraint="uq_task_batch_transition_namespace")) - receipt = await self._session.scalar(select(TaskBatchTransitionReceipt).where( - TaskBatchTransitionReceipt.actor_profile_id == str(self._actor_id), - TaskBatchTransitionReceipt.action_id == operation.value, - TaskBatchTransitionReceipt.idempotency_key == key, - ).with_for_update().execution_options(populate_existing=True)) - if receipt is None: - raise RuntimeError("task batch transition reservation disappeared") - return receipt, receipt.id == identifier - - async def _prepare( - self, snapshot: TaskImportMembershipSnapshot, receipt: TaskBatchTransitionReceipt, - operation: TaskAuthorityOperation, reason: str | None, - ) -> tuple[list[_PreparedMember], int]: - """Acquire every actual Task/assignment in UUID order before the first AUTH.""" - links = (await self._session.scalars(select(TaskBatchTransitionMember).where( - TaskBatchTransitionMember.transition_receipt_id == receipt.id, - ).order_by(TaskBatchTransitionMember.row_index))).all() - by_member = {row.native_member_id: row for row in links} - prepared = [] - for native in sorted(snapshot.members, key=lambda row: row.task_id.int): - retained = by_member.get(str(native.member_id)) - key = retained.task_idempotency_key if retained is not None else uuid4() - task = await self._tasks.prepare_transition( - native.task_id, operation, reason, idempotency_key=key, - project_id=snapshot.creation.project_id, batch_transition_receipt_id=receipt.id, - ) - prepared.append(_PreparedMember(native, task, retained)) - return prepared, len(links) - - @staticmethod - def _validate_custody( - snapshot: TaskImportMembershipSnapshot, receipt: TaskBatchTransitionReceipt, - rows: list[_PreparedMember], digest: str, reason: str | None, - link_count: int, *, reserved: bool, - ) -> None: - """Compare original custody only after every member has fresh authority.""" - if receipt.request_digest != digest or receipt.reason != reason: - raise TaskReplayConflict("idempotency_mismatch") - if (receipt.project_id != str(snapshot.creation.project_id) - or receipt.batch_id != str(snapshot.creation.batch_id) - or receipt.manifest_digest != snapshot.manifest_digest - or receipt.membership_digest != _membership_digest(snapshot) - or receipt.row_count != len(rows)): - raise TaskImportBatchError("task_batch_transition_custody_invalid", 409) - if receipt.status == "pending": - if not reserved: - raise TaskReplayConflict("idempotency_pending") - if link_count or any(row.retained is not None or not row.task.reserved for row in rows): - raise TaskImportBatchError("task_batch_transition_custody_invalid", 409) - return - if receipt.status != "committed" or link_count != len(rows): - raise TaskImportBatchError("task_batch_transition_custody_invalid", 409) - for row in rows: - link, canonical = row.retained, row.task.receipt - if (link is None or row.task.reserved - or link.transition_receipt_id != receipt.id - or link.project_id != receipt.project_id or link.batch_id != receipt.batch_id - or link.task_id != str(row.native.task_id) or link.row_index != row.native.row_index - or link.native_member_id != str(row.native.member_id) - or link.task_command_receipt_id != canonical.id - or link.task_idempotency_key != canonical.idempotency_key - or canonical.status != "committed" or canonical.action_id != receipt.action_id - or canonical.actor_profile_id != receipt.actor_profile_id - or canonical.batch_transition_receipt_id != receipt.id): - raise TaskImportBatchError("task_batch_transition_custody_invalid", 409) - - @staticmethod - def _result(row: _PreparedMember, response: TaskResponse) -> TaskBatchTransitionResult: - """Project actual canonical receipt facts instead of a second state snapshot.""" - canonical = row.task.receipt - if (canonical.response != response.model_dump(mode="json") - or response.id != str(row.native.task_id) - or canonical.locked_context_hash is None): - raise TaskImportBatchError("task_batch_transition_custody_invalid", 409) - return TaskBatchTransitionResult( - task_id=row.native.task_id, row_index=row.native.row_index, status=response.status, - locked_guide_version=response.locked_guide_version, - locked_contribution_policy_version_id=response.locked_contribution_policy_version_id, - locked_context_hash=canonical.locked_context_hash, - ) - - async def _transition( - self, project_id: UUID, batch_id: UUID, operation: TaskAuthorityOperation, - reason: str | None, key: UUID, - ) -> TaskBatchTransitionResponse: - if not all(isinstance(value, UUID) for value in (project_id, batch_id, key)): - raise ValueError("task batch transition selectors are invalid") - reason = TaskBatchTransitionRequest(reason=reason).reason - if operation is TaskAuthorityOperation.RELEASE and (not reason or not reason.strip()): - raise TaskValidationError("release decision reason is required") - digest = canonical_json_hash({"project_id": str(project_id), "batch_id": str(batch_id), - "operation": operation.value, "reason": reason}) - async with self._session.begin(): - snapshot = await self._membership.prepare(project_id, batch_id) - receipt, reserved = await self._reserve(snapshot, operation, reason, key, digest) - rows, link_count = await self._prepare(snapshot, receipt, operation, reason) - decisions: list[TaskAuthorityDecision] = [] - for row in rows: - decisions.append(await self._tasks.authorize_transition(row.task)) - self._validate_custody(snapshot, receipt, rows, digest, reason, link_count, reserved=reserved) - if (any(row.task.facts.actor_profile_id != self._actor_id for row in rows) - or any(decision.identity_link_id != self._link_id for decision in decisions)): - raise TaskImportBatchError("task_batch_transition_custody_invalid", 409) - results = [] - for row, decision in zip(rows, decisions, strict=True): - response = await self._tasks.stage_transition(row.task, decision) - results.append(self._result(row, response)) - if reserved: - self._session.add(TaskBatchTransitionMember( - id=new_record_id(), transition_receipt_id=receipt.id, - project_id=str(project_id), batch_id=str(batch_id), - native_member_id=str(row.native.member_id), task_id=str(row.native.task_id), - row_index=row.native.row_index, task_idempotency_key=row.task.receipt.idempotency_key, - task_command_receipt_id=row.task.receipt.id, - authorization_decision_id=str(decision.decision_id), - )) - response = TaskBatchTransitionResponse( - project_id=project_id, batch_id=batch_id, - operation="screen" if operation is TaskAuthorityOperation.SCREEN else "release", - row_count=len(rows), tasks=tuple(sorted(results, key=lambda row: row.row_index)), - ) - encoded = response.model_dump(mode="json") - if reserved: - receipt.response, receipt.status, receipt.committed_at = encoded, "committed", datetime.now(UTC) - await self._session.flush() - elif receipt.response != encoded: - raise TaskImportBatchError("task_batch_transition_custody_invalid", 409) - # Validate/detach before root commit; serialization failure rolls back - # every Task, receipt, lifecycle event and successful AUTH decision. - response = TaskBatchTransitionResponse.model_validate_json(response.model_dump_json()) - return response diff --git a/backend/app/modules/tasks/task_import_batches.py b/backend/app/modules/tasks/task_import_batches.py deleted file mode 100644 index b54dbbfaf..000000000 --- a/backend/app/modules/tasks/task_import_batches.py +++ /dev/null @@ -1,292 +0,0 @@ -"""One caller-root JSON import using canonical Task creation and ART byte custody.""" - -from datetime import UTC, datetime -from uuid import UUID, uuid4 - -from sqlalchemy import select -from sqlalchemy.dialects.postgresql import insert -from sqlalchemy.ext.asyncio import AsyncSession - -from app.core.hashing import canonical_json_hash -from app.core.identifiers import new_record_id -from app.modules.tasks.api.task_import import ( - ParsedTaskImport, TASK_IMPORT_MAPPING_VERSION, TASK_IMPORT_MAXIMUM_BYTES, - TaskImportSourceCommitment, TaskImportSourceConsumerPort, VerifiedTaskImportSourceBinding, - TaskImportBatchAction, TaskImportBatchAuthorityFacts, TaskImportBatchAuthorizationPort, - TaskImportRow, parse_task_import, -) -from app.modules.tasks.api.task_import_membership import TaskImportBatchError -from app.modules.tasks.task_import_membership import TaskImportMembership -from app.modules.tasks.authorized_commands import AuthorizedTaskCommands, TaskCreationPreparation -from app.modules.tasks.command_replay import TaskReplayConflict -from app.modules.tasks.models import ( - TaskImportBatch, TaskImportBatchCommandReceipt, TaskImportBatchMember, WorkstreamTask, -) -from app.modules.tasks.schemas import ( - ImportedTaskCreate, TaskImportBatchResponse, TaskImportBatchCurrentTask, TaskImportBatchStatus, -) - - -def imported_task_payload(row: TaskImportRow, source: TaskImportSourceCommitment, batch_id: UUID) -> ImportedTaskCreate: - """Map instructions directly and stamp provenance solely from actual native custody.""" - return ImportedTaskCreate( - **row.model_dump(), source_type="json_import", source_ref=f"task-import-source:{source.source_id}", - source_payload_hash=source.sha256, import_batch_id=str(batch_id), - ) - - -def _binding(row: TaskImportBatch | TaskImportBatchCommandReceipt) -> VerifiedTaskImportSourceBinding: - """Recover a closed native ancestry tuple without operational provider fields.""" - return VerifiedTaskImportSourceBinding( - source_id=UUID(row.source_id), project_id=UUID(row.project_id), sha256=row.sha256, byte_count=row.byte_count, - operation_identity=row.source_operation_identity, put_attempt_id=UUID(row.put_attempt_id), - content_id=UUID(row.content_id), replica_id=UUID(row.replica_id), verification_job_id=UUID(row.verification_job_id), - verification_generation=row.verification_generation, verification_receipt_id=UUID(row.verification_receipt_id), - operation_receipt_id=UUID(row.operation_receipt_id) if row.operation_receipt_id is not None else None, - observation_receipt_id=UUID(row.observation_receipt_id) if row.observation_receipt_id is not None else None, - ) - - -def _stage_binding(row: TaskImportBatch | TaskImportBatchCommandReceipt, binding: VerifiedTaskImportSourceBinding) -> None: - """Stage only the concrete native ancestry columns validated by the ART owner.""" - row.source_operation_identity = binding.operation_identity - row.verification_generation = binding.verification_generation - for field in ("put_attempt_id", "content_id", "replica_id", "verification_job_id", - "verification_receipt_id", "operation_receipt_id", "observation_receipt_id"): - value = getattr(binding, field) - setattr(row, field, str(value) if value is not None else None) - - -class TaskImportBatchCommands: - """Own the batch transaction; its Task and ART participants never commit it.""" - - def __init__( - self, session: AsyncSession, *, actor_profile_id: UUID, identity_link_id: UUID, - authorization: TaskImportBatchAuthorizationPort, tasks: AuthorizedTaskCommands, - source: TaskImportSourceConsumerPort, - ) -> None: - self._session, self._actor_id, self._link_id = session, actor_profile_id, identity_link_id - self._authorization, self._tasks = authorization, tasks - self._source = source - - @staticmethod - def _request_digest(project_id: UUID, source_id: UUID) -> str: - return canonical_json_hash({"project_id": str(project_id), "source_id": str(source_id)}) - - async def _command(self, key: UUID, *, lock: bool = False) -> TaskImportBatchCommandReceipt | None: - query = select(TaskImportBatchCommandReceipt).where( - TaskImportBatchCommandReceipt.actor_profile_id == str(self._actor_id), - TaskImportBatchCommandReceipt.action_id == TaskImportBatchAction.IMPORT.value, - TaskImportBatchCommandReceipt.idempotency_key == key, - ).execution_options(populate_existing=True) - return await self._session.scalar(query.with_for_update() if lock else query) - - async def _file_batch(self, facts: TaskImportSourceCommitment, *, lock: bool = False) -> TaskImportBatch | None: - query = select(TaskImportBatch).where( - TaskImportBatch.project_id == str(facts.project_id), TaskImportBatch.sha256 == facts.sha256, - TaskImportBatch.byte_count == facts.byte_count, - ).execution_options(populate_existing=True) - return await self._session.scalar(query.with_for_update() if lock else query) - - async def _preflight(self, project_id: UUID, source_id: UUID, key: UUID) -> tuple[TaskImportSourceCommitment, bool]: - """Determine whether immutable recovery exists without reading provider bytes.""" - async with self._session.begin(): - command = await self._command(key) - if command is not None: - facts = await self._source.source_commitment(UUID(command.project_id), UUID(command.source_id)) - await self._source.authorize_commitment(facts) - return facts, True - facts = await self._source.source_commitment(project_id, source_id) - await self._source.authorize_commitment(facts) - batch = await self._file_batch(facts) - return facts, batch is not None - - async def _read_first_import(self, facts: TaskImportSourceCommitment) -> ParsedTaskImport: - """Finish bounded actual provider verification and parsing before TASK locks.""" - raw = bytearray() - async with self._source.open(facts.project_id, facts.source_id) as opened: - async for chunk in opened.stream: - raw.extend(chunk) - if len(raw) > TASK_IMPORT_MAXIMUM_BYTES: - raise TaskImportBatchError("task_import_source_limit_exceeded", 413) - parsed = parse_task_import(bytes(raw)) - if (parsed.sha256, parsed.byte_count) != (facts.sha256, facts.byte_count): - raise TaskImportBatchError("task_import_source_custody_invalid", 409) - return parsed - - async def _reserve_command( - self, facts: TaskImportSourceCommitment, key: UUID, request_digest: str, - ) -> TaskImportBatchCommandReceipt: - """Reserve the exact actor/action/key before batch, ART or AUTH locks.""" - await self._session.execute(insert(TaskImportBatchCommandReceipt).values( - id=str(new_record_id()), actor_profile_id=str(self._actor_id), identity_link_id=str(self._link_id), - action_id=TaskImportBatchAction.IMPORT.value, - idempotency_key=key, request_digest=request_digest, project_id=str(facts.project_id), - source_id=str(facts.source_id), sha256=facts.sha256, byte_count=facts.byte_count, - media_type="application/json", source_operation_identity=facts.operation_identity, status="pending", - ).on_conflict_do_nothing(constraint="uq_task_import_command_namespace")) - return await self._command(key, lock=True) - - async def _reserve_batch( - self, facts: TaskImportSourceCommitment, parsed: ParsedTaskImport | None, - command: TaskImportBatchCommandReceipt, - ) -> TaskImportBatch: - """Serialize only the exact project/file identity; native FKs remain deferred.""" - if parsed is not None: - await self._session.execute(insert(TaskImportBatch).values( - id=str(new_record_id()), project_id=str(facts.project_id), source_id=str(facts.source_id), - creation_command_receipt_id=command.id, - sha256=facts.sha256, byte_count=facts.byte_count, media_type="application/json", - schema_version=parsed.document.schema_version, mapping_version=TASK_IMPORT_MAPPING_VERSION, - manifest_digest=canonical_json_hash(parsed.document.model_dump(mode="json")), - row_count=len(parsed.document.tasks), actor_profile_id=str(self._actor_id), identity_link_id=str(self._link_id), - metadata_label=parsed.document.metadata.label, - source_operation_identity=facts.operation_identity, status="pending", - ).on_conflict_do_nothing(constraint="uq_task_import_batch_file")) - batch = await self._file_batch(facts, lock=True) - if batch is None: - raise TaskImportBatchError("task_import_batch_custody_invalid", 409) - return batch - - def _facts( - self, batch: TaskImportBatch, selected: VerifiedTaskImportSourceBinding, key: UUID, request_digest: str, - ) -> TaskImportBatchAuthorityFacts: - return TaskImportBatchAuthorityFacts( - UUID(batch.id), UUID(batch.project_id), selected.source_id, self._actor_id, batch.sha256, - batch.byte_count, batch.row_count, batch.manifest_digest, - canonical_json_hash(selected.model_dump(mode="json")), key, request_digest, - ) - - async def _prepare_rows( - self, batch: TaskImportBatch, facts: TaskImportSourceCommitment, parsed: ParsedTaskImport, - ) -> list[tuple[int, TaskCreationPreparation]]: - """Prepare every canonical Task retry identity before any ART/AUTH lock.""" - prepared = [] - rows = sorted(enumerate(parsed.document.tasks), key=lambda item: item[1].external_task_id.encode("utf-8")) - for index, row in rows: - values = imported_task_payload(row, facts, UUID(batch.id)) - prepared.append((index, await self._tasks.prepare_creation( - UUID(batch.project_id), values, idempotency_key=uuid4(), - ))) - return prepared - - async def _prepare_sources( - self, batch: TaskImportBatch, command: TaskImportBatchCommandReceipt, - ) -> VerifiedTaskImportSourceBinding: - """Acquire all selected/original SOURCE custody before current AUTH.""" - expected = {} - if batch.status == "committed": - expected[batch.source_id] = _binding(batch) - if command.status == "committed": - expected[command.source_id] = _binding(command) - expected.setdefault(command.source_id, None) - prepared = {} - for source_id in sorted(expected): - prepared[source_id] = await self._source.prepare_binding( - UUID(batch.project_id), UUID(source_id), expected[source_id], - ) - selected = prepared[command.source_id] - if (selected.sha256, selected.byte_count) != (batch.sha256, batch.byte_count): - raise TaskImportBatchError("task_import_source_custody_invalid", 409) - return selected - - async def _original_response(self, batch: TaskImportBatch) -> TaskImportBatchResponse: - """Recover immutable creation facts through the one native membership owner.""" - return (await TaskImportMembership(self._session).validate(batch)).creation - - async def _stage_rows( - self, batch: TaskImportBatch, parsed: ParsedTaskImport, - prepared: list[tuple[int, TaskCreationPreparation]], - ) -> TaskImportBatchResponse: - """Authorize every CREATE then stage sorted writes in the same caller root.""" - decisions = [(index, creation, await self._tasks.authorize_creation(creation)) for index, creation in prepared] - existing = set(await self._session.scalars(select(WorkstreamTask.external_task_id).where( - WorkstreamTask.project_id == batch.project_id, - WorkstreamTask.external_task_id.in_([row.external_task_id for row in parsed.document.tasks]), - ))) - conflicts = tuple(index for index, row in enumerate(parsed.document.tasks) if row.external_task_id in existing) - if conflicts: - raise TaskImportBatchError("task_import_external_id_conflict", 409, conflicts) - originals = {} - for index, creation, decision in decisions: - try: - original = await self._tasks.stage_creation(creation, decision) - except TaskReplayConflict as exc: - if exc.code == "external_task_id_conflict": - raise TaskImportBatchError("task_import_external_id_conflict", 409, (index,)) from exc - raise - originals[index] = original - self._session.add(TaskImportBatchMember( - id=str(new_record_id()), batch_id=batch.id, project_id=batch.project_id, task_id=original.id, - row_index=index, external_task_id=original.external_task_id, - row_digest=canonical_json_hash(parsed.document.tasks[index].model_dump(mode="json")), - create_idempotency_key=creation.facts.idempotency_key, task_command_receipt_id=creation.receipt.id, - authorization_decision_id=str(decision.decision_id), response=original.model_dump(mode="json"), - )) - return TaskImportBatchResponse( - batch_id=UUID(batch.id), project_id=UUID(batch.project_id), source_id=UUID(batch.source_id), - sha256=batch.sha256, byte_count=batch.byte_count, schema_version=batch.schema_version, - mapping_version=batch.mapping_version, row_count=batch.row_count, created_at=batch.created_at, - label=batch.metadata_label, - tasks=tuple(originals[index] for index in range(batch.row_count)), - ) - - async def import_source(self, project_id: UUID, source_id: UUID, *, idempotency_key: UUID) -> TaskImportBatchResponse: - """Create all rows atomically or freshly authorize immutable exact-file recovery.""" - facts, recoverable = await self._preflight(project_id, source_id, idempotency_key) - parsed = None if recoverable else await self._read_first_import(facts) - digest = self._request_digest(project_id, source_id) - async with self._session.begin(): - command = await self._reserve_command(facts, idempotency_key, digest) - # Namespace custody may now point at the original selector from a competing commit. - facts = await self._source.source_commitment(UUID(command.project_id), UUID(command.source_id)) - batch = await self._reserve_batch(facts, parsed, command) - prepared = (await self._prepare_rows(batch, facts, parsed)) if batch.status == "pending" else [] - selected = await self._prepare_sources(batch, command) - await self._source.authorize_binding(selected) - decision_id = await self._authorization.authorize( - TaskImportBatchAction.IMPORT, self._facts(batch, selected, idempotency_key, digest), - ) - if command.request_digest != digest: - raise TaskImportBatchError("task_import_idempotency_mismatch", 409) - if command.status == "committed": - original = await self._original_response(batch) - if command.batch_id != batch.id or command.response != original.model_dump(mode="json"): - raise TaskImportBatchError("task_import_batch_custody_invalid", 409) - return original - if batch.status == "committed": - original = await self._original_response(batch) - else: - original = await self._stage_rows(batch, parsed, prepared) - _stage_binding(batch, selected) - batch.authorization_decision_id, batch.status = str(decision_id), "committed" - batch.response, batch.committed_at = original.model_dump(mode="json"), datetime.now(UTC) - _stage_binding(command, selected) - command.batch_id, command.authorization_decision_id, command.status = batch.id, str(decision_id), "committed" - command.response, command.committed_at = original.model_dump(mode="json"), datetime.now(UTC) - await self._session.flush() - return original - - async def status(self, project_id: UUID, batch_id: UUID, *, request_id: UUID) -> TaskImportBatchStatus: - """Read only native ordered members, preserving original and current states separately.""" - async with self._session.begin(): - batch = await self._session.scalar(select(TaskImportBatch).where( - TaskImportBatch.id == str(batch_id), TaskImportBatch.project_id == str(project_id), - TaskImportBatch.status == "committed", - ).execution_options(populate_existing=True)) - if batch is None: - raise TaskImportBatchError("task_import_batch_not_found", 404) - binding = await self._source.prepare_binding(project_id, UUID(batch.source_id), _binding(batch)) - await self._source.authorize_binding(binding) - await self._authorization.authorize(TaskImportBatchAction.READ, self._facts( - batch, binding, request_id, canonical_json_hash({"project_id": str(project_id), "batch_id": str(batch_id)}), - )) - original = await self._original_response(batch) - rows = (await self._session.execute(select(TaskImportBatchMember.row_index, WorkstreamTask.id, WorkstreamTask.status) - .join(WorkstreamTask, (WorkstreamTask.id == TaskImportBatchMember.task_id) - & (WorkstreamTask.project_id == TaskImportBatchMember.project_id)) - .where(TaskImportBatchMember.batch_id == batch.id).order_by(TaskImportBatchMember.row_index))).all() - return TaskImportBatchStatus(creation=original, current_tasks=tuple( - TaskImportBatchCurrentTask(row_index=index, task_id=UUID(task_id), status=status) - for index, task_id, status in rows - )) diff --git a/backend/app/modules/tasks/task_import_membership.py b/backend/app/modules/tasks/task_import_membership.py deleted file mode 100644 index 280686c35..000000000 --- a/backend/app/modules/tasks/task_import_membership.py +++ /dev/null @@ -1,86 +0,0 @@ -"""One native membership validator shared by import/status and bulk transitions.""" - -from dataclasses import dataclass -from uuid import UUID - -from sqlalchemy import select -from sqlalchemy.ext.asyncio import AsyncSession - -from app.core.hashing import canonical_json_hash -from app.modules.tasks.api.task_import import TaskImportRow -from app.modules.tasks.api.task_import_membership import ( - TaskImportBatchError, TaskImportMemberIdentity, -) -from app.modules.tasks.models import TaskCommandReceipt, TaskImportBatch, TaskImportBatchMember -from app.modules.tasks.schemas import TaskImportBatchResponse - - -@dataclass(frozen=True, slots=True) -class TaskImportMembershipSnapshot: - """TASK-internal typed original response plus complete immutable member custody.""" - - creation: TaskImportBatchResponse - manifest_digest: str - members: tuple[TaskImportMemberIdentity, ...] - - -class TaskImportMembership: - """Read actual immutable rows; caller AUTH remains separate and mandatory.""" - - def __init__(self, session: AsyncSession): - self._session = session - - async def prepare(self, project_id: UUID, batch_id: UUID) -> TaskImportMembershipSnapshot: - """Select only a committed native batch in the existing caller transaction.""" - transaction = self._session.get_transaction() - if transaction is None or not transaction.is_active: - raise RuntimeError("task import membership requires the caller transaction") - batch = await self._session.scalar(select(TaskImportBatch).where( - TaskImportBatch.id == str(batch_id), TaskImportBatch.project_id == str(project_id), - TaskImportBatch.status == "committed", - ).with_for_update(read=True, key_share=True).execution_options(populate_existing=True)) - if batch is None: - raise TaskImportBatchError("task_import_batch_not_found", 404) - return await self.validate(batch) - - async def validate(self, batch: TaskImportBatch) -> TaskImportMembershipSnapshot: - """Recover immutable creation facts; mutable Task state is not replay input.""" - response = TaskImportBatchResponse.model_validate(batch.response) - if (str(response.batch_id), str(response.project_id), str(response.source_id), response.sha256, - response.byte_count, response.row_count, response.schema_version, response.mapping_version) != ( - batch.id, batch.project_id, batch.source_id, batch.sha256, batch.byte_count, batch.row_count, - batch.schema_version, batch.mapping_version, - ): - raise TaskImportBatchError("task_import_batch_custody_invalid", 409) - rows = (await self._session.execute(select(TaskImportBatchMember, TaskCommandReceipt).join( - TaskCommandReceipt, TaskCommandReceipt.id == TaskImportBatchMember.task_command_receipt_id, - ).where(TaskImportBatchMember.batch_id == batch.id).order_by(TaskImportBatchMember.row_index))).all() - if len(rows) != batch.row_count: - raise TaskImportBatchError("task_import_batch_custody_invalid", 409) - manifest = {"schema_version": response.schema_version, "metadata": {"label": response.label}, - "tasks": [{field: getattr(task, field) for field in TaskImportRow.model_fields} for task in response.tasks]} - if response.label != batch.metadata_label or canonical_json_hash(manifest) != batch.manifest_digest: - raise TaskImportBatchError("task_import_batch_custody_invalid", 409) - for index, (member, receipt) in enumerate(rows): - original = response.tasks[index] - instructions = {field: getattr(original, field) for field in TaskImportRow.model_fields} - if (member.row_index != index or member.project_id != batch.project_id or member.task_id != original.id - or member.external_task_id != original.external_task_id - or member.row_digest != canonical_json_hash(instructions) - or member.response != original.model_dump(mode="json") - or receipt.response != member.response or receipt.status != "committed" - or receipt.action_id != "project.task.create" or receipt.task_id != member.task_id - or receipt.actor_profile_id != batch.actor_profile_id - or receipt.idempotency_key != member.create_idempotency_key - or original.created_by != batch.actor_profile_id): - raise TaskImportBatchError("task_import_batch_custody_invalid", 409) - return TaskImportMembershipSnapshot( - creation=response, manifest_digest=batch.manifest_digest, - members=tuple(TaskImportMemberIdentity( - member_id=UUID(member.id), task_id=UUID(member.task_id), row_index=member.row_index, - external_task_id=member.external_task_id, row_digest=member.row_digest, - create_idempotency_key=member.create_idempotency_key, - task_command_receipt_id=member.task_command_receipt_id, - authorization_decision_id=UUID(member.authorization_decision_id), - ) for member, _ in rows), - ) diff --git a/backend/scripts/behavior_ownership.py b/backend/scripts/behavior_ownership.py index 2649b1e51..71e04345f 100644 --- a/backend/scripts/behavior_ownership.py +++ b/backend/scripts/behavior_ownership.py @@ -686,9 +686,6 @@ "backend/app/modules/artifacts/task_guide_documents.py", "backend/app/modules/tasks/api/guide_documents.py", }) -PILOT_10_PAGINATION_TARGETS = frozenset({ - "backend/app/modules/contributions/records/cursors.py", -}) PILOT_02A_IMPORT_SOURCE_TARGETS = frozenset({ "backend/app/modules/artifacts/api/task_import_source.py", "backend/app/api/routes/artifact_task_import_sources.py", @@ -697,18 +694,6 @@ "backend/app/modules/authorization/task_import_sources.py", "backend/app/modules/tasks/api/task_import.py", }) -PILOT_02B_ATOMIC_IMPORT_TARGETS = frozenset({ - "backend/app/modules/tasks/task_import_batches.py", - "backend/app/modules/tasks/task_import_membership.py", - "backend/app/modules/tasks/api/task_import_membership.py", -}) -PILOT_02C_BULK_TRANSITION_TARGETS = frozenset({ - "backend/app/api/deps/task_batch_transitions.py", - "backend/app/modules/tasks/api/task_batch_transition.py", - "backend/app/modules/tasks/task_batch_transition/models.py", - "backend/app/modules/tasks/task_batch_transition_router.py", - "backend/app/modules/tasks/task_batch_transitions.py", -}) class BehaviorOwnershipError(RuntimeError): @@ -960,9 +945,6 @@ def _validate_additive_partition_transition( | TASK_COMMAND_REPLAY_TARGETS | PILOT_13_GUIDE_READ_TARGETS | PILOT_02A_IMPORT_SOURCE_TARGETS - | PILOT_10_PAGINATION_TARGETS - | PILOT_02B_ATOMIC_IMPORT_TARGETS - | PILOT_02C_BULK_TRANSITION_TARGETS ) expected_additions = (approved_additions & additions) - set(trusted_targets) if POL_03A_DECLARATIVE_MODEL_TARGET in additions: diff --git a/backend/scripts/test_lane_catalogue.py b/backend/scripts/test_lane_catalogue.py index b3467ce10..d410ad64a 100644 --- a/backend/scripts/test_lane_catalogue.py +++ b/backend/scripts/test_lane_catalogue.py @@ -166,7 +166,6 @@ class TestLane: "tests/authorization/task_authority/test_lifecycle_races.py", "tests/authorization/task_authority/test_task_commands.py", "tests/authorization/task_authority/test_management_commands.py", - "tests/authorization/task_authority/test_management_participants.py", "tests/authorization/task_authority/test_management_concurrency.py", "tests/authorization/task_authority/test_management_authority.py", "tests/authorization/task_authority/test_management_contracts.py", @@ -261,15 +260,12 @@ class TestLane: PROJECT_MODULES = ( "tests/contributions/test_export_csv.py", "tests/contributions/test_export_projection.py", - "tests/contributions/test_export_cursors.py", - "tests/contributions/test_export_model_registry.py", "tests/authorization/test_contribution_read_scope.py", "tests/authorization/test_contribution_read_kernel.py", "tests/contributions/exports/test_source_reads.py", "tests/contributions/exports/test_public_reads.py", "tests/contributions/exports/test_failures.py", "tests/contributions/exports/test_concurrency.py", - "tests/contributions/exports/test_pagination.py", # Atomic submission composition shares the existing multi-owner project lanes; # task C and schema are close to their cap on the merged baseline. "tests/tasks/evaluation_delivery/test_custody.py", @@ -423,7 +419,6 @@ class TestLane: # Checker delivery shares project dispatch ownership and the existing # three-way partition; exclusive placement exceeded the hosted execution cap. CHECKER_DELIVERY_MODULES = ( - "tests/authorization/pre_submit/test_contracts.py", "tests/checkers/default/test_contract.py", "tests/checkers/default/test_execution.py", "tests/checkers/external/test_contracts.py", @@ -431,6 +426,7 @@ class TestLane: "tests/checkers/external/test_migration.py", "tests/checkers/external/test_postgresql.py", "tests/checkers/external/test_registry.py", + "tests/checkers/execution/test_results.py", "tests/checkers/external/test_policy.py", "tests/checkers/external/test_selected_post_submit.py", "tests/checkers/external/test_selected_pre_submit.py", @@ -452,12 +448,7 @@ class TestLane: TASK_MODULES = ( - "tests/tasks/test_task_batch_transition_contract.py", - "tests/tasks/test_task_batch_transitions.py", "tests/tasks/test_task_import_contract.py", - "tests/tasks/test_task_import_batch_contract.py", - "tests/tasks/test_task_import_batch_bindings.py", - "tests/tasks/test_task_import_batches.py", "tests/checkers/execution/test_completion_evidence.py", "tests/checkers/execution/test_completion_contract.py", "tests/tasks/post_submit_routing/test_remediation.py", diff --git a/backend/tests/authorization/catalogue_fixtures.py b/backend/tests/authorization/catalogue_fixtures.py index a9bdd2391..f1cb8b08f 100644 --- a/backend/tests/authorization/catalogue_fixtures.py +++ b/backend/tests/authorization/catalogue_fixtures.py @@ -307,8 +307,6 @@ "project.task.queue.read": ("project.task.manage", "WS-ARCH-001-03C4"), "operations.task.queue.read": ("operations.status.read", "WS-ARCH-001-03C4"), "project.task.create": ("project.task.manage", "WS-ARCH-001-03C3"), - "project.task.import": ("project.task.manage", "PILOT-02B"), - "project.task.import_batch.read": ("project.task.manage", "PILOT-02B"), "artifact.task_import_source.declare": ("project.task.manage", "PILOT-02A"), "artifact.task_import_source.upload": ("project.task.manage", "PILOT-02A"), "artifact.task_import_source.read": ("project.task.manage", "PILOT-02A"), @@ -494,8 +492,6 @@ "project.task.queue.read", "operations.task.queue.read", "project.task.create", - "project.task.import", - "project.task.import_batch.read", "artifact.task_import_source.declare", "artifact.task_import_source.upload", "artifact.task_import_source.read", diff --git a/backend/tests/authorization/task_authority/test_audit_contract.py b/backend/tests/authorization/task_authority/test_audit_contract.py index ca35a0364..e8f4679e3 100644 --- a/backend/tests/authorization/task_authority/test_audit_contract.py +++ b/backend/tests/authorization/task_authority/test_audit_contract.py @@ -21,18 +21,13 @@ from tests.test_audit import _authority_input -@pytest.mark.parametrize("action,resource_type", [ - (ActionId.ARTIFACT_TASK_IMPORT_SOURCE_DECLARE, "task_import_source"), - (ActionId.PROJECT_TASK_IMPORT, "task_import_batch"), - (ActionId.PROJECT_TASK_IMPORT_BATCH_READ, "task_import_batch"), -]) -def test_task_import_source_decision_and_exact_audit_target_are_closed(action, resource_type) -> None: +def test_task_import_source_decision_and_exact_audit_target_are_closed() -> None: source_id, project_id, grant_id = uuid4(), uuid4(), uuid4() digest = "sha256:" + "a" * 64 decision = AuthorizationDecision( - decision_id=uuid4(), action_id=action, + decision_id=uuid4(), action_id=ActionId.ARTIFACT_TASK_IMPORT_SOURCE_DECLARE, permission_id=PermissionId.PROJECT_TASK_MANAGE, allowed=True, denial_code=None, - resource_type=resource_type, resource_id=source_id, + resource_type="task_import_source", resource_id=source_id, resource_context_digest=digest, matched_authority_kind=MatchedAuthorityKind.ADMIN_ROLE_GRANT, matched_grant_id=grant_id, matched_scope_project_id=project_id, revalidated=True, request_id=uuid4(), correlation_id=uuid4(), @@ -47,7 +42,7 @@ def test_task_import_source_decision_and_exact_audit_target_are_closed(action, r after_facts={"allowed": True, "resource_context_digest": digest}, ) assert (event.resource_type, event.resource_id, event.target_ref_kind, event.target_ref_id) == ( - resource_type, str(source_id), resource_type, str(source_id), + "task_import_source", str(source_id), "task_import_source", str(source_id), ) with pytest.raises(ValidationError): AuthorizationDecision.model_validate(decision.model_dump() | {"resource_type": "unknown_source"}) diff --git a/backend/tests/authorization/task_authority/test_management_commands.py b/backend/tests/authorization/task_authority/test_management_commands.py index 3f3a5cc75..e88e9af44 100644 --- a/backend/tests/authorization/task_authority/test_management_commands.py +++ b/backend/tests/authorization/task_authority/test_management_commands.py @@ -64,47 +64,6 @@ async def test_create_draft_without_guide(task_client): assert UUID(event.event_payload["references"]["authorization_decision_id"]) -@pytest.mark.parametrize("phase", ["authorize", "stage"]) -async def test_creation_preparation_cannot_move_to_a_later_root(task_client, phase): - """Rolled-back preparation and ALLOW evidence cannot authorize another root.""" - from app.adapters.audit import task_transition_audit - from app.adapters.tasks import task_commands - from app.core.config import get_settings - from app.modules.authorization.task_authorization import PreparedTaskAuthorization - from app.modules.tasks.schemas import TaskCreate - from tests.authorization.task_authority.test_concurrency import actor_context - - project = await task_client.post("/api/v1/projects", headers=auth_headers(), - json={"name": "Preparation root", "slug": "create-root-" + uuid4().hex}) - assert project.status_code == 201, project.text - async with db_session.get_session_factory()() as observer: - from app.modules.actors.models import ActorIdentityLink - actor_id = await observer.scalar(select(ActorIdentityLink.actor_profile_id).where( - ActorIdentityLink.subject == "project-manager-subject", - )) - context = await actor_context(actor_id) - async with db_session.get_session_factory()() as session: - commands = task_commands(session, authorization=PreparedTaskAuthorization(session, context), - audit=task_transition_audit(session), actor_profile_id=context.actor_profile_id, - settings=get_settings()) - async with session.begin(): - prepared = await commands.prepare_creation(UUID(project.json()["id"]), TaskCreate(**complete_task_payload()), - idempotency_key=uuid4()) - decision = await commands.authorize_creation(prepared) - receipt_id = prepared.receipt.id - await session.rollback() - async with session.begin(): - with pytest.raises(RuntimeError, match="original caller transaction"): - if phase == "authorize": - await commands.authorize_creation(prepared) - else: - await commands.stage_creation(prepared, decision) - async with session.begin(): - assert await session.get(WorkstreamTask, str(prepared.task_id)) is None - assert await session.get(TaskCommandReceipt, receipt_id) is None - assert await session.get(AuditEvent, str(decision.decision_id)) is None - - async def test_screen_and_release_lock_approved_context(task_client): project = await create_active_project(task_client) task = await create_draft_task(task_client, project["id"]) diff --git a/backend/tests/authorization/task_authority/test_management_participants.py b/backend/tests/authorization/task_authority/test_management_participants.py deleted file mode 100644 index 9aeffaebc..000000000 --- a/backend/tests/authorization/task_authority/test_management_participants.py +++ /dev/null @@ -1,109 +0,0 @@ -"""Native canonical transitions compose and roll back in one caller-owned root.""" - -from uuid import UUID, uuid4 - -import pytest -from sqlalchemy import select - -from app.adapters.audit import task_transition_audit -from app.adapters.tasks import task_commands -from app.core.config import get_settings -from app.db import session as db_session -from app.modules.actors.models import ActorIdentityLink -from app.modules.authorization.task_authorization import PreparedTaskAuthorization -from app.modules.tasks.api.authorization import TaskAuthorityOperation -from app.modules.tasks.models import AuditEvent, TaskCommandReceipt, WorkstreamTask -from tests.authorization.task_authority.test_concurrency import actor_context -from tests.test_tasks import ( - task_database_env as task_database_env, - task_client as task_client, - create_active_project, - create_draft_task, -) - - -async def manager_context(): - async with db_session.get_session_factory()() as session: - actor_id = await session.scalar(select(ActorIdentityLink.actor_profile_id).where( - ActorIdentityLink.subject == "project-manager-subject", - )) - return await actor_context(actor_id) - - -def commands(session, context): - return task_commands( - session, authorization=PreparedTaskAuthorization(session, context), - audit=task_transition_audit(session), actor_profile_id=context.actor_profile_id, - settings=get_settings(), - ) - - -@pytest.mark.parametrize("phase", ["authorize", "stage"]) -async def test_transition_preparation_cannot_cross_roots(task_client, phase): - project = await create_active_project(task_client) - task = await create_draft_task(task_client, project["id"]) - context = await manager_context() - async with db_session.get_session_factory()() as session: - owner = commands(session, context) - async with session.begin(): - prepared = await owner.prepare_transition( - UUID(task["id"]), TaskAuthorityOperation.SCREEN, "Canonical screening", - idempotency_key=uuid4(), project_id=UUID(project["id"]), - ) - decision = await owner.authorize_transition(prepared) - receipt_id = prepared.receipt.id - await session.rollback() - async with session.begin(): - with pytest.raises(RuntimeError, match="original caller transaction"): - if phase == "authorize": - await owner.authorize_transition(prepared) - else: - await owner.stage_transition(prepared, decision) - async with session.begin(): - assert await session.get(TaskCommandReceipt, receipt_id) is None - assert await session.get(AuditEvent, str(decision.decision_id)) is None - current = await session.get(WorkstreamTask, task["id"]) - assert current.status == "draft" and current.locked_guide_version is None - - -async def test_two_task_transition_late_failure_rolls_back_complete_root(task_client, monkeypatch): - project = await create_active_project(task_client) - tasks = [await create_draft_task(task_client, project["id"]) for _ in range(2)] - context = await manager_context() - async with db_session.get_session_factory()() as session: - owner = commands(session, context) - original = owner._record_management - observed = [] - - async def fail_after_second_audit(*args, **kwargs): - await original(*args, **kwargs) - observed.append(args[0].id) - if len(observed) == 2: - raise RuntimeError("second canonical transition staged") - - monkeypatch.setattr(owner, "_record_management", fail_after_second_audit) - with pytest.raises(RuntimeError, match="second canonical transition staged"): - async with session.begin(): - prepared = [await owner.prepare_transition( - UUID(task["id"]), TaskAuthorityOperation.SCREEN, "Complete batch", - idempotency_key=uuid4(), project_id=UUID(project["id"]), - ) for task in sorted(tasks, key=lambda value: UUID(value["id"]).int)] - decisions = [await owner.authorize_transition(value) for value in prepared] - receipt_ids = [value.receipt.id for value in prepared] - for value, decision in zip(prepared, decisions, strict=True): - await owner.stage_transition(value, decision) - assert observed == [task["id"] for task in sorted(tasks, key=lambda value: UUID(value["id"]).int)] - async with session.begin(): - for value in tasks: - current = await session.get(WorkstreamTask, value["id"], populate_existing=True) - assert current.status == "draft" and current.locked_guide_version is None - assert not list(await session.scalars(select(TaskCommandReceipt.id).where( - TaskCommandReceipt.id.in_(receipt_ids), - ))) - assert not list(await session.scalars(select(AuditEvent.id).where( - AuditEvent.id.in_([str(value.decision_id) for value in decisions]), - ))) - assert not list(await session.scalars(select(AuditEvent.id).where( - AuditEvent.entity_id.in_([value["id"] for value in tasks]), - AuditEvent.event_type == "TaskScreened", - ))) diff --git a/backend/tests/authorization/test_catalogue.py b/backend/tests/authorization/test_catalogue.py index bfcb0dc7c..56c131de2 100644 --- a/backend/tests/authorization/test_catalogue.py +++ b/backend/tests/authorization/test_catalogue.py @@ -26,7 +26,7 @@ def test_closed_permission_and_action_catalogue_is_exact_and_non_executable() -> assert {item.value for item in HISTORICAL_PERMISSION_IDS} == historical_permissions assert {item.value for item in NEW_PERMISSION_IDS} == new_permissions assert {item.value for item in PERMISSION_IDS} == historical_permissions | new_permissions - assert len(ACTION_IDS) == len(ACTION_DEFINITIONS) == len(ACTION_BY_ID) == 154 + assert len(ACTION_IDS) == len(ACTION_DEFINITIONS) == len(ACTION_BY_ID) == 152 assert set(ACTION_BY_ID) == ACTION_IDS assert {definition.owner for definition in ACTION_DEFINITIONS} == set(ActionOwner) assert { @@ -105,7 +105,7 @@ def test_closed_permission_and_action_catalogue_is_exact_and_non_executable() -> } assert all(not owner.value.startswith("WS-REV-") for owner in ActionOwner) assert Counter(definition.availability for definition in ACTION_DEFINITIONS) == { - ActionAvailability.ACTIVE: 118, + ActionAvailability.ACTIVE: 116, ActionAvailability.PLANNED: 36, } assert resolve_executable_action(ActionId.ACTOR_PROFILE_READ_SELF).permission_id is PermissionId.ACTOR_PROFILE_READ_SELF diff --git a/backend/tests/conftest.py b/backend/tests/conftest.py index d35f3f15b..0a9968644 100644 --- a/backend/tests/conftest.py +++ b/backend/tests/conftest.py @@ -113,8 +113,6 @@ "review_admission_idempotency_records", "final_acceptances", "contribution_records", - "contribution_export_members", - "contribution_export_memberships", "compensation_awards", "reviews", "review_findings", @@ -133,11 +131,6 @@ "submission_bundle_durable_intents", "submissions", "task_assignments", - "task_import_batch_command_receipts", - "task_import_batch_members", - "task_import_batches", - "task_batch_transition_members", - "task_batch_transition_receipts", "task_command_receipts", "task_post_submit_routing_manifests", "task_post_submit_routing_requests", @@ -154,11 +147,6 @@ "checker_submission_fences", "checker_results", "task_command_receipts", - "task_import_batch_command_receipts", - "task_import_batch_members", - "task_import_batches", - "task_batch_transition_members", - "task_batch_transition_receipts", "task_post_submit_routing_manifests", "task_post_submit_routing_requests", "checker_policies", @@ -169,8 +157,6 @@ "compensation_adapter_binding_lifecycle_events", "contribution_policy_lifecycle_events", "contribution_policy_transition_custody", - "contribution_export_members", - "contribution_export_memberships", "guide_mutation_idempotency_records", "guide_sufficiency_reports", "guide_sufficiency_report_source_usages", diff --git a/backend/tests/contributions/exports/test_pagination.py b/backend/tests/contributions/exports/test_pagination.py deleted file mode 100644 index 43778abb7..000000000 --- a/backend/tests/contributions/exports/test_pagination.py +++ /dev/null @@ -1,242 +0,0 @@ -"""Real public pages freeze visible membership and reauthorize continuation.""" - -import asyncio -import csv - -import pytest -from io import StringIO - -from sqlalchemy import func, select, text -from sqlalchemy.exc import IntegrityError - -from app.core.identifiers import new_record_id -from app.modules.contributions.records.models import ContributionExportMembership, ContributionExportMember -from app.modules.authorization.repository import AdminAuthorizationRepository -from tests.contributions.records.support import authorized_submitter_source, rows -from tests.tasks.post_submit_routing.support import completed_sibling_source -from tests.tasks.post_submit_routing.outcome_support import apply_outcome, invoked_completion -from .support import export_path - - -async def sibling_ready(h): - """Use real Submission/checker completion and authorized acceptance inputs.""" - sibling = await completed_sibling_source(h) - async with h.factory() as session, session.begin(): - await session.execute(text( - "UPDATE public.task_assignments SET accepted_at=clock_timestamp() " - "WHERE id=:id AND accepted_at IS NULL" - ), {"id": sibling.request.assignment_id}) - sibling.envelope = await invoked_completion(sibling) - return sibling - - -async def test_public_pages_exclude_pre_snapshot_uncommitted_record_after_it_commits( - tmp_path, auth_database_env, admin_access, live_acceptance_lifecycle, monkeypatch, -): - async with authorized_submitter_source(tmp_path, auth_database_env, paid=True) as h: - signed_access = admin_access.signed - reader = admin_access.target - path = export_path(h.submitter_record.project_id) - grant = await signed_access.grant(admin_access.admin, reader, role="project_manager", - project_id=h.submitter_record.project_id) - second = await sibling_ready(h) - async with h.factory() as session, session.begin(): - second_outcome = await apply_outcome(session, second, 2) - late = await sibling_ready(h) - established, proceed = asyncio.Event(), asyncio.Event() - original = AdminAuthorizationRepository.lock_project - name = "pilot10-fixed-membership-first" - - async def before_project_lock(repository, project_id): - if asyncio.current_task().get_name() == name: - assert await repository._session.scalar(text("SHOW transaction_isolation")) == "repeatable read" - established.set() - await proceed.wait() - return await original(repository, project_id) - - # Use project read so the existing AUTH locks establish the RR snapshot - # before waiting for the producer's project lock. The producer already - # inserted its real record before the first export starts. - monkeypatch.setattr(AdminAuthorizationRepository, "lock_project", before_project_lock) - async with h.factory() as producer: - await producer.begin() - late_outcome = await apply_outcome(producer, late, 2) - task = asyncio.create_task(signed_access.client.get( - path, params={"page_size": 1}, headers=reader.headers, - ), name=name) - try: - await asyncio.wait_for(established.wait(), 30) - await producer.commit() - proceed.set() - first = await asyncio.wait_for(task, 30) - finally: - proceed.set() - if not task.done(): - task.cancel() - await asyncio.gather(task, return_exceptions=True) - assert first.status_code == 200, first.text - export_id, retained_facts = await _assert_membership_guards(h, reader, late_outcome) - cursor, ids = await _assert_cursor_membership( - h, admin_access, reader, path, first, second_outcome, late_outcome, - ) - await _assert_expired_cleanup_and_csv( - h, reader, path, signed_access, export_id, retained_facts, ids, late_outcome, - ) - revoked = await signed_access.client.post( - f"/api/v1/admin-role-grants/{grant}/revoke", - headers=admin_access.admin.headers | {"Idempotency-Key": str(new_record_id())}, - json={"reason": "Reauthorize every contribution continuation"}, - ) - assert revoked.status_code == 200, revoked.text - denied = await signed_access.client.get( - path, params={"page_size": 1, "cursor": cursor}, headers=reader.headers, - ) - assert denied.status_code == 404, denied.text - - -async def _assert_membership_guards(h, reader, late_outcome): - """Protect sealed membership and refuse incomplete private exports.""" - # The installed guards must protect the original selection even when a - # later real contribution now exists and would match the same query. - async with h.factory() as session: - membership = await session.scalar(select(ContributionExportMembership).where( - ContributionExportMembership.actor_profile_id == str(reader.id), - ContributionExportMembership.project_id == h.submitter_record.project_id, - ContributionExportMembership.page_size == 1, - ).order_by(ContributionExportMembership.exported_at.desc()).limit(1)) - assert membership is not None and membership.sealed and membership.member_count == 2 - export_id = membership.id - retained_facts = {table: await rows(session, table) for table in ( - "contribution_records", "compensation_awards", "final_acceptances", - )} - assert await session.scalar(select(func.count()).select_from(ContributionExportMember).where( - ContributionExportMember.export_id == export_id, - )) == 2 - for statement, parameters in ( - ("UPDATE contribution_export_memberships SET page_size=2 WHERE id=:export", {}), - ("DELETE FROM contribution_export_memberships WHERE id=:export", {}), - ("UPDATE contribution_export_members SET recorded_at=recorded_at + interval '1 second' " - "WHERE export_id=:export", {}), - ("DELETE FROM contribution_export_members WHERE export_id=:export", {}), - ("INSERT INTO contribution_export_members (export_id, contribution_id, recorded_at) " - "SELECT :export, id, created_at FROM contribution_records WHERE id=:late", - {"late": late_outcome.economic.contribution_record_id}), - ): - async with h.factory() as session: - with pytest.raises(IntegrityError) as rejected: - async with session.begin(): - await session.execute(text(statement), {"export": export_id} | parameters) - assert rejected.value.orig.sqlstate == "23514" - async with h.factory() as session: - assert await session.scalar(select(func.count()).select_from(ContributionExportMember).where( - ContributionExportMember.export_id == export_id, - )) == 2 - async with h.factory() as session: - await session.begin() - await session.execute(text( - "INSERT INTO contribution_export_memberships " - "(id, actor_profile_id, audience, project_id, output_format, page_size, " - "contribution_type, recorded_from, recorded_before, member_count, sealed, " - "query_digest, exported_at, expires_at) " - "SELECT :new, actor_profile_id, audience, project_id, output_format, page_size, " - "contribution_type, recorded_from, recorded_before, 3, false, " - "query_digest, exported_at, expires_at " - "FROM contribution_export_memberships WHERE id=:export" - ), {"new": new_record_id(), "export": export_id}) - with pytest.raises(IntegrityError) as unsealed: - await session.commit() - assert unsealed.value.orig.sqlstate == "23514" - await session.rollback() - return export_id, retained_facts - - -async def _assert_cursor_membership(h, admin_access, reader, path, first, second_outcome, late_outcome): - """Bind continuations to query, authority and original visible records.""" - signed_access = admin_access.signed - cursor = first.json()["next_cursor"] - assert cursor is not None - for changed in ({"page_size": 2}, {"format": "csv"}, {"contribution_type": "completed_review"}): - invalid = await signed_access.client.get( - path, params={"page_size": 1, "cursor": cursor} | changed, headers=reader.headers, - ) - assert invalid.status_code == 422, invalid.text - assert invalid.json()["error"]["code"] == "contribution_export_invalid_cursor" - other = await signed_access.actor("other-membership-reader") - await signed_access.grant(admin_access.admin, other, role="project_manager", - project_id=h.submitter_record.project_id) - crossed = await signed_access.client.get( - path, params={"page_size": 1, "cursor": cursor}, headers=other.headers, - ) - assert crossed.status_code == 422, crossed.text - ungranted = await signed_access.actor("ungranted-membership-reader") - concealed = await signed_access.client.get( - path, params={"page_size": 1, "cursor": cursor}, headers=ungranted.headers, - ) - assert concealed.status_code == 404, concealed.text - next_page = await signed_access.client.get( - path, params={"page_size": 1, "cursor": cursor}, headers=reader.headers, - ) - assert next_page.status_code == 200, next_page.text - assert next_page.json()["next_cursor"] is None - assert next_page.json()["exported_at"] == first.json()["exported_at"] - ids = [row["contribution_id"] for page in (first, next_page) for row in page.json()["items"]] - assert set(ids) == {str(h.submitter_record.id), str(second_outcome.economic.contribution_record_id)} - assert str(late_outcome.economic.contribution_record_id) not in ids - assert all(len(row["awards"]) == 2 for page in (first, next_page) for row in page.json()["items"]) - return cursor, ids - - -async def _assert_expired_cleanup_and_csv(h, reader, path, signed_access, export_id, retained_facts, ids, late_outcome): - """Clean expired selections without changing facts and preserve CSV pages.""" - # Construct only private expiry metadata around the same real immutable - # facts; no economic row or clock is changed. The next public first page - # must remove this nonempty expired selection through its native cascade. - expired_id = new_record_id() - async with h.factory() as session, session.begin(): - await session.execute(text( - "INSERT INTO contribution_export_memberships " - "(id, actor_profile_id, audience, project_id, output_format, page_size, " - "contribution_type, recorded_from, recorded_before, member_count, sealed, " - "query_digest, exported_at, expires_at) " - "SELECT :new, actor_profile_id, audience, project_id, output_format, page_size, " - "contribution_type, recorded_from, recorded_before, 3, false, query_digest, " - "exported_at - interval '16 minutes', expires_at - interval '16 minutes' " - "FROM contribution_export_memberships WHERE id=:export" - ), {"new": expired_id, "export": export_id}) - await session.execute(text( - "INSERT INTO contribution_export_members (export_id, contribution_id, recorded_at) " - "SELECT :export, id, created_at FROM contribution_records WHERE project_id=:project" - ), {"export": expired_id, "project": h.submitter_record.project_id}) - await session.execute(text( - "UPDATE contribution_export_memberships SET sealed=true WHERE id=:export" - ), {"export": expired_id}) - fresh = await signed_access.client.get(path, headers=reader.headers) - assert fresh.status_code == 200 - async with h.factory() as session: - assert await session.get(ContributionExportMembership, expired_id) is None - assert {table: await rows(session, table) for table in retained_facts} == retained_facts - assert await session.scalar(select(func.count()).select_from(ContributionExportMember).where( - ContributionExportMember.export_id == expired_id, - )) == 0 - assert {row["contribution_id"] for row in fresh.json()["items"]} == set(ids) | { - str(late_outcome.economic.contribution_record_id), - } - csv_rows, csv_origin, csv_cursor = [], None, None - for page_number in range(3): - params = {"page_size": 1, "format": "csv"} - if csv_cursor is not None: - params["cursor"] = csv_cursor - csv_page = await signed_access.client.get(path, params=params, headers=reader.headers) - assert csv_page.status_code == 200, csv_page.text - if csv_origin is None: - csv_origin = csv_page.headers["X-Workstream-Exported-At"] - assert csv_page.headers["X-Workstream-Exported-At"] == csv_origin - csv_rows.extend(csv.DictReader(StringIO(csv_page.text, newline=""))) - csv_cursor = csv_page.headers.get("X-Workstream-Next-Cursor") - assert (csv_cursor is None) is (page_number == 2) - assert {row["contribution_id"] for row in csv_rows} == { - row["contribution_id"] for row in fresh.json()["items"] - } - assert len(csv_rows) == 6 - async with h.factory() as session: - assert await session.scalar(select(func.count()).select_from(ContributionExportMembership)) >= 2 diff --git a/backend/tests/contributions/exports/test_source_reads.py b/backend/tests/contributions/exports/test_source_reads.py index 19f90647c..41839ed3a 100644 --- a/backend/tests/contributions/exports/test_source_reads.py +++ b/backend/tests/contributions/exports/test_source_reads.py @@ -21,11 +21,9 @@ async def test_projection_reads_actual_immutable_source_and_complete_awards( await session.connection(execution_options={"isolation_level": "REPEATABLE READ"}) before = {table: await rows(session, table) for table in ("contribution_records", "compensation_awards", "final_acceptances")} - page = await ContributionReadRepository(session, cursor_codec=None).read(ContributionReadRequest( + record, = await ContributionReadRepository(session).read(ContributionReadRequest( audience="self", actor_profile_id=h.actor_context.actor_profile_id, )) - record, = page.records - assert page.next_cursor is None assert record.id == h.submitter_record.id assert record.source_final_acceptance_id == h.acceptance.id assert {definition.instrument for definition in record.award_definitions} == set(instruments) diff --git a/backend/tests/contributions/test_export_cursors.py b/backend/tests/contributions/test_export_cursors.py deleted file mode 100644 index 9d7a9b1be..000000000 --- a/backend/tests/contributions/test_export_cursors.py +++ /dev/null @@ -1,94 +0,0 @@ -"""Continuation cannot expand actor/query scope or outlive one export.""" - -import base64 -from datetime import UTC, datetime, timedelta -import json - -import pytest - -from app.core.identifiers import new_record_id -from app.modules.contributions.api.records import ContributionReadRequest -from app.modules.contributions.records.cursors import ( - ContributionCursor, ContributionCursorCodec, InvalidContributionCursor, contribution_query_digest, -) - -NOW = datetime(2026, 10, 11, 16, tzinfo=UTC) -SECRET = b"a" * 32 - - -def selected(): - return ContributionReadRequest(audience="self", actor_profile_id=new_record_id()) - - -def state(): - return ContributionCursor(new_record_id(), NOW, NOW + timedelta(minutes=15), - NOW - timedelta(days=1), new_record_id()) - - -def test_cursor_roundtrip_retains_exact_membership_position_and_scope(): - codec, request, position = ContributionCursorCodec(SECRET), selected(), state() - digest = contribution_query_digest(request) - token = codec.encode(position, query_digest=digest) - assert len(token) < 4096 - assert codec.decode(token, query_digest=digest, now=NOW) == position - assert contribution_query_digest(request.model_copy(update={"cursor": token})) == digest - - -@pytest.mark.parametrize("field,value", [ - ("actor_profile_id", new_record_id()), ("audience", "project"), - ("project_id", new_record_id()), ("output_format", "csv"), ("page_size", 1), - ("contribution_type", "completed_review"), ("recorded_from", NOW), - ("recorded_before", NOW), -]) -def test_cursor_cannot_cross_actor_audience_filters_or_output(field, value): - codec, request = ContributionCursorCodec(SECRET), selected() - token = codec.encode(state(), query_digest=contribution_query_digest(request)) - other = request.model_copy(update={field: value}) - with pytest.raises(InvalidContributionCursor): - codec.decode(token, query_digest=contribution_query_digest(other), now=NOW) - - -@pytest.mark.parametrize("elapsed", [-1, 900, 901]) -def test_cursor_rejects_future_origin_or_expiry(elapsed): - codec, request = ContributionCursorCodec(SECRET), selected() - digest = contribution_query_digest(request) - token = codec.encode(state(), query_digest=digest) - with pytest.raises(InvalidContributionCursor): - codec.decode(token, query_digest=digest, now=NOW + timedelta(seconds=elapsed)) - - -@pytest.mark.parametrize("mutation", ["payload", "signature", "duplicate", "extra", "boolean_version"]) -def test_forged_envelopes_are_refused_without_echoing_input(mutation): - codec, request = ContributionCursorCodec(SECRET), selected() - digest = contribution_query_digest(request) - token = codec.encode(state(), query_digest=digest) - envelope = json.loads(base64.urlsafe_b64decode(token + "=" * (-len(token) % 4))) - if mutation == "payload": - envelope["p"]["export"] = str(new_record_id()) - elif mutation == "signature": - envelope["s"] = "A" * 43 - elif mutation == "extra": - envelope["extra"] = True - elif mutation == "boolean_version": - envelope["p"]["v"] = True - raw = json.dumps(envelope) - if mutation == "duplicate": - raw = raw.replace('"v": 1', '"v": 1, "v": 1') - forged = base64.urlsafe_b64encode(raw.encode()).decode().rstrip("=") - with pytest.raises(InvalidContributionCursor) as error: - codec.decode(forged, query_digest=digest, now=NOW) - assert str(error.value) == "Invalid contribution export cursor" - - -@pytest.mark.parametrize("value", ["", "x" * 4097, "abc=", "abc.def", "abc\n", "💰", "a"]) -def test_malformed_or_unbounded_cursor_is_refused(value): - with pytest.raises(InvalidContributionCursor): - ContributionCursorCodec(SECRET).decode(value, query_digest="irrelevant", now=NOW) - - -def test_signing_key_rotation_refuses_old_cursor(): - request = selected() - digest = contribution_query_digest(request) - token = ContributionCursorCodec(SECRET).encode(state(), query_digest=digest) - with pytest.raises(InvalidContributionCursor): - ContributionCursorCodec(b"b" * 32).decode(token, query_digest=digest, now=NOW) diff --git a/backend/tests/contributions/test_export_model_registry.py b/backend/tests/contributions/test_export_model_registry.py deleted file mode 100644 index 01e957de5..000000000 --- a/backend/tests/contributions/test_export_model_registry.py +++ /dev/null @@ -1,26 +0,0 @@ -"""Canonical-only process discovery must include private export membership custody.""" - -from pathlib import Path -import subprocess -import sys - - -def test_export_membership_is_registered_without_loading_its_read_repository(): - code = ''' -import sys -import app.db.models -from app.db.base import Base -from sqlalchemy.schema import CreateTable -from sqlalchemy.dialects.postgresql import dialect -assert "app.modules.contributions.records.read_repository" not in sys.modules -for name in ("contribution_export_memberships", "contribution_export_members"): - assert name in Base.metadata.tables, name - table = Base.metadata.tables[name] - assert table.foreign_keys - for foreign_key in table.foreign_keys: - assert foreign_key.column is not None - assert str(CreateTable(table).compile(dialect=dialect())) -''' - result = subprocess.run([sys.executable, "-c", code], cwd=Path(__file__).resolve().parents[2], - capture_output=True, text=True, timeout=60) - assert result.returncode == 0, result.stdout + result.stderr diff --git a/backend/tests/contributions/test_export_projection.py b/backend/tests/contributions/test_export_projection.py index 991f0a947..d0a9e26a8 100644 --- a/backend/tests/contributions/test_export_projection.py +++ b/backend/tests/contributions/test_export_projection.py @@ -11,9 +11,9 @@ from app.modules.compensation.api.awards import CompensationAwardFacts from app.modules.compensation.api.instruments import CompensationInstrumentType from app.modules.contributions.api.records import ( - ContributionExportTooLarge, ContributionExportUnavailable, ContributionReadRequest, InvalidContributionCursor, + ContributionExportTooLarge, ContributionExportUnavailable, ContributionReadRequest, ) -from app.modules.contributions.records.read_facts import ContributionReadFacts, ContributionReadPage, FrozenContributionAward +from app.modules.contributions.records.read_facts import ContributionReadFacts, FrozenContributionAward from app.modules.contributions.records.read_service import ContributionReadService from app.modules.contributions.api.source_reads import ( ContributionAcceptanceSourceFacts, ContributionTaskSourceFacts, @@ -64,7 +64,7 @@ async def authorize(self, request): async def read(self, request): assert self.authorized, "owner load preceded authority" - return ContributionReadPage(records=(self.value.record,), exported_at=TIME) + return (self.value.record,) async def read_contribution_awards(self, selected): assert selected == (self.value.record.id,) @@ -158,15 +158,13 @@ async def test_faulty_over_limit_loader_cannot_start_owner_projections(): class OverLimit(Ports): async def read(self, request): assert self.authorized - return ContributionReadPage(records=(self.value.record,), exported_at=TIME).model_copy( - update={"records": tuple(self.value.record.model_copy(update={"id": new_record_id()}) - for _ in range(1001))}, - ) + return tuple(self.value.record.model_copy(update={"id": new_record_id()}) + for _ in range(1001)) async def read_contribution_awards(self, selected): pytest.fail("over-limit loader started owner projections") - with pytest.raises(ContributionExportUnavailable): + with pytest.raises(ContributionExportTooLarge): await service(OverLimit(value)).read(request(value)) @@ -225,47 +223,3 @@ async def test_human_acceptance_review_reference_does_not_replace_contribution_s assert item.acceptance_review_id == review_id assert item.source_review_id is item.source_review_lease_id is None assert item.source_final_acceptance_id == value.acceptance.id - - -async def test_projection_preserves_original_export_time_and_next_cursor(): - value = facts() - - class Continued(Ports): - async def read(self, request): - assert self.authorized - return ContributionReadPage(records=(self.value.record,), exported_at=TIME, - next_cursor="signed_continuation") - - response = await service(Continued(value)).read(request(value)) - assert response.exported_at == TIME - assert response.next_cursor == "signed_continuation" - - -async def test_page_size_refusal_precedes_loading_other_owners(): - value = facts() - - class FaultyPage(Ports): - async def read(self, request): - assert self.authorized - return ContributionReadPage(records=(self.value.record, self.value.record), exported_at=TIME) - - async def read_contribution_awards(self, selected): - pytest.fail("faulty oversized page loaded other owner facts") - - with pytest.raises(ContributionExportUnavailable): - await service(FaultyPage(value)).read(request(value).model_copy(update={"page_size": 1})) - - -async def test_invalid_cursor_refusal_reaches_public_boundary_without_owner_projections(): - value = facts() - - class InvalidCursor(Ports): - async def read(self, request): - assert self.authorized - raise InvalidContributionCursor("Invalid contribution export cursor") - - async def read_contribution_awards(self, selected): - pytest.fail("invalid cursor loaded award evidence") - - with pytest.raises(InvalidContributionCursor): - await service(InvalidCursor(value)).read(request(value)) diff --git a/backend/tests/tasks/test_task_batch_transition_contract.py b/backend/tests/tasks/test_task_batch_transition_contract.py deleted file mode 100644 index 2a19640b0..000000000 --- a/backend/tests/tasks/test_task_batch_transition_contract.py +++ /dev/null @@ -1,136 +0,0 @@ -"""Compact batch contracts reject partial and substituted ordered success facts.""" - -from pathlib import Path -import subprocess -import sys -from uuid import uuid4 - -import pytest -from pydantic import ValidationError - -from app.modules.tasks.api.task_batch_transition import ( - TaskBatchTransitionRequest, - TaskBatchTransitionResponse, -) -from app.modules.tasks.service import TaskValidationError -from app.modules.tasks.task_batch_transitions import TaskBatchTransitionCommands - - -def response_value(count=2): - """Use different Task identities with the same legitimate locked guide version.""" - return { - "project_id": str(uuid4()), - "batch_id": str(uuid4()), - "operation": "screen", - "row_count": count, - "tasks": [ - { - "task_id": str(uuid4()), - "row_index": index, - "status": "screening", - "locked_guide_version": "v1.0.0", - "locked_contribution_policy_version_id": str(uuid4()), - "locked_context_hash": "sha256:" + "a" * 64, - } - for index in range(count) - ], - } - - -def test_response_preserves_complete_500_row_order_and_string_guide_versions(): - value = response_value(500) - response = TaskBatchTransitionResponse.model_validate(value) - assert response.model_dump(mode="json") == value - assert TaskBatchTransitionResponse.model_validate_json(response.model_dump_json()) == response - - -@pytest.mark.parametrize( - "change", - ["missing", "reordered", "duplicate", "foreign_status", "bad_hash", "unlocked", "extra"], -) -def test_incomplete_or_substituted_success_is_refused(change): - value = response_value() - if change == "missing": - value["tasks"].pop() - elif change == "reordered": - value["tasks"].reverse() - elif change == "duplicate": - value["tasks"][1]["task_id"] = value["tasks"][0]["task_id"] - elif change == "foreign_status": - value["tasks"][1]["status"] = "ready" - elif change == "bad_hash": - value["tasks"][1]["locked_context_hash"] = "unverified" - elif change == "unlocked": - value["tasks"][1]["locked_guide_version"] = None - else: - value["tasks"][1]["instructions"] = "private DTO" - with pytest.raises(ValidationError): - TaskBatchTransitionResponse.model_validate(value) - - -@pytest.mark.parametrize("count", [0, 501]) -def test_public_row_bounds_are_explicit(count): - with pytest.raises(ValidationError): - TaskBatchTransitionResponse.model_validate(response_value(count)) - - -def test_release_and_reason_contracts_are_separate_from_screen(): - value = response_value() - value["operation"] = "release" - for task in value["tasks"]: - task["status"] = "ready" - assert TaskBatchTransitionResponse.model_validate(value).operation == "release" - assert TaskBatchTransitionRequest(reason="Decision\nwith Unicode café").reason.endswith("café") - with pytest.raises(ValidationError): - TaskBatchTransitionRequest(reason="x" * 4001) - with pytest.raises(ValidationError): - TaskBatchTransitionRequest.model_validate({"task_ids": [str(uuid4())]}) - - -@pytest.mark.parametrize("reason", [None, "", " \n"]) -async def test_release_reason_is_refused_before_any_transaction_or_authority(reason): - """Admission must reject incomplete input without accessing a session or Task port.""" - owner = TaskBatchTransitionCommands( - None, actor_profile_id=uuid4(), identity_link_id=uuid4(), tasks=None - ) - with pytest.raises(TaskValidationError, match="release decision reason is required"): - await owner.release(uuid4(), uuid4(), reason, idempotency_key=uuid4()) - - -def test_canonical_model_graph_resolves_bulk_receipt_foreign_keys_in_fresh_process(): - """Runtime/Alembic registration must work without importing the bulk caller first.""" - result = subprocess.run( - [ - sys.executable, - "-c", - """ -import sys -assert not any(name.startswith('app.') for name in sys.modules) -import app.db.models -from app.db.base import Base -from sqlalchemy.dialects.postgresql import dialect -from sqlalchemy.schema import CreateTable - -tables = Base.metadata.tables -receipt = tables['task_command_receipts'] -root = tables['task_batch_transition_receipts'] -member = tables['task_batch_transition_members'] -assert next(iter(receipt.c.batch_transition_receipt_id.foreign_keys)).column is root.c.id -assert next(iter(member.c.transition_receipt_id.foreign_keys)).column is root.c.id -for table in tables.values(): - for foreign_key in table.foreign_keys: - assert foreign_key.column.table.key in tables -for table in (receipt, root, member): - ddl = str(CreateTable(table).compile(dialect=dialect())) - assert 'CREATE TABLE ' + table.name in ddl -print('canonical graph and aggregate receipt FK compilation passed') -""", - ], - cwd=Path(__file__).resolve().parents[2], - capture_output=True, - text=True, - timeout=30, - check=False, - ) - assert result.returncode == 0, result.stdout + result.stderr - assert result.stdout.strip() == "canonical graph and aggregate receipt FK compilation passed" diff --git a/backend/tests/tasks/test_task_batch_transitions.py b/backend/tests/tasks/test_task_batch_transitions.py deleted file mode 100644 index 471db584c..000000000 --- a/backend/tests/tasks/test_task_batch_transitions.py +++ /dev/null @@ -1,367 +0,0 @@ -"""Public complete-member transitions with actual PostgreSQL, AUTH and source bytes.""" - -import asyncio -import time -from datetime import UTC, datetime -from uuid import UUID, uuid4 - -import pytest -from sqlalchemy import event, func, select, text -from sqlalchemy.exc import DBAPIError -from sqlalchemy.orm import Session - -from app.core.hashing import canonical_json_hash -from app.core.identifiers import new_record_id -from app.db import session as db_session -from app.modules.actors.models import ActorIdentityLink -from app.modules.authorization.models import AdminRoleGrant -from app.modules.authorization.runtime import ActorKind, ActorStatus, HumanAuthorizationContext, IdentityLinkStatus -from app.modules.tasks.authorized_commands import AuthorizedTaskCommands -from app.modules.tasks.models import AuditEvent, TaskCommandReceipt, WorkstreamTask -from app.modules.tasks.service import TaskValidationError -from app.modules.tasks.task_batch_transition.models import TaskBatchTransitionMember, TaskBatchTransitionReceipt -from app.modules.tasks.task_batch_transitions import TaskBatchTransitionCommands -from app.modules.tasks.task_batch_transitions import _membership_digest -from app.modules.tasks.task_import_membership import TaskImportMembership -from tests.authorization.guide_activation.pg_support import revoke_manager_grant -from tests.test_task_import_sources import import_source_client as import_source_client -from tests.test_tasks import task_database_env as task_database_env, auth_headers, create_active_project -from tests.tasks.test_task_import_batches import _batch_path, _verified_source -from tests.tasks.test_task_import_contract import document - - -async def _import(client, count=2): - """Create actual retained bytes and native membership with screenable instructions.""" - project = (await create_active_project(client, slug="bulk-" + uuid4().hex))["id"] - value = document(count) - for row in value["tasks"]: - row.update(acceptance_criteria="Accurate, complete work", rejection_criteria="Incomplete work") - source = await _verified_source(client, project, value) - imported = await client.post(_batch_path(project), headers=auth_headers(), json={"source_id": source["source_id"]}) - assert imported.status_code == 201, imported.text - return project, imported.json() - - -def _path(project, batch, operation): - return f"{_batch_path(project)}/{batch['batch_id']}/{operation}" - - -async def _success_facts(project): - """Observe committed success identities rather than relying on response status alone.""" - async with db_session.get_session_factory()() as session: - task_ids = list(await session.scalars(select(WorkstreamTask.id).where(WorkstreamTask.project_id == project))) - tasks = list((await session.execute(select( - WorkstreamTask.id, WorkstreamTask.status, WorkstreamTask.locked_guide_version, - WorkstreamTask.locked_contribution_policy_version_id, - ).where(WorkstreamTask.project_id == project).order_by(WorkstreamTask.id))).all()) - roots = set(await session.scalars(select(TaskBatchTransitionReceipt.id).where(TaskBatchTransitionReceipt.project_id == project))) - members = set(await session.scalars(select(TaskBatchTransitionMember.id).where(TaskBatchTransitionMember.project_id == project))) - receipts = set(await session.scalars(select(TaskCommandReceipt.id).where( - TaskCommandReceipt.task_id.in_(task_ids), TaskCommandReceipt.action_id.in_(["project.task.screen", "project.task.release"]), - ))) - lifecycle = set(await session.scalars(select(AuditEvent.id).where( - AuditEvent.entity_id.in_(task_ids), AuditEvent.event_type.in_(["TaskScreened", "TaskReleased"]), - ))) - allows = set(await session.scalars(select(AuditEvent.id).where( - AuditEvent.resource_id.in_(task_ids), AuditEvent.event_type == "SensitiveAuthorizationAllowed", - AuditEvent.action_id.in_(["project.task.screen", "project.task.release"]), - ))) - return tasks, roots, members, receipts, lifecycle, allows - - -@pytest.mark.parametrize("count", [200, 500]) -async def test_public_source_import_screen_release_complete_journey(import_source_client, count, record_property): - """Every exact native member reaches READY with original ordered retained receipts.""" - client = import_source_client - project, batch = await _import(client, count) - for operation, status in (("screen", "screening"), ("release", "ready")): - key, payload = auth_headers(), {"reason": "Explicit complete-batch decision"} - started = time.monotonic() - result = await client.post(_path(project, batch, operation), headers=key, json=payload) - record_property(f"{count}_{operation}_seconds", time.monotonic() - started) - assert result.status_code == 200, result.text - original = result.json() - assert original["project_id"] == project and original["batch_id"] == batch["batch_id"] - assert original["operation"] == operation and original["row_count"] == count - assert [row["task_id"] for row in original["tasks"]] == [row["id"] for row in batch["tasks"]] - assert [row["row_index"] for row in original["tasks"]] == list(range(count)) - assert all(row["status"] == status and row["locked_guide_version"] for row in original["tasks"]) - before = await _success_facts(project) - replay = await client.post(_path(project, batch, operation), headers=key, json=payload) - assert replay.status_code == 200 and replay.json() == original, replay.text - after = await _success_facts(project) - assert before[:-1] == after[:-1] and len(after[-1] - before[-1]) == count - async with db_session.get_session_factory()() as session: - root = (await session.scalars(select(TaskBatchTransitionReceipt).where( - TaskBatchTransitionReceipt.project_id == project, - TaskBatchTransitionReceipt.action_id == f"project.task.{operation}", - ))).one() - links = list(await session.scalars(select(TaskBatchTransitionMember).where( - TaskBatchTransitionMember.transition_receipt_id == root.id, - ).order_by(TaskBatchTransitionMember.row_index))) - assert root.response == original and root.status == "committed" and len(links) == count - assert len({link.task_idempotency_key for link in links}) == count - for link, row in zip(links, original["tasks"], strict=True): - receipt = await session.get(TaskCommandReceipt, link.task_command_receipt_id) - decision = await session.get(AuditEvent, link.authorization_decision_id) - assert receipt.batch_transition_receipt_id == root.id - assert receipt.task_id == link.task_id == row["task_id"] - assert receipt.response["status"] == row["status"] - assert receipt.locked_context_hash == row["locked_context_hash"] - assert decision.action_id == root.action_id and decision.resource_id == row["task_id"] - assert decision.event_type == "SensitiveAuthorizationAllowed" - facts = await _success_facts(project) - assert len(facts[1]) == 2 and all(len(values) == count * 2 for values in facts[2:5]) - assert all(row.status == "ready" for row in facts[0]) - - -async def test_late_staging_failure_and_partial_advance_replay_roll_back_whole_batch(import_source_client, monkeypatch): - """A real second canonical write followed by failure leaves no partial success.""" - client = import_source_client - project, batch = await _import(client) - before = await _success_facts(project) - original_stage, calls = AuthorizedTaskCommands.stage_transition, 0 - - async def fail_after_second_write(commands, prepared, decision): - nonlocal calls - response = await original_stage(commands, prepared, decision) - calls += 1 - if calls == 2: - raise TaskValidationError("Injected late canonical failure") - return response - - key, payload = auth_headers(), {"reason": "Whole-batch screening"} - monkeypatch.setattr(AuthorizedTaskCommands, "stage_transition", fail_after_second_write) - failed = await client.post(_path(project, batch, "screen"), headers=key, json=payload) - assert failed.status_code == 422 and calls == 2, failed.text - assert await _success_facts(project) == before - monkeypatch.setattr(AuthorizedTaskCommands, "stage_transition", original_stage) - successful = await client.post(_path(project, batch, "screen"), headers=key, json=payload) - assert successful.status_code == 200, successful.text - before = await _success_facts(project) - for reason in (None, " \n"): - refused = await client.post(_path(project, batch, "release"), headers=auth_headers(), json={"reason": reason}) - assert refused.status_code == 422 and refused.json()["error"]["code"] == "task_batch_transition_invalid", refused.text - assert await _success_facts(project) == before - changed = await client.post(_path(project, batch, "screen"), headers=key, json={"reason": "Changed reason"}) - assert changed.status_code == 409 and changed.json()["error"]["code"] == "idempotency_mismatch", changed.text - assert await _success_facts(project) == before - advanced = await client.post(f"/api/v1/tasks/{batch['tasks'][0]['id']}/release", headers=auth_headers(), - json={"reason": "Separate later decision"}) - assert advanced.status_code == 200, advanced.text - before = await _success_facts(project) - replay = await client.post(_path(project, batch, "screen"), headers=key, json=payload) - assert replay.status_code == 409 and replay.json()["error"]["code"] == "task_replay_state_changed", replay.text - assert await _success_facts(project) == before - - -async def test_revoked_manager_cannot_replay_a_successful_bulk_write(import_source_client): - """The real canonical grant-revocation owner invalidates retained-key authority.""" - client = import_source_client - project, batch = await _import(client) - key, payload = auth_headers(), {"reason": "Before revocation"} - result = await client.post(_path(project, batch, "screen"), headers=key, json=payload) - assert result.status_code == 200, result.text - before = await _success_facts(project) - async with db_session.get_session_factory()() as session, session.begin(): - grant = (await session.scalars(select(AdminRoleGrant).where( - AdminRoleGrant.role == "project_manager", AdminRoleGrant.status == "active", - ))).one() - link = (await session.scalars(select(ActorIdentityLink).where( - ActorIdentityLink.actor_profile_id == grant.granted_by_actor_profile_id, - ))).one() - context = HumanAuthorizationContext( - actor_profile_id=UUID(link.actor_profile_id), identity_link_id=UUID(link.id), - actor_kind=ActorKind.HUMAN, actor_status=ActorStatus.ACTIVE, - identity_link_status=IdentityLinkStatus.ACTIVE, request_id=uuid4(), correlation_id=uuid4(), - ) - await revoke_manager_grant(session, context, UUID(str(grant.id))) - denied = await client.post(_path(project, batch, "screen"), headers=key, json=payload) - assert denied.status_code == 403 and denied.json()["error"]["code"] == "permission_not_granted", denied.text - assert await _success_facts(project) == before - async with db_session.get_session_factory()() as session: - denials = list(await session.scalars(select(AuditEvent).where( - AuditEvent.action_id == "project.task.screen", AuditEvent.event_type == "SensitiveAuthorizationDenied", - ))) - assert len(denials) == 1 and denials[0].denial_code == "permission_not_granted" - - -async def test_same_key_concurrent_roots_observe_native_wait_then_one_success(import_source_client, monkeypatch): - """An observed PostgreSQL blocker proves aggregate reservation serialization.""" - client = import_source_client - project, batch = await _import(client) - original = TaskBatchTransitionCommands._reserve - reserved, entered, release = asyncio.Event(), asyncio.Event(), asyncio.Event() - pids, calls = [], 0 - - async def gated(commands, *args, **kwargs): - nonlocal calls - calls += 1 - call = calls - pids.append(await commands._session.scalar(select(func.pg_backend_pid()))) - if call == 2: - entered.set() - result = await original(commands, *args, **kwargs) - if call == 1: - reserved.set() - await asyncio.wait_for(release.wait(), timeout=30) - return result - - monkeypatch.setattr(TaskBatchTransitionCommands, "_reserve", gated) - key, payload = auth_headers(), {"reason": "Concurrent exact request"} - first = asyncio.create_task(client.post(_path(project, batch, "screen"), headers=key, json=payload)) - second = None - try: - await asyncio.wait_for(reserved.wait(), timeout=30) - second = asyncio.create_task(client.post(_path(project, batch, "screen"), headers=key, json=payload)) - await asyncio.wait_for(entered.wait(), timeout=30) - deadline = asyncio.get_running_loop().time() + 10 - async with db_session.get_session_factory()() as observer: - while not await observer.scalar(text("select :holder = any(pg_blocking_pids(:waiter))"), - {"holder": pids[0], "waiter": pids[1]}): - assert asyncio.get_running_loop().time() < deadline, "no aggregate holder/waiter was observed" - await asyncio.sleep(0.05) - release.set() - responses = await asyncio.wait_for(asyncio.gather(first, second), timeout=60) - assert all(response.status_code == 200 for response in responses), [response.text for response in responses] - assert responses[0].json() == responses[1].json() - facts = await _success_facts(project) - assert len(facts[1]) == 1 and all(len(values) == 2 for values in facts[2:5]) and len(facts[-1]) == 4 - finally: - release.set() - for pending in (first, second): - if pending is not None and not pending.done(): - pending.cancel() - await asyncio.gather(*(pending for pending in (first, second) if pending is not None), return_exceptions=True) - - -async def test_sql_cannot_attach_old_standalone_successes_to_a_new_aggregate(import_source_client): - """Real earlier canonical successes lack aggregate-root provenance and cannot enroll.""" - client = import_source_client - project, batch = await _import(client) - reason = "Historical standalone screening" - for task in batch["tasks"]: - screened = await client.post(f"/api/v1/tasks/{task['id']}/screen", headers=auth_headers(), json={"reason": reason}) - assert screened.status_code == 200, screened.text - before = await _success_facts(project) - root_id = new_record_id() - async with db_session.get_session_factory()() as session: - with pytest.raises(DBAPIError) as caught: - async with session.begin(): - snapshot = await TaskImportMembership(session).prepare(UUID(project), UUID(batch["batch_id"])) - receipts = {row.task_id: row for row in await session.scalars(select(TaskCommandReceipt).where( - TaskCommandReceipt.task_id.in_([row["id"] for row in batch["tasks"]]), - TaskCommandReceipt.action_id == "project.task.screen", - ))} - assert len(receipts) == 2 and all(row.batch_transition_receipt_id is None for row in receipts.values()) - actor = next(iter(receipts.values())).actor_profile_id - link = (await session.scalars(select(ActorIdentityLink).where(ActorIdentityLink.actor_profile_id == actor))).one() - compact = {"project_id": project, "batch_id": batch["batch_id"], "operation": "screen", "row_count": 2, - "tasks": [{"task_id": str(row.task_id), "row_index": row.row_index, "status": "screening", - "locked_guide_version": receipts[str(row.task_id)].response["locked_guide_version"], - "locked_contribution_policy_version_id": receipts[str(row.task_id)].response["locked_contribution_policy_version_id"], - "locked_context_hash": receipts[str(row.task_id)].locked_context_hash} for row in snapshot.members]} - root = TaskBatchTransitionReceipt( - id=root_id, actor_profile_id=actor, identity_link_id=link.id, action_id="project.task.screen", - idempotency_key=uuid4(), request_digest=canonical_json_hash({"project_id": project, - "batch_id": batch["batch_id"], "operation": "project.task.screen", "reason": reason}), - reason=reason, project_id=project, batch_id=batch["batch_id"], row_count=2, - manifest_digest=snapshot.manifest_digest, membership_digest=_membership_digest(snapshot), - status="pending", - ) - session.add(root) - await session.flush() - for native in snapshot.members: - receipt = receipts[str(native.task_id)] - event = (await session.scalars(select(AuditEvent).where( - AuditEvent.entity_id == str(native.task_id), AuditEvent.event_type == "TaskScreened", - ))).one() - session.add(TaskBatchTransitionMember( - id=new_record_id(), transition_receipt_id=root_id, project_id=project, batch_id=batch["batch_id"], - native_member_id=str(native.member_id), task_id=str(native.task_id), row_index=native.row_index, - task_idempotency_key=receipt.idempotency_key, task_command_receipt_id=receipt.id, - authorization_decision_id=event.event_payload["references"]["authorization_decision_id"], - )) - root.status, root.response, root.committed_at = "committed", compact, datetime.now(UTC) - await session.flush() - assert getattr(caught.value.orig, "sqlstate", None) == "23514" - assert await _success_facts(project) == before - - -@pytest.mark.parametrize("corruption", ["missing_member", "pending_root"]) -async def test_native_commit_refuses_incomplete_aggregate_after_real_canonical_stages( - import_source_client, corruption, -): - """Initial custody corruption must roll back both actual canonical Task writes.""" - client = import_source_client - project, batch = await _import(client) - before = await _success_facts(project) - changed = False - - def corrupt_before_flush(session, flush_context, instances): - nonlocal changed - if changed: - return - if corruption == "missing_member": - for row in list(session.new): - if isinstance(row, TaskBatchTransitionMember) and row.row_index == 1: - # Remove the initial INSERT; an UPDATE/DELETE guard cannot - # mask missing complete-member commit closure. - session.expunge(row) - changed = True - else: - for row in list(session.dirty): - if isinstance(row, TaskBatchTransitionReceipt) and row.status == "committed": - # Preserve the valid pending declaration without writing an - # invalid state shape. Deferred closure must reject commit. - session.expire(row) - changed = True - - event.listen(Session, "before_flush", corrupt_before_flush) - try: - refused = await client.post( - _path(project, batch, "screen"), headers=auth_headers(), - json={"reason": "Complete canonical stages before native refusal"}, - ) - assert changed, "the intended final aggregate INSERT/completion was not reached" - assert refused.status_code == 503 and refused.json()["error"]["retryable"] is True, refused.text - assert await _success_facts(project) == before - finally: - event.remove(Session, "before_flush", corrupt_before_flush) - - -@pytest.mark.parametrize("table", ["task_batch_transition_receipts", "task_batch_transition_members"]) -@pytest.mark.parametrize("operation", ["update", "delete", "truncate"]) -async def test_committed_aggregate_custody_refuses_direct_sql_mutation( - import_source_client, table, operation, -): - """Retained aggregate facts refuse mutation and each table owns a TRUNCATE guard.""" - client = import_source_client - project, batch = await _import(client) - key, payload = auth_headers(), {"reason": "Immutable aggregate success"} - result = await client.post(_path(project, batch, "screen"), headers=key, json=payload) - assert result.status_code == 200, result.text - async with db_session.get_session_factory()() as session, session.begin(): - snapshot = text(f"select to_jsonb(t) from {table} t order by id") - before = list(await session.scalars(snapshot)) - assert before - if operation == "truncate": - assert await session.scalar(text( - "select count(*) from pg_trigger where tgrelid=cast(:table as regclass) " - "and not tgisinternal and (tgtype & 32)=32 and (tgtype & 1)=0 and tgenabled='O'" - ), {"table": table}) == 1, "each aggregate table needs its own enabled statement guard" - update = { - "task_batch_transition_receipts": "reason='changed retained decision'", - "task_batch_transition_members": "task_idempotency_key=:new_key", - }[table] - statement = { - "update": f"update {table} set {update}", - "delete": f"delete from {table}", - "truncate": f"truncate {table} cascade", - }[operation] - with pytest.raises(DBAPIError): - async with session.begin_nested(): - await session.execute(text(statement), {"new_key": uuid4()}) - assert list(await session.scalars(snapshot)) == before - replay = await client.post(_path(project, batch, "screen"), headers=key, json=payload) - assert replay.status_code == 200 and replay.json() == result.json(), replay.text diff --git a/backend/tests/tasks/test_task_import_batch_bindings.py b/backend/tests/tasks/test_task_import_batch_bindings.py deleted file mode 100644 index 36c720b1b..000000000 --- a/backend/tests/tasks/test_task_import_batch_bindings.py +++ /dev/null @@ -1,68 +0,0 @@ -"""Native immutable source ancestry used by atomic import and provider-free replay.""" - -import json -from uuid import UUID, uuid4 - -import pytest -from sqlalchemy import select - -from app.db import session as db_session -from app.modules.actors.models import ActorIdentityLink, ActorProfile -from app.modules.artifacts.api.task_import_source import TaskImportSourceError -from app.modules.artifacts.models import ArtifactReplica -from app.modules.artifacts.task_import_sources import ArtifactTaskImportSourceCommands -from app.modules.authorization.runtime import ( - ActorKind, ActorStatus, HumanAuthorizationContext, IdentityLinkStatus, -) -from app.modules.authorization.task_import_sources import PreparedTaskImportSourceAuthorization -from tests.test_task_import_sources import ( - import_source_client as import_source_client, _declare, _path, _project, -) -from tests.test_tasks import auth_headers, task_database_env as task_database_env -from tests.tasks.test_task_import_contract import document - - -def _unexpected_runtime(): - raise AssertionError("immutable source replay must never acquire provider runtime") - - -async def test_native_binding_survives_operational_health_and_rejects_substitutions(import_source_client): - """Current health may change; the exact verified native byte ancestry may not.""" - client = import_source_client - project = await _project(client) - raw = json.dumps(document()).encode() - source = await _declare(client, project, raw) - uploaded = await client.put(_path(project, source) + "/content", - headers=auth_headers() | {"Content-Type": "application/json"}, content=raw) - assert uploaded.status_code == 200 and uploaded.json()["status"] == "verified", uploaded.text - async with db_session.get_session_factory()() as session: - async with session.begin(): - link = (await session.scalars(select(ActorIdentityLink).join( - ActorProfile, ActorProfile.id == ActorIdentityLink.actor_profile_id, - ).where(ActorIdentityLink.subject == "project-manager-subject"))).one() - context = HumanAuthorizationContext( - actor_profile_id=UUID(link.actor_profile_id), identity_link_id=UUID(link.id), - actor_kind=ActorKind.HUMAN, actor_status=ActorStatus.ACTIVE, - identity_link_status=IdentityLinkStatus.ACTIVE, request_id=uuid4(), correlation_id=uuid4(), - ) - commands = ArtifactTaskImportSourceCommands( - session, actor_profile_id=context.actor_profile_id, identity_link_id=context.identity_link_id, - authorization=PreparedTaskImportSourceAuthorization(session, context), runtime=_unexpected_runtime, - ) - binding = await commands.prepare_binding(UUID(project), UUID(source["source_id"])) - assert await commands.authorize_binding(binding) - async with session.begin(): - replica = await session.get(ArtifactReplica, str(binding.replica_id)) - replica.availability_state = "unavailable" - async with session.begin(): - assert await commands.prepare_binding(UUID(project), binding.source_id, binding) == binding - assert await commands.authorize_binding(binding) - for replacement in ( - {"verification_receipt_id": uuid4()}, {"sha256": "sha256:" + "a" * 64}, - {"put_attempt_id": uuid4()}, {"project_id": uuid4()}, - {"operation_receipt_id": None, "observation_receipt_id": uuid4()}, - ): - changed = binding.model_copy(update=replacement) - async with session.begin(): - with pytest.raises(TaskImportSourceError): - await commands.prepare_binding(UUID(project), binding.source_id, changed) diff --git a/backend/tests/tasks/test_task_import_batch_contract.py b/backend/tests/tasks/test_task_import_batch_contract.py deleted file mode 100644 index ab14b3436..000000000 --- a/backend/tests/tasks/test_task_import_batch_contract.py +++ /dev/null @@ -1,69 +0,0 @@ -"""Instruction mapping and closed original/current batch projections.""" - -from datetime import UTC, datetime - -import pytest -from pydantic import ValidationError - -from app.core.identifiers import new_record_id -from app.modules.tasks.api.task_import import TaskImportRow, TaskImportSourceCommitment -from app.modules.tasks.schemas import ( - TaskCreate, TaskImportBatchCurrentTask, TaskImportBatchRequest, TaskImportBatchResponse, - TaskImportBatchStatus, TaskResponse, -) -from app.modules.tasks.task_import_batches import imported_task_payload - - -def _source(): - return TaskImportSourceCommitment(new_record_id(), new_record_id(), - "sha256:" + "a" * 64, 100, "sha256:" + "b" * 64) - - -def _original(source, batch_id, external_id): - values = {field: None for field in TaskResponse.model_fields} - values.update(imported_task_payload( - TaskImportRow(external_task_id=external_id, title="Instructions", description="Actual work"), source, batch_id, - ).model_dump()) - values.update(id=str(new_record_id()), project_id=str(source.project_id), status="draft", - created_by=str(new_record_id()), created_at=datetime.now(UTC), updated_at=datetime.now(UTC)) - return TaskResponse.model_validate(values) - - -def test_mapping_preserves_instructions_and_stamps_server_only_json_custody(): - source, batch_id = _source(), new_record_id() - row = TaskImportRow(external_task_id="Case-Sensitive", title="Instructions", description="Exact work", - difficulty="x" * 80, skill_tags=["python"], estimated_time_minutes=30) - mapped = imported_task_payload(row, source, batch_id) - assert {field: getattr(mapped, field) for field in TaskImportRow.model_fields} == row.model_dump() - assert (mapped.source_type, mapped.source_ref, mapped.source_payload_hash, mapped.import_batch_id) == ( - "json_import", f"task-import-source:{source.source_id}", source.sha256, str(batch_id), - ) - assert mapped.deadline_at is None - with pytest.raises(ValidationError): - TaskCreate.model_validate(mapped.model_dump()) - with pytest.raises(ValidationError): - TaskImportBatchRequest.model_validate({"source_id": source.source_id, "source_type": "manual"}) - with pytest.raises(ValidationError): - TaskImportRow.model_validate(row.model_dump() | {"import_batch_id": str(batch_id)}) - - -def test_projection_separates_immutable_creation_from_current_member_states(): - source, batch_id = _source(), new_record_id() - originals = (_original(source, batch_id, "one"), _original(source, batch_id, "two")) - creation = TaskImportBatchResponse( - batch_id=batch_id, project_id=source.project_id, source_id=source.source_id, - sha256=source.sha256, byte_count=source.byte_count, row_count=2, created_at=datetime.now(UTC), - schema_version="workstream.task_import.v1", mapping_version="workstream.task_import.draft_mapping.v1", - tasks=originals, - ) - current = tuple(TaskImportBatchCurrentTask(task_id=original.id, row_index=index, status="ready") - for index, original in enumerate(originals)) - status = TaskImportBatchStatus(creation=creation, current_tasks=current) - assert [row.status for row in status.current_tasks] == ["ready", "ready"] - assert [row.status for row in status.creation.tasks] == ["draft", "draft"] - with pytest.raises(ValidationError): - TaskImportBatchStatus(creation=creation, current_tasks=tuple(reversed(current))) - with pytest.raises(ValidationError): - TaskImportBatchResponse.model_validate(creation.model_dump() | {"project_id": new_record_id()}) - with pytest.raises(ValidationError): - TaskImportBatchResponse.model_validate(creation.model_dump() | {"tasks": (originals[0], originals[0])}) diff --git a/backend/tests/tasks/test_task_import_batches.py b/backend/tests/tasks/test_task_import_batches.py deleted file mode 100644 index 8b2cf0478..000000000 --- a/backend/tests/tasks/test_task_import_batches.py +++ /dev/null @@ -1,607 +0,0 @@ -"""Public atomic JSON-to-DRAFT import with native AUTH, ART and Task custody.""" - -import asyncio -import json -from uuid import uuid4 - -import pytest -from sqlalchemy import func, select, text -from sqlalchemy.exc import DBAPIError - -from app.db import session as db_session -from app.modules.artifacts.models import ArtifactTaskImportSource, ArtifactReplica -from app.modules.artifacts.task_import_sources import ArtifactTaskImportSourceCommands -from app.modules.authorization.task_import_sources import PreparedTaskImportSourceAuthorization -from app.modules.tasks.authorized_commands import AuthorizedTaskCommands -from app.modules.tasks.models import ( - AuditEvent, TaskCommandReceipt, TaskImportBatch, TaskImportBatchCommandReceipt, - TaskImportBatchMember, WorkstreamTask, -) -from app.modules.tasks.task_import_batches import TaskImportBatchCommands -from tests.test_task_import_sources import ( - import_source_client as import_source_client, _declare, _path, _project, -) -from tests.test_tasks import ( - auth_headers, complete_task_payload, create_active_project, set_dev_actor, - task_database_env as task_database_env, -) -from tests.tasks.test_task_import_contract import document - - -async def _verified_source(client, project, value): - """Retain actual bytes through the existing public declaration and upload.""" - raw = (json.dumps(value, ensure_ascii=False, indent=2) + "\n").encode() - source = await _declare(client, project, raw) - uploaded = await client.put(_path(project, source) + "/content", content=raw, - headers=auth_headers() | {"Content-Type": "application/json"}) - assert uploaded.status_code == 200 and uploaded.json()["status"] == "verified", uploaded.text - return source - - -def _batch_path(project): - """Address the sole project-scoped public import owner.""" - return f"/api/v1/projects/{project}/task-import-batches" - - -async def _counts(project): - """Observe committed batch, membership, retry, Task and CREATE effects.""" - async with db_session.get_session_factory()() as session: - counts = [await session.scalar(select(func.count()).select_from(owner).where(owner.project_id == project)) - for owner in (TaskImportBatch, TaskImportBatchMember, TaskImportBatchCommandReceipt, WorkstreamTask)] - counts.append(await session.scalar(select(func.count()).select_from(TaskCommandReceipt).join( - WorkstreamTask, WorkstreamTask.id == TaskCommandReceipt.task_id, - ).where(WorkstreamTask.project_id == project, TaskCommandReceipt.action_id == "project.task.create"))) - counts.append(await session.scalar(select(func.count()).select_from(AuditEvent).where( - AuditEvent.event_payload["references"]["project_id"].as_string() == project, - AuditEvent.event_type == "TaskCreated", - ))) - return tuple(counts) - - -async def test_200_rows_create_one_native_batch_and_exact_task_evidence(import_source_client): - """A real 200-row UTF-8 file creates 200 ordered DRAFT Tasks in one batch.""" - client, value = import_source_client, document(200) - value["tasks"][0]["difficulty"] = "x" * 80 - project = await _project(client) - source = await _verified_source(client, project, value) - headers = auth_headers() - response = await client.post(_batch_path(project), headers=headers, json={"source_id": source["source_id"]}) - assert response.status_code == 201, response.text - result = response.json() - assert (result["project_id"], result["source_id"], result["sha256"], result["byte_count"], result["row_count"]) == ( - project, source["source_id"], source["sha256"], source["byte_count"], 200, - ) - assert result["label"] == value["metadata"]["label"] - assert len({row["id"] for row in result["tasks"]}) == 200 - assert [row["external_task_id"] for row in result["tasks"]] == [row["external_task_id"] for row in value["tasks"]] - assert all(row["status"] == "draft" and row["source_type"] == "json_import" - and row["source_ref"] == f"task-import-source:{source['source_id']}" - and row["source_payload_hash"] == source["sha256"] - and row["import_batch_id"] == result["batch_id"] for row in result["tasks"]) - for instructions, task in zip(value["tasks"], result["tasks"], strict=True): - assert {field: task[field] for field in instructions} == instructions - assert await _counts(project) == (1, 200, 1, 200, 200, 200) - async with db_session.get_session_factory()() as session: - members = list(await session.scalars(select(TaskImportBatchMember).where( - TaskImportBatchMember.batch_id == result["batch_id"], - ).order_by(TaskImportBatchMember.row_index))) - assert [member.task_id for member in members] == [row["id"] for row in result["tasks"]] - for member in members: - receipt = await session.get(TaskCommandReceipt, member.task_command_receipt_id) - decision = await session.get(AuditEvent, member.authorization_decision_id) - event = (await session.scalars(select(AuditEvent).where( - AuditEvent.entity_id == member.task_id, AuditEvent.event_type == "TaskCreated", - ))).one() - assert receipt.response == member.response and receipt.status == "committed" - assert decision.action_id == "project.task.create" and decision.event_type == "SensitiveAuthorizationAllowed" - assert event.event_payload["source_type"] == "json_import" - assert event.event_payload["references"]["authorization_decision_id"] == decision.id - repeated = await client.post(_batch_path(project), headers=headers, json={"source_id": source["source_id"]}) - recovered = await client.post(_batch_path(project), headers=auth_headers(), json={"source_id": source["source_id"]}) - assert repeated.status_code == recovered.status_code == 201 - assert repeated.json() == recovered.json() == result - assert await _counts(project) == (1, 200, 2, 200, 200, 200) - - -async def test_replay_keeps_original_facts_after_advancement_without_provider_or_parser(import_source_client, monkeypatch): - """Committed replay reads native ancestry; current Tasks remain separate facts.""" - client = import_source_client - project = (await create_active_project(client, slug="batch-advance-" + uuid4().hex))["id"] - source = await _verified_source(client, project, document(2)) - headers = auth_headers() - imported = await client.post(_batch_path(project), headers=headers, json={"source_id": source["source_id"]}) - assert imported.status_code == 201, imported.text - result = imported.json() - first = result["tasks"][0]["id"] - for action in ("screen", "release"): - advanced = await client.post(f"/api/v1/tasks/{first}/{action}", headers=auth_headers(), json={}) - assert advanced.status_code == 200, advanced.text - async with db_session.get_session_factory()() as session, session.begin(): - header = await session.get(TaskImportBatch, result["batch_id"]) - replica = await session.get(ArtifactReplica, header.replica_id) - replica.availability_state = "unavailable" - - def forbidden(*args, **kwargs): - raise AssertionError("committed batch replay cannot read provider bytes or reinterpret JSON") - - monkeypatch.setattr(ArtifactTaskImportSourceCommands, "open", forbidden) - monkeypatch.setattr("app.modules.tasks.task_import_batches.parse_task_import", forbidden) - for request_headers in (headers, auth_headers()): - replay = await client.post(_batch_path(project), headers=request_headers, json={"source_id": source["source_id"]}) - assert replay.status_code == 201 and replay.json() == result, replay.text - status = await client.get(_batch_path(project) + "/" + result["batch_id"], headers=auth_headers()) - assert status.status_code == 200, status.text - assert status.json()["creation"] == result - assert [row["status"] for row in status.json()["current_tasks"]] == ["ready", "draft"] - assert await _counts(project) == (1, 2, 2, 2, 2, 2) - - -async def test_different_verified_selector_recovers_but_changed_key_selector_conflicts(import_source_client, monkeypatch): - """Another actual verified source may recover a file, never rewrite its retry key.""" - client = import_source_client - project = await _project(client) - value = document(2) - original = await _verified_source(client, project, value) - headers = auth_headers() - response = await client.post(_batch_path(project), headers=headers, json={"source_id": original["source_id"]}) - assert response.status_code == 201, response.text - alternate = await _verified_source(client, project, value) - assert alternate["source_id"] != original["source_id"] - # A declared parent claims the same SHA/count, but has no verified receipt. - unverified = await _declare(client, project, (json.dumps(value, ensure_ascii=False, indent=2) + "\n").encode()) - - def forbidden(*args, **kwargs): - raise AssertionError("exact-file recovery must not consult provider/parser") - - monkeypatch.setattr(ArtifactTaskImportSourceCommands, "open", forbidden) - monkeypatch.setattr("app.modules.tasks.task_import_batches.parse_task_import", forbidden) - recovered = await client.post(_batch_path(project), headers=auth_headers(), json={"source_id": alternate["source_id"]}) - assert recovered.status_code == 201 and recovered.json() == response.json(), recovered.text - changed = await client.post(_batch_path(project), headers=headers, json={"source_id": alternate["source_id"]}) - assert changed.status_code == 409 and changed.json()["error"]["code"] == "task_import_idempotency_mismatch", changed.text - denied = await client.post(_batch_path(project), headers=auth_headers(), json={"source_id": unverified["source_id"]}) - assert denied.status_code == 409, denied.text - assert await _counts(project) == (1, 2, 2, 2, 2, 2) - - -async def test_existing_manual_external_id_rejects_every_row_without_partial_effects(import_source_client): - """Native external-ID uniqueness covers manual creation and whole-file rollback.""" - client = import_source_client - project = await _project(client) - payload = complete_task_payload() | {"external_task_id": "source-2"} - existing = await client.post(f"/api/v1/projects/{project}/tasks", headers=auth_headers(), json=payload) - assert existing.status_code == 201, existing.text - source = await _verified_source(client, project, document(3)) - rejected = await client.post(_batch_path(project), headers=auth_headers(), json={"source_id": source["source_id"]}) - assert rejected.status_code == 409 and rejected.json()["error"]["code"] == "task_import_external_id_conflict", rejected.text - assert rejected.json()["detail"] == [{"loc": ["tasks", 2, "external_task_id"], "type": "external_task_id_conflict"}] - assert await _counts(project) == (0, 0, 0, 1, 1, 1) - again = await client.post(f"/api/v1/projects/{project}/tasks", headers=auth_headers(), json=payload) - assert again.status_code == 409, again.text - other = await _project(client) - permitted = await client.post(f"/api/v1/projects/{other}/tasks", headers=auth_headers(), json=payload) - case = await client.post(f"/api/v1/projects/{project}/tasks", headers=auth_headers(), json=payload | {"external_task_id": "Source-2"}) - assert permitted.status_code == case.status_code == 201 - for _ in range(2): - nullable = await client.post(f"/api/v1/projects/{project}/tasks", headers=auth_headers(), json=complete_task_payload()) - assert nullable.status_code == 201, nullable.text - - -@pytest.mark.parametrize("failure", ["last_row", "after_all_rows"]) -async def test_late_failure_rolls_back_tasks_receipts_and_successful_evidence(import_source_client, monkeypatch, failure): - """Failure after successful staging leaves no batch or Task creation facts.""" - client = import_source_client - project = await _project(client) - source = await _verified_source(client, project, document(3)) - if failure == "last_row": - stage = AuthorizedTaskCommands.stage_creation - - async def fail_last(commands, prepared, decision): - result = await stage(commands, prepared, decision) - if result.external_task_id == "source-2": - raise RuntimeError("injected failure after the final canonical Task stage") - return result - - monkeypatch.setattr(AuthorizedTaskCommands, "stage_creation", fail_last) - else: - stage = TaskImportBatchCommands._stage_rows - - async def fail_complete(commands, *args, **kwargs): - await stage(commands, *args, **kwargs) - raise RuntimeError("injected failure after all Task and member stages") - - monkeypatch.setattr(TaskImportBatchCommands, "_stage_rows", fail_complete) - response = await client.post(_batch_path(project), headers=auth_headers(), json={"source_id": source["source_id"]}) - assert response.status_code == 500, response.text - assert await _counts(project) == (0, 0, 0, 0, 0, 0) - async with db_session.get_session_factory()() as session: - assert not list(await session.scalars(select(AuditEvent.id).where( - AuditEvent.project_id == project, AuditEvent.action_id.in_(["project.task.create", "project.task.import"]), - AuditEvent.event_type == "SensitiveAuthorizationAllowed", - ))) - assert await session.get(ArtifactTaskImportSource, source["source_id"]) is not None - - -async def test_matching_metadata_label_never_adds_native_membership(import_source_client): - """A manual Task cannot join a batch by spoofing its exposed metadata spelling.""" - client = import_source_client - project = await _project(client) - source = await _verified_source(client, project, document()) - imported = await client.post(_batch_path(project), headers=auth_headers(), json={"source_id": source["source_id"]}) - assert imported.status_code == 201, imported.text - batch = imported.json() - manual = await client.post(f"/api/v1/projects/{project}/tasks", headers=auth_headers(), - json=complete_task_payload() | {"import_batch_id": batch["batch_id"]}) - assert manual.status_code == 201, manual.text - status = await client.get(_batch_path(project) + "/" + batch["batch_id"], headers=auth_headers()) - assert status.status_code == 200 and status.json()["creation"] == batch - assert [row["task_id"] for row in status.json()["current_tasks"]] == [batch["tasks"][0]["id"]] - assert await _counts(project) == (1, 1, 1, 2, 2, 2) - - -@pytest.mark.parametrize("authority", ["ungranted_actor", "revoked_original"]) -async def test_missing_current_authority_cannot_replay_or_read_committed_batch(import_source_client, monkeypatch, authority): - """Original receipts and claimed roles cannot replace current covered authority.""" - client = import_source_client - project = await _project(client) - source = await _verified_source(client, project, document()) - headers = auth_headers() - imported = await client.post(_batch_path(project), headers=headers, json={"source_id": source["source_id"]}) - assert imported.status_code == 201, imported.text - before = await _counts(project) - if authority == "ungranted_actor": - set_dev_actor(monkeypatch, roles="project_manager", subject="ungranted-batch-manager") - else: - from app.modules.authorization.models import AdminRoleGrant - from tests.authorization.guide_activation.pg_support import revoke_manager_grant - from tests.authorization.task_authority.test_concurrency import actor_context - async with db_session.get_session_factory()() as session: - parent = await session.get(ArtifactTaskImportSource, source["source_id"]) - grant = (await session.scalars(select(AdminRoleGrant).where( - AdminRoleGrant.target_actor_profile_id == parent.actor_profile_id, - AdminRoleGrant.role == "project_manager", AdminRoleGrant.status == "active", - ))).one() - grant_id, administrator_id = grant.id, grant.granted_by_actor_profile_id - administrator = await actor_context(administrator_id) - async with db_session.get_session_factory()() as session, session.begin(): - await revoke_manager_grant(session, administrator, grant_id) - captured = [] - restage = PreparedTaskImportSourceAuthorization.restage_denial - - async def observe(authority, error): - captured.append((error.__cause__.decision, authority._context.actor_profile_id)) - await restage(authority, error) - - monkeypatch.setattr(PreparedTaskImportSourceAuthorization, "restage_denial", observe) - for request_headers in (headers, auth_headers()): - denied = await client.post(_batch_path(project), headers=request_headers, json={"source_id": source["source_id"]}) - assert denied.status_code == 403, denied.text - hidden = await client.get(_batch_path(project) + "/" + imported.json()["batch_id"], headers=auth_headers()) - assert hidden.status_code == 404, hidden.text - assert await _counts(project) == before - async with db_session.get_session_factory()() as session: - events = list(await session.scalars(select(AuditEvent).where( - AuditEvent.action_id == "artifact.task_import_source.read", - AuditEvent.event_type == "SensitiveAuthorizationDenied", - ))) - decisions = {str(decision.decision_id): (decision, actor) for decision, actor in captured} - assert len(events) == len(decisions) == 3 - assert set(decisions) == {event.id for event in events} - assert all(event.actor_id == str(decisions[event.id][1]) - and event.request_id == str(decisions[event.id][0].request_id) - and event.action_id == decisions[event.id][0].action_id.value - and event.denial_code == "permission_not_granted" - and event.after_facts["resource_context_digest"] == decisions[event.id][0].resource_context_digest - for event in events) - - -async def test_two_import_roots_wait_on_actual_file_custody_then_recover_one_batch(import_source_client, monkeypatch): - """A gated PostgreSQL wait proves concurrent first imports share one original.""" - client = import_source_client - project = await _project(client) - source = await _verified_source(client, project, document(3)) - original = TaskImportBatchCommands._reserve_batch - first_reserved, second_entered, release = asyncio.Event(), asyncio.Event(), asyncio.Event() - pids, calls = [], 0 - - async def gated(commands, *args, **kwargs): - nonlocal calls - calls += 1 - call = calls - pids.append(await commands._session.scalar(select(func.pg_backend_pid()))) - if call == 2: - second_entered.set() - batch = await original(commands, *args, **kwargs) - if call == 1: - first_reserved.set() - await asyncio.wait_for(release.wait(), timeout=30) - return batch - - monkeypatch.setattr(TaskImportBatchCommands, "_reserve_batch", gated) - path, payload = _batch_path(project), {"source_id": source["source_id"]} - first = asyncio.create_task(client.post(path, headers=auth_headers(), json=payload)) - second = None - try: - await asyncio.wait_for(first_reserved.wait(), timeout=30) - second = asyncio.create_task(client.post(path, headers=auth_headers(), json=payload)) - await asyncio.wait_for(second_entered.wait(), timeout=30) - deadline = asyncio.get_running_loop().time() + 10 - async with db_session.get_session_factory()() as observer: - while True: - blocked = await observer.scalar(text("select :holder = any(pg_blocking_pids(:waiter))"), - {"holder": pids[0], "waiter": pids[1]}) - if blocked: - break - assert asyncio.get_running_loop().time() < deadline, "second root never waited on the original file holder" - await asyncio.sleep(0.05) - release.set() - responses = await asyncio.wait_for(asyncio.gather(first, second), timeout=30) - assert [response.status_code for response in responses] == [201, 201], [response.text for response in responses] - assert responses[0].json() == responses[1].json() - assert await _counts(project) == (1, 3, 2, 3, 3, 3) - finally: - release.set() - for pending in (first, second): - if pending is not None and not pending.done(): - pending.cancel() - await asyncio.gather(*(pending for pending in (first, second) if pending is not None), return_exceptions=True) - - -async def test_distinct_covered_actors_with_reversed_ids_wait_then_roll_back_one_import(import_source_client, monkeypatch): - """Sorted unique-key writes avoid crossed waits between independently covered actors.""" - from uuid import UUID - from app.adapters.artifacts import task_import_source_commands - from app.adapters.audit import task_transition_audit - from app.adapters.tasks import task_import_batch_commands - from app.core.config import get_settings - from app.modules.authorization.task_authorization import PreparedTaskAuthorization - from app.modules.tasks.schemas import TaskImportBatchResponse - from app.modules.tasks.api.task_import_membership import TaskImportBatchError - from tests.authorization.task_authority.test_concurrency import actor_context - from tests.project_create_fixtures import grant_system_project_manager - - client = import_source_client - project = await _project(client) - value = document(2) - source = await _verified_source(client, project, value) - async with db_session.get_session_factory()() as session: - original_source = await session.get(ArtifactTaskImportSource, source["source_id"]) - first_context = await actor_context(original_source.actor_profile_id) - set_dev_actor(monkeypatch, roles="project_manager", subject="second-covered-importer") - admitted = await client.get("/api/v1/actors/me", headers=auth_headers()) - assert admitted.status_code == 200, admitted.text - async with db_session.get_session_factory()() as session, session.begin(): - link, _ = await grant_system_project_manager(session, issuer="flow-test", subject="second-covered-importer") - second_actor = link.actor_profile_id - second_context = await actor_context(second_actor) - value["tasks"].reverse() - alternate = await _verified_source(client, project, value) - first_written, second_entered, release = asyncio.Event(), asyncio.Event(), asyncio.Event() - pids, first_calls, second_calls = {}, 0, 0 - original = AuthorizedTaskCommands.stage_creation - - async def gate(commands, *args, **kwargs): - nonlocal first_calls, second_calls - actor = commands._actor_id - if actor == first_context.actor_profile_id: - first_calls += 1 - if first_calls == 1: - pids["first"] = await commands._session.scalar(select(func.pg_backend_pid())) - else: - second_calls += 1 - if second_calls == 1: - pids["second"] = await commands._session.scalar(select(func.pg_backend_pid())) - second_entered.set() - result = await original(commands, *args, **kwargs) - if actor == first_context.actor_profile_id and first_calls == 1: - first_written.set() - await asyncio.wait_for(release.wait(), timeout=30) - return result - - async def run(context, selected_source): - async with db_session.get_session_factory()() as session: - commands = task_import_batch_commands( - session, authorization=PreparedTaskAuthorization(session, context), audit=task_transition_audit(session), - actor_profile_id=context.actor_profile_id, identity_link_id=context.identity_link_id, settings=get_settings(), - source=task_import_source_commands(session, settings=get_settings(), context=context), - ) - return await commands.import_source(UUID(project), UUID(selected_source), idempotency_key=uuid4()) - - monkeypatch.setattr(AuthorizedTaskCommands, "stage_creation", gate) - first = asyncio.create_task(run(first_context, source["source_id"])) - second = None - try: - await asyncio.wait_for(first_written.wait(), timeout=30) - second = asyncio.create_task(run(second_context, alternate["source_id"])) - await asyncio.wait_for(second_entered.wait(), timeout=30) - deadline = asyncio.get_running_loop().time() + 10 - async with db_session.get_session_factory()() as observer: - while True: - blocked = await observer.scalar(text("select :holder = any(pg_blocking_pids(:waiter))"), - {"holder": pids["first"], "waiter": pids["second"]}) - if blocked: - break - assert asyncio.get_running_loop().time() < deadline, "competing sorted uniqueness write never waited" - await asyncio.sleep(0.05) - release.set() - outcomes = await asyncio.wait_for(asyncio.gather(first, second, return_exceptions=True), timeout=30) - assert isinstance(outcomes[0], TaskImportBatchResponse), outcomes - assert isinstance(outcomes[1], TaskImportBatchError) and outcomes[1].code == "task_import_external_id_conflict", outcomes - assert await _counts(project) == (1, 2, 1, 2, 2, 2) - finally: - release.set() - for pending in (first, second): - if pending is not None and not pending.done(): - pending.cancel() - await asyncio.gather(*(pending for pending in (first, second) if pending is not None), return_exceptions=True) - - -async def test_normal_create_takes_common_authority_before_competing_external_id(import_source_client, monkeypatch): - """Normal create waits on the import's AUTH custody before touching uniqueness.""" - from uuid import UUID - from app.adapters.audit import task_transition_audit - from app.adapters.tasks import task_commands - from app.core.config import get_settings - from app.modules.authorization.task_authorization import PreparedTaskAuthorization - from app.modules.tasks.command_replay import TaskReplayConflict - from app.modules.tasks.schemas import TaskCreate - from tests.authorization.task_authority.test_concurrency import actor_context - - client = import_source_client - project = await _project(client) - source = await _verified_source(client, project, document(2)) - async with db_session.get_session_factory()() as session: - parent = await session.get(ArtifactTaskImportSource, source["source_id"]) - context = await actor_context(parent.actor_profile_id) - held, entered, release = asyncio.Event(), asyncio.Event(), asyncio.Event() - pids = {} - stage, authorize = TaskImportBatchCommands._stage_rows, AuthorizedTaskCommands.authorize_creation - - async def hold_import(commands, *args, **kwargs): - result = await stage(commands, *args, **kwargs) - pids["holder"] = await commands._session.scalar(select(func.pg_backend_pid())) - held.set() - await asyncio.wait_for(release.wait(), timeout=30) - return result - - async def observe_manual(commands, prepared): - if json.loads(prepared.payload_json)["source_type"] == "manual": - pids["waiter"] = await commands._session.scalar(select(func.pg_backend_pid())) - entered.set() - return await authorize(commands, prepared) - - async def manual_create(): - async with db_session.get_session_factory()() as session: - commands = task_commands(session, authorization=PreparedTaskAuthorization(session, context), - audit=task_transition_audit(session), actor_profile_id=context.actor_profile_id, - settings=get_settings()) - return await commands.create_task(UUID(project), TaskCreate(**(complete_task_payload() | { - "external_task_id": "source-0", - })), idempotency_key=uuid4()) - - monkeypatch.setattr(TaskImportBatchCommands, "_stage_rows", hold_import) - monkeypatch.setattr(AuthorizedTaskCommands, "authorize_creation", observe_manual) - first = asyncio.create_task(client.post(_batch_path(project), headers=auth_headers(), json={"source_id": source["source_id"]})) - second = None - try: - await asyncio.wait_for(held.wait(), timeout=30) - second = asyncio.create_task(manual_create()) - await asyncio.wait_for(entered.wait(), timeout=30) - deadline = asyncio.get_running_loop().time() + 10 - async with db_session.get_session_factory()() as observer: - while True: - blocked = await observer.scalar(text("select :holder = any(pg_blocking_pids(:waiter))"), pids) - if blocked: - break - assert asyncio.get_running_loop().time() < deadline, "normal CREATE never waited on the import authority holder" - await asyncio.sleep(0.05) - release.set() - outcomes = await asyncio.wait_for(asyncio.gather(first, second, return_exceptions=True), timeout=30) - assert outcomes[0].status_code == 201, outcomes[0].text - assert isinstance(outcomes[1], TaskReplayConflict) and outcomes[1].code == "external_task_id_conflict", outcomes - assert await _counts(project) == (1, 2, 1, 2, 2, 2) - finally: - release.set() - for pending in (first, second): - if pending is not None and not pending.done(): - pending.cancel() - await asyncio.gather(*(pending for pending in (first, second) if pending is not None), return_exceptions=True) - - -@pytest.mark.parametrize("substitution", ["foreign_verification", "foreign_task", "pending_header"]) -async def test_native_commit_refuses_partial_or_foreign_custody(import_source_client, monkeypatch, substitution): - """Native closure rejects corruption after genuine ART and CREATE validation.""" - client = import_source_client - project = await _project(client) - value = document(2) - source = await _verified_source(client, project, value) - foreign_receipt, foreign_task = None, None - if substitution == "foreign_verification": - alternate = await _verified_source(client, project, value) - from app.modules.artifacts.models import ArtifactPutAttempt, ArtifactVerificationJob, ArtifactVerificationReceipt - async with db_session.get_session_factory()() as session: - foreign_receipt = await session.scalar(select(ArtifactVerificationReceipt.id).join( - ArtifactVerificationJob, ArtifactVerificationJob.id == ArtifactVerificationReceipt.verification_job_id, - ).join(ArtifactPutAttempt, ArtifactPutAttempt.id == ArtifactVerificationJob.originating_put_attempt_id).where( - ArtifactPutAttempt.task_import_source_id == alternate["source_id"], - ).order_by(ArtifactVerificationReceipt.created_at.desc()).limit(1)) - assert foreign_receipt is not None - elif substitution == "foreign_task": - created = await client.post(f"/api/v1/projects/{project}/tasks", headers=auth_headers(), json=complete_task_payload()) - assert created.status_code == 201, created.text - foreign_task = created.json()["id"] - before = await _counts(project) - original = TaskImportBatchCommands._stage_rows - - async def corrupt(commands, batch, parsed, prepared): - result = await original(commands, batch, parsed, prepared) - if substitution == "foreign_task": - # Corrupt the final, not-yet-flushed member INSERT so an existing - # append-only UPDATE guard cannot mask a missing initial binding. - members = [row for row in commands._session.new if isinstance(row, TaskImportBatchMember)] - assert len(members) == 1 - members[0].task_id = foreign_task - return result - - monkeypatch.setattr(TaskImportBatchCommands, "_stage_rows", corrupt) - if substitution == "foreign_verification": - from app.modules.tasks import task_import_batches as owner - stage_binding = owner._stage_binding - - def corrupt_header(row, binding): - stage_binding(row, binding) - if isinstance(row, TaskImportBatch): - row.verification_receipt_id = str(foreign_receipt) - - monkeypatch.setattr(owner, "_stage_binding", corrupt_header) - elif substitution == "pending_header": - from sqlalchemy import event - from sqlalchemy.orm import Session - - def retain_pending(session, flush_context, instances): - for row in list(session.dirty): - if isinstance(row, TaskImportBatch): - # Discard completion entirely. No invalid header UPDATE or - # CHECK can mask the missing deferred reservation closure. - session.expire(row) - - event.listen(Session, "before_flush", retain_pending) - try: - rejected = await client.post(_batch_path(project), headers=auth_headers(), json={"source_id": source["source_id"]}) - assert rejected.status_code == 503, rejected.text - assert rejected.json()["error"]["retryable"] is True - assert await _counts(project) == before - finally: - if substitution == "pending_header": - event.remove(Session, "before_flush", retain_pending) - - -@pytest.mark.parametrize("table", ["task_import_batches", "task_import_batch_members", "task_import_batch_command_receipts"]) -@pytest.mark.parametrize("operation", ["update", "delete", "truncate"]) -async def test_committed_custody_rejects_direct_sql_mutation(import_source_client, table, operation): - """Each native table refuses row mutation and statement-level truncation.""" - client = import_source_client - project = await _project(client) - source = await _verified_source(client, project, document()) - imported = await client.post(_batch_path(project), headers=auth_headers(), json={"source_id": source["source_id"]}) - assert imported.status_code == 201, imported.text - async with db_session.get_session_factory()() as session, session.begin(): - before = list((await session.execute(text(f"select to_jsonb(t) from {table} t order by id"))).scalars()) - if operation == "truncate": - assert await session.scalar(text( - "select count(*) from pg_trigger where tgrelid=cast(:table as regclass) " - "and not tgisinternal and (tgtype & 32)=32 and (tgtype & 1)=0 and tgenabled='O'" - ), {"table": table}) == 1, "each owner requires its own enabled statement-level TRUNCATE guard" - updates = { - "task_import_batches": "metadata_label='changed display label'", - "task_import_batch_members": "row_index=1", - "task_import_batch_command_receipts": "request_digest='sha256:" + "a" * 64 + "'", - } - statement = {"update": f"update {table} set {updates[table]}", "delete": f"delete from {table}", - "truncate": f"truncate {table} cascade"}[operation] - with pytest.raises(DBAPIError): - async with session.begin_nested(): - await session.execute(text(statement)) - assert list((await session.execute(text(f"select to_jsonb(t) from {table} t order by id"))).scalars()) == before - recovered = await client.post(_batch_path(project), headers=auth_headers(), json={"source_id": source["source_id"]}) - assert recovered.status_code == 201 and recovered.json() == imported.json(), recovered.text diff --git a/backend/tests/test_alembic.py b/backend/tests/test_alembic.py index 8126c30b2..424429a62 100644 --- a/backend/tests/test_alembic.py +++ b/backend/tests/test_alembic.py @@ -79,7 +79,7 @@ def test_v01_graph_has_one_root_and_head() -> None: script = ScriptDirectory.from_config(config) revisions = list(script.walk_revisions()) - assert [revision.revision for revision in revisions] == [HEAD_REVISION, "0036_contribution_export_pages", "0035_task_batch_transitions", "0034_task_import_batches", "0033_contribution_reads", "0032_checker_remediation", "0031_task_import_source", "0030_routing_outcomes", "0029_external_checker_registry", "0028_lifecycle_transitions", "0027_markdown_guide_media", "0026_task_guide_read", "0025_submission_dispatch", "0024_require_second_review_false", "0023_remove_task_payment_policy", "0022_submission_packet_custody", "0021_submission_manifest", "0020_review_admission_lock_order", "0019_submitter_awards", "0018_task_routing_request", "0017_acceptance_source_contracts", "0016_review_lifecycle_fence", "0015_contribution_awards", "0014_final_acceptance", "0013_review_source", "0012_review_packet", "0011_task_routing_source", "0010_post_submit_authority", "0009_checker_material_lineage", "0008_checker_execution", "0007_checker_output_custody", "0006_history_read_authority", "0005_task_evidence_authority", "0004_task_context_authority", "0003_task_read_authority", "0002_task_queue_authority", BASELINE_REVISION] + assert [revision.revision for revision in revisions] == [HEAD_REVISION, "0033_contribution_reads", "0032_checker_remediation", "0031_task_import_source", "0030_routing_outcomes", "0029_external_checker_registry", "0028_lifecycle_transitions", "0027_markdown_guide_media", "0026_task_guide_read", "0025_submission_dispatch", "0024_require_second_review_false", "0023_remove_task_payment_policy", "0022_submission_packet_custody", "0021_submission_manifest", "0020_review_admission_lock_order", "0019_submitter_awards", "0018_task_routing_request", "0017_acceptance_source_contracts", "0016_review_lifecycle_fence", "0015_contribution_awards", "0014_final_acceptance", "0013_review_source", "0012_review_packet", "0011_task_routing_source", "0010_post_submit_authority", "0009_checker_material_lineage", "0008_checker_execution", "0007_checker_output_custody", "0006_history_read_authority", "0005_task_evidence_authority", "0004_task_context_authority", "0003_task_read_authority", "0002_task_queue_authority", BASELINE_REVISION] assert revisions[-1].down_revision is None assert script.get_heads() == [HEAD_REVISION] diff --git a/backend/tests/test_ci_lane_catalogue.py b/backend/tests/test_ci_lane_catalogue.py index aca4ef77e..55bd16f6e 100644 --- a/backend/tests/test_ci_lane_catalogue.py +++ b/backend/tests/test_ci_lane_catalogue.py @@ -44,7 +44,6 @@ def test_committed_lanes_cover_recursive_inventory_exactly_once() -> None: def test_checker_delivery_and_routing_preparation_partition_every_node_once() -> None: delivery = { - "tests/authorization/pre_submit/test_contracts.py", "tests/checkers/default/test_contract.py", "tests/checkers/default/test_execution.py", "tests/checkers/external/test_contracts.py", @@ -52,6 +51,7 @@ def test_checker_delivery_and_routing_preparation_partition_every_node_once() -> "tests/checkers/external/test_postgresql.py", "tests/checkers/external/test_registry.py", "tests/checkers/external/test_runtime.py", + "tests/checkers/execution/test_results.py", "tests/checkers/external/test_policy.py", "tests/checkers/external/test_selected_post_submit.py", "tests/checkers/external/test_selected_pre_submit.py", @@ -129,15 +129,12 @@ def test_measured_hotspots_have_explicit_semantic_owners() -> None: | { "tests/contributions/test_export_csv.py", "tests/contributions/test_export_projection.py", - "tests/contributions/test_export_cursors.py", - "tests/contributions/test_export_model_registry.py", "tests/authorization/test_contribution_read_scope.py", "tests/authorization/test_contribution_read_kernel.py", "tests/contributions/exports/test_source_reads.py", "tests/contributions/exports/test_public_reads.py", "tests/contributions/exports/test_failures.py", "tests/contributions/exports/test_concurrency.py", - "tests/contributions/exports/test_pagination.py", "tests/tasks/evaluation_delivery/test_custody.py", "tests/tasks/evaluation_delivery/test_delivery.py", "tests/tasks/evaluation_delivery/test_isolation.py", @@ -317,11 +314,6 @@ def test_measured_hotspots_have_explicit_semantic_owners() -> None: "tests/tasks/test_public_queues.py", "tests/tasks/test_locked_compensation.py", "tests/tasks/test_task_import_contract.py", - "tests/tasks/test_task_batch_transition_contract.py", - "tests/tasks/test_task_batch_transitions.py", - "tests/tasks/test_task_import_batch_contract.py", - "tests/tasks/test_task_import_batch_bindings.py", - "tests/tasks/test_task_import_batches.py", "tests/authorization/task_queues/test_authority.py", "tests/authorization/task_queues/test_contracts.py", "tests/authorization/task_queues/test_transactions.py", @@ -374,7 +366,6 @@ def test_measured_hotspots_have_explicit_semantic_owners() -> None: assert shared_a == shared_b == set(catalogue.SHARED_FOUNDATION_MODULES) assert "tests/tasks/evaluation_delivery/test_worker_materialization.py" in shared_a assert "tests/artifacts/test_review_packet_contract.py" in shared_a - assert "tests/authorization/task_authority/test_management_participants.py" in shared_a assert { "tests/test_task_import_sources.py", "tests/authorization/post_submit/test_atomicity.py", diff --git a/cli/README.md b/cli/README.md index c3df039d9..429ccbe54 100644 --- a/cli/README.md +++ b/cli/README.md @@ -472,85 +472,6 @@ foreign projects and unauthenticated/unauthorized callers are also denied. Explicit worker application is not queued broker-delivery, live setup inference or deployment proof. -## Prepare a task-import JSON source - -```sh -workstream project task-batch convert-csv --input briefs.csv --out briefs.json --label 'Evaluation briefs' --output json -workstream project task-batch source-declare PROJECT_ID --input briefs.json --idempotency-key SOURCE_UUID --output json -workstream project task-batch source-upload PROJECT_ID SOURCE_ID --input briefs.json --output json -workstream project task-batch source-status PROJECT_ID SOURCE_ID --output json -``` - -Conversion is local and needs no token or API configuration. It accepts quoted -UTF-8 CSV, including embedded commas/newlines and one optional UTF-8 BOM. It -requires 1..500 task rows and bounds both input CSV and generated JSON to 8MiB. -Invalid input produces no JSON file. `--out` must name a new file; an existing -file is never overwritten. The report names the SHA-256 and byte count of the -complete generated JSON, including its final newline. Upload those exact bytes. -Workstream retains the converted JSON source; this does not retain the original -CSV. Retain that original separately if your own workflow requires it. - -| CSV header | JSON task field | Conversion | -| --- | --- | --- | -| `external_task_id` or `source_id` | `external_task_id` | Required exact, case-sensitive source identifier | -| `title`, `description` | Same names | Required nonblank instruction text, preserved without trimming | -| `task_type` or `category` | `task_type` | Optional category, preserved | -| `skill_tags`, `languages`, `tools` | `skill_tags` | Semicolon segments concatenate in this order; trim segments and omit blank segments | -| `difficulty`, `acceptance_criteria`, `rejection_criteria` | Same names | Optional text, preserved | -| `estimated_time_minutes` | Same name | Optional whole minutes in 1..525600 | - -Unknown/duplicate headers, simultaneous alias/canonical headers, duplicate IDs, -padded/control-character IDs, invalid UTF-8/NUL, malformed quoting and row/field -limits are refused. No Task identities, guide locks or creator authority can be -supplied through CSV. The canonical JSON contract is -[`contracts/task-import.schema.json`](../contracts/task-import.schema.json). -JSON files also receive bounded canonical validation before declaration/upload, -including duplicate object members, strict field types and exact external IDs. -Their original whitespace/bytes are preserved for the commitment and upload. - -Declaration, upload and status are separate operations under current covered-PM -authority. Declaration sends only the exact JSON SHA/count with the caller's -UUID key and returns a source ID. Upload sends one raw `application/json` PUT -to that explicit project/source and carries no separate idempotency key; retained -source custody controls its replay. Status reads the actual retained ART state. -The CLI verifies returned selectors and, for writes, the exact file commitment. -A returned source/status establishes byte custody only; it does not create, -screen or release Tasks. - -Continue with explicit batch operations after source verification: - -```sh -workstream project task-batch import PROJECT_ID SOURCE_ID --idempotency-key IMPORT_UUID --output json -workstream project task-batch status PROJECT_ID BATCH_ID --output json -workstream project task-batch screen PROJECT_ID BATCH_ID --idempotency-key SCREEN_UUID --reason 'Briefs meet the approved guide' --output json -workstream project task-batch release PROJECT_ID BATCH_ID --idempotency-key RELEASE_UUID --reason 'All members are ready for work' --output json -``` - -Import returns the complete original ordered DRAFT creation facts. Status keeps -those originals separate from the current member states. SCREEN and RELEASE -select every member from immutable native membership and return ordered compact -Task IDs, statuses and locked lineage. Normal guide/policy prerequisites still -apply; release requires a nonblank reason. Each write requires its own retained -caller UUID. No command combines upload/import/screen/release or chooses per-row -retry keys. Responses are limited to 1..500 complete members: original/status -JSON is bounded to 16MiB and compact transition JSON to 2MiB. Invalid, crossed, -duplicate or partial responses are refused without partial output. - -Batch writes never retry automatically. An unknown outcome requires inspection -of `status` as an observation, followed by manual replay of the unchanged project, -source/batch, action, reason and key. SCREEN/RELEASE replay also requires every -member to retain its original post-state, locked context and unassigned custody; -later Task changes or revoked authority can prevent recovery with the same key. -The aggregate migration and real 200/500-row journey/timing proofs remain pending -in this draft implementation; no native bulk readiness is claimed. - -Source writes never retry automatically, including after HTTP/2 GOAWAY. If a -declaration outcome is unknown, manually replay only the unchanged project, -JSON file bytes and caller key. For an uncertain upload, inspect `source-status` -and then manually replay the unchanged project/source/file if appropriate. -Server storage recovery can remain pending; inspect the actual returned status -instead of treating every successful HTTP response as verified storage. - ## Create a draft project shell ```sh diff --git a/cli/internal/api/client.go b/cli/internal/api/client.go index 99656410a..a71995bfa 100644 --- a/cli/internal/api/client.go +++ b/cli/internal/api/client.go @@ -318,7 +318,7 @@ func (c *Client) requestWithKey(ctx context.Context, method, path, query string, } func (c *Client) requestWithResponseLimit(ctx context.Context, method, path, query string, body []byte, key string, successStatus, responseLimit int) (json.RawMessage, error) { - mutation := method == http.MethodPatch || method == http.MethodPost || method == http.MethodPut + mutation := method == http.MethodPatch || method == http.MethodPost response, err := c.openRequest(ctx, c.http, method, path, query, body, key, "application/json") if err != nil { return nil, err @@ -349,7 +349,7 @@ func (c *Client) openRequest(ctx context.Context, requestClient *http.Client, me } func (c *Client) openBodyRequest(ctx context.Context, requestClient *http.Client, method, path, query string, reader io.Reader, length int64, key, accept, contentType string) (*http.Response, error) { - mutation := method == http.MethodPatch || method == http.MethodPost || method == http.MethodPut + mutation := method == http.MethodPatch || method == http.MethodPost target := c.origin + path if query != "" { target += "?" + query @@ -398,7 +398,7 @@ func (c *Client) responseCorrelation(response *http.Response) string { } func (c *Client) responseFailure(method string, response *http.Response, responseBody []byte) error { - mutation := method == http.MethodPatch || method == http.MethodPost || method == http.MethodPut + mutation := method == http.MethodPatch || method == http.MethodPost correlation := c.responseCorrelation(response) code := "api_error" knownEnvelope := false @@ -415,7 +415,7 @@ func (c *Client) responseFailure(method string, response *http.Response, respons code = envelope.Error.Code } } - if method == http.MethodPost || method == http.MethodPut { + if method == http.MethodPost { knownEnvelope = canonicalMutationError(responseBody, response.Header.Get("Content-Type")) } // A complete API 4xx envelope is a known denial, independent of code @@ -424,7 +424,7 @@ func (c *Client) responseFailure(method string, response *http.Response, respons OutcomeUnknown: mutation && (response.StatusCode < 400 || response.StatusCode >= 500 || !knownEnvelope)} } -// POST/PUT writes need a complete public ApiError, not a gateway's code-shaped +// POST writes need a complete public ApiError, not a gateway's code-shaped // JSON. Profile PATCH deliberately retains its existing response contract. func canonicalMutationError(raw []byte, contentType string) bool { mediaType, _, err := mime.ParseMediaType(contentType) diff --git a/cli/internal/api/task_import_batch.go b/cli/internal/api/task_import_batch.go deleted file mode 100644 index 7d5b343cd..000000000 --- a/cli/internal/api/task_import_batch.go +++ /dev/null @@ -1,305 +0,0 @@ -package api - -import ( - "context" - "encoding/json" - jsonv2 "encoding/json/v2" - "errors" - "net/http" - "net/url" - "regexp" - "strings" - "unicode/utf8" - - "github.com/Flow-Research/workstream/cli/internal/taskimport" -) - -const taskImportResponseLimit = 16 * 1024 * 1024 -const taskBatchTransitionResponseLimit = 2 * 1024 * 1024 - -// ImportedTask identifies one original DRAFT creation, even after later advancement. -type ImportedTask struct { - ID string `json:"id"` - ExternalTaskID string `json:"external_task_id"` - Status string `json:"status"` - ProjectID string `json:"project_id"` - SourceType string `json:"source_type"` - SourceRef string `json:"source_ref"` - SourcePayloadHash string `json:"source_payload_hash"` - ImportBatchID string `json:"import_batch_id"` - CreatedBy string `json:"created_by"` - CreatedAt string `json:"created_at"` - UpdatedAt string `json:"updated_at"` -} - -// TaskImportBatch preserves original complete ordered creation custody. -type TaskImportBatch struct { - BatchID string `json:"batch_id"` - ProjectID string `json:"project_id"` - SourceID string `json:"source_id"` - SHA256 string `json:"sha256"` - ByteCount int `json:"byte_count"` - SchemaVersion string `json:"schema_version"` - MappingVersion string `json:"mapping_version"` - Label *string `json:"label"` - RowCount int `json:"row_count"` - CreatedAt string `json:"created_at"` - Tasks []ImportedTask `json:"-"` -} - -type taskImportEnvelope struct { - BatchID string `json:"batch_id"` - ProjectID string `json:"project_id"` - SourceID string `json:"source_id"` - SHA256 string `json:"sha256"` - ByteCount int `json:"byte_count"` - SchemaVersion string `json:"schema_version"` - MappingVersion string `json:"mapping_version"` - Label *string `json:"label"` - RowCount int `json:"row_count"` - CreatedAt string `json:"created_at"` - Tasks []json.RawMessage `json:"tasks"` -} - -type CurrentBatchTask struct { - TaskID string `json:"task_id"` - RowIndex int `json:"row_index"` - Status string `json:"status"` -} - -type TaskImportBatchStatus struct { - Creation TaskImportBatch - CurrentTasks []CurrentBatchTask -} - -type TaskBatchTransitionTask struct { - TaskID string `json:"task_id"` - RowIndex int `json:"row_index"` - Status string `json:"status"` - LockedGuideVersion string `json:"locked_guide_version"` - LockedContributionPolicyVersionID string `json:"locked_contribution_policy_version_id"` - LockedContextHash string `json:"locked_context_hash"` -} - -type TaskBatchTransition struct { - ProjectID string `json:"project_id"` - BatchID string `json:"batch_id"` - Operation string `json:"operation"` - RowCount int `json:"row_count"` - Tasks []TaskBatchTransitionTask `json:"tasks"` -} - -func taskImportBatchPath(project string) string { - return "/api/v1/projects/" + url.PathEscape(project) + "/task-import-batches" -} - -func validBatchSelectors(values ...string) bool { - for _, value := range values { - if len(value) > 100 || !validUUID(value) { - return false - } - } - return true -} - -// ImportTaskBatch selects existing source custody. It does not upload, screen or release. -func (c *Client) ImportTaskBatch(ctx context.Context, project, source, key string) (Result[TaskImportBatch], error) { - var result Result[TaskImportBatch] - if !validBatchSelectors(project, source, key) { - return result, errors.New("PROJECT_ID, SOURCE_ID and --idempotency-key must be UUIDs") - } - body, _ := json.Marshal(map[string]string{"source_id": source}) - raw, err := c.requestWithResponseLimit(ctx, http.MethodPost, taskImportBatchPath(project), "", body, key, http.StatusCreated, taskImportResponseLimit) - if err != nil { - return result, taskBatchWriteFailure(err) - } - value, err := c.decodeTaskImportBatch(raw, project, "", source) - if err != nil { - return result, taskBatchWriteFailure(&Failure{Code: "invalid_api_response", OutcomeUnknown: true}) - } - return Result[TaskImportBatch]{Raw: raw, Value: value}, nil -} - -func (c *Client) TaskBatchStatus(ctx context.Context, project, batch string) (Result[TaskImportBatchStatus], error) { - var result Result[TaskImportBatchStatus] - if !validBatchSelectors(project, batch) { - return result, errors.New("PROJECT_ID and BATCH_ID must be UUIDs") - } - raw, err := c.requestWithResponseLimit(ctx, http.MethodGet, taskImportBatchPath(project)+"/"+url.PathEscape(batch), "", nil, "", http.StatusOK, taskImportResponseLimit) - if err != nil { - return result, err - } - var envelope struct { - Creation json.RawMessage `json:"creation"` - CurrentTasks []json.RawMessage `json:"current_tasks"` - } - if _, err = contextObject(raw, &envelope, []string{"creation", "current_tasks"}, nil); err != nil { - return result, &Failure{Code: "invalid_api_response"} - } - creation, err := c.decodeTaskImportBatch(envelope.Creation, project, batch, "") - if err != nil || len(envelope.CurrentTasks) != creation.RowCount { - return result, &Failure{Code: "invalid_api_response"} - } - value := TaskImportBatchStatus{Creation: creation, CurrentTasks: make([]CurrentBatchTask, 0, creation.RowCount)} - for index, rawTask := range envelope.CurrentTasks { - var task CurrentBatchTask - _, err = contextObject(rawTask, &task, []string{"task_id", "row_index", "status"}, nil) - if err != nil || task.RowIndex != index || !sameUUID(task.TaskID, creation.Tasks[index].ID) || !batchStatusPattern.MatchString(task.Status) || !c.safeMetadata(task.Status) { - return result, &Failure{Code: "invalid_api_response"} - } - value.CurrentTasks = append(value.CurrentTasks, task) - } - return Result[TaskImportBatchStatus]{Raw: raw, Value: value}, nil -} - -func (c *Client) TransitionTaskBatch(ctx context.Context, project, batch, operation, key string, reason *string) (Result[TaskBatchTransition], error) { - var result Result[TaskBatchTransition] - if !validBatchSelectors(project, batch, key) || (operation != "screen" && operation != "release") { - return result, errors.New("PROJECT_ID, BATCH_ID and --idempotency-key must be UUIDs; action must be screen or release") - } - if (reason != nil && (!utf8.ValidString(*reason) || utf8.RuneCountInString(*reason) > 4000)) || - (operation == "release" && (reason == nil || strings.TrimSpace(*reason) == "")) { - return result, errors.New("reason must contain at most 4000 UTF-8 characters; release requires a nonblank reason") - } - body, err := json.Marshal(struct { - Reason *string `json:"reason"` - }{reason}) - if err != nil { - return result, err - } - raw, err := c.requestWithResponseLimit(ctx, http.MethodPost, taskImportBatchPath(project)+"/"+url.PathEscape(batch)+"/"+operation, "", body, key, http.StatusOK, taskBatchTransitionResponseLimit) - if err != nil { - return result, taskBatchWriteFailure(err) - } - value, err := c.decodeBatchTransition(raw, project, batch, operation) - if err != nil { - return result, taskBatchWriteFailure(&Failure{Code: "invalid_api_response", OutcomeUnknown: true}) - } - return Result[TaskBatchTransition]{Raw: raw, Value: value}, nil -} - -var batchStatusPattern = regexp.MustCompile(`^[a-z][a-z0-9_]{0,29}$`) - -func taskBatchWriteFailure(err error) error { - var failure *Failure - if errors.As(err, &failure) && failure.OutcomeUnknown { - failure.RecoveryHint = "batch outcome unknown; inspect status as observation, then manually replay only the unchanged project, source/batch, action, reason and idempotency key; later Task or authority changes may prevent replay" - } - return err -} - -func (c *Client) decodeBatchTransition(raw json.RawMessage, project, batch, operation string) (TaskBatchTransition, error) { - var value TaskBatchTransition - fields, err := contextObject(raw, &value, []string{"project_id", "batch_id", "operation", "row_count", "tasks"}, nil) - if err != nil || !sameUUID(value.ProjectID, project) || !sameUUID(value.BatchID, batch) || value.Operation != operation || value.RowCount < 1 || value.RowCount > taskimport.MaxRows || len(value.Tasks) != value.RowCount { - return value, &Failure{Code: "invalid_api_response"} - } - var rows []json.RawMessage - if jsonv2.Unmarshal(fields["tasks"], &rows) != nil { - return value, &Failure{Code: "invalid_api_response"} - } - seen := make(map[[16]byte]bool) - status := "screening" - if operation == "release" { - status = "ready" - } - for index, task := range value.Tasks { - var exact TaskBatchTransitionTask - _, err := contextObject(rows[index], &exact, []string{"task_id", "row_index", "status", "locked_guide_version", "locked_contribution_policy_version_id", "locked_context_hash"}, nil) - id, valid := uuidIdentity(task.TaskID) - if err != nil || !valid || seen[id] || task.RowIndex != index || task.Status != status || - !validUUID(task.LockedContributionPolicyVersionID) || !policyHash.MatchString(task.LockedContextHash) || - !utf8.ValidString(task.LockedGuideVersion) || utf8.RuneCountInString(task.LockedGuideVersion) < 1 || utf8.RuneCountInString(task.LockedGuideVersion) > 100 || - !c.safeMetadata(task.TaskID) || !c.safeMetadata(task.LockedGuideVersion) || !c.safeMetadata(task.LockedContributionPolicyVersionID) || !c.safeMetadata(task.LockedContextHash) { - return value, &Failure{Code: "invalid_api_response"} - } - seen[id] = true - } - return value, nil -} - -func (c *Client) decodeTaskImportBatch(raw json.RawMessage, project, batch, source string) (TaskImportBatch, error) { - var envelope taskImportEnvelope - _, err := contextObject(raw, &envelope, []string{"batch_id", "project_id", "source_id", "sha256", "byte_count", "schema_version", "mapping_version", "row_count", "created_at", "tasks"}, nil) - if err != nil || !validUUID(envelope.BatchID) || !sameUUID(envelope.ProjectID, project) || !validUUID(envelope.SourceID) || - (batch != "" && !sameUUID(envelope.BatchID, batch)) || (source != "" && !sameUUID(envelope.SourceID, source)) || - !policyHash.MatchString(envelope.SHA256) || envelope.ByteCount < 1 || envelope.ByteCount > taskimport.MaxBytes || - envelope.RowCount < 1 || envelope.RowCount > taskimport.MaxRows || len(envelope.Tasks) != envelope.RowCount || - envelope.SchemaVersion != "workstream.task_import.v1" || envelope.MappingVersion != "workstream.task_import.draft_mapping.v1" || !validTime(envelope.CreatedAt) { - return TaskImportBatch{}, &Failure{Code: "invalid_api_response"} - } - if envelope.Label != nil && (!utf8.ValidString(*envelope.Label) || utf8.RuneCountInString(*envelope.Label) < 1 || utf8.RuneCountInString(*envelope.Label) > 255 || strings.ContainsRune(*envelope.Label, 0) || !c.safeMetadata(*envelope.Label)) { - return TaskImportBatch{}, &Failure{Code: "invalid_api_response"} - } - value := TaskImportBatch{BatchID: envelope.BatchID, ProjectID: envelope.ProjectID, SourceID: envelope.SourceID, SHA256: envelope.SHA256, ByteCount: envelope.ByteCount, SchemaVersion: envelope.SchemaVersion, MappingVersion: envelope.MappingVersion, Label: envelope.Label, RowCount: envelope.RowCount, CreatedAt: envelope.CreatedAt, Tasks: make([]ImportedTask, 0, envelope.RowCount)} - seen, external := make(map[[16]byte]bool), make(map[string]bool) - for _, row := range envelope.Tasks { - task, err := c.decodeImportedTask(row, value) - id, valid := uuidIdentity(task.ID) - if err != nil || !valid || seen[id] || external[task.ExternalTaskID] { - return value, &Failure{Code: "invalid_api_response"} - } - seen[id], external[task.ExternalTaskID] = true, true - value.Tasks = append(value.Tasks, task) - } - return value, nil -} - -var originalTaskFields = []string{ - "id", "project_id", "locked_contribution_policy_version_id", "locked_guide_version", "locked_review_policy_id", "locked_review_policy_generation", "locked_review_policy_hash", "locked_revision_policy_id", "locked_revision_policy_generation", "locked_revision_policy_hash", "locked_guide_source_snapshot_id", "locked_guide_source_snapshot_hash", "locked_effective_project_submission_artifact_policy_id", "locked_effective_project_submission_artifact_policy_hash", "locked_pre_submit_checker_policy_id", "locked_pre_submit_checker_bundle_hash", "source_type", "source_ref", "source_payload_hash", "import_batch_id", "external_task_id", "title", "description", "task_type", "difficulty", "skill_tags", "estimated_time_minutes", "status", "acceptance_criteria", "rejection_criteria", "deadline_at", "created_by", "assigned_to", "created_at", "updated_at", -} - -func (c *Client) decodeImportedTask(raw json.RawMessage, batch TaskImportBatch) (ImportedTask, error) { - var task ImportedTask - var fields map[string]json.RawMessage - if err := jsonv2.Unmarshal(raw, &fields); err != nil || len(fields) != len(originalTaskFields) { - return task, &Failure{Code: "invalid_api_response"} - } - for _, field := range originalTaskFields { - value, present := fields[field] - if !present || ((strings.HasPrefix(field, "locked_") || field == "assigned_to" || field == "deadline_at") && string(value) != "null") { - return task, &Failure{Code: "invalid_api_response"} - } - } - // The complete public TaskResponse field set was checked above. Decode only - // identities used by CLI output; validate instructions through the canonical - // local import parser without retaining a second private Task DTO. - if jsonv2.Unmarshal(raw, &task) != nil || !sameUUID(task.ProjectID, batch.ProjectID) || task.Status != "draft" || - task.SourceType != "json_import" || task.SourceRef != "task-import-source:"+batch.SourceID || task.SourcePayloadHash != batch.SHA256 || - !sameUUID(task.ImportBatchID, batch.BatchID) || !validUUID(task.CreatedBy) || !validTime(task.CreatedAt) || !validTime(task.UpdatedAt) { - return task, &Failure{Code: "invalid_api_response"} - } - instructions := make(map[string]json.RawMessage) - for _, field := range []string{"external_task_id", "title", "description", "task_type", "difficulty", "skill_tags", "estimated_time_minutes", "acceptance_criteria", "rejection_criteria"} { - instructions[field] = fields[field] - if field == "skill_tags" { - var tags []string - if jsonv2.Unmarshal(fields[field], &tags) != nil { - return task, &Failure{Code: "invalid_api_response"} - } - for _, tag := range tags { - if !c.safeMetadata(tag) { - return task, &Failure{Code: "invalid_api_response"} - } - } - } else if field != "estimated_time_minutes" && string(fields[field]) != "null" { - var text string - if jsonv2.Unmarshal(fields[field], &text) != nil || !c.safeMetadata(text) { - return task, &Failure{Code: "invalid_api_response"} - } - } - } - validation, err := json.Marshal(map[string]any{"schema_version": "workstream.task_import.v1", "tasks": []any{instructions}}) - if err == nil { - _, err = taskimport.ValidateJSON(validation) - } - if err != nil { - return task, &Failure{Code: "invalid_api_response"} - } - for _, metadata := range []string{task.ID, task.ProjectID, task.SourceRef, task.SourcePayloadHash, task.ImportBatchID, task.CreatedBy, task.CreatedAt, task.UpdatedAt} { - if !c.safeMetadata(metadata) { - return task, &Failure{Code: "invalid_api_response"} - } - } - return task, nil -} diff --git a/cli/internal/api/task_import_source.go b/cli/internal/api/task_import_source.go deleted file mode 100644 index 730164a81..000000000 --- a/cli/internal/api/task_import_source.go +++ /dev/null @@ -1,123 +0,0 @@ -package api - -import ( - "context" - "encoding/json" - "errors" - "net/http" - "net/url" - - "github.com/Flow-Research/workstream/cli/internal/taskimport" -) - -// TaskImportSource reports retained JSON byte custody, never Task creation. -type TaskImportSource struct { - SourceID string `json:"source_id"` - ProjectID string `json:"project_id"` - SHA256 string `json:"sha256"` - ByteCount int `json:"byte_count"` - MediaType string `json:"media_type"` - Status string `json:"status"` - CreatedAt string `json:"created_at"` -} - -func taskImportSourcePath(project string) string { - return "/api/v1/projects/" + url.PathEscape(project) + "/task-import-sources" -} - -// DeclareTaskImportSource commits only the exact original JSON SHA/byte count. -// Source upload and atomic Task import remain separate explicit commands. -func (c *Client) DeclareTaskImportSource(ctx context.Context, project string, body []byte, key string) (Result[TaskImportSource], error) { - var result Result[TaskImportSource] - if !validUUID(project) || !validUUID(key) || len(project) > 100 || len(key) > 100 { - return result, errors.New("PROJECT_ID and --idempotency-key must be UUIDs") - } - commitment, err := taskimport.ValidateJSON(body) - if err != nil { - return result, err - } - request, err := json.Marshal(struct { - SHA256 string `json:"sha256"` - ByteCount int `json:"byte_count"` - }{commitment.SHA256, commitment.ByteCount}) - if err != nil { - return result, err - } - raw, err := c.requestWithKey(ctx, http.MethodPost, taskImportSourcePath(project), "", request, key, http.StatusCreated) - if err != nil { - return result, taskImportSourceFailure(err, "declare") - } - result, err = c.decodeTaskImportSource(raw, project, "") - if err != nil || result.Value.SHA256 != commitment.SHA256 || result.Value.ByteCount != commitment.ByteCount { - return Result[TaskImportSource]{}, taskImportSourceFailure(&Failure{Code: "invalid_api_response", OutcomeUnknown: true}, "declare") - } - return result, nil -} - -// UploadTaskImportSource sends the unchanged validated JSON once to the explicit -// retained source. It does not declare a source or create/screen/release Tasks. -func (c *Client) UploadTaskImportSource(ctx context.Context, project, source string, body []byte) (Result[TaskImportSource], error) { - var result Result[TaskImportSource] - if !validUUID(project) || !validUUID(source) || len(project) > 100 || len(source) > 100 { - return result, errors.New("PROJECT_ID and SOURCE_ID must be UUIDs") - } - commitment, err := taskimport.ValidateJSON(body) - if err != nil { - return result, err - } - raw, err := c.requestWithKey(ctx, http.MethodPut, taskImportSourcePath(project)+"/"+url.PathEscape(source)+"/content", "", body, "", http.StatusOK) - if err != nil { - return result, taskImportSourceFailure(err, "upload") - } - result, err = c.decodeTaskImportSource(raw, project, source) - if err != nil || result.Value.SHA256 != commitment.SHA256 || result.Value.ByteCount != commitment.ByteCount { - return Result[TaskImportSource]{}, taskImportSourceFailure(&Failure{Code: "invalid_api_response", OutcomeUnknown: true}, "upload") - } - return result, nil -} - -func (c *Client) TaskImportSourceStatus(ctx context.Context, project, source string) (Result[TaskImportSource], error) { - var result Result[TaskImportSource] - if !validUUID(project) || !validUUID(source) || len(project) > 100 || len(source) > 100 { - return result, errors.New("PROJECT_ID and SOURCE_ID must be UUIDs") - } - raw, err := c.request(ctx, http.MethodGet, taskImportSourcePath(project)+"/"+url.PathEscape(source), "", nil) - if err != nil { - return result, err - } - return c.decodeTaskImportSource(raw, project, source) -} - -func (c *Client) decodeTaskImportSource(raw json.RawMessage, project, source string) (Result[TaskImportSource], error) { - var value TaskImportSource - _, err := contextObject(raw, &value, []string{"source_id", "project_id", "sha256", "byte_count", "media_type", "status", "created_at"}, nil) - status := map[string]bool{ - "declared": true, "prepared": true, "put_in_flight": true, "acknowledgement_unknown": true, - "object_confirmed": true, "absent_replay_required": true, "integrity_mismatch": true, - "provider_unavailable": true, "conflict": true, "verified": true, "missing": true, - } - if err != nil || !validUUID(value.SourceID) || !sameUUID(value.ProjectID, project) || - (source != "" && !sameUUID(value.SourceID, source)) || !contextPolicyDigest.MatchString(value.SHA256) || - value.ByteCount < 1 || value.ByteCount > taskimport.MaxBytes || value.MediaType != "application/json" || - !status[value.Status] || !validTime(value.CreatedAt) { - return Result[TaskImportSource]{}, &Failure{Code: "invalid_api_response"} - } - for _, metadata := range []string{value.SourceID, value.ProjectID, value.SHA256, value.MediaType, value.Status, value.CreatedAt} { - if !c.safeMetadata(metadata) || sameUUID(metadata, c.token) { - return Result[TaskImportSource]{}, &Failure{Code: "invalid_api_response"} - } - } - return Result[TaskImportSource]{Raw: raw, Value: value}, nil -} - -func taskImportSourceFailure(err error, operation string) error { - var failure *Failure - if errors.As(err, &failure) && failure.OutcomeUnknown { - if operation == "declare" { - failure.RecoveryHint = "source declaration outcome unknown; manually replay only the unchanged project, JSON file bytes and idempotency key" - } else { - failure.RecoveryHint = "source upload outcome unknown; inspect source-status, then manually replay only the unchanged project, source and JSON file bytes" - } - } - return err -} diff --git a/cli/internal/command/command.go b/cli/internal/command/command.go index f3e4ba3bc..ba8484c70 100644 --- a/cli/internal/command/command.go +++ b/cli/internal/command/command.go @@ -109,7 +109,6 @@ func Run(args []string, stdout, stderr io.Writer, getenv environment, version st project := &cobra.Command{Use: "project", Short: "Public project operations"} addTaskReads(project, client, &output, stdout) - addTaskBatch(project, client, &output, stdout) addProjectCreate(project, client, &output, stdout) addGuideCreate(project, client, &output, stdout) project.AddCommand(&cobra.Command{ diff --git a/cli/internal/command/task_batch.go b/cli/internal/command/task_batch.go deleted file mode 100644 index 0fcd47193..000000000 --- a/cli/internal/command/task_batch.go +++ /dev/null @@ -1,99 +0,0 @@ -package command - -import ( - "encoding/json" - "fmt" - "io" - "os" - - "github.com/Flow-Research/workstream/cli/internal/api" - "github.com/Flow-Research/workstream/cli/internal/taskimport" - "github.com/spf13/cobra" -) - -func addTaskBatch(project *cobra.Command, client func() (*api.Client, error), output *string, stdout io.Writer) { - batch := &cobra.Command{Use: "task-batch", Short: "Explicit task import, screening and release operations"} - addTaskBatchCSV(batch, output, stdout) - addTaskBatchSources(batch, client, output, stdout) - addTaskBatchCommands(batch, client, output, stdout) - project.AddCommand(batch) -} - -func addTaskBatchCSV(batch *cobra.Command, output *string, stdout io.Writer) { - var input, destination, label string - convert := &cobra.Command{ - Use: "convert-csv", Short: "Convert local CSV briefs to uploadable JSON without contacting the server", Args: cobra.NoArgs, - RunE: func(_ *cobra.Command, _ []string) error { - if *output != "text" && *output != "json" { - return commandError{"invalid_output", "--output must be text or json"} - } - if destination == "" { - return commandError{"invalid_arguments", "--out must name a new JSON file"} - } - file, err := openTaskBatchInput(input) - if err != nil { - return err - } - defer file.Close() - converted, err := taskimport.ConvertCSV(file, label) - if err != nil { - return commandError{"invalid_task_import_csv", err.Error()} - } - if err := writeNewTaskBatchJSON(destination, converted.Bytes); err != nil { - return err - } - if *output == "json" { - raw, err := json.Marshal(struct { - JSONPath string `json:"json_path"` - SHA256 string `json:"sha256"` - ByteCount int `json:"byte_count"` - RowCount int `json:"row_count"` - }{destination, converted.SHA256, converted.ByteCount, converted.RowCount}) - if err != nil { - return err - } - return writeJSON(stdout, raw) - } - _, err = fmt.Fprintf(stdout, "JSON file: %s\nSHA-256: %s\nJSON bytes: %d\nTasks: %d\n", safeText(destination), converted.SHA256, converted.ByteCount, converted.RowCount) - return err - }, - } - convert.Flags().StringVar(&input, "input", "", "Required regular UTF-8 CSV file, at most 8MiB") - convert.Flags().StringVar(&destination, "out", "", "Required new JSON file; existing files are never overwritten") - convert.Flags().StringVar(&label, "label", "", "Optional batch display label, at most 255 characters") - batch.AddCommand(convert) -} - -func openTaskBatchInput(path string) (*os.File, error) { - bad := commandError{"invalid_arguments", "--input must be a readable regular file of 1..8388608 bytes"} - info, err := os.Stat(path) - if err != nil || !info.Mode().IsRegular() || info.Size() < 1 || info.Size() > taskimport.MaxBytes { - return nil, bad - } - file, err := os.Open(path) - if err != nil { - return nil, bad - } - info, err = file.Stat() - if err != nil || !info.Mode().IsRegular() || info.Size() < 1 || info.Size() > taskimport.MaxBytes { - file.Close() - return nil, bad - } - return file, nil -} - -func writeNewTaskBatchJSON(path string, body []byte) error { - file, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_EXCL, 0o600) - if err != nil { - return commandError{"invalid_arguments", "--out must name a writable new file; existing files are never overwritten"} - } - written, writeErr := file.Write(body) - closeErr := file.Close() - if writeErr != nil || closeErr != nil || written != len(body) { - // This command created the file and has not published a commitment. - // Remove only its incomplete local conversion output. - os.Remove(path) - return commandError{"task_import_output_failed", "could not write complete JSON output"} - } - return nil -} diff --git a/cli/internal/command/task_batch_commands.go b/cli/internal/command/task_batch_commands.go deleted file mode 100644 index b4e9f4d01..000000000 --- a/cli/internal/command/task_batch_commands.go +++ /dev/null @@ -1,106 +0,0 @@ -package command - -import ( - "fmt" - "io" - - "github.com/Flow-Research/workstream/cli/internal/api" - "github.com/spf13/cobra" -) - -func addTaskBatchCommands(batch *cobra.Command, client func() (*api.Client, error), output *string, stdout io.Writer) { - var importKey string - importCommand := &cobra.Command{ - Use: "import PROJECT_ID SOURCE_ID", Short: "Import every retained JSON row into DRAFT; does not screen or release", Args: cobra.ExactArgs(2), - RunE: func(cmd *cobra.Command, args []string) error { - apiClient, err := client() - if err != nil { - return err - } - result, err := apiClient.ImportTaskBatch(cmd.Context(), args[0], args[1], importKey) - if err != nil { - return err - } - if *output == "json" { - return writeJSON(stdout, result.Raw) - } - if err := writeTaskBatchCreation(stdout, result.Value); err != nil { - return err - } - for index, task := range result.Value.Tasks { - if _, err := fmt.Fprintf(stdout, "Row %d: %s | %s | original %s\n", index, task.ID, safeText(task.ExternalTaskID), task.Status); err != nil { - return err - } - } - return nil - }, - } - importCommand.Flags().StringVar(&importKey, "idempotency-key", "", "Required caller UUID; retain unchanged source and key for manual replay") - batch.AddCommand(importCommand) - batch.AddCommand(&cobra.Command{ - Use: "status PROJECT_ID BATCH_ID", Short: "Read complete native membership, original creation and separate current states", Args: cobra.ExactArgs(2), - RunE: func(cmd *cobra.Command, args []string) error { - apiClient, err := client() - if err != nil { - return err - } - result, err := apiClient.TaskBatchStatus(cmd.Context(), args[0], args[1]) - if err != nil { - return err - } - if *output == "json" { - return writeJSON(stdout, result.Raw) - } - if err := writeTaskBatchCreation(stdout, result.Value.Creation); err != nil { - return err - } - for _, task := range result.Value.CurrentTasks { - if _, err := fmt.Fprintf(stdout, "Row %d: %s | current %s\n", task.RowIndex, task.TaskID, safeText(task.Status)); err != nil { - return err - } - } - return nil - }, - }) - for _, operation := range []string{"screen", "release"} { - var key, reason string - command := &cobra.Command{ - Use: operation + " PROJECT_ID BATCH_ID", Short: "Explicitly " + operation + " every native member atomically", Args: cobra.ExactArgs(2), - RunE: func(cmd *cobra.Command, args []string) error { - apiClient, err := client() - if err != nil { - return err - } - var decision *string - if cmd.Flags().Changed("reason") { - decision = &reason - } - result, err := apiClient.TransitionTaskBatch(cmd.Context(), args[0], args[1], operation, key, decision) - if err != nil { - return err - } - if *output == "json" { - return writeJSON(stdout, result.Raw) - } - value := result.Value - if _, err := fmt.Fprintf(stdout, "Batch: %s\nProject: %s\nOperation: %s\nTasks: %d\n", value.BatchID, value.ProjectID, value.Operation, value.RowCount); err != nil { - return err - } - for _, task := range value.Tasks { - if _, err := fmt.Fprintf(stdout, "Row %d: %s | %s | guide %s\n", task.RowIndex, task.TaskID, task.Status, safeText(task.LockedGuideVersion)); err != nil { - return err - } - } - return nil - }, - } - command.Flags().StringVar(&key, "idempotency-key", "", "Required caller UUID; manual unchanged-key replay requires every member still matches its original post-state") - command.Flags().StringVar(&reason, "reason", "", "At most 4000 UTF-8 characters; release requires a nonblank decision reason") - batch.AddCommand(command) - } -} - -func writeTaskBatchCreation(stdout io.Writer, value api.TaskImportBatch) error { - _, err := fmt.Fprintf(stdout, "Batch: %s\nProject: %s\nSource: %s\nSHA-256: %s\nJSON bytes: %d\nTasks: %d\nOriginal state: draft\n", value.BatchID, value.ProjectID, value.SourceID, value.SHA256, value.ByteCount, value.RowCount) - return err -} diff --git a/cli/internal/command/task_batch_source.go b/cli/internal/command/task_batch_source.go deleted file mode 100644 index 244bd4336..000000000 --- a/cli/internal/command/task_batch_source.go +++ /dev/null @@ -1,92 +0,0 @@ -package command - -import ( - "fmt" - "io" - - "github.com/Flow-Research/workstream/cli/internal/api" - "github.com/Flow-Research/workstream/cli/internal/taskimport" - "github.com/spf13/cobra" -) - -func addTaskBatchSources(batch *cobra.Command, client func() (*api.Client, error), output *string, stdout io.Writer) { - var input, key string - declare := &cobra.Command{ - Use: "source-declare PROJECT_ID", Short: "Declare exact JSON byte custody; does not upload or import", Args: cobra.ExactArgs(1), - RunE: func(cmd *cobra.Command, args []string) error { - apiClient, err := client() - if err != nil { - return err - } - body, err := readTaskBatchJSON(input) - if err != nil { - return err - } - result, err := apiClient.DeclareTaskImportSource(cmd.Context(), args[0], body, key) - if err != nil { - return err - } - return writeTaskBatchSource(stdout, *output, result) - }, - } - declare.Flags().StringVar(&input, "input", "", "Required canonical UTF-8 JSON file, at most 8MiB; exact bytes determine the commitment") - declare.Flags().StringVar(&key, "idempotency-key", "", "Required caller UUID; retain unchanged file and key for manual declaration replay") - batch.AddCommand(declare) - var uploadInput string - upload := &cobra.Command{ - Use: "source-upload PROJECT_ID SOURCE_ID", Short: "Upload exact JSON once to a declared source; does not import", Args: cobra.ExactArgs(2), - RunE: func(cmd *cobra.Command, args []string) error { - apiClient, err := client() - if err != nil { - return err - } - body, err := readTaskBatchJSON(uploadInput) - if err != nil { - return err - } - result, err := apiClient.UploadTaskImportSource(cmd.Context(), args[0], args[1], body) - if err != nil { - return err - } - return writeTaskBatchSource(stdout, *output, result) - }, - } - upload.Flags().StringVar(&uploadInput, "input", "", "Required unchanged canonical JSON file matching the source SHA/count, at most 8MiB") - batch.AddCommand(upload) - batch.AddCommand(&cobra.Command{ - Use: "source-status PROJECT_ID SOURCE_ID", Short: "Inspect retained JSON custody under current authority", Args: cobra.ExactArgs(2), - RunE: func(cmd *cobra.Command, args []string) error { - apiClient, err := client() - if err != nil { - return err - } - result, err := apiClient.TaskImportSourceStatus(cmd.Context(), args[0], args[1]) - if err != nil { - return err - } - return writeTaskBatchSource(stdout, *output, result) - }, - }) -} - -func readTaskBatchJSON(path string) ([]byte, error) { - file, err := openTaskBatchInput(path) - if err != nil { - return nil, err - } - defer file.Close() - body, err := io.ReadAll(io.LimitReader(file, taskimport.MaxBytes+1)) - if err != nil || len(body) < 1 || len(body) > taskimport.MaxBytes { - return nil, commandError{"invalid_arguments", "--input must contain 1..8388608 readable JSON bytes"} - } - return body, nil -} - -func writeTaskBatchSource(stdout io.Writer, output string, result api.Result[api.TaskImportSource]) error { - if output == "json" { - return writeJSON(stdout, result.Raw) - } - value := result.Value - _, err := fmt.Fprintf(stdout, "Source: %s\nProject: %s\nSHA-256: %s\nJSON bytes: %d\nStorage status: %s\n", safeText(value.SourceID), safeText(value.ProjectID), value.SHA256, value.ByteCount, safeText(value.Status)) - return err -} diff --git a/cli/internal/taskimport/convert.go b/cli/internal/taskimport/convert.go deleted file mode 100644 index f3cfaa1c6..000000000 --- a/cli/internal/taskimport/convert.go +++ /dev/null @@ -1,231 +0,0 @@ -// Package taskimport converts local CSV briefs into the server's sole JSON -// import format. The returned commitment identifies JSON bytes, never CSV bytes. -package taskimport - -import ( - "bytes" - "crypto/sha256" - "encoding/csv" - "encoding/hex" - "encoding/json" - "fmt" - "io" - "strconv" - "strings" - "unicode" - "unicode/utf8" -) - -const MaxBytes = 8 * 1024 * 1024 -const MaxRows = 500 - -// Conversion carries the exact upload bytes and their independently reportable -// commitment. Callers must write/upload Bytes without reserializing the document. -type Conversion struct { - Bytes []byte - SHA256 string - ByteCount int - RowCount int -} - -type document struct { - SchemaVersion string `json:"schema_version"` - Metadata metadata `json:"metadata"` - Tasks []row `json:"tasks"` -} - -type metadata struct { - Label *string `json:"label"` -} - -type row struct { - ExternalTaskID string `json:"external_task_id"` - Title string `json:"title"` - Description string `json:"description"` - TaskType string `json:"task_type,omitempty"` - Difficulty string `json:"difficulty,omitempty"` - SkillTags []string `json:"skill_tags"` - EstimatedTimeMinutes *int `json:"estimated_time_minutes,omitempty"` - AcceptanceCriteria string `json:"acceptance_criteria,omitempty"` - RejectionCriteria string `json:"rejection_criteria,omitempty"` -} - -// InputError identifies a bounded CSV row/field failure without echoing briefs. -// Row is the one-based task row, excluding the header; zero denotes the document. -type InputError struct { - Row int - Field string - Code string -} - -func (e *InputError) Error() string { - if e.Row > 0 { - return fmt.Sprintf("CSV task row %d: %s (%s)", e.Row, e.Code, e.Field) - } - return fmt.Sprintf("CSV input: %s (%s)", e.Code, e.Field) -} - -func invalid(index int, field, code string) error { - return &InputError{Row: index, Field: field, Code: code} -} - -// ConvertCSV accepts quoted UTF-8 CSV with required external_task_id (or source_id), -// title and description headers. category aliases task_type; semicolon-separated -// skill_tags, languages and tools concatenate in that order, omitting blank -// segments. Aliases cannot coexist. No input text is otherwise trimmed/repaired. -func ConvertCSV(input io.Reader, label string) (Conversion, error) { - body, err := io.ReadAll(io.LimitReader(input, MaxBytes+1)) - if err != nil { - return Conversion{}, invalid(0, "document", "unreadable") - } - if len(body) == 0 || len(body) > MaxBytes { - return Conversion{}, invalid(0, "document", "requires_1_to_8388608_bytes") - } - if !utf8.Valid(body) || bytes.IndexByte(body, 0) >= 0 { - return Conversion{}, invalid(0, "document", "requires_utf8_without_nul") - } - if label != "" && !validText(label, 255, true) { - return Conversion{}, invalid(0, "label", "invalid_label") - } - reader := csv.NewReader(bytes.NewReader(bytes.TrimPrefix(body, []byte{0xef, 0xbb, 0xbf}))) - reader.FieldsPerRecord = -1 - header, err := reader.Read() - if err != nil { - return Conversion{}, invalid(0, "header", "invalid_csv_header") - } - columns, err := headers(header) - if err != nil { - return Conversion{}, err - } - doc := document{SchemaVersion: "workstream.task_import.v1", Tasks: make([]row, 0)} - if label != "" { - doc.Metadata.Label = &label - } - seen := make(map[string]struct{}) - for index := 1; ; index++ { - values, readErr := reader.Read() - if readErr == io.EOF { - break - } - if index > MaxRows { - return Conversion{}, invalid(index, "tasks", "maximum_500_rows") - } - if readErr != nil || len(values) != len(header) { - return Conversion{}, invalid(index, "row", "invalid_csv_row") - } - value, parseErr := parseRow(values, columns, index) - if parseErr != nil { - return Conversion{}, parseErr - } - if _, duplicate := seen[value.ExternalTaskID]; duplicate { - return Conversion{}, invalid(index, "external_task_id", "duplicate_external_task_id") - } - seen[value.ExternalTaskID] = struct{}{} - doc.Tasks = append(doc.Tasks, value) - } - if len(doc.Tasks) == 0 { - return Conversion{}, invalid(0, "tasks", "requires_at_least_one_row") - } - encoded, err := json.Marshal(doc) - if err != nil { - return Conversion{}, invalid(0, "document", "cannot_encode_json") - } - encoded = append(encoded, '\n') - if len(encoded) > MaxBytes { - return Conversion{}, invalid(0, "document", "json_exceeds_8388608_bytes") - } - sum := sha256.Sum256(encoded) - return Conversion{Bytes: encoded, SHA256: "sha256:" + hex.EncodeToString(sum[:]), ByteCount: len(encoded), RowCount: len(doc.Tasks)}, nil -} - -func headers(values []string) (map[string]int, error) { - allowed := map[string]bool{ - "external_task_id": true, "source_id": true, "title": true, "description": true, - "task_type": true, "category": true, "difficulty": true, "skill_tags": true, - "languages": true, "tools": true, "estimated_time_minutes": true, - "acceptance_criteria": true, "rejection_criteria": true, - } - columns := make(map[string]int) - for index, field := range values { - if !allowed[field] { - return nil, invalid(0, "header", "unknown_header") - } - if _, exists := columns[field]; exists { - return nil, invalid(0, "header", "duplicate_header") - } - columns[field] = index - } - for alias, canonical := range map[string]string{"source_id": "external_task_id", "category": "task_type"} { - if index, exists := columns[alias]; exists { - if _, conflict := columns[canonical]; conflict { - return nil, invalid(0, "header", "conflicting_alias_headers") - } - columns[canonical] = index - } - } - for _, required := range []string{"external_task_id", "title", "description"} { - if _, present := columns[required]; !present { - return nil, invalid(0, required, "required_header_missing") - } - } - return columns, nil -} - -func validText(value string, maximum int, nonblank bool) bool { - return utf8.ValidString(value) && !strings.ContainsRune(value, 0) && utf8.RuneCountInString(value) <= maximum && (!nonblank || strings.TrimSpace(value) != "") -} - -func parseRow(values []string, columns map[string]int, index int) (row, error) { - get := func(field string) string { - if column, exists := columns[field]; exists { - return values[column] - } - return "" - } - result := row{ - ExternalTaskID: get("external_task_id"), Title: get("title"), Description: get("description"), - TaskType: get("task_type"), Difficulty: get("difficulty"), SkillTags: []string{}, - AcceptanceCriteria: get("acceptance_criteria"), RejectionCriteria: get("rejection_criteria"), - } - for _, field := range []struct { - name string - value string - maximum int - nonblank bool - }{ - {"external_task_id", result.ExternalTaskID, 200, true}, {"title", result.Title, 255, true}, - {"description", result.Description, 50000, true}, {"task_type", result.TaskType, 80, false}, - {"difficulty", result.Difficulty, 80, false}, {"acceptance_criteria", result.AcceptanceCriteria, 50000, false}, - {"rejection_criteria", result.RejectionCriteria, 50000, false}, - } { - if !validText(field.value, field.maximum, field.nonblank) { - return row{}, invalid(index, field.name, "invalid_field") - } - } - if strings.TrimSpace(result.ExternalTaskID) != result.ExternalTaskID || strings.IndexFunc(result.ExternalTaskID, unicode.IsControl) >= 0 { - return row{}, invalid(index, "external_task_id", "ambiguous_external_task_id") - } - for _, field := range []string{"skill_tags", "languages", "tools"} { - for _, part := range strings.Split(get(field), ";") { - tag := strings.TrimSpace(part) - if tag == "" { - continue - } - if !validText(tag, 200, true) { - return row{}, invalid(index, field, "invalid_skill_tag") - } - result.SkillTags = append(result.SkillTags, tag) - } - } - if len(result.SkillTags) > 100 { - return row{}, invalid(index, "skill_tags", "maximum_100_tags") - } - if text := get("estimated_time_minutes"); text != "" { - minutes, err := strconv.Atoi(text) - if err != nil || minutes < 1 || minutes > 525600 { - return row{}, invalid(index, "estimated_time_minutes", "invalid_minutes") - } - result.EstimatedTimeMinutes = &minutes - } - return result, nil -} diff --git a/cli/internal/taskimport/convert_test.go b/cli/internal/taskimport/convert_test.go deleted file mode 100644 index 20228e9ae..000000000 --- a/cli/internal/taskimport/convert_test.go +++ /dev/null @@ -1,115 +0,0 @@ -package taskimport - -import ( - "crypto/sha256" - "encoding/csv" - "encoding/hex" - "encoding/json" - "errors" - "fmt" - "strings" - "testing" -) - -func TestQuotedUnicodeCSVCommitment(t *testing.T) { - input := "\ufeffsource_id,title,description,category,skill_tags,languages,tools,estimated_time_minutes,acceptance_criteria\r\n" + - "brief-É,\"Caption, français\",\"First line\nSecond line: 日本語\",caption,\" review ; ;accuracy\",fr;ja,editor,30,Usable caption\r\n" - result, err := ConvertCSV(strings.NewReader(input), "Multilingual briefs") - if err != nil { - t.Fatal(err) - } - var value document - if err := json.Unmarshal(result.Bytes, &value); err != nil { - t.Fatal(err) - } - if value.SchemaVersion != "workstream.task_import.v1" || value.Metadata.Label == nil || *value.Metadata.Label != "Multilingual briefs" || len(value.Tasks) != 1 { - t.Fatalf("unexpected document metadata: %#v", value) - } - task := value.Tasks[0] - if task.ExternalTaskID != "brief-É" || task.Title != "Caption, français" || task.Description != "First line\nSecond line: 日本語" || task.TaskType != "caption" || strings.Join(task.SkillTags, ";") != "review;accuracy;fr;ja;editor" || task.EstimatedTimeMinutes == nil || *task.EstimatedTimeMinutes != 30 { - t.Fatalf("CSV instructions were mapped incorrectly: %#v", task) - } - sum := sha256.Sum256(result.Bytes) - if result.SHA256 != "sha256:"+hex.EncodeToString(sum[:]) || result.ByteCount != len(result.Bytes) || result.RowCount != 1 || result.Bytes[len(result.Bytes)-1] != '\n' { - t.Fatal("commitment does not identify the complete written JSON bytes") - } - again, err := ConvertCSV(strings.NewReader(input), "Multilingual briefs") - if err != nil || string(again.Bytes) != string(result.Bytes) { - t.Fatal("unchanged conversion did not produce identical bytes") - } -} - -func TestCSVRefusalsProduceNoOutput(t *testing.T) { - for _, test := range []struct { - name, input, code string - row int - }{ - {"duplicate header", "external_task_id,title,title,description\na,T,T,D\n", "duplicate_header", 0}, - {"unknown header", "external_task_id,title,description,created_by\na,T,D,actor\n", "unknown_header", 0}, - {"missing id header", "title,description\nT,D\n", "required_header_missing", 0}, - {"crossed id aliases", "external_task_id,source_id,title,description\na,b,T,D\n", "conflicting_alias_headers", 0}, - {"crossed category aliases", "external_task_id,title,description,task_type,category\na,T,D,A,B\n", "conflicting_alias_headers", 0}, - {"no rows", "external_task_id,title,description\n", "requires_at_least_one_row", 0}, - {"bad quote", "external_task_id,title,description\na,\"unterminated,D\n", "invalid_csv_row", 1}, - {"wrong columns", "external_task_id,title,description\na,T,D,extra\n", "invalid_csv_row", 1}, - {"duplicate id", "external_task_id,title,description\na,T,D\na,T2,D2\n", "duplicate_external_task_id", 2}, - {"blank instructions", "external_task_id,title,description\na, ,D\n", "invalid_field", 1}, - {"padded id", "external_task_id,title,description\n a,T,D\n", "ambiguous_external_task_id", 1}, - {"control id", "external_task_id,title,description\na\t,T,D\n", "ambiguous_external_task_id", 1}, - {"nul", "external_task_id,title,description\na,T,D\x00\n", "requires_utf8_without_nul", 0}, - {"invalid utf8", "external_task_id,title,description\na,T,D\xff\n", "requires_utf8_without_nul", 0}, - {"bad minutes", "external_task_id,title,description,estimated_time_minutes\na,T,D,0\n", "invalid_minutes", 1}, - {"oversized title", "external_task_id,title,description\na," + strings.Repeat("é", 256) + ",D\n", "invalid_field", 1}, - {"too many tags", "external_task_id,title,description,skill_tags\na,T,D," + strings.Repeat("tag;", 101) + "\n", "maximum_100_tags", 1}, - } { - t.Run(test.name, func(t *testing.T) { - result, err := ConvertCSV(strings.NewReader(test.input), "") - var refusal *InputError - if !errors.As(err, &refusal) || refusal.Code != test.code || refusal.Row != test.row || len(result.Bytes) != 0 { - t.Fatalf("expected bounded refusal %s at row %d with zero output; got %#v, %v", test.code, test.row, result, err) - } - }) - } -} - -func TestRowAndByteBoundaries(t *testing.T) { - var input strings.Builder - input.WriteString("external_task_id,title,description\n") - for index := 0; index < MaxRows; index++ { - fmt.Fprintf(&input, "task-%d,T,D\n", index) - } - result, err := ConvertCSV(strings.NewReader(input.String()), "") - if err != nil || result.RowCount != MaxRows { - t.Fatalf("500 rows should be admitted: %v", err) - } - input.WriteString("task-501,T,D\n") - _, err = ConvertCSV(strings.NewReader(input.String()), "") - var refusal *InputError - if !errors.As(err, &refusal) || refusal.Code != "maximum_500_rows" || refusal.Row != 501 { - t.Fatalf("501 rows should be refused: %v", err) - } - _, err = ConvertCSV(strings.NewReader(strings.Repeat("x", MaxBytes+1)), "") - if !errors.As(err, &refusal) || refusal.Code != "requires_1_to_8388608_bytes" { - t.Fatalf("oversized CSV should be refused before parsing: %v", err) - } - // JSON escapes these otherwise valid CSV instructions. Enforce the output - // bound too; input within 8MiB must not produce an unuploadable document. - var expanded strings.Builder - writer := csv.NewWriter(&expanded) - writer.Write([]string{"external_task_id", "title", "description"}) - for index := 0; index < 40; index++ { - writer.Write([]string{fmt.Sprint(index), "T", strings.Repeat("\x01", 40000)}) - } - writer.Flush() - _, err = ConvertCSV(strings.NewReader(expanded.String()), "") - if !errors.As(err, &refusal) || refusal.Code != "json_exceeds_8388608_bytes" { - t.Fatalf("oversized converted JSON should be refused: %v", err) - } -} - -func TestExternalIDsAreCaseSensitive(t *testing.T) { - result, err := ConvertCSV(strings.NewReader("external_task_id,title,description\na,T,D\nA,T,D\n"), "") - if err != nil || result.RowCount != 2 { - t.Fatalf("distinct case-sensitive IDs should survive: %v", err) - } -} diff --git a/cli/internal/taskimport/json.go b/cli/internal/taskimport/json.go deleted file mode 100644 index ede51e0dd..000000000 --- a/cli/internal/taskimport/json.go +++ /dev/null @@ -1,155 +0,0 @@ -package taskimport - -import ( - "bytes" - "crypto/sha256" - "encoding/hex" - "encoding/json" - jsonv2 "encoding/json/v2" - "strconv" - "strings" - "unicode" - "unicode/utf8" -) - -// ValidateJSON checks the canonical server input without rewriting its bytes. -// The commitment is therefore usable for separate declaration and upload. -func ValidateJSON(body []byte) (Conversion, error) { - if len(body) == 0 || len(body) > MaxBytes { - return Conversion{}, invalid(0, "document", "requires_1_to_8388608_bytes") - } - if !utf8.Valid(body) { - return Conversion{}, invalid(0, "document", "requires_utf8_without_nul") - } - fields, err := jsonObject(body, map[string]bool{"schema_version": true, "metadata": true, "tasks": true}) - if err != nil { - return Conversion{}, invalid(0, "document", "invalid_json_document") - } - version, err := jsonString(fields["schema_version"], false) - if err != nil || version != "workstream.task_import.v1" { - return Conversion{}, invalid(0, "schema_version", "invalid_schema_version") - } - if raw, present := fields["metadata"]; present { - metadata, err := jsonObject(raw, map[string]bool{"label": true}) - if err != nil { - return Conversion{}, invalid(0, "metadata", "invalid_metadata") - } - if raw, present := metadata["label"]; present && !jsonNull(raw) { - label, err := jsonString(raw, false) - if err != nil || len(label) == 0 || !validText(label, 255, false) { - return Conversion{}, invalid(0, "label", "invalid_label") - } - } - } - var members []json.RawMessage - if jsonv2.Unmarshal(fields["tasks"], &members) != nil || len(members) < 1 || len(members) > MaxRows { - return Conversion{}, invalid(0, "tasks", "requires_1_to_500_rows") - } - seen := make(map[string]bool) - for index, raw := range members { - id, err := validateJSONRow(raw, index+1) - if err != nil { - return Conversion{}, err - } - if seen[id] { - return Conversion{}, invalid(index+1, "external_task_id", "duplicate_external_task_id") - } - seen[id] = true - } - sum := sha256.Sum256(body) - return Conversion{Bytes: body, SHA256: "sha256:" + hex.EncodeToString(sum[:]), ByteCount: len(body), RowCount: len(members)}, nil -} - -func jsonObject(raw []byte, allowed map[string]bool) (map[string]json.RawMessage, error) { - var fields map[string]json.RawMessage - if err := jsonv2.Unmarshal(raw, &fields); err != nil { - return nil, err - } - if fields == nil { - return nil, invalid(0, "object", "requires_object") - } - for field := range fields { - if !allowed[field] { - return nil, invalid(0, "object", "unknown_field") - } - } - return fields, nil -} - -func jsonString(raw []byte, nullable bool) (string, error) { - if nullable && jsonNull(raw) { - return "", nil - } - var value *string - if err := jsonv2.Unmarshal(raw, &value); err != nil { - return "", err - } - if value == nil { - return "", invalid(0, "text", "requires_string") - } - return *value, nil -} - -func jsonNull(raw []byte) bool { return bytes.Equal(bytes.TrimSpace(raw), []byte("null")) } - -func validateJSONRow(raw []byte, index int) (string, error) { - allowed := map[string]bool{ - "external_task_id": true, "title": true, "description": true, "task_type": true, - "difficulty": true, "skill_tags": true, "estimated_time_minutes": true, - "acceptance_criteria": true, "rejection_criteria": true, - } - fields, err := jsonObject(raw, allowed) - if err != nil { - return "", invalid(index, "row", "invalid_json_row") - } - var id string - for _, field := range []struct { - name string - maximum int - required bool - }{ - {"external_task_id", 200, true}, {"title", 255, true}, {"description", 50000, true}, - {"task_type", 80, false}, {"difficulty", 80, false}, - {"acceptance_criteria", 50000, false}, {"rejection_criteria", 50000, false}, - } { - raw, present := fields[field.name] - if !present && !field.required { - continue - } - value, err := jsonString(raw, !field.required) - if err != nil || !validText(value, field.maximum, field.required) { - return "", invalid(index, field.name, "invalid_field") - } - if field.name == "external_task_id" { - if strings.TrimSpace(value) != value || strings.IndexFunc(value, unicode.IsControl) >= 0 { - return "", invalid(index, field.name, "ambiguous_external_task_id") - } - id = value - } - } - if raw, present := fields["skill_tags"]; present { - var tags []*string - if jsonv2.Unmarshal(raw, &tags) != nil || tags == nil || len(tags) > 100 { - return "", invalid(index, "skill_tags", "invalid_skill_tags") - } - for _, tag := range tags { - if tag == nil || !validText(*tag, 200, true) { - return "", invalid(index, "skill_tags", "invalid_skill_tag") - } - } - } - if raw, present := fields["estimated_time_minutes"]; present && !jsonNull(raw) { - raw = bytes.TrimSpace(raw) - // Pydantic's strict integer excludes JSON decimal/exponent notation. - for _, digit := range raw { - if digit < '0' || digit > '9' { - return "", invalid(index, "estimated_time_minutes", "invalid_minutes") - } - } - minutes, err := strconv.Atoi(string(raw)) - if err != nil || minutes < 1 || minutes > 525600 { - return "", invalid(index, "estimated_time_minutes", "invalid_minutes") - } - } - return id, nil -} diff --git a/cli/internal/taskimport/json_test.go b/cli/internal/taskimport/json_test.go deleted file mode 100644 index 0d1537fc0..000000000 --- a/cli/internal/taskimport/json_test.go +++ /dev/null @@ -1,49 +0,0 @@ -package taskimport - -import ( - "crypto/sha256" - "encoding/hex" - "strings" - "testing" -) - -func TestJSONValidationPreservesInputCommitment(t *testing.T) { - input := []byte(" {\n\"schema_version\":\"workstream.task_import.v1\",\"metadata\": {\"label\": null},\"tasks\":[{\"external_task_id\":\"É\",\"title\":\"Caption\",\"description\":\"日本語\",\"skill_tags\":[],\"difficulty\":null,\"estimated_time_minutes\": 30}]}\n") - result, err := ValidateJSON(input) - sum := sha256.Sum256(input) - if err != nil || string(result.Bytes) != string(input) || result.ByteCount != len(input) || result.RowCount != 1 || result.SHA256 != "sha256:"+hex.EncodeToString(sum[:]) { - t.Fatalf("valid original JSON bytes must remain unchanged: %#v, %v", result, err) - } - converted, err := ConvertCSV(strings.NewReader("external_task_id,title,description\na,T,D\n"), "") - if err != nil { - t.Fatal(err) - } - checked, err := ValidateJSON(converted.Bytes) - if err != nil || checked.SHA256 != converted.SHA256 { - t.Fatalf("converter output must pass canonical validation unchanged: %v", err) - } -} - -func TestAmbiguousAndNoncanonicalJSONRefused(t *testing.T) { - base := `{"schema_version":"workstream.task_import.v1","tasks":[{"external_task_id":"a","title":"T","description":"D"}]}` - for _, input := range []string{ - strings.Replace(base, `"title":"T"`, `"title":"T","title":"other"`, 1), - strings.Replace(base, `"title":"T"`, `"title":null`, 1), - strings.Replace(base, `"title":"T"`, `"title":"\ud800"`, 1), - strings.Replace(base, `"title":"T"`, `"title":"\u0000"`, 1), - strings.Replace(base, `"external_task_id":"a"`, `"external_task_id":" a"`, 1), - strings.Replace(base, `"description":"D"`, `"description":"D","skill_tags":null`, 1), - strings.Replace(base, `"description":"D"`, `"description":"D","skill_tags":[null]`, 1), - strings.Replace(base, `"description":"D"`, `"description":"D","estimated_time_minutes":1.0`, 1), - strings.Replace(base, `"description":"D"`, `"description":"D","estimated_time_minutes":true`, 1), - strings.Replace(base, `"description":"D"`, `"description":"D","created_by":"actor"`, 1), - strings.Replace(base, `"tasks":`, `"metadata":null,"tasks":`, 1), - strings.Replace(base, `"tasks":`, `"metadata":{"label":""},"tasks":`, 1), - base + `{}`, - } { - result, err := ValidateJSON([]byte(input)) - if err == nil || len(result.Bytes) != 0 { - t.Fatalf("noncanonical JSON must produce no upload commitment: %s", input) - } - } -} diff --git a/cli/tests/integration/test_http_boundary.py b/cli/tests/integration/test_http_boundary.py index 7a0ba8480..5c9cf1b0d 100644 --- a/cli/tests/integration/test_http_boundary.py +++ b/cli/tests/integration/test_http_boundary.py @@ -94,9 +94,6 @@ def do_POST(self): # noqa: N802 - standard HTTP handler interface after_body() self.do_GET() - def do_PUT(self): # noqa: N802 - same exact-byte capture for source writes - self.do_POST() - def do_CONNECT(self): # noqa: N802 - captures attempted HTTPS proxy use requests.append( (self.command, self.path, self.headers.get("Authorization")) diff --git a/cli/tests/integration/test_task_batch_commands_http.py b/cli/tests/integration/test_task_batch_commands_http.py deleted file mode 100644 index 38c8f637e..000000000 --- a/cli/tests/integration/test_task_batch_commands_http.py +++ /dev/null @@ -1,269 +0,0 @@ -"""Built batch CLI uses separate typed calls and preserves uncertain-write recovery.""" - -from copy import deepcopy -import json -from uuid import UUID - -from app.modules.tasks.schemas import TaskResponse -from http2_fixture import goaway_fixture -from test_contributor_task_mutations import KEY, canonical_error -from test_http_boundary import ACTOR, PROJECT, TOKEN, http_fixture -from test_task_batch_sources_http import SOURCE - -BATCH = "018f0ebc-7966-7e8d-bc4d-1cae1e000006" - - -def creation(count=2): - """Construct public DTO-shaped HTTP fixtures; these are not native custody proof.""" - tasks = [] - for index in range(count): - row = dict.fromkeys(TaskResponse.model_fields) - row.update( - id=str(UUID(int=UUID(ACTOR).int + 1000 + index)), - project_id=PROJECT, - external_task_id=f"brief-{index}", - title="Caption café", - description="Quoted\nbrief", - skill_tags=["French"], - source_type="json_import", - source_ref=f"task-import-source:{SOURCE}", - source_payload_hash="sha256:" + "a" * 64, - import_batch_id=BATCH, - status="draft", - created_by=ACTOR, - created_at="2026-10-11T12:00:00Z", - updated_at="2026-10-11T12:00:00Z", - ) - tasks.append(TaskResponse.model_validate(row).model_dump(mode="json")) - return { - "batch_id": BATCH, - "project_id": PROJECT, - "source_id": SOURCE, - "sha256": "sha256:" + "a" * 64, - "byte_count": 1000, - "schema_version": "workstream.task_import.v1", - "mapping_version": "workstream.task_import.draft_mapping.v1", - "label": None, - "row_count": count, - "created_at": "2026-10-11T12:00:00Z", - "tasks": tasks, - } - - -def status(count=2): - original = creation(count) - return { - "creation": original, - "current_tasks": [ - {"task_id": row["id"], "row_index": index, "status": "ready"} - for index, row in enumerate(original["tasks"]) - ], - } - - -def transition(operation="screen", count=2): - return { - "project_id": PROJECT, - "batch_id": BATCH, - "operation": operation, - "row_count": count, - "tasks": [ - { - "task_id": row["id"], - "row_index": index, - "status": "screening" if operation == "screen" else "ready", - "locked_guide_version": "v1.0.0", - "locked_contribution_policy_version_id": ACTOR, - "locked_context_hash": "sha256:" + "b" * 64, - } - for index, row in enumerate(creation(count)["tasks"]) - ], - } - - -def invoke( - cli, - origin, - operation, - *, - project=PROJECT, - target=None, - key=KEY, - reason="Decision", - **kwargs, -): - args = [ - "-o", - "json", - "project", - "task-batch", - operation, - project, - target or (SOURCE if operation == "import" else BATCH), - ] - if operation != "status": - args.extend(("--idempotency-key", key)) - if operation in {"screen", "release"} and reason is not None: - args.extend(("--reason", reason)) - return cli(origin, TOKEN, *args, **kwargs) - - -def test_explicit_commands_preserve_original_and_current_facts_and_exact_requests(cli): - with http_fixture() as (origin, response, requests): - response.update(status=201, body=json.dumps(creation()).encode()) - result = invoke(cli, origin, "import") - assert result.returncode == 0 and json.loads(result.stdout) == creation(), ( - result.stderr - ) - response.update(status=200, body=json.dumps(status()).encode()) - result = invoke(cli, origin, "status") - assert result.returncode == 0 and json.loads(result.stdout) == status(), ( - result.stderr - ) - for operation in ("screen", "release"): - response.update(body=json.dumps(transition(operation)).encode()) - for _ in range(2): - result = invoke(cli, origin, operation) - assert result.returncode == 0 and json.loads( - result.stdout - ) == transition(operation), result.stderr - prefix = f"/api/v1/projects/{PROJECT}/task-import-batches" - assert requests == [ - ("POST", prefix, "Bearer " + TOKEN), - ("GET", f"{prefix}/{BATCH}", "Bearer " + TOKEN), - *( - ("POST", f"{prefix}/{BATCH}/{operation}", "Bearer " + TOKEN) - for operation in ("screen", "screen", "release", "release") - ), - ] - assert response["commands"] == [ - ("application/json", [KEY], {"source_id": SOURCE}), - *[("application/json", [KEY], {"reason": "Decision"}) for _ in range(4)], - ] - - -def test_complete_500_row_original_status_and_compact_results_are_not_truncated(cli): - with http_fixture() as (origin, response, _requests): - for operation, body, code in ( - ("import", creation(500), 201), - ("status", status(500), 200), - ("screen", transition(count=500), 200), - ): - raw = json.dumps(body).encode() - assert len(raw) > 64 * 1024 - response.update(status=code, body=raw) - result = invoke(cli, origin, operation) - assert result.returncode == 0 and json.loads(result.stdout) == body, ( - result.stderr - ) - - -def test_malformed_or_crossed_original_receipts_are_uncertain_imports(cli): - values = [] - for field, value in ( - ("project_id", SOURCE), - ("source_id", PROJECT), - ("row_count", 3), - ("schema_version", "other"), - ): - values.append(creation() | {field: value}) - for change in ("advanced", "locked", "duplicate", "source", "extra", "null"): - value = deepcopy(creation()) - row = value["tasks"][1] - if change == "advanced": - row["status"] = "ready" - elif change == "locked": - row["locked_guide_version"] = "v1.0.0" - elif change == "duplicate": - row["id"] = value["tasks"][0]["id"] - elif change == "source": - row["source_ref"] = "task-import-source:" + PROJECT - elif change == "extra": - row["provider_path"] = "private" - else: - row["title"] = None - values.append(value) - with http_fixture() as (origin, response, requests): - for value in values: - response.update(status=201, body=json.dumps(value).encode()) - result = invoke(cli, origin, "import") - assert result.returncode == 1 and result.stdout == "", result.stderr - assert json.loads(result.stderr)["error"]["outcome_unknown"] is True - assert len(requests) == len(values) - - -def test_malformed_complete_membership_and_current_projection_are_refused(cli): - with http_fixture() as (origin, response, _requests): - value = status() - value["current_tasks"].reverse() - response.update(body=json.dumps(value).encode()) - result = invoke(cli, origin, "status") - assert ( - result.returncode == 1 - and "outcome_unknown" not in json.loads(result.stderr)["error"] - ) - for change in ( - "missing", - "duplicate", - "reordered", - "null_index", - "foreign_status", - "missing_lock", - ): - value = transition() - if change == "missing": - value["tasks"].pop() - elif change == "duplicate": - value["tasks"][1]["task_id"] = value["tasks"][0]["task_id"] - elif change == "reordered": - value["tasks"].reverse() - elif change == "null_index": - value["tasks"][0]["row_index"] = None - elif change == "foreign_status": - value["tasks"][1]["status"] = "ready" - else: - value["tasks"][1]["locked_context_hash"] = None - response.update(body=json.dumps(value).encode()) - result = invoke(cli, origin, "screen") - assert ( - result.returncode == 1 - and json.loads(result.stderr)["error"]["outcome_unknown"] is True - ) - - -def test_invalid_selectors_keys_and_release_reasons_make_zero_requests(cli): - with http_fixture() as (origin, _response, requests): - for operation in ("import", "status", "screen", "release"): - assert invoke(cli, origin, operation, project="../private").returncode == 2 - assert invoke(cli, origin, operation, target="../private").returncode == 2 - for operation in ("import", "screen", "release"): - assert invoke(cli, origin, operation, key="").returncode == 2 - assert invoke(cli, origin, "release", reason=None).returncode == 2 - assert invoke(cli, origin, "release", reason=" \n").returncode == 2 - assert invoke(cli, origin, "screen", reason="x" * 4001).returncode == 2 - assert requests == [] - - -def test_uncertain_batch_writes_are_once_only_and_preserve_manual_recovery( - cli, tmp_path -): - with http_fixture() as (origin, response, requests): - for operation in ("import", "screen", "release"): - response.update(drop=True) - result = invoke(cli, origin, operation) - assert result.returncode == 1 and result.stdout == "" - assert json.loads(result.stderr)["error"]["outcome_unknown"] is True - assert len(requests) == 3 - response.update( - drop=False, status=403, body=json.dumps(canonical_error()).encode() - ) - result = invoke(cli, origin, "release") - assert "outcome_unknown" not in json.loads(result.stderr)["error"] - response.update(body=b'{"detail":"unrecognized denial"}') - result = invoke(cli, origin, "release") - assert json.loads(result.stderr)["error"]["outcome_unknown"] is True - with goaway_fixture(tmp_path) as (origin, env, bodies, connections): - result = invoke(cli, origin, "release", extra_env=env) - assert result.returncode == 1 and connections == ["h2"] - assert bodies == [b'{"reason":"Decision"}'] - assert json.loads(result.stderr)["error"]["outcome_unknown"] is True diff --git a/cli/tests/integration/test_task_batch_csv.py b/cli/tests/integration/test_task_batch_csv.py deleted file mode 100644 index 26562921a..000000000 --- a/cli/tests/integration/test_task_batch_csv.py +++ /dev/null @@ -1,102 +0,0 @@ -"""Built offline CSV conversion produces the exact server-accepted JSON source.""" - -from hashlib import sha256 -import json - -from app.modules.tasks.api.task_import import parse_task_import - - -def convert(cli, source, destination, *extra): - return cli( - "not-an-api-origin", - "", - "--output", - "json", - "project", - "task-batch", - "convert-csv", - "--input", - str(source), - "--out", - str(destination), - *extra, - ) - - -def test_offline_conversion_server_contract_and_no_clobber(cli, tmp_path): - source = tmp_path / "briefs.csv" - source.write_text( - "source_id,title,description,category,skill_tags,languages,tools\n" - 'brief-é,"Caption, français","First line\n日本語",caption,' - "review;accuracy,fr;ja,editor\n", - encoding="utf-8", - ) - destination = tmp_path / "briefs.json" - result = convert(cli, source, destination, "--label", "Multilingual briefs") - assert result.returncode == 0 and result.stderr == "", result.stderr - raw = destination.read_bytes() - report = json.loads(result.stdout) - assert report == { - "json_path": str(destination), - "sha256": "sha256:" + sha256(raw).hexdigest(), - "byte_count": len(raw), - "row_count": 1, - } - parsed = parse_task_import(raw) - assert parsed.sha256 == report["sha256"] - assert parsed.byte_count == report["byte_count"] - task = parsed.document.tasks[0] - assert task.external_task_id == "brief-é" - assert task.title == "Caption, français" - assert task.description == "First line\n日本語" - assert task.task_type == "caption" - assert task.skill_tags == ["review", "accuracy", "fr", "ja", "editor"] - assert parsed.document.metadata.label == "Multilingual briefs" - - repeated = convert(cli, source, destination) - assert repeated.returncode == 2 - assert json.loads(repeated.stderr)["error"]["code"] == "invalid_arguments" - assert destination.read_bytes() == raw - second = tmp_path / "second.json" - assert ( - convert(cli, source, second, "--label", "Multilingual briefs").returncode == 0 - ) - assert second.read_bytes() == raw - - -def test_invalid_csv_does_not_create_or_modify_output(cli, tmp_path): - source = tmp_path / "briefs.csv" - destination = tmp_path / "briefs.json" - for raw in ( - b"external_task_id,title,description\na,T,D\na,T,D\n", - b"external_task_id,title,description\na,T,D\xff\n", - b"external_task_id,title,description\na,T,D\x00\n", - b"external_task_id,title,description\na,T\n", - b'external_task_id,title,description\na,"broken,D\n', - b"external_task_id,title,description,unknown\na,T,D,x\n", - ): - source.write_bytes(raw) - result = convert(cli, source, destination) - assert result.returncode == 2 - assert json.loads(result.stderr)["error"]["code"] == "invalid_task_import_csv" - assert not destination.exists() - - -def test_csv_500_vs_501_rows(cli, tmp_path): - source = tmp_path / "briefs.csv" - source.write_text( - "external_task_id,title,description\n" - + "".join(f"brief-{index},Task,Instructions\n" for index in range(500)), - encoding="utf-8", - ) - destination = tmp_path / "briefs.json" - result = convert(cli, source, destination) - assert result.returncode == 0, result.stderr - assert len(parse_task_import(destination.read_bytes()).document.tasks) == 500 - with source.open("a", encoding="utf-8") as stream: - stream.write("brief-501,Task,Instructions\n") - refused = tmp_path / "refused.json" - result = convert(cli, source, refused) - assert result.returncode == 2 - assert json.loads(result.stderr)["error"]["code"] == "invalid_task_import_csv" - assert not refused.exists() diff --git a/cli/tests/integration/test_task_batch_sources_http.py b/cli/tests/integration/test_task_batch_sources_http.py deleted file mode 100644 index 18c66f9b8..000000000 --- a/cli/tests/integration/test_task_batch_sources_http.py +++ /dev/null @@ -1,158 +0,0 @@ -"""Built source CLI preserves exact bytes and treats uncertain PUTs as writes.""" - -from hashlib import sha256 -import json - -from http2_fixture import goaway_fixture -from test_contributor_task_mutations import KEY, canonical_error -from test_guide_proposal_http import OTHER -from test_http_boundary import PROJECT, TOKEN, http_fixture - -SOURCE = OTHER -RAW = ( - b'{\n "schema_version":"workstream.task_import.v1", "tasks":[' - b'{"external_task_id":"brief-1","title":"Caption","description":"Brief"}]}\n' -) - - -def source(status="verified"): - return { - "source_id": SOURCE, - "project_id": PROJECT, - "sha256": "sha256:" + sha256(RAW).hexdigest(), - "byte_count": len(RAW), - "media_type": "application/json", - "status": status, - "created_at": "2026-10-11T12:00:00Z", - } - - -def invoke( - cli, origin, operation, path=None, *, project=PROJECT, target=SOURCE, **kwargs -): - args = ["-o", "json", "project", "task-batch", operation, project] - if operation != "source-declare": - args.append(target) - if path is not None: - args.extend(("--input", str(path))) - if operation == "source-declare": - args.extend(("--idempotency-key", KEY)) - return cli(origin, TOKEN, *args, **kwargs) - - -def test_source_operations_are_separate_exact_requests(cli, tmp_path): - path = tmp_path / "briefs.json" - path.write_bytes(RAW) - with http_fixture() as (origin, response, requests): - response.update(status=201, body=json.dumps(source("declared")).encode()) - result = invoke(cli, origin, "source-declare", path) - assert result.returncode == 0 and result.stderr == "", result.stderr - assert json.loads(result.stdout) == source("declared") - assert response["commands"] == [ - ( - "application/json", - [KEY], - {"sha256": source()["sha256"], "byte_count": len(RAW)}, - ) - ] - response.update(status=200, body=json.dumps(source()).encode()) - result = invoke(cli, origin, "source-upload", path) - assert result.returncode == 0 and result.stderr == "", result.stderr - assert json.loads(result.stdout) == source() - assert response["raw_commands"][-1] == RAW - assert response["commands"][-1][0:2] == ("application/json", None) - result = invoke(cli, origin, "source-status") - assert result.returncode == 0 and json.loads(result.stdout) == source() - prefix = f"/api/v1/projects/{PROJECT}/task-import-sources" - assert requests == [ - ("POST", prefix, "Bearer " + TOKEN), - ("PUT", f"{prefix}/{SOURCE}/content", "Bearer " + TOKEN), - ("GET", f"{prefix}/{SOURCE}", "Bearer " + TOKEN), - ] - - -def test_source_invalid_requests_never_contact_server(cli, tmp_path): - path = tmp_path / "briefs.json" - with http_fixture() as (origin, _response, requests): - for raw in ( - RAW.replace(b'"title":"Caption"', b'"title":"Caption","title":"x"'), - RAW.replace( - b'"description":"Brief"', b'"description":"Brief","created_by":"x"' - ), - RAW.replace( - b'"external_task_id":"brief-1"', b'"external_task_id":" brief-1"' - ), - RAW.replace(b'"title":"Caption"', b'"title":null'), - RAW + b"{}", - b" ", - ): - path.write_bytes(raw) - for operation in ("source-declare", "source-upload"): - assert invoke(cli, origin, operation, path).returncode == 2 - path.write_bytes(RAW) - assert ( - invoke(cli, origin, "source-upload", path, target="../private").returncode - == 2 - ) - assert ( - invoke(cli, origin, "source-status", project="../private").returncode == 2 - ) - assert requests == [] - - -def test_source_crossed_or_malformed_receipts_are_uncertain_writes(cli, tmp_path): - path = tmp_path / "briefs.json" - path.write_bytes(RAW) - with http_fixture() as (origin, response, requests): - variants = [ - source() | {"project_id": SOURCE}, - source() | {"source_id": PROJECT}, - source() | {"sha256": "sha256:" + "f" * 64}, - source() | {"byte_count": len(RAW) + 1}, - source() | {"media_type": "text/csv"}, - source() | {"status": "imported"}, - source() | {"storage_key": "private"}, - ] - for body in variants: - response.update(status=200, body=json.dumps(body).encode()) - result = invoke(cli, origin, "source-upload", path) - assert result.returncode == 1 and result.stdout == "" - error = json.loads(result.stderr)["error"] - assert error["code"] == "invalid_api_response" - assert error["outcome_unknown"] is True - assert len(requests) == len(variants) - - -def test_source_put_error_envelope_and_connection_loss(cli, tmp_path): - path = tmp_path / "briefs.json" - path.write_bytes(RAW) - with http_fixture() as (origin, response, requests): - response.update(status=403, body=json.dumps(canonical_error()).encode()) - denied = invoke(cli, origin, "source-upload", path) - assert denied.returncode == 1 - assert not json.loads(denied.stderr)["error"].get("outcome_unknown", False) - for status, body in ( - (403, b'{"error":{"code":"permission_not_granted"}}'), - (500, json.dumps(canonical_error()).encode()), - ): - response.update(status=status, body=body) - result = invoke(cli, origin, "source-upload", path) - assert result.returncode == 1 - assert json.loads(result.stderr)["error"]["outcome_unknown"] is True - response.update(drop=True) - result = invoke(cli, origin, "source-upload", path) - assert result.returncode == 1 - assert json.loads(result.stderr)["error"]["outcome_unknown"] is True - assert len(requests) == 4 - assert response["raw_commands"] == [RAW] * 4 - - -def test_source_put_http2_goaway_never_replays_bytes(cli, tmp_path): - path = tmp_path / "briefs.json" - path.write_bytes(RAW) - with goaway_fixture(tmp_path) as (origin, env, bodies, connections): - result = invoke(cli, origin, "source-upload", path, extra_env=env) - assert connections == ["h2"] and bodies == [RAW] - assert result.returncode == 1 - error = json.loads(result.stderr)["error"] - assert error["code"] == "service_unavailable" and error["outcome_unknown"] is True diff --git a/docs/engineering/authorization_activation_custody.md b/docs/engineering/authorization_activation_custody.md index 883499cd9..0c94c2ef8 100644 --- a/docs/engineering/authorization_activation_custody.md +++ b/docs/engineering/authorization_activation_custody.md @@ -340,12 +340,3 @@ delivered through canonical PREP. ARCH-04E2-B activates this exact action only inside the hidden complete outcome, with actual immutable AUTH-event/service verification and atomic source publication. No production routing handler is registered. - - -PILOT-02B owns the distinct TASK actions `project.task.import` and -`project.task.import_batch.read` under existing `project.task.manage`. They -require an active human covering Project Manager grant and exact native batch, -selected source, received-byte identity and original manifest facts. They do -not enlarge the ART action custody table or grant screen/release authority. -The [atomic import contract](../spec_chunk_4_task_queue_assignment.md#atomic-json-to-draft-import-contract) -separates immutable original creation facts from current member states. diff --git a/docs/roadmap_status.md b/docs/roadmap_status.md index 41e18792c..0d39c9f48 100644 --- a/docs/roadmap_status.md +++ b/docs/roadmap_status.md @@ -18,8 +18,7 @@ requests are the transient view of work currently under review. Bounded contribution evidence reads expose existing immutable work and award facts to the current human or authorized project exporter. They do not activate recognition writers, complete the public contribution journey or assert payment. -Fixed-membership signed pagination extends those same authorized reads; CLI -consumption remains separate work. +CLI consumption and fixed-membership pagination remain separate work. ## Product Goal @@ -279,7 +278,7 @@ cannot be reused as post-submission review-gate evidence. See the | Review queue and lease | **Hidden persistence foundation** | Queue/admission idempotency and ReviewLease/preference persistence; complete unavailable REV action/principal catalogue and typed AUTH contracts; ART-07A1 metadata-only packet contract and REV-03B immutable normalized packet persistence with live ingest custody; REV-04A Review/finding/resolution and completed request storage | Future resolver proof; canonical admission from `allow_review`; claim/lease/packet authority; lease copies the Submission-stamped policy version with no CON lookup | | Review decision and revision | **Hidden acceptance core; runtime planned** | Review/revision policy identities and mutation authority, with `requires_second_review` fixed false through typed and database boundaries; REV-04A immutable Review storage; REV-04B source storage; REV-04C hidden source-neutral FinalAcceptance/TASK/CON participant; approved same-task revision-rebase semantics | ARCH-04E2-B supplies mandatory source AUTH and complete database/audit/outbox closure for hidden automated outcomes. Human decision authority/composition, revision preparation, replay and recovery remain | | Contribution and compensation truth | **Hidden shared participant plus public policy administration** | ContributionPolicyVersion persistence; lifecycle-audit participant; adapter bindings; public Finance policy administration; REV-04B shared acceptance source storage; CON-03C immutable ContributionRecord/CompensationAward storage; obsolete guide-keyed payment storage and task-local payment fields removed; CON-07 source-neutral submitter participant and complete award sets; REV-04C composes it with FinalAcceptance/TASK effects in the caller transaction; 04F2 checker remediation creates no contribution or award | ARCH-04E2-B supplies exact routing authority/evidence, complete-set database closure and audit/outbox under REV-12A4A. Hidden B8 completion delivery is implemented; replacement/recovery and live composition remain before production consumption. Only actual Reviews create reviewer records. Obligation/root/ordinal custody remains deferred until fulfillment activation; no public recognition or fulfillment route is live | -| Contribution evidence reads | **Public bounded backend reads** | PILOT-10A exposes current human self-read and one-project JSON/CSV export for covering Project Managers or exact-project Finance Authorities; one fresh repeatable-read response with one narrowly bounded serialization-conflict retry and fresh authority, complete zero/one/two immutable awards, exact decimals, recorded-time filters and formula-neutralized CSV; fixed membership up to 100,000 contributions and signed 15-minute continuation with up to 1,000 contributions per page | CLI consumption remains separate; no recognition mutation, fulfillment, payout or deployed-service claim | +| Contribution evidence reads | **Public bounded backend reads** | PILOT-10A exposes current human self-read and one-project JSON/CSV export for covering Project Managers or exact-project Finance Authorities; one fresh repeatable-read response with one narrowly bounded serialization-conflict retry and fresh authority, complete zero/one/two immutable awards, exact decimals, recorded-time filters and formula-neutralized CSV; 1,000-contribution maximum refuses excess without truncation | CLI consumption and stable fixed-membership paginated list remain separate; no recognition mutation, fulfillment, payout or deployed-service claim | | Fulfillment, reconciliation, and audit | **Planned** | Shared audit foundations, provider-neutral adapter convention, AUTH-OUTBOX-02 live dispatcher authority, retained phase audit decisions, Celery delivery/recovery scans and CON-02B custody | Feature-specific handlers and authority, conditional award fulfillment, callbacks, idempotent recovery, reconciliation, bounded operational reads, and release controls | | Runtime diagnostics | **Implemented foundation** | Closed structured logging, explicit API/Celery tracing, bounded metrics, safe correlation and optional typed OTLP export | Restrict broker publishers; configure and secure collector/log access, egress, encryption and finite deletion; prove diagnostics during the release drill; no deployed monitoring claim | | Frontend and pilot | **Local runtime foundation; product pilot planned** | Checkout-isolated Docker Compose API, prefork Celery process, beat, PostgreSQL, Redis and MinIO stack with local Flow-HMAC identities, existing authority bootstrap/grants, configurable loopback ports and project-scoped state; a pinned offline sample image build and separate oracle were proved under gVisor; React + Vite + TypeScript stack decision | Implement the external launcher/checker images and benchmark a representative task before choosing production limits; complete provider-backed guide compilation and activated-guide scoped task-denial proof on the base stack, implement only stable backed frontend surfaces, run the real internal pilot, repair findings, and complete release drills; Docker Desktop/macOS runtime proof remains | @@ -387,12 +386,6 @@ cannot be reused as post-submission review-gate evidence. See the automatic recovery, proven through public routes on PostgreSQL and MinIO. It creates no Tasks; issue 489 retains atomic DRAFT import, explicit batch screen/release and CLI conversion as future boundaries. - The [PILOT-02C bulk/CLI candidate](../.commitrail/changes/pilot02-bulk-transitions-cli.md) - implements caller-root canonical SCREEN/RELEASE composition and separate CLI - source/import/status/screen/release commands with local CSV-to-JSON conversion. - Focused model/contract and controlled CLI HTTP proof do not establish native - aggregate readiness: sole-author DDL, public PostgreSQL/MinIO 200/500-member - journeys and complete review/CI remain pending. Issue 489 stays open. [CLI manager task browsing](../.commitrail/initiatives/WS-CLI-001/WS-CLI-001-04.md) adds one-page task discovery and exact task detail through existing manager reads, with server-owned live authority and opaque continuation. @@ -879,8 +872,7 @@ Delivered foundations (not a claim of full public integration) PILOT-10A public bounded evidence reads over existing immutable CON/awards active human self or covering PM / exact-project Finance -> JSON or CSV - PILOT-10B fixed membership + signed expiring pages, fresh authority each page - no recognition writer or fulfillment dependency; CLI remains + no recognition writer or fulfillment dependency; CLI/pagination remain Remaining integration PILOT-02 separately scoped atomic DRAFT import -> explicit batch screen/release @@ -971,8 +963,8 @@ v0.1 is not ready until all of the following are true: - Fulfillment and recovery are idempotent, observable, reconcilable, and safe under durable-job, provider, transaction, and unknown-commit failures. - Contribution evidence reads retain complete source/award identities with fresh - self or project authority, one fresh response snapshot and fixed-membership - signed pagination. CLI access remains later bounded work; exported + self or project authority, one response snapshot and explicit over-limit refusal. + CLI access and fixed-membership pagination remain later bounded work; exported award quantities are earned facts, not proof of external payment. - Configure secured diagnostic collection with bounded retention and access, and prove API/Celery correlation, privacy and collector-outage behavior in @@ -1102,12 +1094,9 @@ remaining trace sequence is: - Review/revision: REV packet/schema foundations may proceed independently, but live admission starts after `ARCH-04E`; the first live Review commit also requires the atomic CON decision participant on the delivered CON-03C storage. -- [PILOT-10B's fixed-membership pagination](../.commitrail/changes/pilot10-stable-contribution-pagination.md) - extends existing authorized evidence reads without economic mutation. - [PILOT-10A's bounded read/export record](../.commitrail/changes/pilot10-contribution-award-export.md) distinguishes public evidence reads from hidden recognition and deferred - fulfillment. Fixed-membership signed pagination extends the same read owner; - CLI consumption remains separately scoped. The [canonical read contract](spec_contribution_compensation.md#bounded-contribution-evidence-reads) + fulfillment. The [canonical read contract](spec_contribution_compensation.md#bounded-contribution-evidence-reads) defines scope, limits, exact quantities, time semantics and CSV safeguards. For implementation ownership and exact contracts, contributors can follow diff --git a/docs/spec_authorization_service.md b/docs/spec_authorization_service.md index b8053163b..9ccbfa7d8 100644 --- a/docs/spec_authorization_service.md +++ b/docs/spec_authorization_service.md @@ -1737,12 +1737,3 @@ replay rechecks live authority and the complete original tuple without issuing another allow or repairing effects. B8 supplies hidden completion delivery; production registration remains unavailable. Human acceptance-source authority is still future work; detached human receipts grant nothing. - - -PILOT-02B owns the distinct TASK actions `project.task.import` and -`project.task.import_batch.read` under existing `project.task.manage`. They -require an active human covering Project Manager grant and exact native batch, -selected source, received-byte identity and original manifest facts. They do -not enlarge the ART action custody table or grant screen/release authority. -The [atomic import contract](spec_chunk_4_task_queue_assignment.md#atomic-json-to-draft-import-contract) -separates immutable original creation facts from current member states. diff --git a/docs/spec_chunk_4_task_queue_assignment.md b/docs/spec_chunk_4_task_queue_assignment.md index 14fe536e0..626b19b63 100644 --- a/docs/spec_chunk_4_task_queue_assignment.md +++ b/docs/spec_chunk_4_task_queue_assignment.md @@ -92,78 +92,12 @@ locked guide/policy identities, creator identity or server provenance fields. PILOT-02A supplies usable authorized declaration, upload, status and verified download through the [ART source custody contract](spec_artifact_storage_service.md#task-import-source-custody). These operations create no Tasks. Failed or abandoned declarations remain -retained source records with no batch/task success claim. The separate atomic JSON-to-DRAFT import contract is below. Source custody alone -still supplies no batch screen/release or CLI conversion. - -### Atomic JSON-to-DRAFT import contract - -`POST /api/v1/projects/{project_id}/task-import-batches` accepts only a native -`source_id` and the shared UUID `Idempotency-Key`. A covered Project Manager's -first import reads and verifies actual provider bytes, parses the retained JSON, -then creates one immutable native batch and every DRAFT Task in one root. Each -row uses the normal authorized Task creation and `TaskCreated` evidence; a -later row, audit, binding or uniqueness failure rolls back the complete batch. -Case-sensitive project/external-ID uniqueness covers all non-NULL Task external -IDs, including normal creation. Existing arbitrary `import_batch_id` strings -remain metadata; only immutable native membership supplies batch custody. - -The server stamps `json_import`, `task-import-source:`, the actual -received-file SHA and the native batch UUID spelling. Normal manual TaskCreate -cannot select `json_import`; row input cannot supply these labels or other -provenance. Published difficulty values through 80 characters are preserved. -The response retains original document order, optional display label and original -Task creation facts; it does not transition or assign any Task. - -After commit, same-key replay and a new key selecting the same actual project/ -SHA/byte-count recover the original batch and Task IDs after fresh batch/source -authority, even after Tasks advance. This recovery uses immutable native -source/verification/acknowledgement receipts and performs no provider read or -reparsing. A different source needs its own actual verified receipt; a claimed -SHA alone cannot recover. Reusing the original key with a changed source selector -conflicts even if both verified sources contain identical bytes. - -`GET /api/v1/projects/{project_id}/task-import-batches/{batch_id}` returns original -creation facts separately from current states selected by ordered native -membership. Missing, foreign and revoked status access is concealed. The bounded -implementation and required native proof are recorded in the -[atomic-import change record](../.commitrail/changes/pilot02-atomic-json-draft-import.md). - -### Explicit whole-batch screening and release contract - -Separate `POST /api/v1/projects/{project_id}/task-import-batches/{batch_id}/screen` -and `/release` accept a reason and exactly one UUID `Idempotency-Key`. SCREEN -permits an omitted reason; RELEASE requires the normal nonblank decision reason. -Both operate on the complete immutable native import membership, preserving -original row order. Arbitrary `Task.import_batch_id` metadata cannot select -members. Each actual Task consumes fresh covered-PM authority through the normal -SCREEN/RELEASE owner, with all Task/assignment custody locked before authority -and guide/policy evaluation. One caller transaction commits every member's normal -transition, guide/policy locks, authority evidence and success receipt together; -a late failure rolls back the complete successful effect set. - -The compact response identifies project, native batch, operation and row count, -then returns every ordered Task ID, row index, poststate, locked guide version, -locked ContributionPolicyVersion ID and locked context hash. It repeats no Task -instructions. SCREEN returns `screening`; RELEASE returns `ready`. The server -records a separate aggregate retry namespace and retained canonical per-Task -keys; callers cannot choose those row keys or attach old standalone successes. - -Same-key replay reauthorizes every current member and recovers the exact recorded -response only while all Tasks retain their corresponding poststate, unassigned -custody and locked context. A partially advanced or assigned member refuses the -whole operation, as does a changed reason, selector or member set. This differs -from import replay, which recovers original DRAFT creation facts after Tasks -advance. An uncertain client write requires manual replay of the unchanged -project, batch, operation, reason and key; later authority or Task changes may -prevent recovery. There are no automatic write retries or per-row commits. - -The CLI keeps local CSV conversion, source declaration/upload/status, import, -batch status, screening and release explicit. UTF-8 quoted CSV and semicolon skill -fields produce validated canonical JSON; its exact bytes supply the uploaded -SHA/count. The server retains those JSON bytes, with no claim to retaining the -original CSV. Native aggregate DDL and the public 200/500-member journey remain -pending in the [bulk/CLI change record](../.commitrail/changes/pilot02-bulk-transitions-cli.md); -this contract does not establish delivered bulk readiness. +retained source records with no batch/task success claim. A later bounded +PILOT-02 operation must import a verified source into DRAFT atomically, enforce +project/external-ID uniqueness and replay/conflict rules, and bind exact ART +and AUTH custody. Explicit screen and release, their existing locked-guide +prerequisites and normal transitions remain unchanged. No public batch import, +batch screen/release or CLI conversion is delivered by source custody alone. ## Transitions and locked lineage diff --git a/docs/spec_contribution_compensation.md b/docs/spec_contribution_compensation.md index 2e90067d0..ba8329b63 100644 --- a/docs/spec_contribution_compensation.md +++ b/docs/spec_contribution_compensation.md @@ -989,33 +989,12 @@ errors are not retried; a second 40001 remains unavailable. This bounded read recovery does not retry product mutations. Export reads mutate no recognition or economic facts. -The complete fixed membership is bounded at 100,000 selected contributions. -Each response accepts `page_size` (1–1,000, default 100) and optional `cursor`. -Filters apply before membership capture; excess selection returns 422 +The maximum is 1,000 selected contributions. Filters apply before the repository +probes the 1,001st row; excess selection returns 422 `contribution_export_too_large` with no partial export. Empty selections succeed. -Rows sort by `(recorded_at, contribution_id)`, not business commit order. - -The first response captures its visible selected contribution identities in -CON-private, expiring native membership rows, separate from retained economic -facts. Native guards require sealing the complete member set before commit and -refuse subsequent additions or changes. Later commits, even from transactions -already in progress at capture, cannot enter the original selection. Every page -reapplies the selected actor/project/type/time filters and fresh canonical AUTH; -stored membership confers no read authority. Source display labels may reflect -the fresh page snapshot; contribution membership and economic facts are fixed. - -JSON returns `exported_at`, `items` and `next_cursor` (null on the final page). -CSV returns `X-Workstream-Exported-At` and, when another page exists, -`X-Workstream-Next-Cursor`. The export instant is identical on every page. -Signed cursors bind the original member set, actor, audience, project, normalized -filters, output format, page size, expiry and last ordering key. Change none of -those selections during traversal. Cursors expire after 15 minutes; malformed, -forged, expired or mismatched continuation returns 422 -`contribution_export_invalid_cursor`. Restart an export for a fresh selection. -The existing `WORKSTREAM_PAGINATION_CURSOR_HMAC_SECRET` is required for -continuation; an unavailable key refuses pagination rather than inventing one. -Expired private membership alone is cleaned in bounded batches, never retained -contributions, awards or audits. CLI consumption is a separate bounded change. +Rows sort by `(recorded_at, contribution_id)` for display, not commit order. +There is no continuation cursor or snapshot retained across requests. Fixed +membership pagination and CLI consumption remain separate implementation work. CSV uses the same validated projection, quotes every UTF-8 cell and retains one row for an unpaid contribution or one row per award (at most 2,000 data rows). @@ -1204,11 +1183,11 @@ repository; all communication is through typed ports. Contribution and award reads use PostgreSQL canonical truth directly. They do not depend on ART, optional evidence, provider availability, balances, or -settlement ledgers. The public contribution reads use the bounded fixed-membership -page contract above, with signed expiring continuation, exact self/project scope, -pre-filtering and fresh authorization/concealment on every page. CLI consumption -remains separately scoped issue #497 work. Provider references, credentials and -secret routes are never returned. +settlement ledgers. The public contribution reads use the bounded single-response +contract above, with no continuation cursor, exact self/project scope, +pre-filtering, and concealment. Stable fixed-membership pagination remains later +issue #497 work. Provider references, credentials, and secret routes are never +returned. CP05A exposes only ContributionPolicy administration, using the existing CP05 Finance authority and caller-owned transaction. Under the project-scoped @@ -1325,9 +1304,8 @@ not wait for contribution/award persistence or REV decisions. PILOT-10's bounded reads consume existing immutable CON/award facts after their own exact AUTH/audit activation and snapshot proof. They do not wait for CON-08B -fulfillment or the historical CON-10A ordering below. The fixed-membership -list extends those reads without changing economic facts; CLI remains separately -scoped under issue 497. +fulfillment or the historical CON-10A ordering below. The later fixed-membership +list and CLI remain separately scoped under issue 497. ```text CON-01 -> CON-02A diff --git a/mcp_server/contracts/authorization_context_get.json b/mcp_server/contracts/authorization_context_get.json index 434d62b14..72c26ce8f 100644 --- a/mcp_server/contracts/authorization_context_get.json +++ b/mcp_server/contracts/authorization_context_get.json @@ -1,9 +1,9 @@ { - "canonical_sha256": "35b07a456650ba74bd0f8a243298fb01e1a9062718b61f03feaf1fdaf678dbc7", + "canonical_sha256": "d49f96eb6f6b2731b8b18ca023676402dfe7b0236e1615586839c3326b109316", "components": { "schemas": { "ActionId": { - "description": "Closed action identifiers reserved by approved owner chunks.", + "type": "string", "enum": [ "task.submission.list", "submission.read", @@ -17,8 +17,6 @@ "project.task.queue.read", "operations.task.queue.read", "project.task.create", - "project.task.import", - "project.task.import_batch.read", "project.task.screen", "project.task.release", "task.claim", @@ -159,57 +157,57 @@ "contribution.read_project" ], "title": "ActionId", - "type": "string" + "description": "Closed action identifiers reserved by approved owner chunks." }, "ActorAuthorizationContextResponse": { - "additionalProperties": false, - "description": "Self-only effective authority projected onto one canonical project.", "properties": { "actor_profile_id": { + "type": "string", "format": "uuid", - "title": "Actor Profile Id", - "type": "string" + "title": "Actor Profile Id" + }, + "status": { + "type": "string", + "enum": [ + "active", + "suspended", + "deactivated" + ], + "title": "Status" + }, + "project_id": { + "type": "string", + "format": "uuid", + "title": "Project Id" }, "admin_roles": { "items": { "type": "string" }, - "title": "Admin Roles", - "type": "array" - }, - "effective_action_ids": { - "items": { - "$ref": "#/components/schemas/ActionId" - }, - "title": "Effective Action Ids", - "type": "array" - }, - "project_id": { - "format": "uuid", - "title": "Project Id", - "type": "string" + "type": "array", + "title": "Admin Roles" }, "project_roles": { "items": { + "type": "string", "enum": [ "submitter", "reviewer" - ], - "type": "string" + ] }, - "title": "Project Roles", - "type": "array" + "type": "array", + "title": "Project Roles" }, - "status": { - "enum": [ - "active", - "suspended", - "deactivated" - ], - "title": "Status", - "type": "string" + "effective_action_ids": { + "items": { + "$ref": "#/components/schemas/ActionId" + }, + "type": "array", + "title": "Effective Action Ids" } }, + "additionalProperties": false, + "type": "object", "required": [ "actor_profile_id", "status", @@ -219,34 +217,34 @@ "effective_action_ids" ], "title": "ActorAuthorizationContextResponse", - "type": "object" + "description": "Self-only effective authority projected onto one canonical project." }, "ApiError": { - "additionalProperties": false, - "description": "Canonical machine-readable API error.", "properties": { "code": { - "title": "Code", - "type": "string" + "type": "string", + "title": "Code" }, - "correlation_id": { - "title": "Correlation Id", - "type": "string" + "message": { + "type": "string", + "title": "Message" }, "details": { "additionalProperties": true, - "title": "Details", - "type": "object" + "type": "object", + "title": "Details" }, - "message": { - "title": "Message", - "type": "string" + "correlation_id": { + "type": "string", + "title": "Correlation Id" }, "retryable": { - "title": "Retryable", - "type": "boolean" + "type": "boolean", + "title": "Retryable" } }, + "additionalProperties": false, + "type": "object", "required": [ "code", "message", @@ -255,12 +253,13 @@ "retryable" ], "title": "ApiError", - "type": "object" + "description": "Canonical machine-readable API error." }, "ApiErrorResponse": { - "additionalProperties": false, - "description": "Canonical error plus additive legacy compatibility fields.", "properties": { + "error": { + "$ref": "#/components/schemas/ApiError" + }, "detail": { "anyOf": [ {}, @@ -269,79 +268,88 @@ } ], "title": "Detail" - }, - "error": { - "$ref": "#/components/schemas/ApiError" } }, + "additionalProperties": false, + "type": "object", "required": [ "error" ], "title": "ApiErrorResponse", - "type": "object" + "description": "Canonical error plus additive legacy compatibility fields." }, "HTTPValidationError": { - "additionalProperties": false, + "type": "object", + "required": [ + "detail", + "error" + ], "properties": { "detail": { + "type": "array", "items": { "type": "object" - }, - "type": "array" + } }, "error": { "$ref": "#/components/schemas/ApiError" } }, - "required": [ - "detail", - "error" - ], - "type": "object" + "additionalProperties": false } } }, "operation": { + "tags": [ + "actors" + ], + "summary": "Read Current Actor Authorization Context", "description": "Return the caller's effective authority for one canonical project.", "operationId": "read_current_actor_authorization_context_api_v1_actors_me_authorization_context_get", + "security": [ + { + "HTTPBearer": [] + } + ], "parameters": [ { - "in": "query", "name": "project_id", + "in": "query", "required": true, "schema": { - "maxLength": 100, + "type": "string", "minLength": 1, + "maxLength": 100, "pattern": "^[^\\x00]*$", - "title": "Project Id", - "type": "string" + "title": "Project Id" } }, { - "in": "header", "name": "X-Request-ID", + "in": "header", "required": false, "schema": { + "type": "string", "format": "uuid", - "maxLength": 36, "minLength": 36, - "type": "string" + "maxLength": 36 } }, { - "in": "header", "name": "X-Correlation-ID", + "in": "header", "required": false, "schema": { + "type": "string", "format": "uuid", - "maxLength": 36, "minLength": 36, - "type": "string" + "maxLength": 36 } } ], "responses": { "200": { + "description": "Successful Response", "content": { "application/json": { "schema": { @@ -349,201 +357,191 @@ } } }, - "description": "Successful Response", "headers": { - "X-Correlation-ID": { + "X-Request-ID": { "required": true, "schema": { - "format": "uuid", - "type": "string" + "type": "string", + "format": "uuid" } }, - "X-Request-ID": { + "X-Correlation-ID": { "required": true, "schema": { - "format": "uuid", - "type": "string" + "type": "string", + "format": "uuid" } } } }, "400": { - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ApiErrorResponse" - } - } - }, "description": "Invalid request.", "headers": { - "X-Correlation-ID": { + "X-Request-ID": { "required": true, "schema": { - "format": "uuid", - "type": "string" + "type": "string", + "format": "uuid" } }, - "X-Request-ID": { + "X-Correlation-ID": { "required": true, "schema": { - "format": "uuid", - "type": "string" + "type": "string", + "format": "uuid" } } - } - }, - "401": { + }, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorResponse" } } - }, - "description": "Authentication failed.", + } + }, + "500": { + "description": "Internal server error.", "headers": { - "WWW-Authenticate": { + "X-Request-ID": { + "required": true, "schema": { - "type": "string" + "type": "string", + "format": "uuid" } }, "X-Correlation-ID": { "required": true, "schema": { - "format": "uuid", - "type": "string" + "type": "string", + "format": "uuid" } - }, - "X-Request-ID": { - "required": true, + } + }, + "content": { + "application/json": { "schema": { - "format": "uuid", - "type": "string" + "$ref": "#/components/schemas/ApiErrorResponse" } } } }, - "403": { + "422": { + "description": "Validation Error", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ApiErrorResponse" + "$ref": "#/components/schemas/HTTPValidationError" } } }, - "description": "Permission denied.", "headers": { - "X-Correlation-ID": { + "X-Request-ID": { "required": true, "schema": { - "format": "uuid", - "type": "string" + "type": "string", + "format": "uuid" } }, - "X-Request-ID": { + "X-Correlation-ID": { "required": true, "schema": { - "format": "uuid", - "type": "string" + "type": "string", + "format": "uuid" } } } }, - "422": { - "content": { - "application/json": { + "401": { + "description": "Authentication failed.", + "headers": { + "X-Request-ID": { + "required": true, "schema": { - "$ref": "#/components/schemas/HTTPValidationError" + "type": "string", + "format": "uuid" } - } - }, - "description": "Validation Error", - "headers": { + }, "X-Correlation-ID": { "required": true, "schema": { - "format": "uuid", - "type": "string" + "type": "string", + "format": "uuid" } }, - "X-Request-ID": { - "required": true, + "WWW-Authenticate": { "schema": { - "format": "uuid", "type": "string" } } - } - }, - "500": { + }, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorResponse" } } - }, - "description": "Internal server error.", + } + }, + "403": { + "description": "Permission denied.", "headers": { - "X-Correlation-ID": { + "X-Request-ID": { "required": true, "schema": { - "format": "uuid", - "type": "string" + "type": "string", + "format": "uuid" } }, - "X-Request-ID": { + "X-Correlation-ID": { "required": true, "schema": { - "format": "uuid", - "type": "string" + "type": "string", + "format": "uuid" } } - } - }, - "503": { + }, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ApiErrorResponse" } } - }, + } + }, + "503": { "description": "Identity verification unavailable.", "headers": { - "X-Correlation-ID": { + "X-Request-ID": { "required": true, "schema": { - "format": "uuid", - "type": "string" + "type": "string", + "format": "uuid" } }, - "X-Request-ID": { + "X-Correlation-ID": { "required": true, "schema": { - "format": "uuid", - "type": "string" + "type": "string", + "format": "uuid" + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ApiErrorResponse" } } } } }, - "security": [ - { - "HTTPBearer": [] - } - ], - "summary": "Read Current Actor Authorization Context", - "tags": [ - "actors" - ], "x-workstream-action-id": "actor.authorization_context.read" }, "schema_version": 1, "source": { "action_id": "actor.authorization_context.read", - "backend_git_sha": "b6a56caa19d45c0850aba4241b3f3f626da244d1", + "backend_git_sha": "e8d5983e8fcd83980c709a4a2d7c3469a936e11b", "method": "GET", "openapi_version": "3.1.0", "path": "/api/v1/actors/me/authorization-context" From 777d4e868a459d37a8e91f08a1c81731227bcf93 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 08:29:52 +0100 Subject: [PATCH 142/283] [PILOT-04] Exercise configured production checker delivery --- .../evaluation_delivery/test_completion.py | 10 ++- .../run_selected_end_to_end_probe.py | 62 +++++++++++++++++-- 2 files changed, 65 insertions(+), 7 deletions(-) diff --git a/backend/tests/tasks/evaluation_delivery/test_completion.py b/backend/tests/tasks/evaluation_delivery/test_completion.py index ab3dd0fa8..5bb18be8d 100644 --- a/backend/tests/tasks/evaluation_delivery/test_completion.py +++ b/backend/tests/tasks/evaluation_delivery/test_completion.py @@ -183,6 +183,14 @@ async def test_production_registry_delivers_request_then_completion_exactly_once ) as h: await provision_router(h.factory) await delivery_fixture(h) + # This fixture has no external POST bindings; use the real configured + # adapter without requiring an unused service to run. Actual image + # execution is covered by the production Rust/MinIO probe. + settings = h.settings.model_copy(update={ + "external_checker_service_socket": tmp_path / "checker.sock", + "external_checker_material_root": h.scratch, + }) + monkeypatch.setattr("app.core.config.get_settings", lambda: settings) monkeypatch.setattr( artifact_adapters, "worker_post_submission_materialization", @@ -199,7 +207,7 @@ async def test_production_registry_delivers_request_then_completion_exactly_once h.request.project_id, "production-request", ) - assert outcome(request_receipt)["delivery_state"] == "acknowledged" + assert outcome(request_receipt)["delivery_state"] == "acknowledged", outcome(request_receipt) completed = await state(h) assert completed["run"]["status"] == "completed" completion_event_id = completed["run"]["completion_event_id"] diff --git a/experiments/pilot04_external_checker_runtime/run_selected_end_to_end_probe.py b/experiments/pilot04_external_checker_runtime/run_selected_end_to_end_probe.py index 1f37af6f6..670719408 100644 --- a/experiments/pilot04_external_checker_runtime/run_selected_end_to_end_probe.py +++ b/experiments/pilot04_external_checker_runtime/run_selected_end_to_end_probe.py @@ -12,6 +12,7 @@ from io import BytesIO from types import SimpleNamespace from uuid import UUID +from unittest.mock import patch from zipfile import ZipFile, ZipInfo from aiobotocore.config import AioConfig @@ -25,6 +26,8 @@ get_submission_bundle_preparation_command, ) from app.adapters.checkers import external_checker_execution_factory +from app.adapters.outbox import production_outbox_delivery +from app.adapters.artifacts.internal_workers import shutdown_artifact_internal_runtime from app.api.deps.authorization import compose_hidden_submission_creation_command from app.core.identifiers import new_record_id from app.modules.actors.api.service_identities import ServiceIdentity @@ -50,7 +53,10 @@ from app.modules.tasks.models import Submission, SubmissionDispatch, WorkstreamTask from experiments.pilot04_external_checker_runtime.run_probe import _image_identity from tests.artifact_store_helpers import artifact_admission_limit_settings -from tests.checkers.execution.support import live_executor, reserve +from app.modules.checkers.execution_repository import stored_result +from tests.authorization.post_submit_routing.support import provision_router +from tests.tasks.evaluation_delivery.support import delivery_fixture, outcome +from tests.tasks.post_submit_routing.outcome_support import outcome_snapshot from tests.checkers.external.test_selected_post_submit import _post_spec from tests.checkers.external.test_selected_pre_submit import _policy from tests.archive_fixtures import byte_source @@ -418,6 +424,53 @@ async def _prove_infrastructure_recovery( } +async def _production_post_delivery(fixture, settings): + """Use production handlers and a fresh worker runtime, then replay delivery.""" + await provision_router(fixture.factory) + await delivery_fixture(fixture) + # Supply only this isolated run's configuration. Every provider, grant, + # authority, execution and routing operation remains the production owner. + with patch("app.core.config.get_settings", return_value=settings), patch( + "app.adapters.artifacts.internal_workers.get_settings", return_value=settings + ): + shutdown_artifact_internal_runtime() + try: + delivery = production_outbox_delivery(fixture.factory) + requested = await delivery.deliver( + fixture.created.evaluation_event_id, fixture.facts.project_id, + "selected-production-request", + ) + if requested is None or outcome(requested)["delivery_state"] != "acknowledged": + raise RuntimeError("production evaluation request was not acknowledged") + async with fixture.factory() as session: + run = await session.get(CheckerRun, str(fixture.created.evaluation_attempt_id)) + if run.status != "completed" or run.completion_event_id is None: + raise RuntimeError("production selected execution did not emit completion") + result = stored_result(run) + completion_id = run.completion_event_id + # Reconstruct the worker between the two durable events. No callback + # grant, lease capability or in-memory result crosses this boundary. + shutdown_artifact_internal_runtime() + delivery = production_outbox_delivery(fixture.factory) + completed = await delivery.deliver( + completion_id, fixture.facts.project_id, "selected-production-completion", + ) + if completed is None or outcome(completed)["delivery_state"] != "acknowledged": + raise RuntimeError("production completion was not acknowledged") + async with fixture.factory() as session: + before = await outcome_snapshot(session) + if await delivery.deliver( + completion_id, fixture.facts.project_id, "selected-production-replay", + ) is not None: + raise RuntimeError("production completion was delivered twice") + async with fixture.factory() as session: + if await outcome_snapshot(session) != before: + raise RuntimeError("duplicate completion changed retained owner facts") + return result + finally: + shutdown_artifact_internal_runtime() + + async def run( *, database_url: str, image_reference: str, service_binary: Path, root: Path ) -> dict[str, object]: @@ -476,10 +529,7 @@ async def run( post_scratch_root=scratch, scratch_limits=artifact_preparation_limits(settings), ) as fixture: - await reserve(fixture) - result = await live_executor( - fixture, selected_execution=adapter - ).evaluate_post_submission(fixture.request) + result = await _production_post_delivery(fixture, settings) async with fixture.factory() as session: task = await session.get(WorkstreamTask, str(fixture.facts.task_id)) submission_count = await session.scalar( @@ -488,7 +538,7 @@ async def run( run_row = await session.get(CheckerRun, str(result.attempt_id)) if ( submission_count != 1 - or task.status != "evaluation_pending" + or task.status != "review_pending" or result.outcome != "completed" or result.execution is None or len(result.execution.external_members) != 1 From 01573c8e0218eef62fddc334eb9546df3fee3712 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 08:40:39 +0100 Subject: [PATCH 143/283] [PILOT-04] Bind approved configuration for external pre checks --- .../pilot04-workstream-default-checker.md | 11 ++++ backend/app/interfaces/project_agents.py | 29 ++++++--- .../modules/checkers/api/external_policy.py | 10 ++- .../tests/checkers/external/test_policy.py | 62 ++++++++++++++++++- docs/architecture_checker_framework.md | 7 +++ 5 files changed, 101 insertions(+), 18 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index bb254047b..09564e761 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -251,3 +251,14 @@ both human review and shared automatic acceptance with complete awards. Its runtime result remains pending until the isolated PostgreSQL command completes. Publication must remove the accidentally stacked PILOT-02/PILOT-10 source and reconcile the selected-flow successor with the actual merged migration chain. + +## External PRE configuration repair + +PRE bindings previously forced configuration to an empty object, so an otherwise +registered PRE image with required configuration could never be approved. PRE now +uses the existing bounded flat CapabilityParameter contract, enforces unique +parameter names and validates the exact registered schema in both compilation +and approval. Configuration arrays are normalized to JSON arrays for both +phases. Empty PRE parameters are excluded during serialization, preserving +retained empty-binding hashes. Focused compiler regressions cover configured +PRE success, required/type rejection, duplicate names and retained serialization. diff --git a/backend/app/interfaces/project_agents.py b/backend/app/interfaces/project_agents.py index 06f14e0b0..b96070f53 100644 --- a/backend/app/interfaces/project_agents.py +++ b/backend/app/interfaces/project_agents.py @@ -185,7 +185,7 @@ class CapabilityParameter(BaseModel): @field_validator("name") @classmethod def validate_name(cls, value: str) -> str: - """Require a canonical catalogue-owned parameter name.""" + """Require a canonical registered-checker parameter name.""" return _validated_identifier(value) @field_validator("value") @@ -226,7 +226,19 @@ def validate_identifiers(cls, value: str) -> str: class PreSubmissionBindingProposal(_CapabilityBindingIdentity): - """Reference intake capability; its settings live only in the artifact policy.""" + """Reference an external intake image with approved typed configuration.""" + + parameters: tuple[CapabilityParameter, ...] = Field( + default=(), max_length=50, exclude_if=lambda value: not value, + ) + + @model_validator(mode="after") + def validate_parameter_names(self) -> PreSubmissionBindingProposal: + """Reject duplicate names without changing retained empty bindings.""" + names = [parameter.name for parameter in self.parameters] + if len(names) != len(set(names)): + raise ValueError("capability parameters must be unique") + return self class PostSubmissionBindingProposal(_CapabilityBindingIdentity): @@ -744,14 +756,11 @@ def _validate_bindings( raise ValueError("compilation capability binding is invalid") if binding.capability_version != definition.capability_version: raise ValueError("compilation capability version is stale") - if expected_stage == "post_submit": - if not isinstance(binding, PostSubmissionBindingProposal): - raise ValueError("compilation capability binding is invalid") - if definition.registry_entry is None: - raise ValueError("compilation capability binding is invalid") - definition.registry_entry.configuration_schema.validate_instance( - {item.name: item.value for item in binding.parameters} - ) + if definition.registry_entry is None: + raise ValueError("compilation capability binding is invalid") + definition.registry_entry.configuration_schema.validate_instance( + {item.name: item.model_dump(mode="json")["value"] for item in binding.parameters} + ) seen_requirements.add(binding.requirement_id) return seen_requirements diff --git a/backend/app/modules/checkers/api/external_policy.py b/backend/app/modules/checkers/api/external_policy.py index a8d7e2aff..6a1f758e3 100644 --- a/backend/app/modules/checkers/api/external_policy.py +++ b/backend/app/modules/checkers/api/external_policy.py @@ -208,7 +208,6 @@ async def compile_external_checker_policy_bundle( async def _resolve(bindings, requirements, registry, phase): from app.interfaces.project_agents import ( - PostSubmissionBindingProposal, RequirementDisposition, ) @@ -239,11 +238,10 @@ async def _resolve(bindings, requirements, registry, phase): or entry.phase != phase ): raise ExternalCheckerPolicyError("checker registry identity mismatch") - configuration = ( - {parameter.name: parameter.value for parameter in binding.parameters} - if isinstance(binding, PostSubmissionBindingProposal) - else {} - ) + configuration = { + parameter.name: parameter.model_dump(mode="json")["value"] + for parameter in binding.parameters + } resolved.append( LockedExternalCheckerBinding( requirement_id=binding.requirement_id, diff --git a/backend/tests/checkers/external/test_policy.py b/backend/tests/checkers/external/test_policy.py index 50758ccf9..16589bc7a 100644 --- a/backend/tests/checkers/external/test_policy.py +++ b/backend/tests/checkers/external/test_policy.py @@ -8,6 +8,7 @@ from app.core.identifiers import new_record_id from app.interfaces.project_agents import ( AtomicGuideRequirement, + CapabilityParameter, CompilationStage, PostSubmissionBindingProposal, PreSubmissionBindingProposal, @@ -15,6 +16,8 @@ ) from app.modules.checkers.api.external import ( ExternalCheckerRegistryEntry, + ExternalCheckerSchema, + external_checker_json_hash, ExternalCheckerRegistryUnavailable, ) from app.modules.checkers.api.external_policy import ( @@ -27,8 +30,11 @@ from tests.projects.guide_compilation.helpers import result -def _entry(capability_id: str, phase: str) -> ExternalCheckerRegistryEntry: - spec = registry_spec(phase).model_copy(update={"capability_id": capability_id}) +def _entry(capability_id: str, phase: str, configuration_schema=None) -> ExternalCheckerRegistryEntry: + changes = {"capability_id": capability_id} + if configuration_schema is not None: + changes["configuration_schema"] = configuration_schema + spec = registry_spec(phase).model_copy(update=changes) # Revalidate after changing one digest-bound specification field. spec = type(spec).model_validate(spec.model_dump()) return ExternalCheckerRegistryEntry( @@ -195,3 +201,55 @@ async def test_selected_pre_budget_binds_ordered_deadlines_to_art_custody(): assert selected_pre_submit_execution_budget_ms(pre, artifact_deadline_ms=150_000) == 150_000 with pytest.raises(ExternalCheckerPolicyError, match="exceeds ART"): selected_pre_submit_execution_budget_ms(pre, artifact_deadline_ms=149_999) + + +@pytest.mark.asyncio +async def test_pre_configuration_is_schema_checked_and_locked_as_json(): + document = { + "type": "object", + "properties": { + "threshold": {"type": "integer", "minimum": 1}, + "tags": {"type": "array", "items": {"type": "string"}}, + }, + "required": ["threshold", "tags"], + "additionalProperties": False, + } + schema = ExternalCheckerSchema( + schema_id="acme.pre.configuration", schema_version="v1", document=document, + schema_sha256=external_checker_json_hash(document), + ) + registry = _Registry(( + _entry("acme.safe_archive", "pre_submit", schema), + _entry("acme.quality_review", "post_submit"), + )) + proposal = _proposal() + parameters = ( + CapabilityParameter(name="threshold", value=3), + CapabilityParameter(name="tags", value=("alpha", "beta")), + ) + binding = proposal.pre_submit_bindings[0].model_copy(update={"parameters": parameters}) + configured = proposal.model_copy(update={"pre_submit_bindings": (binding,)}) + pre, _ = await compile_external_checker_policies(configured, registry) + assert pre.entries[0].configuration == {"threshold": 3, "tags": ["alpha", "beta"]} + assert pre.entries[0].configuration_sha256 == external_checker_json_hash( + {"threshold": 3, "tags": ["alpha", "beta"]} + ) + for invalid in ((), (CapabilityParameter(name="threshold", value="three"),)): + wrong = binding.model_copy(update={"parameters": invalid}) + with pytest.raises(ValueError): + await compile_external_checker_policies( + proposal.model_copy(update={"pre_submit_bindings": (wrong,)}), registry, + ) + + +def test_pre_configuration_preserves_retained_empty_binding_and_rejects_duplicates(): + binding = _proposal().pre_submit_bindings[0] + retained = { + "requirement_id": "safe_archive", "capability_id": "acme.safe_archive", + "capability_version": "v1.2.3", "stage": "pre_submit", + } + assert binding.model_dump(mode="json") == retained + assert PreSubmissionBindingProposal.model_validate(retained).model_dump(mode="json") == retained + duplicate = CapabilityParameter(name="threshold", value=3) + with pytest.raises(ValueError, match="unique"): + PreSubmissionBindingProposal.model_validate(retained | {"parameters": (duplicate, duplicate)}) diff --git a/docs/architecture_checker_framework.md b/docs/architecture_checker_framework.md index d239a3ed9..e8dcb93e7 100644 --- a/docs/architecture_checker_framework.md +++ b/docs/architecture_checker_framework.md @@ -966,3 +966,10 @@ changing the current-generation fence. Request/completion handlers remain unregistered; this stored intent alone does not invoke checker execution or accept work. Preparation has no stored Submission to observe and never replaces the TASK evaluation guard. + +External PRE and POST bindings may carry the same bounded, flat typed parameters. +Approval validates their JSON values against the exact registered configuration +schema and retains both the values and configuration digest in the locked policy. +Empty PRE parameters remain absent from serialized bindings so reading historical +compilation evidence does not change its original hash. Array values serialize +as JSON arrays before schema validation and digest computation. From 498c04f74a6826ea56513327ec38182a042e8e2d Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 08:50:16 +0100 Subject: [PATCH 144/283] [PILOT-04] Pin selected checker flow schema fingerprint --- backend/tests/conftest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/tests/conftest.py b/backend/tests/conftest.py index e9fc0a4a0..64bfece09 100644 --- a/backend/tests/conftest.py +++ b/backend/tests/conftest.py @@ -23,7 +23,7 @@ DDL_LOCK_DIRECTORY = Path("/tmp") # Match the PostgreSQL 16 engine used by Backend CI. Catalog identity rendering # differs across major versions; regenerate only after comparing actual objects. -EXPECTED_PUBLIC_SCHEMA_SHA256 = "5125dcbb74b9502dbbca216fa1dc46c37e4a417ffd413d85a602f1fffadd7a3e" +EXPECTED_PUBLIC_SCHEMA_SHA256 = "6bf1f6f66fe28a061fd220a78ea1d09c91a1d3588db144b802d3f43a06779bc6" PROTECTED_TEST_TABLES = ( "actor_profile_migration_state", "alembic_version", From d5e6388c8c4d7d9768d3ff2944afebb64028accf Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 08:54:20 +0100 Subject: [PATCH 145/283] [PILOT-04] Reconcile selected flow behavior ownership --- .ci/behavior-ownership/partition.v1.json | 30 +++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/.ci/behavior-ownership/partition.v1.json b/.ci/behavior-ownership/partition.v1.json index 60f9e85e2..1cacd2e93 100644 --- a/.ci/behavior-ownership/partition.v1.json +++ b/.ci/behavior-ownership/partition.v1.json @@ -400,6 +400,14 @@ "group": "artifacts", "target": "backend/app/modules/artifacts/schemas.py" }, + { + "group": "artifacts", + "target": "backend/app/modules/artifacts/selected_pre_submit_admission.py" + }, + { + "group": "artifacts", + "target": "backend/app/modules/artifacts/selected_pre_submit_execution.py" + }, { "group": "artifacts", "target": "backend/app/modules/artifacts/service.py" @@ -660,6 +668,10 @@ "group": "auth", "target": "backend/app/modules/authorization/domain/post_submit_routing.py" }, + { + "group": "auth", + "target": "backend/app/modules/authorization/domain/pre_submit.py" + }, { "group": "auth", "target": "backend/app/modules/authorization/domain/prepared_adapter_bindings.py" @@ -780,6 +792,10 @@ "group": "auth", "target": "backend/app/modules/authorization/post_submit_routing_authorization.py" }, + { + "group": "auth", + "target": "backend/app/modules/authorization/pre_submit_authorization.py" + }, { "group": "auth", "target": "backend/app/modules/authorization/pre_submit_materialization.py" @@ -900,6 +916,10 @@ "group": "artifacts", "target": "backend/app/modules/checkers/api/default_checker.py" }, + { + "group": "artifacts", + "target": "backend/app/modules/checkers/api/evaluation_contract.py" + }, { "group": "artifacts", "target": "backend/app/modules/checkers/api/execution.py" @@ -920,6 +940,10 @@ "group": "artifacts", "target": "backend/app/modules/checkers/api/history.py" }, + { + "group": "artifacts", + "target": "backend/app/modules/checkers/api/material.py" + }, { "group": "artifacts", "target": "backend/app/modules/checkers/api/materialization.py" @@ -954,11 +978,11 @@ }, { "group": "artifacts", - "target": "backend/app/modules/checkers/default_checker.py" + "target": "backend/app/modules/checkers/checker_retry.py" }, { "group": "artifacts", - "target": "backend/app/modules/checkers/checker_retry.py" + "target": "backend/app/modules/checkers/default_checker.py" }, { "group": "artifacts", @@ -1909,7 +1933,7 @@ "target": "backend/scripts/validate_test_lane_evidence.py" } ], - "authority_digest": "4c48eb383f3d00de9e709bf3d4364958477ec93d228dda91fa0f39a26cd5ced7", + "authority_digest": "34e9996548e3d2cb0e45ce520c93c2e3382b9854aab9271cd3732898b48b34a5", "protected_base_commit": "7676ce4347db0c9694962a9b587a20765e16eac6", "schema": "workstream.behavior-ownership-partition.v1" } From f82f8d11c0a2d12c0cad8f09a9ef97641913cf12 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 09:06:40 +0100 Subject: [PATCH 146/283] [PILOT-04] Resolve exact checker capability versions --- backend/app/interfaces/project_agents.py | 27 +++---- ...est_project_guide_compilation_contracts.py | 70 ++++++++++++++++++- 2 files changed, 83 insertions(+), 14 deletions(-) diff --git a/backend/app/interfaces/project_agents.py b/backend/app/interfaces/project_agents.py index b96070f53..469b35bef 100644 --- a/backend/app/interfaces/project_agents.py +++ b/backend/app/interfaces/project_agents.py @@ -229,7 +229,9 @@ class PreSubmissionBindingProposal(_CapabilityBindingIdentity): """Reference an external intake image with approved typed configuration.""" parameters: tuple[CapabilityParameter, ...] = Field( - default=(), max_length=50, exclude_if=lambda value: not value, + default=(), + max_length=50, + exclude_if=lambda value: not value, ) @model_validator(mode="after") @@ -554,12 +556,12 @@ def validate_project_guide_compilation_result( capabilities = ExternalCheckerCapabilityProjection.model_validate(context.checker_capabilities) pre_definitions = { - definition.capability_id: definition + (definition.capability_id, definition.capability_version): definition for definition in capabilities.definitions if definition.phase == "pre_submit" } post_definitions = { - definition.capability_id: definition + (definition.capability_id, definition.capability_version): definition for definition in capabilities.definitions if definition.phase == "post_submit" } @@ -601,7 +603,7 @@ def validate_post_submission_bindings( result.post_submit_bindings, requirements, { - item.capability_id: item + (item.capability_id, item.capability_version): item for item in capabilities.definitions if item.phase == "post_submit" }, @@ -673,8 +675,8 @@ def _validate_status_consistency(result: ProjectGuideCompilationResult) -> None: def _validate_platform_coverage( requirements: tuple[AtomicGuideRequirement, ...], - pre_definitions: dict[str, ExternalCheckerCapabilityDefinition], - post_definitions: dict[str, ExternalCheckerCapabilityDefinition], + pre_definitions: dict[tuple[str, str], ExternalCheckerCapabilityDefinition], + post_definitions: dict[tuple[str, str], ExternalCheckerCapabilityDefinition], ) -> None: """Resolve platform coverage only against eligible phase-owner truth.""" for requirement in requirements: @@ -686,10 +688,9 @@ def _validate_platform_coverage( if coverage is None: raise ValueError("platform-covered requirement requires canonical proof") if coverage.stage is CompilationStage.PRE_SUBMIT: - definition = pre_definitions.get(coverage.capability_id) + definition = pre_definitions.get((coverage.capability_id, coverage.capability_version)) valid = ( definition is not None - and definition.capability_version == coverage.capability_version and definition.capability_id == "workstream.default" and not definition.selectable ) @@ -732,7 +733,7 @@ def _validate_evidence_lineage( def _validate_bindings( bindings: tuple[PreSubmissionBindingProposal | PostSubmissionBindingProposal, ...], requirements: dict[str, AtomicGuideRequirement], - definitions: dict[str, ExternalCheckerCapabilityDefinition], + definitions: dict[tuple[str, str], ExternalCheckerCapabilityDefinition], expected_stage: Literal["pre_submit", "post_submit"], ) -> set[str]: """Validate exact stage, version, selectability, and parameter ownership.""" @@ -744,7 +745,11 @@ def _validate_bindings( ) for binding in bindings: requirement = requirements.get(binding.requirement_id) - definition = definitions.get(binding.capability_id) + definition = definitions.get((binding.capability_id, binding.capability_version)) + if definition is None and any( + capability_id == binding.capability_id for capability_id, _ in definitions + ): + raise ValueError("compilation capability version is stale") if ( requirement is None or requirement.disposition is not expected_disposition @@ -754,8 +759,6 @@ def _validate_bindings( or binding.stage.value != expected_stage ): raise ValueError("compilation capability binding is invalid") - if binding.capability_version != definition.capability_version: - raise ValueError("compilation capability version is stale") if definition.registry_entry is None: raise ValueError("compilation capability binding is invalid") definition.registry_entry.configuration_schema.validate_instance( diff --git a/backend/tests/test_project_guide_compilation_contracts.py b/backend/tests/test_project_guide_compilation_contracts.py index 0e3b1015a..0bc09515c 100644 --- a/backend/tests/test_project_guide_compilation_contracts.py +++ b/backend/tests/test_project_guide_compilation_contracts.py @@ -171,8 +171,13 @@ def test_task_requirements_response_carries_valid_locked_archive_limit(limit, fi DOCUMENT_VERSION_ID = new_record_id() -def _registered_capability(capability_id: str, phase: str): - spec = registry_spec(phase).model_copy(update={"capability_id": capability_id}) +def _registered_capability(capability_id: str, phase: str, capability_version: str = "v1.2.3"): + spec = registry_spec(phase).model_copy( + update={ + "capability_id": capability_id, + "capability_version": capability_version, + } + ) spec = type(spec).model_validate(spec.model_dump()) entry = ExternalCheckerRegistryEntry( **spec.model_dump(), @@ -510,6 +515,67 @@ def test_unified_result_accepts_exact_stage_capability_and_closed_parameters() - validate_project_guide_compilation_result(context, result) +def test_unified_result_selects_each_exact_registered_capability_version() -> None: + definitions = tuple( + sorted( + ( + ExternalCheckerCapabilityDefinition( + capability_id=WORKSTREAM_DEFAULT_CHECKER_ID, + capability_version=WORKSTREAM_DEFAULT_CHECKER_VERSION, + phase="pre_submit", + selectable=False, + ), + _registered_capability("acme.pre", "pre_submit", "v1.0.0"), + _registered_capability("acme.pre", "pre_submit", "v2.0.0"), + _registered_capability("acme.post", "post_submit"), + ), + key=lambda item: (item.phase, item.capability_id, item.capability_version), + ) + ) + body = { + "schema_version": "external_checker_capabilities.v1", + "definitions": [item.model_dump(mode="json") for item in definitions], + } + capabilities = ExternalCheckerCapabilityProjection( + definitions=definitions, + manifest_sha256=external_checker_json_hash(body), + ) + context = _context().model_copy(update={"checker_capabilities": capabilities}) + + for version in ("v1.0.0", "v2.0.0"): + result = ProjectGuideCompilationResult( + status="draft_ready", + submission_artifact_policy=_artifact_policy(), + requirements=( + AtomicGuideRequirement( + requirement_id="requirement.packet", + statement="Validate the submission packet.", + disposition="supported_pre_submit", + ), + ), + pre_submit_bindings=( + PreSubmissionBindingProposal( + requirement_id="requirement.packet", + capability_id="acme.pre", + capability_version=version, + stage="pre_submit", + ), + ), + agent_version="v1", + ) + validate_project_guide_compilation_result(context, result) + + wrong_version = result.model_copy( + update={ + "pre_submit_bindings": ( + result.pre_submit_bindings[0].model_copy(update={"capability_version": "v1.5.0"}), + ) + } + ) + with pytest.raises(ValueError, match="version is stale"): + validate_project_guide_compilation_result(context, wrong_version) + + @pytest.mark.parametrize( ("capability_id", "version", "stage", "expected_error"), [ From 18d21c5b424f7b80ea7965d781006bfbf8e20f99 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 08:45:42 +0100 Subject: [PATCH 147/283] [PILOT-04] Establish routing fixture assignment custody --- .../tasks/evaluation_delivery/test_completion.py | 10 +++++++++- .../run_selected_end_to_end_probe.py | 11 ++++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/backend/tests/tasks/evaluation_delivery/test_completion.py b/backend/tests/tasks/evaluation_delivery/test_completion.py index 5bb18be8d..c55b31ccb 100644 --- a/backend/tests/tasks/evaluation_delivery/test_completion.py +++ b/backend/tests/tasks/evaluation_delivery/test_completion.py @@ -181,6 +181,14 @@ async def test_production_registry_delivers_request_then_completion_exactly_once human_review_required=human, contribution_awards=awards, ) as h: + # The shared ART fixture arranges an in-progress assignment without + # proving contributor start authority; routing requires accepted custody. + async with h.factory() as session, session.begin(): + accepted = await session.execute(text( + "UPDATE public.task_assignments SET accepted_at=clock_timestamp() " + "WHERE id=:id AND accepted_at IS NULL" + ), {"id": str(h.request.assignment_id)}) + assert accepted.rowcount == 1 await provision_router(h.factory) await delivery_fixture(h) # This fixture has no external POST bindings; use the real configured @@ -218,7 +226,7 @@ async def test_production_registry_delivers_request_then_completion_exactly_once h.request.project_id, "production-completion", ) - assert outcome(completion_receipt)["delivery_state"] == "acknowledged" + assert outcome(completion_receipt)["delivery_state"] == "acknowledged", outcome(completion_receipt) await assert_committed(h, human=human, award_count=len(awards)) async with h.factory() as session: snapshot = await outcome_snapshot(session) diff --git a/experiments/pilot04_external_checker_runtime/run_selected_end_to_end_probe.py b/experiments/pilot04_external_checker_runtime/run_selected_end_to_end_probe.py index 670719408..2d708ad68 100644 --- a/experiments/pilot04_external_checker_runtime/run_selected_end_to_end_probe.py +++ b/experiments/pilot04_external_checker_runtime/run_selected_end_to_end_probe.py @@ -17,7 +17,7 @@ from aiobotocore.config import AioConfig from aiobotocore.session import AioSession -from sqlalchemy import func, select +from sqlalchemy import func, select, text from starlette.requests import Request from app.adapters.artifacts import ( @@ -426,6 +426,15 @@ async def _prove_infrastructure_recovery( async def _production_post_delivery(fixture, settings): """Use production handlers and a fresh worker runtime, then replay delivery.""" + # The ART arrangement is not a contributor-start authority proof. Supply + # its exact accepted-assignment prerequisite before testing routing owners. + async with fixture.factory() as session, session.begin(): + accepted = await session.execute(text( + "UPDATE public.task_assignments SET accepted_at=clock_timestamp() " + "WHERE id=:id AND accepted_at IS NULL" + ), {"id": str(fixture.request.assignment_id)}) + if accepted.rowcount != 1: + raise RuntimeError("fixture assignment acceptance was not established") await provision_router(fixture.factory) await delivery_fixture(fixture) # Supply only this isolated run's configuration. Every provider, grant, From 893e10b2ff4024166029d8efcf7480e0fbda6aee Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 09:18:36 +0100 Subject: [PATCH 148/283] [PILOT-04] Preserve exact replacement cause through selected intake --- .../pilot04-workstream-default-checker.md | 18 ++ backend/app/adapters/tasks/__init__.py | 2 + .../selected_pre_submit_admission.py | 1 + backend/app/modules/artifacts/service.py | 3 + .../modules/artifacts/submission_admission.py | 6 +- .../pre_submit_materialization.py | 25 +- backend/app/modules/authorization/prepared.py | 27 +- .../checkers/api/selected_pre_submit.py | 240 +++++++++--------- .../external/test_selected_pre_submit.py | 28 +- .../test_selected_pre_submit_coordination.py | 85 ++++--- ...est_project_guide_compilation_contracts.py | 20 +- ...st_submission_preparation_authorization.py | 7 +- 12 files changed, 260 insertions(+), 202 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 09564e761..d73caef75 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -262,3 +262,21 @@ and approval. Configuration arrays are normalized to JSON arrays for both phases. Empty PRE parameters are excluded during serialization, preserving retained empty-binding hashes. Focused compiler regressions cover configured PRE success, required/type rejection, duplicate names and retained serialization. + +### Selected replacement cause repair + +After reconciling merged replacement intake and the operator-retry branch, source +review found selected PRE lineage omitted the remediation manifest. The repair +binds the exact cause through canonical reservation JSON, TASK revalidation, +ART final authority and ready-admission facts. Initial attempts require no cause; +replacement attempts require a UUID cause alongside the predecessor. Focused +proof covers cause round trips, publication and substitution denial. The first +contract run passed 120 tests; the expanded run passed 121 with one stale AUTH +fixture missing required packet/manifest facts. That fixture is being corrected +without changing authority guards. PostgreSQL currentness and full Rust/MinIO +proof remain pending on the final reconciled migration. + +The reconciled AUTH composition exceeded its existing 1,200-line boundary. Move +its exact artifact-binding matcher to the existing materialization binding owner, +with explicit context/digest inputs and unchanged predicates; do not alter the +structural debt ledger or its limit. diff --git a/backend/app/adapters/tasks/__init__.py b/backend/app/adapters/tasks/__init__.py index 3f399388a..447a53609 100644 --- a/backend/app/adapters/tasks/__init__.py +++ b/backend/app/adapters/tasks/__init__.py @@ -75,6 +75,8 @@ async def lock_selected_pre_submit_scope( != lineage.predecessor_submission_id or (predecessor.version if predecessor is not None else None) != lineage.predecessor_submission_version + or context.checker_remediation_manifest_id + != lineage.checker_remediation_manifest_id or references.project_id != reservation.project_id or references.guide_version != lineage.guide_version or references.source_snapshot_id != lineage.source_snapshot_id diff --git a/backend/app/modules/artifacts/selected_pre_submit_admission.py b/backend/app/modules/artifacts/selected_pre_submit_admission.py index 7521a4a3e..64f9769cd 100644 --- a/backend/app/modules/artifacts/selected_pre_submit_admission.py +++ b/backend/app/modules/artifacts/selected_pre_submit_admission.py @@ -139,6 +139,7 @@ def build_selected_pre_submit_reservation( predecessor_submission_version=( predecessor.version if predecessor is not None else None ), + checker_remediation_manifest_id=task.checker_remediation_manifest_id, guide_id=project.guide_id, guide_version=project.guide_version, source_snapshot_id=project.source_snapshot_id, diff --git a/backend/app/modules/artifacts/service.py b/backend/app/modules/artifacts/service.py index 61c9a51c8..e1902a9ce 100644 --- a/backend/app/modules/artifacts/service.py +++ b/backend/app/modules/artifacts/service.py @@ -2757,6 +2757,8 @@ async def _selected_submission_bundle_facts( != lineage.predecessor_submission_id or (predecessor.version if predecessor is not None else None) != lineage.predecessor_submission_version + or task.checker_remediation_manifest_id + != lineage.checker_remediation_manifest_id or locked.project_id != reservation.project_id or locked.guide_id != lineage.guide_id or locked.guide_version != lineage.guide_version @@ -2786,6 +2788,7 @@ async def _selected_submission_bundle_facts( assignment_id=reservation.assignment_id, predecessor_submission_id=lineage.predecessor_submission_id, predecessor_submission_version=lineage.predecessor_submission_version, + checker_remediation_manifest_id=lineage.checker_remediation_manifest_id, pre_submit_evidence_set_id=None, prepared_generation_id=reservation.prepared_generation_id, guide_id=lineage.guide_id, diff --git a/backend/app/modules/artifacts/submission_admission.py b/backend/app/modules/artifacts/submission_admission.py index 010a62463..5d3c4ce42 100644 --- a/backend/app/modules/artifacts/submission_admission.py +++ b/backend/app/modules/artifacts/submission_admission.py @@ -471,7 +471,11 @@ async def publish_verified( else evidence.predecessor_submission_version ), checker_remediation_manifest_id=( - None if evidence is None else evidence.checker_remediation_manifest_id + str(selected_lineage.checker_remediation_manifest_id) + if selected_lineage is not None + and selected_lineage.checker_remediation_manifest_id is not None + else evidence.checker_remediation_manifest_id + if evidence is not None else None ), locked_policy_context_hash=( selected_lineage.locked_policy_context_hash diff --git a/backend/app/modules/authorization/pre_submit_materialization.py b/backend/app/modules/authorization/pre_submit_materialization.py index 82fbdce76..f7a21896a 100644 --- a/backend/app/modules/authorization/pre_submit_materialization.py +++ b/backend/app/modules/authorization/pre_submit_materialization.py @@ -6,7 +6,11 @@ from app.core.hashing import canonical_json_hash from app.modules.authorization.catalogue import ActionId from app.modules.authorization.domain.resource_digest import authorization_resource_digest -from app.modules.authorization.runtime import PreSubmitCheckerInputPreparationContext, TaskImportSourceResourceContext +from app.modules.authorization.runtime import ( + PreSubmitCheckerInputPreparationContext, TaskImportSourceResourceContext, + PreSubmitCheckerInputResourceContext, SubmissionBindingResourceContext, + SubmissionCreationResourceContext, +) from app.modules.authorization.submission_consumption import parse_consumption_binding from app.modules.authorization.submission_preparation import ( parse_submission_preparation_or_invalid, submission_preparation_binding_fields, @@ -70,3 +74,22 @@ def parse_project_create_binding(raw: dict, invalid_error): if type(generation) is not int or generation < 1 or operation_id == project_id: raise invalid_error("invalid prepared authorization handle") return operation_id, project_id, generation + +def exact_artifact_binding_matches( + prepared_context: dict | None, + prepared_digest: str | None, + resource: PreSubmitCheckerInputResourceContext + | SubmissionBindingResourceContext + | SubmissionCreationResourceContext, +) -> bool: + """Require every materialization fact to equal the prepared request.""" + if isinstance(resource, PreSubmitCheckerInputResourceContext): + context = resource.model_dump(mode="json", exclude={"semantic_manifest_sha256"}) + return prepared_context == context and ( + prepared_digest + == canonical_json_hash({"pre_submit_checker_input_preparation": context}) + ) + context = resource.model_dump(mode="json") + return prepared_context == context and ( + prepared_digest == authorization_resource_digest(resource) + ) diff --git a/backend/app/modules/authorization/prepared.py b/backend/app/modules/authorization/prepared.py index b3a5bb3b5..bc9eacd2d 100644 --- a/backend/app/modules/authorization/prepared.py +++ b/backend/app/modules/authorization/prepared.py @@ -17,7 +17,6 @@ from sqlalchemy.ext.asyncio import AsyncSession -from app.core.hashing import canonical_json_hash from app.modules.actors.repository import ActorRepository from app.modules.actors.api import ServiceIdentity from app.modules.audit.schemas import ActorReferenceKind @@ -138,7 +137,7 @@ from app.modules.authorization.prepared_submission_replay import validate_submission_replay from app.modules.authorization.prepared_post_submit_replay import validate_post_submit_replay from app.modules.authorization.pre_submit_materialization import ( - parse_prepared_artifact_bindings, + parse_prepared_artifact_bindings, exact_artifact_binding_matches, parse_project_create_binding, ) @@ -396,25 +395,6 @@ def _submission_policy_binding_matches( ) and binding.submission_policy_resource_digest == authorization_resource_digest(resource) -def _exact_artifact_binding_matches( - binding: _PreparedAuthorizationBinding, - resource: PreSubmitCheckerInputResourceContext - | SubmissionBindingResourceContext - | SubmissionCreationResourceContext, -) -> bool: - """Require every materialization fact to equal the prepared request.""" - if isinstance(resource, PreSubmitCheckerInputResourceContext): - context = resource.model_dump(mode="json", exclude={"semantic_manifest_sha256"}) - return binding.exact_artifact_context == context and ( - binding.exact_artifact_resource_digest - == canonical_json_hash({"pre_submit_checker_input_preparation": context}) - ) - context = resource.model_dump(mode="json") - return binding.exact_artifact_context == context and ( - binding.exact_artifact_resource_digest == authorization_resource_digest(resource) - ) - - def _submission_preparation_binding_matches( binding: _PreparedAuthorizationBinding, resource: SubmissionBundlePreparationPreflightResourceContext @@ -727,7 +707,10 @@ async def consume( SubmissionCreationResourceContext, TaskImportSourceResourceContext, ), - ) and not _exact_artifact_binding_matches(issuance.binding, final_resource_context): + ) and not exact_artifact_binding_matches( + issuance.binding.exact_artifact_context, + issuance.binding.exact_artifact_resource_digest, final_resource_context, + ): raise PreparedAuthorizationHandleInvalid("invalid prepared authorization handle") if isinstance( final_resource_context, SubmissionBundlePreparationResourceContext diff --git a/backend/app/modules/checkers/api/selected_pre_submit.py b/backend/app/modules/checkers/api/selected_pre_submit.py index 5d18fe1a2..31ad2323a 100644 --- a/backend/app/modules/checkers/api/selected_pre_submit.py +++ b/backend/app/modules/checkers/api/selected_pre_submit.py @@ -20,6 +20,7 @@ class SelectedPreSubmitAdmissionLineage: predecessor_submission_id: UUID | None predecessor_submission_version: int | None + checker_remediation_manifest_id: UUID | None guide_id: UUID guide_version: str source_snapshot_id: UUID @@ -75,11 +76,15 @@ def __post_init__(self) -> None: or self.predecessor_submission_version < 1 ) ) + or (self.predecessor_submission_id is None) + != (self.checker_remediation_manifest_id is None) + or ( + self.checker_remediation_manifest_id is not None + and type(self.checker_remediation_manifest_id) is not UUID + ) or not self.guide_version.strip() or any( - type(value) is not str - or len(value) != 71 - or not value.startswith("sha256:") + type(value) is not str or len(value) != 71 or not value.startswith("sha256:") for value in digests ) or type(self.semantic_manifest_body) is not dict @@ -92,8 +97,7 @@ def __post_init__(self) -> None: } ) != self.post_submit_policy_sha256 - or self.post_submit_policy_body.get("policy_sha256") - != self.post_submit_policy_sha256 + or self.post_submit_policy_body.get("policy_sha256") != self.post_submit_policy_sha256 or self.storage_scheme not in {"local", "s3"} ): raise ValueError("selected PRE admission lineage is invalid") @@ -107,6 +111,11 @@ def canonical_body(self) -> dict[str, object]: else None ), "predecessor_submission_version": self.predecessor_submission_version, + "checker_remediation_manifest_id": ( + str(self.checker_remediation_manifest_id) + if self.checker_remediation_manifest_id is not None + else None + ), "guide_id": str(self.guide_id), "guide_version": self.guide_version, "source_snapshot_id": str(self.source_snapshot_id), @@ -118,9 +127,7 @@ def canonical_body(self) -> dict[str, object]: "pre_submit_policy_sha256": self.pre_submit_policy_sha256, "effective_plan_sha256": self.effective_plan_sha256, "rules_sha256": self.rules_sha256, - "external_checker_policies_sha256": ( - self.external_checker_policies_sha256 - ), + "external_checker_policies_sha256": (self.external_checker_policies_sha256), "post_submit_policy_sha256": self.post_submit_policy_sha256, "post_submit_policy_body": self.post_submit_policy_body, "locked_policy_context_hash": self.locked_policy_context_hash, @@ -131,13 +138,12 @@ def canonical_body(self) -> dict[str, object]: } @classmethod - def from_canonical_body( - cls, body: object - ) -> SelectedPreSubmitAdmissionLineage: + def from_canonical_body(cls, body: object) -> SelectedPreSubmitAdmissionLineage: """Parse the exact closed body copied into ART's durable intent.""" if type(body) is not dict or set(body) != { "predecessor_submission_id", "predecessor_submission_version", + "checker_remediation_manifest_id", "guide_id", "guide_version", "source_snapshot_id", @@ -161,10 +167,13 @@ def from_canonical_body( raise ValueError("selected PRE admission lineage is invalid") predecessor = body["predecessor_submission_id"] return cls( - predecessor_submission_id=( - UUID(str(predecessor)) if predecessor is not None else None - ), + predecessor_submission_id=(UUID(str(predecessor)) if predecessor is not None else None), predecessor_submission_version=body["predecessor_submission_version"], + checker_remediation_manifest_id=( + UUID(str(body["checker_remediation_manifest_id"])) + if body["checker_remediation_manifest_id"] is not None + else None + ), guide_id=UUID(str(body["guide_id"])), guide_version=body["guide_version"], source_snapshot_id=UUID(str(body["source_snapshot_id"])), @@ -176,9 +185,7 @@ def from_canonical_body( pre_submit_policy_sha256=body["pre_submit_policy_sha256"], effective_plan_sha256=body["effective_plan_sha256"], rules_sha256=body["rules_sha256"], - external_checker_policies_sha256=body[ - "external_checker_policies_sha256" - ], + external_checker_policies_sha256=body["external_checker_policies_sha256"], post_submit_policy_sha256=body["post_submit_policy_sha256"], post_submit_policy_body=body["post_submit_policy_body"], locked_policy_context_hash=body["locked_policy_context_hash"], @@ -255,9 +262,7 @@ def __post_init__(self) -> None: raise ValueError("selected PRE execution facts are invalid") external_passed = all(item.result.verdict == "passed" for item in members) complete = len(members) == self.required_external_count - if self.eligible != ( - self.workstream_default.eligible and complete and external_passed - ): + if self.eligible != (self.workstream_default.eligible and complete and external_passed): raise ValueError("selected PRE eligibility differs from required results") if ( not self.workstream_default.eligible @@ -289,18 +294,21 @@ def canonical_body(self) -> dict[str, object]: } @classmethod - def from_canonical_body( - cls, body: object - ) -> SelectedPreSubmitExecutionFacts: + def from_canonical_body(cls, body: object) -> SelectedPreSubmitExecutionFacts: """Parse the exact bounded result retained for idempotent work replay.""" - if type(body) is not dict or set(body) != { - "schema_version", - "policy_sha256", - "workstream_default", - "required_external_count", - "external_members", - "eligible", - } or body["schema_version"] != "workstream.selected_pre_submit_execution.v1": + if ( + type(body) is not dict + or set(body) + != { + "schema_version", + "policy_sha256", + "workstream_default", + "required_external_count", + "external_members", + "eligible", + } + or body["schema_version"] != "workstream.selected_pre_submit_execution.v1" + ): raise ValueError("selected PRE execution facts are invalid") members = body["external_members"] if type(members) is not list: @@ -320,11 +328,7 @@ def from_canonical_body( request_digest=item["request_digest"], result=ExternalCheckerExecutionResult.model_validate( item["result"] - | { - "registry_entry_id": UUID( - str(item["result"]["registry_entry_id"]) - ) - } + | {"registry_entry_id": UUID(str(item["result"]["registry_entry_id"]))} ), isolation=ExternalPreSubmitIsolationFacts(**item["isolation"]), ) @@ -384,9 +388,7 @@ def __post_init__(self) -> None: if ( any(type(value) is not UUID for value in identifiers) or any( - type(value) is not str - or len(value) != 71 - or not value.startswith("sha256:") + type(value) is not str or len(value) != 71 or not value.startswith("sha256:") for value in digests ) or self.default_behavior_sha256 != WORKSTREAM_DEFAULT_BEHAVIOR_SHA256 @@ -396,18 +398,14 @@ def __post_init__(self) -> None: or not 100 <= self.execution_budget_ms <= 14_400_000 or ( self.admission_lineage is not None - and type(self.admission_lineage) - is not SelectedPreSubmitAdmissionLineage + and type(self.admission_lineage) is not SelectedPreSubmitAdmissionLineage ) or ( self.admission_lineage is not None and ( - canonical_json_hash( - self.admission_lineage.semantic_manifest_body - ) + canonical_json_hash(self.admission_lineage.semantic_manifest_body) != self.semantic_manifest_sha256 - or self.admission_lineage.effective_plan_sha256 - != self.policy_sha256 + or self.admission_lineage.effective_plan_sha256 != self.policy_sha256 ) ) ): @@ -441,30 +439,33 @@ def canonical_body(self) -> dict[str, object]: } @classmethod - def from_canonical_body( - cls, body: object - ) -> SelectedPreSubmitReservationFacts: + def from_canonical_body(cls, body: object) -> SelectedPreSubmitReservationFacts: """Recover and validate the durable request snapshot at ART publication.""" - if type(body) is not dict or set(body) != { - "schema_version", - "actor_profile_id", - "identity_link_id", - "project_id", - "task_id", - "assignment_id", - "attempt_id", - "idempotency_key", - "attempt_request_digest", - "prepared_generation_id", - "policy_sha256", - "default_behavior_sha256", - "default_input_sha256", - "archive_sha256", - "archive_byte_count", - "semantic_manifest_sha256", - "execution_budget_ms", - "admission_lineage", - } or body["schema_version"] != "workstream.selected_pre_submit_reservation.v1": + if ( + type(body) is not dict + or set(body) + != { + "schema_version", + "actor_profile_id", + "identity_link_id", + "project_id", + "task_id", + "assignment_id", + "attempt_id", + "idempotency_key", + "attempt_request_digest", + "prepared_generation_id", + "policy_sha256", + "default_behavior_sha256", + "default_input_sha256", + "archive_sha256", + "archive_byte_count", + "semantic_manifest_sha256", + "execution_budget_ms", + "admission_lineage", + } + or body["schema_version"] != "workstream.selected_pre_submit_reservation.v1" + ): raise ValueError("selected PRE reservation facts are invalid") lineage_body = body["admission_lineage"] return cls( @@ -589,9 +590,7 @@ def __post_init__(self) -> None: if self.execution.policy_sha256 != self.lease.reservation.policy_sha256: raise ValueError("selected PRE finalize policy is invalid") else: - SelectedPreSubmitInfrastructureUnavailable( - self.infrastructure_failure_code or "" - ) + SelectedPreSubmitInfrastructureUnavailable(self.infrastructure_failure_code or "") @property def facts_digest(self) -> str: @@ -599,13 +598,9 @@ def facts_digest(self) -> str: return canonical_json_hash( { "schema_version": "workstream.selected_pre_submit_finalize.v1", - "execute_facts_digest": SelectedPreSubmitExecuteFacts( - self.lease - ).facts_digest, + "execute_facts_digest": SelectedPreSubmitExecuteFacts(self.lease).facts_digest, "execution": ( - self.execution.canonical_body() - if self.execution is not None - else None + self.execution.canonical_body() if self.execution is not None else None ), "infrastructure_failure_code": self.infrastructure_failure_code, } @@ -726,30 +721,29 @@ def __post_init__(self) -> None: """Keep work findings separate from recoverable infrastructure outcomes.""" if type(self.lease) is not SelectedPreSubmitLeaseFacts: raise ValueError("selected PRE terminal lease is invalid") - if any(value.tzinfo is None for value in ( - self.queued_at, - self.started_at, - self.completed_at, - )) or not (self.queued_at <= self.started_at <= self.completed_at): + if any( + value.tzinfo is None + for value in ( + self.queued_at, + self.started_at, + self.completed_at, + ) + ) or not (self.queued_at <= self.started_at <= self.completed_at): raise ValueError("selected PRE terminal timing is invalid") if self.outcome == "completed": if ( type(self.execution) is not SelectedPreSubmitExecutionFacts or self.infrastructure_failure_code is not None - or self.execution.policy_sha256 - != self.lease.reservation.policy_sha256 + or self.execution.policy_sha256 != self.lease.reservation.policy_sha256 ): raise ValueError("selected PRE completed outcome is invalid") - elif ( - self.execution is not None - or self.infrastructure_failure_code not in { - "capacity_exceeded", - "deadline_exceeded", - "material_unavailable", - "implementation_unavailable", - "invalid_output", - } - ): + elif self.execution is not None or self.infrastructure_failure_code not in { + "capacity_exceeded", + "deadline_exceeded", + "material_unavailable", + "implementation_unavailable", + "invalid_output", + }: raise ValueError("selected PRE infrastructure outcome is invalid") def canonical_body(self) -> dict[str, object]: @@ -767,39 +761,38 @@ def canonical_body(self) -> dict[str, object]: "queued_at": self.queued_at.isoformat(), "started_at": self.started_at.isoformat(), "completed_at": self.completed_at.isoformat(), - "queue_latency_ms": int( - (self.started_at - self.queued_at).total_seconds() * 1000 - ), + "queue_latency_ms": int((self.started_at - self.queued_at).total_seconds() * 1000), "execution_latency_ms": int( (self.completed_at - self.started_at).total_seconds() * 1000 ), } @classmethod - def from_canonical_body( - cls, body: object - ) -> SelectedPreSubmitTerminalFacts: + def from_canonical_body(cls, body: object) -> SelectedPreSubmitTerminalFacts: """Parse and revalidate every persisted lease, result and timing fact.""" - if type(body) is not dict or set(body) != { - "schema_version", - "reservation", - "request_digest", - "lease_id", - "lease_generation", - "lease_expires_at", - "outcome", - "execution", - "infrastructure_failure_code", - "queued_at", - "started_at", - "completed_at", - "queue_latency_ms", - "execution_latency_ms", - } or body["schema_version"] != "workstream.selected_pre_submit_terminal.v1": + if ( + type(body) is not dict + or set(body) + != { + "schema_version", + "reservation", + "request_digest", + "lease_id", + "lease_generation", + "lease_expires_at", + "outcome", + "execution", + "infrastructure_failure_code", + "queued_at", + "started_at", + "completed_at", + "queue_latency_ms", + "execution_latency_ms", + } + or body["schema_version"] != "workstream.selected_pre_submit_terminal.v1" + ): raise ValueError("selected PRE terminal facts are invalid") - reservation = SelectedPreSubmitReservationFacts.from_canonical_body( - body["reservation"] - ) + reservation = SelectedPreSubmitReservationFacts.from_canonical_body(body["reservation"]) if body["request_digest"] != reservation.request_digest: raise ValueError("selected PRE terminal request is invalid") execution_body = body["execution"] @@ -841,14 +834,13 @@ class SelectedPreSubmitCurrentFacts: terminal: SelectedPreSubmitTerminalFacts | None def __post_init__(self) -> None: - terminal_status = ( - self.terminal.outcome if self.terminal is not None else None - ) + terminal_status = self.terminal.outcome if self.terminal is not None else None if ( type(self.run_id) is not UUID or type(self.reservation) is not SelectedPreSubmitReservationFacts or self.run_id != self.reservation.attempt_id - or self.status not in { + or self.status + not in { "queued", "running", "completed", diff --git a/backend/tests/checkers/external/test_selected_pre_submit.py b/backend/tests/checkers/external/test_selected_pre_submit.py index 57ab61a5a..1d195dd58 100644 --- a/backend/tests/checkers/external/test_selected_pre_submit.py +++ b/backend/tests/checkers/external/test_selected_pre_submit.py @@ -113,6 +113,7 @@ def _selected_admission_reservation(): lineage = SelectedPreSubmitAdmissionLineage( predecessor_submission_id=None, predecessor_submission_version=None, + checker_remediation_manifest_id=None, guide_id=new_record_id(), guide_version="v2", source_snapshot_id=new_record_id(), @@ -288,6 +289,7 @@ async def _request( submission_artifact_policy_id=lineage.effective_policy_id, checker_policy_id=lineage.pre_submit_policy_id, predecessor_submission_version=None, + checker_remediation_manifest_id=None, prepared_artifact=prepared, effective_plan=plan, inspection=inspection, @@ -567,8 +569,25 @@ async def test_selected_pre_runs_default_then_locked_external_image( @pytest.mark.asyncio -async def test_selected_pre_terminal_publishes_self_contained_ready_admission() -> None: +@pytest.mark.parametrize("replacement", [False, True]) +async def test_selected_pre_terminal_publishes_self_contained_ready_admission( + replacement: bool, +) -> None: manifest, post_policy, selected = _selected_admission_reservation() + if replacement: + selected = replace( + selected, + admission_lineage=replace( + selected.admission_lineage, + predecessor_submission_id=new_record_id(), + predecessor_submission_version=1, + checker_remediation_manifest_id=new_record_id(), + ), + ) + lineage = selected.admission_lineage + assert ( + SelectedPreSubmitAdmissionLineage.from_canonical_body(lineage.canonical_body()) == lineage + ) session, job, verification = _selected_admission_publisher_fixture(selected) admission = await SubmissionBundleAdmissionPublisher(session).publish_verified( @@ -576,6 +595,9 @@ async def test_selected_pre_terminal_publishes_self_contained_ready_admission() verification_receipt_id=verification.id, ) + assert admission.checker_remediation_manifest_id == ( + str(lineage.checker_remediation_manifest_id) if replacement else None + ) assert admission.pre_submit_evidence_set_id is None assert admission.selected_pre_submit_run_id == str(selected.attempt_id) assert admission.packet_sha256 == selected.admission_lineage.packet_sha256 @@ -692,6 +714,7 @@ async def test_selected_admission_binds_unchanged_work_to_current_task_rules( contributor_id=actor_profile_id, task_id=request.task_id, assignment_id=assignment_id, + checker_remediation_manifest_id=new_record_id(), predecessor=SimpleNamespace( submission_id=predecessor.submission_id, version=predecessor.submission_version, @@ -757,6 +780,9 @@ async def test_selected_admission_binds_unchanged_work_to_current_task_rules( assert reservation.admission_lineage is not None assert reservation.admission_lineage.semantic_manifest_body == (request.manifest.as_dict()) assert reservation.admission_lineage.packet_sha256 == request.packet.sha256 + assert reservation.admission_lineage.checker_remediation_manifest_id == ( + task.checker_remediation_manifest_id + ) assert reservation.admission_lineage.predecessor_submission_id == ( predecessor.submission_id ) diff --git a/backend/tests/checkers/external/test_selected_pre_submit_coordination.py b/backend/tests/checkers/external/test_selected_pre_submit_coordination.py index 05a68b104..caca974d1 100644 --- a/backend/tests/checkers/external/test_selected_pre_submit_coordination.py +++ b/backend/tests/checkers/external/test_selected_pre_submit_coordination.py @@ -46,9 +46,7 @@ "entries": [], } _POST_POLICY_SHA256 = canonical_json_hash(_POST_POLICY_WITHOUT_DIGEST) -_POST_POLICY = _POST_POLICY_WITHOUT_DIGEST | { - "policy_sha256": _POST_POLICY_SHA256 -} +_POST_POLICY = _POST_POLICY_WITHOUT_DIGEST | {"policy_sha256": _POST_POLICY_SHA256} def _reservation() -> SelectedPreSubmitReservationFacts: @@ -128,9 +126,7 @@ async def test_selected_pre_current_replays_only_stable_actor_key_facts() -> Non SelectedPreSubmitRequestConflict, match="selected_pre_submit_request_conflict", ): - await coordinator.read_current( - replace(fresh, archive_sha256="sha256:" + "f" * 64) - ) + await coordinator.read_current(replace(fresh, archive_sha256="sha256:" + "f" * 64)) @pytest.mark.asyncio @@ -168,6 +164,7 @@ async def test_selected_pre_task_guard_rechecks_exact_locked_lineage(monkeypatch lineage = SelectedPreSubmitAdmissionLineage( predecessor_submission_id=new_record_id(), predecessor_submission_version=2, + checker_remediation_manifest_id=new_record_id(), guide_id=new_record_id(), guide_version="guide-v2", source_snapshot_id=new_record_id(), @@ -208,6 +205,7 @@ async def test_selected_pre_task_guard_rechecks_exact_locked_lineage(monkeypatch task_id=reservation.task_id, assignment_id=reservation.assignment_id, contributor_id=reservation.actor_profile_id, + checker_remediation_manifest_id=(lineage.checker_remediation_manifest_id), predecessor=SimpleNamespace( submission_id=lineage.predecessor_submission_id, version=lineage.predecessor_submission_version, @@ -223,17 +221,18 @@ async def lock(_repository, request): guard = selected_pre_submit_task_guard(SimpleNamespace()) await guard.lock_selected_pre_submit_scope(reservation) + context.checker_remediation_manifest_id = new_record_id() + with pytest.raises(RuntimeError, match="selected PRE TASK custody changed"): + await guard.lock_selected_pre_submit_scope(reservation) + context.checker_remediation_manifest_id = lineage.checker_remediation_manifest_id + locked.pre_submit_policy_bundle_hash = "sha256:" + "c" * 64 with pytest.raises(RuntimeError, match="selected PRE TASK custody changed"): await guard.lock_selected_pre_submit_scope(reservation) def test_selected_pre_model_compiles_complete_owner_and_authority_custody() -> None: - sql = str( - CreateTable(SelectedPreSubmitRun.__table__).compile( - dialect=postgresql.dialect() - ) - ) + sql = str(CreateTable(SelectedPreSubmitRun.__table__).compile(dialect=postgresql.dialect())) for value in ( "fk_selected_pre_run_task_project", "fk_selected_pre_run_assignment", @@ -245,14 +244,10 @@ def test_selected_pre_model_compiles_complete_owner_and_authority_custody() -> N assert "pre_submit_execution_attempts" not in sql intent_sql = str( - CreateTable(SubmissionBundleDurableIntent.__table__).compile( - dialect=postgresql.dialect() - ) + CreateTable(SubmissionBundleDurableIntent.__table__).compile(dialect=postgresql.dialect()) ) admission_sql = str( - CreateTable(SubmissionBundleAdmission.__table__).compile( - dialect=postgresql.dialect() - ) + CreateTable(SubmissionBundleAdmission.__table__).compile(dialect=postgresql.dialect()) ) for compiled in (intent_sql, admission_sql): assert "selected_pre_submit_run_id" in compiled @@ -291,9 +286,7 @@ def test_selected_pre_admission_capability_is_exact_and_single_use() -> None: with pytest.raises( SelectedPreSubmitUnavailable, match="selected_pre_submit_admission_unavailable" ): - capability.consume( - **(values | {"semantic_manifest_sha256": "sha256:" + "6" * 64}) - ) + capability.consume(**(values | {"semantic_manifest_sha256": "sha256:" + "6" * 64})) assert capability.consume(**values) == run_id with pytest.raises(SelectedPreSubmitUnavailable): capability.consume(**values) @@ -320,10 +313,13 @@ def test_selected_pre_execution_capability_is_exact_and_single_use() -> None: SelectedPreSubmitUnavailable, match="selected_pre_submit_execution_unavailable" ): capability.consume(run_id=new_record_id(), lease=lease) - assert capability.consume( - run_id=reservation.attempt_id, - lease=lease, - ) == lease + assert ( + capability.consume( + run_id=reservation.attempt_id, + lease=lease, + ) + == lease + ) with pytest.raises(SelectedPreSubmitUnavailable): capability.consume(run_id=reservation.attempt_id, lease=lease) @@ -354,11 +350,14 @@ def test_selected_pre_authority_digests_bind_lease_and_infrastructure_outcome() ) assert execution.facts_digest != changed.facts_digest - assert terminal.facts_digest != SelectedPreSubmitFinalizeFacts( - lease=lease, - execution=None, - infrastructure_failure_code="material_unavailable", - ).facts_digest + assert ( + terminal.facts_digest + != SelectedPreSubmitFinalizeFacts( + lease=lease, + execution=None, + infrastructure_failure_code="material_unavailable", + ).facts_digest + ) with pytest.raises(ValueError, match="outcome"): SelectedPreSubmitFinalizeFacts( lease=lease, @@ -373,6 +372,7 @@ def test_selected_pre_request_binds_complete_later_admission_lineage() -> None: lineage = SelectedPreSubmitAdmissionLineage( predecessor_submission_id=None, predecessor_submission_version=None, + checker_remediation_manifest_id=None, guide_id=new_record_id(), guide_version="locked-v1", source_snapshot_id=new_record_id(), @@ -401,13 +401,17 @@ def test_selected_pre_request_binds_complete_later_admission_lineage() -> None: ) assert reservation.canonical_body()["admission_lineage"] == lineage.canonical_body() - assert SelectedPreSubmitReservationFacts.from_canonical_body( - reservation.canonical_body() - ) == reservation - assert reservation.request_digest != replace( - reservation, - admission_lineage=replace(lineage, packet_sha256="sha256:" + "9" * 64), - ).request_digest + assert ( + SelectedPreSubmitReservationFacts.from_canonical_body(reservation.canonical_body()) + == reservation + ) + assert ( + reservation.request_digest + != replace( + reservation, + admission_lineage=replace(lineage, packet_sha256="sha256:" + "9" * 64), + ).request_digest + ) with pytest.raises(ValueError, match="reservation"): replace(reservation, semantic_manifest_sha256=SHA) @@ -448,6 +452,7 @@ def test_selected_ready_admission_no_longer_requires_legacy_evidence() -> None: assignment_id=str(new_record_id()), predecessor_submission_id=None, predecessor_submission_version=None, + checker_remediation_manifest_id=None, guide_id=str(new_record_id()), guide_version="v1", source_snapshot_id=str(new_record_id()), @@ -475,11 +480,7 @@ def test_selected_ready_admission_no_longer_requires_legacy_evidence() -> None: submission_version=1, ) - assert SubmissionAdmissionConsumptionService._art_lineage_is_intact( - admission, None, content - ) - facts = SubmissionAdmissionConsumptionService._authority_facts( - admission, request - ) + assert SubmissionAdmissionConsumptionService._art_lineage_is_intact(admission, None, content) + facts = SubmissionAdmissionConsumptionService._authority_facts(admission, request) assert facts.evidence_set_id is None assert facts.selected_pre_submit_run_id == run_id diff --git a/backend/tests/test_project_guide_compilation_contracts.py b/backend/tests/test_project_guide_compilation_contracts.py index 0bc09515c..968d8189c 100644 --- a/backend/tests/test_project_guide_compilation_contracts.py +++ b/backend/tests/test_project_guide_compilation_contracts.py @@ -963,16 +963,16 @@ def test_blocked_result_cannot_publish_policy_or_bindings() -> None: @pytest.mark.parametrize("parameters", [[], [{"name": "maximum_file_size_bytes", "value": 1000}]]) -def test_pre_submission_binding_rejects_duplicate_policy_configuration(parameters): - """The sole intake configuration is the artifact policy, never a second copy.""" - with pytest.raises(ValidationError, match="Extra inputs"): - PreSubmissionBindingProposal( - requirement_id="requirement.size", - capability_id="policy.file_size.limit", - capability_version="v1", - stage="pre_submit", - parameters=parameters, - ) +def test_pre_submission_binding_accepts_explicit_checker_configuration(parameters): + """Approved PRE image configuration is distinct from platform intake limits.""" + binding = PreSubmissionBindingProposal( + requirement_id="requirement.size", + capability_id="policy.file_size.limit", + capability_version="v1", + stage="pre_submit", + parameters=parameters, + ) + assert [item.model_dump(mode="json") for item in binding.parameters] == parameters def test_context_rejects_instruction_version_separate_from_snapshot() -> None: diff --git a/backend/tests/test_submission_preparation_authorization.py b/backend/tests/test_submission_preparation_authorization.py index 02eefe29d..3dd77f83c 100644 --- a/backend/tests/test_submission_preparation_authorization.py +++ b/backend/tests/test_submission_preparation_authorization.py @@ -3,6 +3,7 @@ from types import SimpleNamespace from uuid import UUID from app.core.identifiers import new_record_id +from app.core.hashing import canonical_json_hash import pytest @@ -47,7 +48,11 @@ def _final_values(request_values): "effective_policy_sha256": "sha256:" + "2" * 64, "pre_submit_policy_sha256": "sha256:" + "3" * 64, "effective_plan_sha256": "sha256:" + "4" * 64, - "semantic_manifest_sha256": "sha256:" + "5" * 64, + "semantic_manifest_body": {"schema_version": "submission_manifest.v1", "entries": []}, + "semantic_manifest_sha256": canonical_json_hash( + {"schema_version": "submission_manifest.v1", "entries": []} + ), + "packet_sha256": "sha256:" + "8" * 64, "archive_sha256": "sha256:" + "6" * 64, "archive_byte_count": 42, "media_type": "application/zip", From bb3f6dcc7412102e8c3eebec319f3c433959a8dc Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 09:24:55 +0100 Subject: [PATCH 149/283] [PILOT-04] Restore canonical task context after branch reconciliation --- .../pilot04-workstream-default-checker.md | 8 +++ backend/app/adapters/tasks/__init__.py | 2 +- backend/app/modules/tasks/repository.py | 58 +++++++++++++------ .../test_selected_pre_submit_coordination.py | 4 +- 4 files changed, 50 insertions(+), 22 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index d73caef75..37aa4e0fe 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -280,3 +280,11 @@ The reconciled AUTH composition exceeded its existing 1,200-line boundary. Move its exact artifact-binding matcher to the existing materialization binding owner, with explicit context/digest inputs and unchanged predicates; do not alter the structural debt ledger or its limit. + +The first reconciled Rust probe exposed a branch-reconstruction error: TASK's +repository reverted the merged `select_submission_context` operation while its +service still called it. Restore the merged repository operation, retaining +selected-policy decoding, and make selected PRE locking use the same canonical +TASK context service as all intake callers. This also retains CHECKERS currentness +validation for replacement attempts. The failed probe's owned database was +cleaned; rerun the real service proof after the repaired candidate is frozen. diff --git a/backend/app/adapters/tasks/__init__.py b/backend/app/adapters/tasks/__init__.py index 447a53609..6cb52b8af 100644 --- a/backend/app/adapters/tasks/__init__.py +++ b/backend/app/adapters/tasks/__init__.py @@ -49,7 +49,7 @@ class _SelectedPreSubmitTaskGuard: """Project selected PRE custody through TASK's canonical submission lock.""" def __init__(self, session: AsyncSession) -> None: - self._contexts = TaskRepository(session) + self._contexts = task_submission_context_port(session) async def lock_selected_pre_submit_scope( self, reservation: SelectedPreSubmitReservationFacts diff --git a/backend/app/modules/tasks/repository.py b/backend/app/modules/tasks/repository.py index 908dae327..6336dadc0 100644 --- a/backend/app/modules/tasks/repository.py +++ b/backend/app/modules/tasks/repository.py @@ -651,17 +651,18 @@ async def has_submission(self, task_id: UUID) -> bool: ) ) - async def lock_submission_context( + async def select_submission_context( self, request: TaskSubmissionContextRequest, - ) -> TaskSubmissionContextFacts: - """Lock and project exact TASK-owned Submission lifecycle facts. + ) -> tuple[TaskSubmissionContextFacts, TaskPostSubmitRoutingManifest | None]: + """Lock TASK rows and select one owner-qualified remediation source. Args: request: Exact task, assignment, contributor, and predecessor selectors. Returns: - Immutable TASK-owned context facts from the locked rows. + Provisional TASK facts and selected immutable routing source. The + caller must verify current CHECKERS custody before exposing facts. Raises: TaskSubmissionContextUnavailable: When the context is invalid or the @@ -685,8 +686,7 @@ async def lock_submission_context( or assignment is None or assignment.project_id != task.project_id or assignment.submitter_contribution_policy_version_id is None - or assignment.submitter_contribution_policy_version_id - != task.locked_contribution_policy_version_id + or assignment.submitter_contribution_policy_version_id != task.locked_contribution_policy_version_id or assignment.task_id != str(request.task_id) or assignment.contributor_id != contributor_id or assignment.status != "active" @@ -707,11 +707,30 @@ async def lock_submission_context( (task.status == "in_progress" and latest_submission is not None) or (task.status == "needs_revision" and latest_submission is None) or ( - latest_submission is not None and latest_submission.contributor_id != contributor_id + latest_submission is not None + and latest_submission.contributor_id != contributor_id ) ): raise TaskSubmissionContextUnavailable("task_submission_context_invalid") + remediation = None + if latest_submission is not None: + candidates = (await self._session.scalars( + select(TaskPostSubmitRoutingManifest).where( + TaskPostSubmitRoutingManifest.project_id == task.project_id, + TaskPostSubmitRoutingManifest.task_id == task.id, + TaskPostSubmitRoutingManifest.assignment_id == assignment.id, + TaskPostSubmitRoutingManifest.contributor_id == contributor_id, + TaskPostSubmitRoutingManifest.submission_id == latest_submission.id, + TaskPostSubmitRoutingManifest.submission_version == latest_submission.version, + TaskPostSubmitRoutingManifest.routing_recommendation == "needs_revision", + ).order_by(TaskPostSubmitRoutingManifest.evaluation_generation.desc()).limit(2) + )).all() + if (not candidates or len(candidates) == 2 and + candidates[0].evaluation_generation == candidates[1].evaluation_generation): + raise TaskSubmissionContextUnavailable("task_submission_context_invalid") + remediation = candidates[0] + locked_values = ( task.project_id, task.locked_guide_version, @@ -725,15 +744,11 @@ async def lock_submission_context( if any(value is None for value in locked_values): raise TaskSubmissionContextUnavailable("task_submission_context_invalid") try: - locked_policy = TaskPolicyLineage.model_validate_json( - json.dumps( - { - key: str(value) if isinstance(value, UUID) else value - for key in TaskPolicyLineage.model_fields - for value in (getattr(task, key),) - } - ) - ) + locked_policy = TaskPolicyLineage.model_validate_json(json.dumps({ + key: str(value) if isinstance(value, UUID) else value + for key in TaskPolicyLineage.model_fields + for value in (getattr(task, key),) + })) post_body = task.locked_post_submit_checker_policy_body if post_body.get("schema_version") == "external_post_submit_policy.v1": selected_post = validate_stored_external_post_policy(post_body) @@ -774,20 +789,25 @@ async def lock_submission_context( if latest_submission is not None else None ) - return TaskSubmissionContextFacts( + facts = TaskSubmissionContextFacts( task_id=request.task_id, assignment_id=request.assignment_id, contributor_id=request.contributor_id, status=task.status, - kind="revision" if predecessor is not None else "initial", + kind="checker_remediation" if predecessor is not None else "initial", predecessor=predecessor, locked_project_context=locked_project_context, locked_policy=locked_policy, acceptance_criteria=task.acceptance_criteria, submitter_contribution_policy_version_id=assignment.submitter_contribution_policy_version_id, + checker_remediation_manifest_id=remediation.id if remediation is not None else None, ) + return facts, remediation except (TypeError, ValueError) as exc: - raise TaskSubmissionContextUnavailable("task_submission_context_invalid") from exc + raise TaskSubmissionContextUnavailable( + "task_submission_context_invalid" + ) from exc + async def add_submission(self, submission: Submission) -> Submission: """Persist a submission packet and its evidence items. diff --git a/backend/tests/checkers/external/test_selected_pre_submit_coordination.py b/backend/tests/checkers/external/test_selected_pre_submit_coordination.py index caca974d1..0e91025a6 100644 --- a/backend/tests/checkers/external/test_selected_pre_submit_coordination.py +++ b/backend/tests/checkers/external/test_selected_pre_submit_coordination.py @@ -31,7 +31,7 @@ SelectedPreSubmitUnavailable, ) from app.adapters.tasks import selected_pre_submit_task_guard -from app.modules.tasks.repository import TaskRepository +from app.modules.tasks.submission_context import TaskSubmissionContextService from app.modules.checkers.models import SelectedPreSubmitRun from app.modules.checkers.selected_pre_submit_coordination import ( SelectedPreSubmitAdmissionCapability, @@ -217,7 +217,7 @@ async def lock(_repository, request): assert request.task_id == reservation.task_id return context - monkeypatch.setattr(TaskRepository, "lock_submission_context", lock) + monkeypatch.setattr(TaskSubmissionContextService, "lock_submission_context", lock) guard = selected_pre_submit_task_guard(SimpleNamespace()) await guard.lock_selected_pre_submit_scope(reservation) From 1b292b6e8ba9ab029c68c90c85a5b17c0e8b7bdf Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 09:26:00 +0100 Subject: [PATCH 150/283] [PILOT-04] Prove selected replacement retains routed cause --- backend/tests/test_submission_predecessor_custody.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/backend/tests/test_submission_predecessor_custody.py b/backend/tests/test_submission_predecessor_custody.py index ba1da9be8..0bfdb0925 100644 --- a/backend/tests/test_submission_predecessor_custody.py +++ b/backend/tests/test_submission_predecessor_custody.py @@ -32,6 +32,7 @@ PreparedArtifactInternalAuthority, PreparedSubmissionBundlePreparationAuthorization, ) +from app.modules.checkers.models import SelectedPreSubmitRun from app.modules.artifacts.models import ( PreSubmitEvidenceSet, SubmissionBundleAdmission, @@ -247,15 +248,18 @@ async def test_real_replacement_compares_consumed_predecessor_and_replays_exactl SubmissionBundleAdmission, str(h.creation_request.admission_id) ) admission = await session.get(SubmissionBundleAdmission, str(admission_id)) - evidence = await session.get(PreSubmitEvidenceSet, admission.pre_submit_evidence_set_id) + selected = await session.get(SelectedPreSubmitRun, admission.selected_pre_submit_run_id) assert predecessor_admission.status == "consumed" assert admission.status == "ready" assert admission.predecessor_submission_id == str(predecessor_id) assert admission.predecessor_submission_version == 1 assert admission.checker_remediation_manifest_id == source_id - assert evidence.predecessor_submission_id == str(predecessor_id) - assert evidence.predecessor_submission_version == 1 - assert evidence.checker_remediation_manifest_id == source_id + assert admission.pre_submit_evidence_set_id is None + assert selected is not None and selected.eligible + lineage = selected.request_json["admission_lineage"] + assert lineage["predecessor_submission_id"] == str(predecessor_id) + assert lineage["predecessor_submission_version"] == 1 + assert lineage["checker_remediation_manifest_id"] == str(source_id) assert admission.archive_sha256 != predecessor_admission.archive_sha256 assert ( admission.semantic_manifest_sha256 != predecessor_admission.semantic_manifest_sha256 From 5368bc6cb75482a44591fee72bd71b46c090aa20 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 09:21:57 +0100 Subject: [PATCH 151/283] [PILOT-04] Bind selected remediation cause in SQL custody --- backend/alembic/versions/0036_selected_checker_flow.py | 5 +++++ backend/tests/conftest.py | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/backend/alembic/versions/0036_selected_checker_flow.py b/backend/alembic/versions/0036_selected_checker_flow.py index 07063aae2..ebd4e37f6 100644 --- a/backend/alembic/versions/0036_selected_checker_flow.py +++ b/backend/alembic/versions/0036_selected_checker_flow.py @@ -257,6 +257,8 @@ def _replace_admission_guards() -> None: and new.assignment_id=evidence.assignment_id and new.predecessor_submission_id is not distinct from evidence.predecessor_submission_id and new.predecessor_submission_version is not distinct from evidence.predecessor_submission_version + and new.checker_remediation_manifest_id is not distinct from + evidence.checker_remediation_manifest_id and new.locked_policy_context_hash=evidence.locked_policy_context_hash and new.semantic_manifest_id=evidence.semantic_manifest_id and new.semantic_manifest_sha256=evidence.semantic_manifest_sha256 @@ -306,6 +308,8 @@ def _replace_admission_guards() -> None: nullif(r.request_json#>>'{admission_lineage,predecessor_submission_id}','')::uuid and new.predecessor_submission_version is not distinct from (r.request_json#>>'{admission_lineage,predecessor_submission_version}')::integer + and new.checker_remediation_manifest_id is not distinct from + nullif(r.request_json#>>'{admission_lineage,checker_remediation_manifest_id}','')::uuid and new.guide_id=(r.request_json#>>'{admission_lineage,guide_id}')::uuid and new.guide_version=r.request_json#>>'{admission_lineage,guide_version}' and new.source_snapshot_id=(r.request_json#>>'{admission_lineage,source_snapshot_id}')::uuid @@ -792,6 +796,7 @@ def _replace_submission_binding_resource() -> None: 'project_id',a.project_id,'task_id',a.task_id,'assignment_id',a.assignment_id, 'predecessor_submission_id',a.predecessor_submission_id, 'predecessor_submission_version',a.predecessor_submission_version, + 'checker_remediation_manifest_id',a.checker_remediation_manifest_id, 'submission_id',a.consumed_by_submission_id, 'submission_version',a.consumed_by_submission_version, 'guide_id',a.guide_id,'guide_version',a.guide_version, diff --git a/backend/tests/conftest.py b/backend/tests/conftest.py index 64bfece09..37dfe1885 100644 --- a/backend/tests/conftest.py +++ b/backend/tests/conftest.py @@ -23,7 +23,7 @@ DDL_LOCK_DIRECTORY = Path("/tmp") # Match the PostgreSQL 16 engine used by Backend CI. Catalog identity rendering # differs across major versions; regenerate only after comparing actual objects. -EXPECTED_PUBLIC_SCHEMA_SHA256 = "6bf1f6f66fe28a061fd220a78ea1d09c91a1d3588db144b802d3f43a06779bc6" +EXPECTED_PUBLIC_SCHEMA_SHA256 = "811b17460cd323c91c962302b3fd06b9ec95c7102eff66ff145e6e624422e2ae" PROTECTED_TEST_TABLES = ( "actor_profile_migration_state", "alembic_version", From d03a5434fc9c916d97521f006cace4f417093ac4 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 09:26:38 +0100 Subject: [PATCH 152/283] [PILOT-04] Retain replacement authority test dependencies --- backend/tests/test_submission_predecessor_custody.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/backend/tests/test_submission_predecessor_custody.py b/backend/tests/test_submission_predecessor_custody.py index 0bfdb0925..d0c2db9fc 100644 --- a/backend/tests/test_submission_predecessor_custody.py +++ b/backend/tests/test_submission_predecessor_custody.py @@ -34,7 +34,6 @@ ) from app.modules.checkers.models import SelectedPreSubmitRun from app.modules.artifacts.models import ( - PreSubmitEvidenceSet, SubmissionBundleAdmission, ) from app.modules.artifacts.submission_admission import ( @@ -45,6 +44,16 @@ SubmissionChangeRejectedError, ) from app.modules.authorization.api import ActorIdentityFacts, ActorKind +from app.modules.checkers.api.execution import CheckerExecutionUnavailable +from app.modules.tasks.api import SubmissionCreationRequest +from app.modules.tasks.api.submission_context import ( + TaskSubmissionContextRequest, TaskSubmissionContextUnavailable, +) +from app.modules.tasks.models import SubmissionDispatch +from app.modules.tasks.submission_composition import TaskSubmissionCreationService +from app.modules.tasks.submission_context import TaskSubmissionContextService +from app.adapters.tasks import task_submission_context_port +from tests.auth_concurrency_support import wait_for_named_database_lock from tests.artifact_store_helpers import artifact_byte_stream from tests.checkers.execution.support import reserve from tests.checkers.execution.completion_fixture import completed_evidence From 1c20f028df9522e969fb45525dfd31b4254ba974 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 09:37:34 +0100 Subject: [PATCH 153/283] [PILOT-04] Admit bounded machine configuration and retain replacement proof --- .../pilot04-workstream-default-checker.md | 13 +++++++++++++ backend/app/interfaces/project_agents.py | 9 ++++++++- .../test_project_guide_compilation_contracts.py | 16 ++++++++++++++++ .../tests/test_submission_predecessor_custody.py | 5 +++-- 4 files changed, 40 insertions(+), 3 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 37aa4e0fe..b117f631c 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -288,3 +288,16 @@ selected-policy decoding, and make selected PRE locking use the same canonical TASK context service as all intake callers. This also retains CHECKERS currentness validation for replacement attempts. The failed probe's owned database was cleaned; rerun the real service proof after the repaired candidate is frozen. + +Configuration repair: PRE and POST machine configuration accepts bounded +canonical relative paths/patterns through the existing CHECKERS syntax validator, +while retaining command, credential and control-character guards. Actual model +prose fields remain unchanged. The affected 127 contract/policy tests pass; an +independent 18-control replay confirms the former valid-path rejection is fixed. + +The first reconciled native owner run failed four cases at deferred Submission +dispatch custody, before completion/replacement assertions. The new selected +admission has no historical evidence row, but merged replacement dispatch SQL +still used an inner join to that row. Preserve the replacement cause predicates +and adapt that join for the explicit selected lineage. All owned database, role +and MinIO resources were cleaned. No passing full-flow claim is made for that run. diff --git a/backend/app/interfaces/project_agents.py b/backend/app/interfaces/project_agents.py index 469b35bef..cf20300c6 100644 --- a/backend/app/interfaces/project_agents.py +++ b/backend/app/interfaces/project_agents.py @@ -201,7 +201,14 @@ def validate_value( if type(item) not in {str, int, float, bool}: raise ValueError("capability parameter scalar is invalid") if isinstance(item, str): - _validated_safe_model_text(item) + if "/" in item or "\\" in item: + if not is_canonical_relative_pattern(item): + raise ValueError("capability parameter path is invalid") + # Machine paths belong to the image configuration. Keep + # command/credential checks without treating '/' as prose. + _validated_safe_model_text(item.replace("/", " ")) + else: + _validated_safe_model_text(item) elif isinstance(item, (int, float)): if not math.isfinite(item) or abs(item) > 10**12: raise ValueError("capability parameter number is out of range") diff --git a/backend/tests/test_project_guide_compilation_contracts.py b/backend/tests/test_project_guide_compilation_contracts.py index 968d8189c..9822c6b69 100644 --- a/backend/tests/test_project_guide_compilation_contracts.py +++ b/backend/tests/test_project_guide_compilation_contracts.py @@ -980,3 +980,19 @@ def test_context_rejects_instruction_version_separate_from_snapshot() -> None: payload["instruction_version"] = "different" with pytest.raises(ValidationError, match="instruction configuration mismatch"): ProjectGuideCompilationContext.model_validate_json(json.dumps(payload)) + + +@pytest.mark.parametrize("value", ["outputs/answer.md", "src/main.py", "tests/**/*.py"]) +def test_checker_configuration_accepts_canonical_relative_paths(value: str) -> None: + parameter = CapabilityParameter(name="required_path", value=value) + assert parameter.value == value + + +@pytest.mark.parametrize("value", [ + "/etc/passwd", "../answer.md", "src/../answer.md", "https://example.invalid/x", + "file:///tmp/x", "src/answer.md\x00", "src/$(command)", "bash/run", + "token=secret", "Bearer opaque-token", "import subprocess", "src\\main.py", +]) +def test_checker_configuration_rejects_unsafe_machine_values(value: str) -> None: + with pytest.raises(ValidationError): + CapabilityParameter(name="required_path", value=value) diff --git a/backend/tests/test_submission_predecessor_custody.py b/backend/tests/test_submission_predecessor_custody.py index d0c2db9fc..f42052de9 100644 --- a/backend/tests/test_submission_predecessor_custody.py +++ b/backend/tests/test_submission_predecessor_custody.py @@ -66,6 +66,7 @@ _PREPARATION_TABLES = ( + "selected_pre_submit_runs", "pre_submit_execution_attempts", "pre_submit_evidence_sets", "pre_submit_evidence_results", @@ -122,8 +123,8 @@ def _replacement_request(h, data: bytes, *, predecessor_id: UUID, idempotency_ke assignment_id=h.request.assignment_id, predecessor_submission_id=predecessor_id, idempotency_key=idempotency_key, - summary=h.request.structural_input.summary, - contributor_attestation=h.request.structural_input.worker_attestation, + summary=h.creation_request.summary, + contributor_attestation=h.creation_request.contributor_attestation, media_type="application/zip", byte_source=artifact_byte_stream(data), ) From fbb397a482ce639c1dfbf3eec7033747cc690aca Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 09:41:50 +0100 Subject: [PATCH 154/283] [PILOT-04] Preserve selected dispatch custody --- .../versions/0036_selected_checker_flow.py | 28 ++++++++++++++++++- backend/tests/conftest.py | 2 +- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/backend/alembic/versions/0036_selected_checker_flow.py b/backend/alembic/versions/0036_selected_checker_flow.py index ebd4e37f6..7edc2e93f 100644 --- a/backend/alembic/versions/0036_selected_checker_flow.py +++ b/backend/alembic/versions/0036_selected_checker_flow.py @@ -781,7 +781,33 @@ def _replace_submission_dispatch_custody() -> None: AND (r.request_json::jsonb->'structural_input'->>'worker_attestation')=s.worker_attestation))""" if definition.count(old_packet) != 1: raise RuntimeError("submission dispatch packet custody shape changed") - op.execute(definition.replace(old_packet, new_packet)) + definition = definition.replace(old_packet, new_packet) + old_evidence_join = ( + "JOIN public.pre_submit_evidence_sets evidence " + "ON evidence.id = a.pre_submit_evidence_set_id" + ) + if old_evidence_join not in definition: + old_evidence_join = old_evidence_join.replace(" = ", "=") + if definition.count(old_evidence_join) != 1: + raise RuntimeError("submission dispatch evidence join shape changed") + definition = definition.replace( + old_evidence_join, + old_evidence_join.replace("JOIN public", "LEFT JOIN public"), + ) + old_evidence_cause = ( + "evidence.checker_remediation_manifest_id IS NOT DISTINCT FROM " + "a.checker_remediation_manifest_id" + ) + if definition.count(old_evidence_cause) != 1: + raise RuntimeError("submission dispatch evidence cause shape changed") + new_evidence_cause = """((a.selected_pre_submit_run_id IS NULL + AND evidence.id IS NOT NULL + AND evidence.checker_remediation_manifest_id IS NOT DISTINCT FROM + a.checker_remediation_manifest_id) + OR (a.selected_pre_submit_run_id IS NOT NULL + AND a.pre_submit_evidence_set_id IS NULL + AND evidence.id IS NULL))""" + op.execute(definition.replace(old_evidence_cause, new_evidence_cause)) def _replace_submission_binding_resource() -> None: diff --git a/backend/tests/conftest.py b/backend/tests/conftest.py index 37dfe1885..7bcb6cec5 100644 --- a/backend/tests/conftest.py +++ b/backend/tests/conftest.py @@ -23,7 +23,7 @@ DDL_LOCK_DIRECTORY = Path("/tmp") # Match the PostgreSQL 16 engine used by Backend CI. Catalog identity rendering # differs across major versions; regenerate only after comparing actual objects. -EXPECTED_PUBLIC_SCHEMA_SHA256 = "811b17460cd323c91c962302b3fd06b9ec95c7102eff66ff145e6e624422e2ae" +EXPECTED_PUBLIC_SCHEMA_SHA256 = "2970241168e5b843b0526a94d32e87166c8956fbbcb9e73de2c395b2f3a154cf" PROTECTED_TEST_TABLES = ( "actor_profile_migration_state", "alembic_version", From 43f279b2a29e5bf903ff179d7c36f6fbf626af2e Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 09:55:43 +0100 Subject: [PATCH 155/283] [PILOT-04] Remove product catalogue fixture paths and normalize cause custody --- .../pilot04-workstream-default-checker.md | 17 +++ backend/app/adapters/checkers/__init__.py | 124 +----------------- .../checkers/api/historical_post_submit.py | 82 +----------- backend/app/modules/checkers/checker_retry.py | 9 +- backend/app/modules/tasks/repository.py | 4 +- backend/tests/checkers/post_submit/support.py | 4 +- backend/tests/historical_checker_metadata.py | 88 +++++++++++++ .../tests/historical_submission_fixtures.py | 113 +++++++++++++++- 8 files changed, 227 insertions(+), 214 deletions(-) create mode 100644 backend/tests/historical_checker_metadata.py diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index b117f631c..440f844db 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -301,3 +301,20 @@ admission has no historical evidence row, but merged replacement dispatch SQL still used an inner join to that row. Preserve the replacement cause predicates and adapt that join for the explicit selected lineage. All owned database, role and MinIO resources were cleaned. No passing full-flow claim is made for that run. + +Full-cutover cleanup after the user's clarification: remove the unused production +historical catalogue factory and historical Submission-content adapter. Move +only the frozen metadata needed to seed actual predecessor schemas into +`tests/historical_checker_metadata.py` and the migration-only Submission fixture. +No product adapter constructs the removed catalogue. New Operator retries only +construct selected external requests; immutable receipt replay is preserved. + +Real local selected Rust/MinIO run at fbb397a passed default/PRE/Submission/POST +and production completion to review_pending, default-secret rejection without a +Submission, and unavailable-PRE recovery through fresh verified bytes. All owned +DB/role/MinIO/scratch cleanup passed. The runtime was runc/docker-dev, not gVisor. +The same-head native run passed the real production automatic acceptance case +(with exact contribution and both awards); replacement failed at strict UUID +lineage construction. Normalize the native PostgreSQL remediation UUID to the +TASK public port's Python UUID representation rather than weakening validation. +Replacement proof and runtime-budget alignment remain pending. diff --git a/backend/app/adapters/checkers/__init__.py b/backend/app/adapters/checkers/__init__.py index b2560e3dc..ac54c9422 100644 --- a/backend/app/adapters/checkers/__init__.py +++ b/backend/app/adapters/checkers/__init__.py @@ -1,27 +1,13 @@ """CHECKER-owned composition adapters.""" -import json from app.adapters.checkers.external_service import ( EXTERNAL_CHECKER_CAPABILITY_KEY, EXTERNAL_CHECKER_PROVIDER_KEY, UnixSocketExternalCheckerAdapter, ) from app.interfaces.external_services import ExternalServiceAdapterFactory -from app.modules.artifacts.api import SubmissionBundleFile from app.modules.tasks.api import TaskSubmissionContextFacts -from app.modules.projects.api import ProjectLockedPolicyContextFacts -from app.modules.checkers.api import SubmissionPacketView -from app.modules.checkers.api.artifact_paths import required_evidence_path -from app.modules.checkers.api.historical_post_submit import CompiledPostSubmitPolicy -from app.modules.checkers.api.post_submit import ( - ExpectedPostSubmitContext, - ObservedPostSubmitContext, - PostSubmissionEvaluationContent, - PostSubmissionStructuralInput, - PostSubmitEvidenceEntry, - PostSubmitManifestEntry, - PostSubmitPolicyInputs, -) + from app.modules.checkers.api.external_policy import LockedExternalPostSubmitPolicy from app.modules.checkers.api.selected_post_submit import ( SelectedPostSubmissionContent, @@ -289,114 +275,6 @@ def current_post_submit_execution(session): return CurrentExecution(session) -def _historical_post_submit_catalogue(): - """Resolve the frozen pre-cutover catalogue for retained fixture decoding only.""" - from app.modules.checkers.api.historical_post_submit import ( - current_post_submit_catalogue, - ) - - return current_post_submit_catalogue() - - -def submission_evaluation_content( - task_context: TaskSubmissionContextFacts, - project_context: ProjectLockedPolicyContextFacts, - packet: SubmissionPacketView, - files: tuple[SubmissionBundleFile, ...], - archive_sha256: str, -) -> PostSubmissionEvaluationContent: - """Project immutable pre-cutover evidence for retained historical fixtures. - - New admission and execution callers use selected checker policies. This - compatibility projection exists only so historical Submission fixtures can - continue proving retained evidence without restoring catalogue eligibility. - """ - from app.adapters.tasks import validate_submission_policy_context - - validate_submission_policy_context(task_context, project_context) - stamps = task_context.locked_policy - expected = ExpectedPostSubmitContext( - guide_version=stamps.locked_guide_version, - source_id=stamps.locked_guide_source_snapshot_id, - source_hash=stamps.locked_guide_source_snapshot_hash, - effective_policy_id=( - stamps.locked_effective_project_submission_artifact_policy_id - ), - effective_policy_hash=( - stamps.locked_effective_project_submission_artifact_policy_hash - ), - pre_policy_id=stamps.locked_pre_submit_checker_policy_id, - pre_policy_hash=stamps.locked_pre_submit_checker_bundle_hash, - post_policy_id=stamps.locked_post_submit_checker_policy_id, - post_policy_version=stamps.locked_post_submit_checker_policy_version, - post_policy_hash=stamps.locked_post_submit_checker_policy_hash, - review_policy_id=stamps.locked_review_policy_id, - review_generation=stamps.locked_review_policy_generation, - review_hash=stamps.locked_review_policy_hash, - revision_policy_id=stamps.locked_revision_policy_id, - revision_generation=stamps.locked_revision_policy_generation, - revision_hash=stamps.locked_revision_policy_hash, - ) - effective = json.loads(project_context.effective_policy.value) - policy_inputs = PostSubmitPolicyInputs( - required_evidence_keys=tuple( - item["key"] - for item in effective.get("required_evidence", []) - if item.get("required", True) - ), - required_artifact_paths=tuple( - item["path"] - for item in effective.get("required_artifacts", []) - if item.get("required", True) - ), - forbidden_artifact_patterns=tuple( - item["pattern"] - for item in effective.get("forbidden_artifacts", []) - if item.get("pattern") - ), - required_attestation_terms=tuple( - term for term in effective.get("attestation_terms", []) if term - ), - ) - by_path = {item.normalized_path: item for item in files} - return PostSubmissionEvaluationContent( - project_id=project_context.project_id, - expected_context=expected, - catalogue=_historical_post_submit_catalogue(), - policy=CompiledPostSubmitPolicy.model_validate_json( - project_context.compiled_post_submit_policy.value - ), - structural_input=PostSubmissionStructuralInput( - summary=packet.summary, - worker_attestation=packet.contributor_attestation, - package_hash=archive_sha256, - criteria=task_context.acceptance_criteria or "", - manifest=tuple( - PostSubmitManifestEntry( - artifact=item.normalized_path, - hash=item.sha256, - size_bytes=item.byte_count, - ) - for item in files - ), - evidence=tuple( - PostSubmitEvidenceEntry( - label=key, - type="file", - key=key, - uri=item.normalized_path, - hash=item.sha256, - ) - for key in policy_inputs.required_evidence_keys - for item in (by_path.get(required_evidence_path(key)),) - if item is not None - ), - policy_inputs=policy_inputs, - observed_context=ObservedPostSubmitContext(**expected.model_dump()), - ), - ) - - def selected_submission_evaluation_content( task_context: TaskSubmissionContextFacts, policy: LockedExternalPostSubmitPolicy, diff --git a/backend/app/modules/checkers/api/historical_post_submit.py b/backend/app/modules/checkers/api/historical_post_submit.py index e8d888bf8..3ecae6af2 100644 --- a/backend/app/modules/checkers/api/historical_post_submit.py +++ b/backend/app/modules/checkers/api/historical_post_submit.py @@ -1,4 +1,4 @@ -"""Immutable post-submit catalogue and compiled-policy value contracts.""" +"""Decode immutable stored pre-cutover policy facts; no catalogue construction.""" from __future__ import annotations @@ -298,86 +298,6 @@ def canonical_post_submit_bytes( ).encode("utf-8") -_STRUCTURAL_DEFINITIONS = ( - ("check_submission_packet", "packet_presence", "packet_fields_missing", "submission_structure"), - ( - "check_policy_context_present", - "policy_context_consistency", - "policy_context_invalid", - "task_configuration", - ), - ("check_evidence_present", "evidence_presence", "evidence_missing", "submission_structure"), - ( - "check_evidence_integrity", - "evidence_structure", - "evidence_structure_invalid", - "submission_structure", - ), - ( - "check_required_files", - "required_path_presence", - "required_files_missing", - "submission_structure", - ), - ( - "check_forbidden_files", - "forbidden_path_detection", - "forbidden_path_present", - "submission_structure", - ), - ( - "check_confidentiality_attestation", - "attestation_presence", - "attestation_missing", - "submission_structure", - ), - ( - "check_low_quality_generated_artifacts", - "placeholder_signal_detection", - "placeholder_signal", - "submission_structure", - ), - ( - "check_acceptance_criteria_present", - "criteria_presence", - "acceptance_criteria_missing", - "task_configuration", - ), -) - - -def structural_definition(name: str) -> PostSubmitDefinition: - """Mint the code-owned metadata attached to an explicit registration entry.""" - for order, (checker_id, claim, failure, category) in enumerate(_STRUCTURAL_DEFINITIONS, 1): - if checker_id == name: - warning = name == "check_low_quality_generated_artifacts" - return PostSubmitDefinition( - capability_id=name, - implementation_version=POST_SUBMIT_IMPLEMENTATION_ID, - platform_default=order <= 8, - selectable=order == 9, - order=order, - supported_claim=claim, - failure_code=failure, - failure_category=category, - failure_status="warning" if warning else "failed", - failure_severity="medium" if warning else "high", - ) - raise ValueError("unknown structural post-submit definition") - - -def current_post_submit_catalogue() -> PostSubmitCatalogue: - """Return code-owned immutable metadata, without execution authority.""" - definitions = tuple(structural_definition(row[0]) for row in _STRUCTURAL_DEFINITIONS) - body = { - "catalogue_id": POST_SUBMIT_CATALOGUE_ID, - "source_version": "v0.1", - "schema_version": POST_SUBMIT_CATALOGUE_SCHEMA, - "definitions": [item.model_dump(mode="json") for item in definitions], - } - return PostSubmitCatalogue(**body, manifest_sha256=canonical_json_hash(body)) - - def parse_locked_post_submit_policy( body: object, *, diff --git a/backend/app/modules/checkers/checker_retry.py b/backend/app/modules/checkers/checker_retry.py index 06948ed7a..4963f59ea 100644 --- a/backend/app/modules/checkers/checker_retry.py +++ b/backend/app/modules/checkers/checker_retry.py @@ -18,7 +18,6 @@ CheckerRetrySuccessor, EvaluationTaskGuard, ) from app.modules.checkers.api.evaluation_contract import PostSubmissionExecutionRequest -from app.modules.checkers.api.post_submit import make_post_submit_request from app.modules.checkers.api.selected_post_submit import ( SelectedPostSubmissionEvaluationRequest, make_selected_post_submit_request, @@ -165,6 +164,8 @@ async def retry(self, command: CheckerRetryCommand) -> CheckerRetryResult: raise CheckerExecutionUnavailable("checker_retry_source_unavailable") if existing is not None: return await self._replay(command, existing, source) + if not isinstance(source_request, SelectedPostSubmissionEvaluationRequest): + raise CheckerExecutionUnavailable("checker_retry_policy_unavailable") preparation = CheckerRetryPreparation( actor_profile_id=self._actor_profile_id, request_key=command.request_key, reason=command.reason, source=source, @@ -178,11 +179,7 @@ async def retry(self, command: CheckerRetryCommand) -> CheckerRetryResult: "evaluation_request_id": new_record_id(), "evaluation_generation": source.source_generation + 1, } - next_request = ( - make_selected_post_submit_request(**request_fields) - if isinstance(source_request, SelectedPostSubmissionEvaluationRequest) - else make_post_submit_request(**request_fields) - ) + next_request = make_selected_post_submit_request(**request_fields) reserved = await self._evaluations._reserve_after_task_lock( next_request, terminal_source_id=source.source_run_id, ) diff --git a/backend/app/modules/tasks/repository.py b/backend/app/modules/tasks/repository.py index 6336dadc0..c7e664b14 100644 --- a/backend/app/modules/tasks/repository.py +++ b/backend/app/modules/tasks/repository.py @@ -800,7 +800,9 @@ async def select_submission_context( locked_policy=locked_policy, acceptance_criteria=task.acceptance_criteria, submitter_contribution_policy_version_id=assignment.submitter_contribution_policy_version_id, - checker_remediation_manifest_id=remediation.id if remediation is not None else None, + checker_remediation_manifest_id=( + UUID(str(remediation.id)) if remediation is not None else None + ), ) return facts, remediation except (TypeError, ValueError) as exc: diff --git a/backend/tests/checkers/post_submit/support.py b/backend/tests/checkers/post_submit/support.py index 60efb61b1..2b21341fe 100644 --- a/backend/tests/checkers/post_submit/support.py +++ b/backend/tests/checkers/post_submit/support.py @@ -18,9 +18,9 @@ PostSubmitCatalogue, PostSubmitDefinition, PostSubmitPolicyEntry, - current_post_submit_catalogue, ) from app.modules.checkers.api.post_submit import make_post_submit_request +from tests.historical_checker_metadata import historical_post_submit_catalogue HASH = "sha256:" + "a" * 64 OTHER_HASH = "sha256:" + "b" * 64 @@ -29,7 +29,7 @@ def catalogue(): """Return the frozen retained-history decoder, never an executable registry.""" - return current_post_submit_catalogue() + return historical_post_submit_catalogue() def _policy(*, project_id: UUID, snapshot: PostSubmitCatalogue) -> CompiledPostSubmitPolicy: diff --git a/backend/tests/historical_checker_metadata.py b/backend/tests/historical_checker_metadata.py new file mode 100644 index 000000000..8347bcc98 --- /dev/null +++ b/backend/tests/historical_checker_metadata.py @@ -0,0 +1,88 @@ +"""Frozen pre-cutover metadata used only by retained-record migration fixtures.""" + +from app.core.hashing import canonical_json_hash +from app.modules.checkers.api.historical_post_submit import ( + POST_SUBMIT_CATALOGUE_ID, POST_SUBMIT_CATALOGUE_SCHEMA, POST_SUBMIT_IMPLEMENTATION_ID, + PostSubmitCatalogue, PostSubmitDefinition, +) + +_STRUCTURAL_DEFINITIONS = ( + ("check_submission_packet", "packet_presence", "packet_fields_missing", "submission_structure"), + ( + "check_policy_context_present", + "policy_context_consistency", + "policy_context_invalid", + "task_configuration", + ), + ("check_evidence_present", "evidence_presence", "evidence_missing", "submission_structure"), + ( + "check_evidence_integrity", + "evidence_structure", + "evidence_structure_invalid", + "submission_structure", + ), + ( + "check_required_files", + "required_path_presence", + "required_files_missing", + "submission_structure", + ), + ( + "check_forbidden_files", + "forbidden_path_detection", + "forbidden_path_present", + "submission_structure", + ), + ( + "check_confidentiality_attestation", + "attestation_presence", + "attestation_missing", + "submission_structure", + ), + ( + "check_low_quality_generated_artifacts", + "placeholder_signal_detection", + "placeholder_signal", + "submission_structure", + ), + ( + "check_acceptance_criteria_present", + "criteria_presence", + "acceptance_criteria_missing", + "task_configuration", + ), +) + + +def structural_definition(name: str) -> PostSubmitDefinition: + """Mint the code-owned metadata attached to an explicit registration entry.""" + for order, (checker_id, claim, failure, category) in enumerate(_STRUCTURAL_DEFINITIONS, 1): + if checker_id == name: + warning = name == "check_low_quality_generated_artifacts" + return PostSubmitDefinition( + capability_id=name, + implementation_version=POST_SUBMIT_IMPLEMENTATION_ID, + platform_default=order <= 8, + selectable=order == 9, + order=order, + supported_claim=claim, + failure_code=failure, + failure_category=category, + failure_status="warning" if warning else "failed", + failure_severity="medium" if warning else "high", + ) + raise ValueError("unknown structural post-submit definition") + + +def historical_post_submit_catalogue() -> PostSubmitCatalogue: + """Return code-owned immutable metadata, without execution authority.""" + definitions = tuple(structural_definition(row[0]) for row in _STRUCTURAL_DEFINITIONS) + body = { + "catalogue_id": POST_SUBMIT_CATALOGUE_ID, + "source_version": "v0.1", + "schema_version": POST_SUBMIT_CATALOGUE_SCHEMA, + "definitions": [item.model_dump(mode="json") for item in definitions], + } + return PostSubmitCatalogue(**body, manifest_sha256=canonical_json_hash(body)) + + diff --git a/backend/tests/historical_submission_fixtures.py b/backend/tests/historical_submission_fixtures.py index 0bd6c7db6..026a914e1 100644 --- a/backend/tests/historical_submission_fixtures.py +++ b/backend/tests/historical_submission_fixtures.py @@ -22,6 +22,20 @@ from tests.migration_fixtures import current_art_attempt_seed_schema +import json +from app.modules.artifacts.api import SubmissionBundleFile +from app.modules.projects.api import ProjectLockedPolicyContextFacts +from app.modules.tasks.api import TaskSubmissionContextFacts +from app.modules.checkers.api import SubmissionPacketView +from app.modules.checkers.api.artifact_paths import required_evidence_path +from app.modules.checkers.api.historical_post_submit import CompiledPostSubmitPolicy +from app.modules.checkers.api.post_submit import ( + ExpectedPostSubmitContext, ObservedPostSubmitContext, PostSubmissionEvaluationContent, + PostSubmissionStructuralInput, PostSubmitEvidenceEntry, PostSubmitManifestEntry, PostSubmitPolicyInputs, +) +from tests.historical_checker_metadata import historical_post_submit_catalogue + + async def write_historical_submission(factory, context, request): """Seed only an actual predecessor schema; never bypass current constraints.""" from sqlalchemy import text @@ -75,10 +89,107 @@ async def write_historical_submission(factory, context, request): artifact_content_id=UUID(admission.artifact_content_id), task_context=facts) +def submission_evaluation_content( + task_context: TaskSubmissionContextFacts, + project_context: ProjectLockedPolicyContextFacts, + packet: SubmissionPacketView, + files: tuple[SubmissionBundleFile, ...], + archive_sha256: str, +) -> PostSubmissionEvaluationContent: + """Project immutable pre-cutover evidence for retained historical fixtures. + + This test-only projection reconstructs the exact predecessor record shape + for migration and immutable-evidence proofs. Product callers cannot use it. + """ + from app.adapters.tasks import validate_submission_policy_context + + validate_submission_policy_context(task_context, project_context) + stamps = task_context.locked_policy + expected = ExpectedPostSubmitContext( + guide_version=stamps.locked_guide_version, + source_id=stamps.locked_guide_source_snapshot_id, + source_hash=stamps.locked_guide_source_snapshot_hash, + effective_policy_id=( + stamps.locked_effective_project_submission_artifact_policy_id + ), + effective_policy_hash=( + stamps.locked_effective_project_submission_artifact_policy_hash + ), + pre_policy_id=stamps.locked_pre_submit_checker_policy_id, + pre_policy_hash=stamps.locked_pre_submit_checker_bundle_hash, + post_policy_id=stamps.locked_post_submit_checker_policy_id, + post_policy_version=stamps.locked_post_submit_checker_policy_version, + post_policy_hash=stamps.locked_post_submit_checker_policy_hash, + review_policy_id=stamps.locked_review_policy_id, + review_generation=stamps.locked_review_policy_generation, + review_hash=stamps.locked_review_policy_hash, + revision_policy_id=stamps.locked_revision_policy_id, + revision_generation=stamps.locked_revision_policy_generation, + revision_hash=stamps.locked_revision_policy_hash, + ) + effective = json.loads(project_context.effective_policy.value) + policy_inputs = PostSubmitPolicyInputs( + required_evidence_keys=tuple( + item["key"] + for item in effective.get("required_evidence", []) + if item.get("required", True) + ), + required_artifact_paths=tuple( + item["path"] + for item in effective.get("required_artifacts", []) + if item.get("required", True) + ), + forbidden_artifact_patterns=tuple( + item["pattern"] + for item in effective.get("forbidden_artifacts", []) + if item.get("pattern") + ), + required_attestation_terms=tuple( + term for term in effective.get("attestation_terms", []) if term + ), + ) + by_path = {item.normalized_path: item for item in files} + return PostSubmissionEvaluationContent( + project_id=project_context.project_id, + expected_context=expected, + catalogue=historical_post_submit_catalogue(), + policy=CompiledPostSubmitPolicy.model_validate_json( + project_context.compiled_post_submit_policy.value + ), + structural_input=PostSubmissionStructuralInput( + summary=packet.summary, + worker_attestation=packet.contributor_attestation, + package_hash=archive_sha256, + criteria=task_context.acceptance_criteria or "", + manifest=tuple( + PostSubmitManifestEntry( + artifact=item.normalized_path, + hash=item.sha256, + size_bytes=item.byte_count, + ) + for item in files + ), + evidence=tuple( + PostSubmitEvidenceEntry( + label=key, + type="file", + key=key, + uri=item.normalized_path, + hash=item.sha256, + ) + for key in policy_inputs.required_evidence_keys + for item in (by_path.get(required_evidence_path(key)),) + if item is not None + ), + policy_inputs=policy_inputs, + observed_context=ObservedPostSubmitContext(**expected.model_dump()), + ), + ) + + async def _historical_request(session, facts, created, data): """Project genuine historical inputs without creating a future reservation.""" from app.adapters.tasks import task_service - from app.adapters.checkers import submission_evaluation_content from app.core.config import get_settings from app.modules.checkers.api import SubmissionPacketView from app.modules.tasks.models import WorkstreamTask From d9b676c98624bf0e741e9ce4244c4ca37029af20 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 09:59:35 +0100 Subject: [PATCH 156/283] [PILOT-04] Align checker owner contracts with the active external flow --- backend/app/adapters/checkers/__init__.py | 2 +- backend/app/modules/checkers/api/historical_post_submit.py | 2 +- backend/app/modules/checkers/api/policy_compilation.py | 2 +- backend/app/modules/checkers/api/post_submit.py | 2 +- backend/app/modules/checkers/execution_coordination.py | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/backend/app/adapters/checkers/__init__.py b/backend/app/adapters/checkers/__init__.py index ac54c9422..c0fa82c1d 100644 --- a/backend/app/adapters/checkers/__init__.py +++ b/backend/app/adapters/checkers/__init__.py @@ -262,7 +262,7 @@ def post_submission_executor(*, sessions, materialization): def checker_output_reservations(session): - """Resolve exact active run/lease custody; current catalogue has zero slots.""" + """Resolve exact active run/lease custody for artifact output reservations.""" from app.modules.checkers.execution_coordination import CheckerOutputReservations return CheckerOutputReservations(session) diff --git a/backend/app/modules/checkers/api/historical_post_submit.py b/backend/app/modules/checkers/api/historical_post_submit.py index 3ecae6af2..05909f83d 100644 --- a/backend/app/modules/checkers/api/historical_post_submit.py +++ b/backend/app/modules/checkers/api/historical_post_submit.py @@ -34,7 +34,7 @@ class PostSubmitValue(BaseModel): class EmptyPostSubmitConfiguration(PostSubmitValue): - """The current registered structural implementations accept no parameters.""" + """The stored pre-cutover structural configuration had no parameters.""" class PostSubmitResourceLimits(PostSubmitValue): diff --git a/backend/app/modules/checkers/api/policy_compilation.py b/backend/app/modules/checkers/api/policy_compilation.py index 04db38486..269d2d99f 100644 --- a/backend/app/modules/checkers/api/policy_compilation.py +++ b/backend/app/modules/checkers/api/policy_compilation.py @@ -19,7 +19,7 @@ class CompiledPreSubmitCheckerPolicy: class PreSubmissionPolicyCompilationPort(EffectivePreSubmissionPlanningPort, Protocol): - """The canonical catalogue supplies both compilation steps to approval.""" + """The CHECKERS owner supplies the exact default and external policy compilation.""" def compile_policy_bundle( self, *, effective_policy: Mapping[str, object], effective_policy_hash: str, diff --git a/backend/app/modules/checkers/api/post_submit.py b/backend/app/modules/checkers/api/post_submit.py index 3ef7e25ff..e352909b6 100644 --- a/backend/app/modules/checkers/api/post_submit.py +++ b/backend/app/modules/checkers/api/post_submit.py @@ -109,7 +109,7 @@ def validate_versions(self) -> Self: class PostSubmissionStructuralInput(PostSubmitValue): - """Immutable detached values consumed by the actual structural handlers.""" + """Immutable detached structural facts retained in pre-cutover request records.""" schema_version: Literal["post_submit_structural_input"] = "post_submit_structural_input" summary: Text diff --git a/backend/app/modules/checkers/execution_coordination.py b/backend/app/modules/checkers/execution_coordination.py index 32c7041a3..a38bbc4cf 100644 --- a/backend/app/modules/checkers/execution_coordination.py +++ b/backend/app/modules/checkers/execution_coordination.py @@ -343,7 +343,7 @@ async def require_current_execution(self, facts): class CheckerOutputReservations: - """Current structural handlers have exactly zero output slots.""" + """Selected evidence-only checker executions have no artifact output slots.""" def __init__(self, session: AsyncSession): """Resolve output custody within the supplied CHECKERS session.""" From 1ce0f5784f3b553fd2f5c0af281113573d3e77aa Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 10:01:06 +0100 Subject: [PATCH 157/283] [PILOT-04] Replace obsolete predecessor controls with selected custody --- .../tests/selected_predecessor_fixtures.py | 173 +++++++ .../test_submission_predecessor_custody.py | 462 +++++++++--------- 2 files changed, 391 insertions(+), 244 deletions(-) create mode 100644 backend/tests/selected_predecessor_fixtures.py diff --git a/backend/tests/selected_predecessor_fixtures.py b/backend/tests/selected_predecessor_fixtures.py new file mode 100644 index 000000000..3bf7402ba --- /dev/null +++ b/backend/tests/selected_predecessor_fixtures.py @@ -0,0 +1,173 @@ +"""Selected PRE replacement evidence fixtures; no alternate execution owner.""" + +from dataclasses import replace +from io import BytesIO +import json +from zipfile import ZipFile + +from sqlalchemy import select, text + +from app.core.identifiers import new_record_id +from app.modules.artifacts.selected_pre_submit_admission import ( + selected_pre_submit_attempt_request_digest, +) +from app.modules.checkers.models import SelectedPreSubmitRun +from app.modules.checkers.api.selected_pre_submit import ( + SelectedPreSubmitReservationFacts, + SelectedPreSubmitTerminalFacts, +) + +_PREPARATION_TABLES = ( + "selected_pre_submit_runs", + "pre_submit_execution_attempts", + "pre_submit_evidence_sets", + "pre_submit_evidence_results", + "submission_bundle_durable_intents", + "artifact_put_attempts", + "artifact_put_attempt_charges", + "artifact_contents", + "artifact_replicas", + "artifact_operation_receipts", + "artifact_put_observation_receipts", + "artifact_verification_jobs", + "artifact_verification_receipts", + "submission_bundle_admissions", +) + + +async def _snapshot(h) -> tuple[tuple[str, int], ...]: + async with h.factory() as session: + rows = [] + for table in _PREPARATION_TABLES: + count = await session.scalar(text(f"SELECT pg_catalog.count(*) FROM public.{table}")) + assert count is not None + rows.append((table, int(count))) + return tuple(rows) + + +def _secret_archive(data: bytes) -> bytes: + """Keep the real changed packet and introduce one known secret signature.""" + output = BytesIO(data) + with ZipFile(output, "a") as archive: + archive.writestr("probe.txt", b"-----BEGIN OPENSSH PRIVATE KEY-----\nprobe\n") + return output.getvalue() + + +async def _assert_default_failure(h, request, failure, before, code: str) -> None: + """Allow only the exact terminal selected run while ART remains untouched.""" + assert failure.facts.eligible is False + failed = tuple( + check for check in failure.facts.workstream_default.checks if check.status == "failed" + ) + assert tuple(check.failure_code for check in failed) == (code,) + assert failure.facts.external_members == () + after = dict(await _snapshot(h)) + expected = dict(before) + expected["selected_pre_submit_runs"] += 1 + assert after == expected + async with h.factory() as session: + run = ( + await session.scalars( + select(SelectedPreSubmitRun).where( + SelectedPreSubmitRun.actor_profile_id == str(request.actor.actor_profile_id), + SelectedPreSubmitRun.idempotency_key == str(request.idempotency_key), + ) + ) + ).one() + terminal = SelectedPreSubmitTerminalFacts.from_canonical_body(run.terminal_json) + reservation = terminal.lease.reservation + assert run.status == terminal.outcome == "completed" + assert run.eligible is False and terminal.execution == failure.facts + assert terminal.terminal_digest == run.terminal_digest + assert reservation.request_digest == run.request_digest + assert reservation.task_id == request.task_id + assert reservation.assignment_id == request.assignment_id + assert reservation.actor_profile_id == request.actor.actor_profile_id + assert ( + reservation.admission_lineage.predecessor_submission_id + == request.predecessor_submission_id + ) + assert ( + await session.scalar( + text(""" + SELECT public.selected_pre_submit_receipt_valid(r,'execute',false) + AND public.selected_pre_submit_receipt_valid(r,'finalize',false) + FROM public.selected_pre_submit_runs r WHERE id=:id + """), + {"id": run.id}, + ) + is True + ) + + +async def _queued_selected_body(h, admission_id, *, cause=None) -> dict: + """Build a valid fresh reservation from one actual selected admission.""" + async with h.factory() as session: + body = await session.scalar( + text(""" + SELECT to_jsonb(r) FROM public.selected_pre_submit_runs r + JOIN public.submission_bundle_admissions a ON a.selected_pre_submit_run_id=r.id + WHERE a.id=:id + """), + {"id": admission_id}, + ) + assert body is not None and body["status"] == "completed" and body["eligible"] is True + facts = SelectedPreSubmitReservationFacts.from_canonical_body(body["request_json"]) + lineage = facts.admission_lineage + assert lineage is not None + key = new_record_id() + facts = replace( + facts, + attempt_id=new_record_id(), + idempotency_key=key, + prepared_generation_id=new_record_id(), + admission_lineage=( + replace(lineage, checker_remediation_manifest_id=cause) + if cause is not None + else lineage + ), + attempt_request_digest=selected_pre_submit_attempt_request_digest( + actor_profile_id=facts.actor_profile_id, + identity_link_id=facts.identity_link_id, + task_id=facts.task_id, + assignment_id=facts.assignment_id, + predecessor_submission_id=lineage.predecessor_submission_id, + idempotency_key=key, + archive_sha256=facts.archive_sha256, + archive_byte_count=facts.archive_byte_count, + packet_sha256=lineage.packet_sha256, + ), + ) + return body | { + "id": str(facts.attempt_id), + "idempotency_key": str(key), + "prepared_generation_id": str(facts.prepared_generation_id), + "request_json": facts.canonical_body(), + "request_digest": facts.request_digest, + "status": "queued", + "lease_id": None, + "lease_generation": 0, + "lease_expires_at": None, + "execute_evidence_id": None, + "finalize_evidence_id": None, + "terminal_json": None, + "terminal_digest": None, + "eligible": None, + "started_at": None, + "completed_at": None, + } + + +async def _insert_selected_reservation(h, body) -> None: + """Exercise installed native INSERT guards without disabling any custody.""" + async with h.factory.begin() as session: + await session.execute( + text(""" + INSERT INTO public.selected_pre_submit_runs + SELECT (pg_catalog.jsonb_populate_record( + NULL::public.selected_pre_submit_runs, CAST(:body AS jsonb) + || pg_catalog.jsonb_build_object('queued_at',clock_timestamp()) + )).* + """), + {"body": json.dumps(body)}, + ) diff --git a/backend/tests/test_submission_predecessor_custody.py b/backend/tests/test_submission_predecessor_custody.py index f42052de9..34391bce8 100644 --- a/backend/tests/test_submission_predecessor_custody.py +++ b/backend/tests/test_submission_predecessor_custody.py @@ -23,6 +23,7 @@ from app.core.identifiers import new_record_id from app.core.hashing import canonical_json_hash from app.modules.actors.api.service_identities import ServiceIdentity +from app.interfaces.artifacts import ArtifactStoreUnavailableError from app.modules.artifacts.api import ( SubmissionBundlePreparationCheckFailed, SubmissionBundlePreparationRejected, @@ -32,22 +33,19 @@ PreparedArtifactInternalAuthority, PreparedSubmissionBundlePreparationAuthorization, ) -from app.modules.checkers.models import SelectedPreSubmitRun +from app.modules.checkers.models import CheckerRun, SelectedPreSubmitRun from app.modules.artifacts.models import ( SubmissionBundleAdmission, ) from app.modules.artifacts.submission_admission import ( PreparedSubmissionBundlePreparationCommand, ) -from app.modules.artifacts.submission_manifest import ( - SubmissionChangeFailureCode, - SubmissionChangeRejectedError, -) from app.modules.authorization.api import ActorIdentityFacts, ActorKind from app.modules.checkers.api.execution import CheckerExecutionUnavailable from app.modules.tasks.api import SubmissionCreationRequest from app.modules.tasks.api.submission_context import ( - TaskSubmissionContextRequest, TaskSubmissionContextUnavailable, + TaskSubmissionContextRequest, + TaskSubmissionContextUnavailable, ) from app.modules.tasks.models import SubmissionDispatch from app.modules.tasks.submission_composition import TaskSubmissionCreationService @@ -55,31 +53,17 @@ from app.adapters.tasks import task_submission_context_port from tests.auth_concurrency_support import wait_for_named_database_lock from tests.artifact_store_helpers import artifact_byte_stream -from tests.checkers.execution.support import reserve -from tests.checkers.execution.completion_fixture import completed_evidence +from tests.checkers.execution.support import live_executor, reserve +from tests.post_submit_materialization_helpers import material_fixture from tests.tasks.post_submit_routing.remediation_support import ( no_economic_effects, remediation_source, ) from tests.tasks.post_submit_routing.support import next_request, revision_archive from tests.tasks.submission_lineage_support import _verified_admission - - -_PREPARATION_TABLES = ( - "selected_pre_submit_runs", - "pre_submit_execution_attempts", - "pre_submit_evidence_sets", - "pre_submit_evidence_results", - "submission_bundle_durable_intents", - "artifact_put_attempts", - "artifact_put_attempt_charges", - "artifact_contents", - "artifact_replicas", - "artifact_operation_receipts", - "artifact_put_observation_receipts", - "artifact_verification_jobs", - "artifact_verification_receipts", - "submission_bundle_admissions", +from tests.selected_predecessor_fixtures import ( + _snapshot, _secret_archive, _assert_default_failure, + _queued_selected_body, _insert_selected_reservation, ) @@ -147,16 +131,6 @@ async def _prepare(h, request: SubmissionBundlePreparationRequest): ).prepare(request) -async def _snapshot(h) -> tuple[tuple[str, int], ...]: - async with h.factory() as session: - rows = [] - for table in _PREPARATION_TABLES: - count = await session.scalar(text(f"SELECT pg_catalog.count(*) FROM public.{table}")) - assert count is not None - rows.append((table, int(count))) - return tuple(rows) - - async def _fixture_revision_context(h): """Commit the real routed checker failure before replacement intake.""" async with h.factory() as session, session.begin(): @@ -380,19 +354,19 @@ async def test_unchanged_replacement_archive_or_manifest_denied( provider_writes.clear() predecessor_id = h.created.submission_id for data, expected in ( - (h.data, SubmissionChangeFailureCode.ARCHIVE_UNCHANGED), + (h.data, "submission_archive_unchanged"), ( _same_semantics_different_archive(h.data), - SubmissionChangeFailureCode.MANIFEST_UNCHANGED, + "submission_manifest_unchanged", ), ): request = _replacement_request( h, data, predecessor_id=predecessor_id, idempotency_key=new_record_id(), ) - with pytest.raises(SubmissionChangeRejectedError) as failure: + with pytest.raises(SubmissionBundlePreparationCheckFailed) as failure: await _prepare(h, request) - assert failure.value.code is expected - assert await _snapshot(h) == baseline + await _assert_default_failure(h, request, failure.value, baseline, expected) + baseline = await _snapshot(h) assert provider_writes == [] admission_id = await _verified_admission( @@ -408,35 +382,58 @@ async def test_unchanged_replacement_archive_or_manifest_denied( async def test_blocked_replacement_precheck_preserves_revision_state( - tmp_path, isolated_database_env, monkeypatch, + tmp_path, + isolated_database_env, + monkeypatch, ): provider_writes = _trace_provider_writes(monkeypatch) async with remediation_source(tmp_path, isolated_database_env) as h: await _fixture_revision_context(h) provider_writes.clear() changed_data = revision_archive(h.data) + baseline = await _snapshot(h) + request = replace( + _replacement_request( + h, + _secret_archive(changed_data), + predecessor_id=h.created.submission_id, + idempotency_key=new_record_id(), + ), + contributor_attestation="", + ) with pytest.raises(SubmissionBundlePreparationCheckFailed) as blocked: - await _prepare(h, replace( - _replacement_request( - h, changed_data, predecessor_id=h.created.submission_id, - idempotency_key=new_record_id(), - ), - contributor_attestation="", - )) - assert blocked.value.facts.eligible is False - assert any(entry.checker_execution_status == "failed" - for entry in blocked.value.facts.entries) + await _prepare(h, request) + await _assert_default_failure( + h, + request, + blocked.value, + baseline, + "high_confidence_secret_detected", + ) + assert tuple( + warning.code for warning in blocked.value.facts.workstream_default.warnings + ) == ("submission_attestation_missing",) assert provider_writes == [] async with h.factory() as session: assert await session.scalar(text("SELECT count(*) FROM public.submissions")) == 1 - assert await session.scalar(text( - "SELECT status FROM public.workstream_tasks WHERE id=:id" - ), {"id": h.request.task_id}) == "needs_revision" + assert ( + await session.scalar( + text("SELECT status FROM public.workstream_tasks WHERE id=:id"), + {"id": h.request.task_id}, + ) + == "needs_revision" + ) admission_id = await _verified_admission( - h.factory, h.store, h.namespace, h.settings, h.actor_context, + h.factory, + h.store, + h.namespace, + h.settings, + h.actor_context, _replacement_request( - h, changed_data, predecessor_id=h.created.submission_id, + h, + changed_data, + predecessor_id=h.created.submission_id, idempotency_key=new_record_id(), ), ) @@ -464,20 +461,22 @@ async def traced_load(self, task_context): await _fixture_revision_context(h) loaded.clear() for data in (h.data, _same_semantics_different_archive(h.data)): - with pytest.raises(SubmissionChangeRejectedError): + with pytest.raises(SubmissionBundlePreparationCheckFailed): await _prepare(h, _replacement_request( h, data, predecessor_id=predecessor_id, idempotency_key=new_record_id(), )) changed_data = revision_archive(h.data) - with pytest.raises(SubmissionBundlePreparationCheckFailed): - await _prepare(h, replace( - _replacement_request( - h, changed_data, predecessor_id=predecessor_id, - idempotency_key=new_record_id(), - ), - contributor_attestation="", - )) + baseline = await _snapshot(h) + secret_request = _replacement_request( + h, _secret_archive(changed_data), predecessor_id=predecessor_id, + idempotency_key=new_record_id(), + ) + with pytest.raises(SubmissionBundlePreparationCheckFailed) as blocked: + await _prepare(h, secret_request) + await _assert_default_failure( + h, secret_request, blocked.value, baseline, "high_confidence_secret_detected", + ) idempotency_key = new_record_id() admission_id = await _verified_admission( h.factory, h.store, h.namespace, h.settings, h.actor_context, @@ -557,207 +556,159 @@ async def test_replacement_dispatch_sql_rejects_cause_and_receipt_substitution( ) is False, field -async def test_sql_evidence_insert_rejects_superseded_checker_cause( - tmp_path, isolated_database_env, +async def test_sql_selected_pre_reservation_rejects_superseded_checker_cause( + tmp_path, + isolated_database_env, ): async with remediation_source(tmp_path, isolated_database_env) as h: source_id = await _fixture_revision_context(h) admission_id = await _verified_admission( - h.factory, h.store, h.namespace, h.settings, h.actor_context, + h.factory, + h.store, + h.namespace, + h.settings, + h.actor_context, _replacement_request( - h, revision_archive(h.data), predecessor_id=h.created.submission_id, + h, + revision_archive(h.data), + predecessor_id=h.created.submission_id, idempotency_key=new_record_id(), ), ) - async with h.factory() as session: - admission = await session.get(SubmissionBundleAdmission, str(admission_id)) - assert admission.status == "ready" - assert admission.checker_remediation_manifest_id == source_id - donor_id = admission.pre_submit_evidence_set_id - donor = (await session.execute(text( - "SELECT attempt_id,attempt_request_digest FROM public.pre_submit_evidence_sets " - "WHERE id=:id" - ), {"id": donor_id})).one() - result_ids = list((await session.execute(text( - "SELECT id FROM public.pre_submit_evidence_results " - "WHERE evidence_set_id=:id ORDER BY result_order" - ), {"id": donor_id})).scalars()) - assert result_ids - + positive = await _queued_selected_body(h, admission_id) + assert positive["request_json"]["admission_lineage"][ + "checker_remediation_manifest_id" + ] == str(source_id) + await _insert_selected_reservation(h, positive) + rejected = await _queued_selected_body(h, admission_id) await reserve(h, await next_request(h)) before = await _snapshot(h) async with h.factory() as session: - current_run_id = await session.scalar(text( - "SELECT current_run_id FROM public.checker_submission_fences " - "WHERE submission_id=:id" - ), {"id": h.created.submission_id}) - routed_run_id = await session.scalar(text( - "SELECT checker_run_id FROM public.task_post_submit_routing_manifests " - "WHERE id=:id" - ), {"id": source_id}) - assert current_run_id != routed_run_id - attempt_id, evidence_id = new_record_id(), new_record_id() - operation = canonical_json_hash({"test_clone_evidence_id": str(evidence_id)}) + current = await session.scalar( + text( + "SELECT current_run_id FROM public.checker_submission_fences WHERE submission_id=:id" + ), + {"id": h.created.submission_id}, + ) + routed = await session.scalar( + text( + "SELECT checker_run_id FROM public.task_post_submit_routing_manifests WHERE id=:id" + ), + {"id": source_id}, + ) + assert current != routed with pytest.raises( - IntegrityError, match="pre-submit remediation evaluation is not current", - ): - async with h.factory() as session, session.begin(): - await session.execute(text(""" - INSERT INTO public.pre_submit_execution_attempts - SELECT (pg_catalog.jsonb_populate_record( - NULL::public.pre_submit_execution_attempts, - pg_catalog.to_jsonb(a) || pg_catalog.jsonb_build_object( - 'id', CAST(:attempt_id AS text), - 'idempotency_key', CAST(:idempotency_key AS text), - 'claim_nonce', CAST(:claim_nonce AS text), - 'status', 'reserved', 'evidence_set_id', NULL, - 'created_at', transaction_timestamp() - ))).* - FROM public.pre_submit_execution_attempts a WHERE a.id=:donor_attempt - """), { - "attempt_id": str(attempt_id), "idempotency_key": str(new_record_id()), - "claim_nonce": str(new_record_id()), "donor_attempt": donor.attempt_id, - }) - await session.execute(text(""" - INSERT INTO public.pre_submit_evidence_sets - SELECT (pg_catalog.jsonb_populate_record( - NULL::public.pre_submit_evidence_sets, - pg_catalog.to_jsonb(e) || pg_catalog.jsonb_build_object( - 'id', CAST(:evidence_id AS text), - 'operation_identity', CAST(:operation AS text), - 'attempt_id', CAST(:attempt_id AS text), - 'created_at', transaction_timestamp() - ))).* - FROM public.pre_submit_evidence_sets e WHERE e.id=:donor_id - """), { - "evidence_id": str(evidence_id), "operation": operation, - "attempt_id": str(attempt_id), "donor_id": donor_id, - }) - for result_id in result_ids: - await session.execute(text(""" - INSERT INTO public.pre_submit_evidence_results - SELECT (pg_catalog.jsonb_populate_record( - NULL::public.pre_submit_evidence_results, - pg_catalog.to_jsonb(r) || pg_catalog.jsonb_build_object( - 'id', CAST(:new_id AS text), - 'evidence_set_id', CAST(:evidence_id AS text), - 'created_at', transaction_timestamp() - ))).* - FROM public.pre_submit_evidence_results r WHERE r.id=:donor_id - """), { - "new_id": str(new_record_id()), - "evidence_id": str(evidence_id), "donor_id": result_id, - }) - await session.execute(text(""" - UPDATE public.pre_submit_execution_attempts - SET status='completed',evidence_set_id=:evidence_id WHERE id=:attempt_id - """), {"evidence_id": evidence_id, "attempt_id": attempt_id}) + IntegrityError, match="selected PRE reservation routed cause is not current" + ) as denied: + await _insert_selected_reservation(h, rejected) + assert denied.value.orig.sqlstate == "23514" assert await _snapshot(h) == before + async with h.factory() as session: + admission = await session.get(SubmissionBundleAdmission, str(admission_id)) + assert admission.status == "ready" + assert admission.checker_remediation_manifest_id == source_id + assert await session.scalar(text("SELECT count(*) FROM public.submissions")) == 1 + await no_economic_effects(session) -async def test_sql_attempt_reconstruction_rejects_foreign_routed_cause( - tmp_path, isolated_database_env, +async def test_sql_selected_pre_reservation_and_admission_reject_foreign_routed_cause( + tmp_path, + isolated_database_env, ): async with remediation_source(tmp_path / "local", isolated_database_env) as local: async with remediation_source( - tmp_path / "foreign", isolated_database_env, provision_services=False, + tmp_path / "foreign", + isolated_database_env, + provision_services=False, storage_settings=local.settings, ) as foreign: local_source = await _fixture_revision_context(local) foreign_source = await _fixture_revision_context(foreign) admission_id = await _verified_admission( - local.factory, local.store, local.namespace, local.settings, + local.factory, + local.store, + local.namespace, + local.settings, local.actor_context, _replacement_request( - local, revision_archive(local.data), + local, + revision_archive(local.data), predecessor_id=local.created.submission_id, idempotency_key=new_record_id(), ), ) - async with local.factory() as session: - admission = await session.get(SubmissionBundleAdmission, str(admission_id)) - assert admission.status == "ready" - assert admission.checker_remediation_manifest_id == local_source - donor_id = admission.pre_submit_evidence_set_id - donor = (await session.execute(text(""" - SELECT e.attempt_id, a.request_json::jsonb AS request_body - FROM public.pre_submit_evidence_sets e - JOIN public.pre_submit_execution_attempts a ON a.id=e.attempt_id - WHERE e.id=:id - """), {"id": donor_id})).mappings().one() - result_ids = list((await session.execute(text( - "SELECT id FROM public.pre_submit_evidence_results " - "WHERE evidence_set_id=:id ORDER BY result_order" - ), {"id": donor_id})).scalars()) - assert result_ids - request_body = dict(donor["request_body"]) - assert request_body["checker_remediation_manifest_id"] == str(local_source) - request_body["checker_remediation_manifest_id"] = str(foreign_source) - request_digest = canonical_json_hash(request_body) - attempt_id, evidence_id = new_record_id(), new_record_id() - operation = canonical_json_hash({"test_clone_evidence_id": str(evidence_id)}) + positive = await _queued_selected_body(local, admission_id) + assert positive["request_json"]["admission_lineage"][ + "checker_remediation_manifest_id" + ] == str(local_source) + await _insert_selected_reservation(local, positive) + rejected = await _queued_selected_body(local, admission_id, cause=foreign_source) before = await _snapshot(local) - with pytest.raises(IntegrityError, match="pre-submit evidence resource mismatch"): + with pytest.raises( + IntegrityError, match="selected PRE reservation routed cause is foreign" + ) as denied: + await _insert_selected_reservation(local, rejected) + assert denied.value.orig.sqlstate == "23514" + assert await _snapshot(local) == before + with pytest.raises( + IntegrityError, match="selected PRE request custody is immutable" + ) as immutable: async with local.factory.begin() as session: - await session.execute(text(""" - INSERT INTO public.pre_submit_execution_attempts - SELECT (pg_catalog.jsonb_populate_record( - NULL::public.pre_submit_execution_attempts, - pg_catalog.to_jsonb(a) || pg_catalog.jsonb_build_object( - 'id', CAST(:attempt_id AS text), - 'idempotency_key', CAST(:idempotency_key AS text), - 'claim_nonce', CAST(:claim_nonce AS text), - 'request_json', CAST(:request_body AS jsonb), - 'request_digest', CAST(:request_digest AS text), - 'status', 'reserved', 'evidence_set_id', NULL, - 'created_at', transaction_timestamp() - ))).* - FROM public.pre_submit_execution_attempts a WHERE a.id=:donor_attempt - """), { - "attempt_id": str(attempt_id), - "idempotency_key": str(new_record_id()), - "claim_nonce": str(new_record_id()), - "request_body": json.dumps(request_body), - "request_digest": request_digest, - "donor_attempt": donor["attempt_id"], - }) - await session.execute(text(""" - INSERT INTO public.pre_submit_evidence_sets + await session.execute( + text(""" + UPDATE public.selected_pre_submit_runs + SET request_json=CAST(:request AS jsonb), request_digest=:digest WHERE id=:id + """), + { + "id": positive["id"], + "request": json.dumps( + positive["request_json"] + | { + "admission_lineage": rejected["request_json"][ + "admission_lineage" + ] + } + ), + "digest": canonical_json_hash( + positive["request_json"] + | { + "admission_lineage": rejected["request_json"][ + "admission_lineage" + ] + } + ), + }, + ) + assert immutable.value.orig.sqlstate == "55000" + assert await _snapshot(local) == before + with pytest.raises( + IntegrityError, match="submission bundle admission verified lineage mismatch" + ) as mismatch: + async with local.factory.begin() as session: + await session.execute( + text(""" + INSERT INTO public.submission_bundle_admissions SELECT (pg_catalog.jsonb_populate_record( - NULL::public.pre_submit_evidence_sets, - pg_catalog.to_jsonb(e) || pg_catalog.jsonb_build_object( - 'id', CAST(:evidence_id AS text), - 'operation_identity', CAST(:operation AS text), - 'attempt_id', CAST(:attempt_id AS text), - 'attempt_request_digest', CAST(:request_digest AS text), - 'created_at', transaction_timestamp() - ))).* - FROM public.pre_submit_evidence_sets e WHERE e.id=:donor_id - """), { - "evidence_id": str(evidence_id), "operation": operation, - "attempt_id": str(attempt_id), "request_digest": request_digest, - "donor_id": donor_id, - }) - for result_id in result_ids: - await session.execute(text(""" - INSERT INTO public.pre_submit_evidence_results - SELECT (pg_catalog.jsonb_populate_record( - NULL::public.pre_submit_evidence_results, - pg_catalog.to_jsonb(r) || pg_catalog.jsonb_build_object( - 'id', CAST(:new_id AS text), - 'evidence_set_id', CAST(:evidence_id AS text), - 'created_at', transaction_timestamp() - ))).* - FROM public.pre_submit_evidence_results r WHERE r.id=:donor_id - """), { - "new_id": str(new_record_id()), - "evidence_id": str(evidence_id), "donor_id": result_id, - }) - await session.execute(text(""" - UPDATE public.pre_submit_execution_attempts - SET status='completed',evidence_set_id=:evidence_id WHERE id=:attempt_id - """), {"evidence_id": evidence_id, "attempt_id": attempt_id}) + NULL::public.submission_bundle_admissions, to_jsonb(a) + || pg_catalog.jsonb_build_object( + 'id',CAST(:new_id AS uuid), + 'checker_remediation_manifest_id',CAST(:cause AS uuid) + ) + )).* FROM public.submission_bundle_admissions a WHERE a.id=:id + """), + {"new_id": new_record_id(), "cause": foreign_source, "id": admission_id}, + ) + assert mismatch.value.orig.sqlstate == "23514" assert await _snapshot(local) == before + async with local.factory() as session: + admission = await session.get(SubmissionBundleAdmission, str(admission_id)) + assert ( + admission.status == "ready" and admission.selected_pre_submit_run_id is not None + ) + assert admission.pre_submit_evidence_set_id is None + assert admission.checker_remediation_manifest_id == local_source + assert await session.scalar(text("SELECT count(*) FROM public.submissions")) == 2 + await no_economic_effects(session) @pytest.mark.parametrize("advance_fence", [False, True]) @@ -954,26 +905,49 @@ async def forbidden_load(*_args, **_kwargs): )}) is False -@pytest.mark.parametrize("recommendation", ["task_setup_blocked", "allow_review"]) -async def test_setup_fault_or_success_cannot_authorize_replacement_before_bytes( - tmp_path, isolated_database_env, monkeypatch, recommendation, +@pytest.mark.parametrize("outcome", ["infrastructure_failed", "completed"]) +async def test_nonremediation_outcome_cannot_authorize_replacement_before_bytes( + tmp_path, + isolated_database_env, + monkeypatch, + outcome, ): provider_writes = _trace_provider_writes(monkeypatch) - async with completed_evidence(tmp_path, isolated_database_env, recommendation) as h: - assert h.run.routing_recommendation == recommendation + async with material_fixture(tmp_path, isolated_database_env) as h: + await reserve(h) + with monkeypatch.context() as failure: + if outcome == "infrastructure_failed": + + async def unavailable(*_args, **_kwargs): + raise ArtifactStoreUnavailableError("selected input unavailable") + + failure.setattr(h.store, "open", unavailable) + result = await live_executor(h).evaluate_post_submission(h.request) + assert result.outcome == outcome + async with h.factory() as session: + run = await session.get(CheckerRun, str(result.attempt_id)) + assert run.status == outcome + assert run.routing_recommendation == ( + "not_evaluated" if outcome == "infrastructure_failed" else "allow_review" + ) before = await _snapshot(h) provider_writes.clear() with pytest.raises( SubmissionBundlePreparationRejected, match="submission_bundle_preparation_context_changed", ): - await _prepare(h, replace( - _replacement_request( - h, revision_archive(h.data), predecessor_id=h.created.submission_id, - idempotency_key=new_record_id(), + await _prepare( + h, + replace( + _replacement_request( + h, + revision_archive(h.data), + predecessor_id=h.created.submission_id, + idempotency_key=new_record_id(), + ), + byte_source=_forbidden_bytes(), ), - byte_source=_forbidden_bytes(), - )) + ) assert await _snapshot(h) == before assert provider_writes == [] From 07d7ee64be82e2329829c46db8529109eef9fda4 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 10:09:48 +0100 Subject: [PATCH 158/283] [PILOT-04] Preserve selected PRE currentness custody --- .../versions/0036_selected_checker_flow.py | 113 ++++++++++++++++++ backend/tests/conftest.py | 2 +- 2 files changed, 114 insertions(+), 1 deletion(-) diff --git a/backend/alembic/versions/0036_selected_checker_flow.py b/backend/alembic/versions/0036_selected_checker_flow.py index 7edc2e93f..cf8251808 100644 --- a/backend/alembic/versions/0036_selected_checker_flow.py +++ b/backend/alembic/versions/0036_selected_checker_flow.py @@ -348,6 +348,119 @@ def _replace_admission_guards() -> None: def _selected_run_guards() -> None: op.execute(r""" +create function public.guard_selected_pre_submit_run_insert() returns trigger +language plpgsql set search_path=pg_catalog,public,pg_temp as $$ +declare lineage jsonb; predecessor_id uuid; predecessor_version integer; + remediation_id uuid; +begin + lineage := new.request_json->'admission_lineage'; + if new.status is distinct from 'queued' + or new.id is distinct from (new.request_json->>'attempt_id')::uuid + or new.actor_profile_id is distinct from (new.request_json->>'actor_profile_id')::uuid + or new.identity_link_id is distinct from (new.request_json->>'identity_link_id')::uuid + or new.project_id is distinct from (new.request_json->>'project_id')::uuid + or new.task_id is distinct from (new.request_json->>'task_id')::uuid + or new.assignment_id is distinct from (new.request_json->>'assignment_id')::uuid + or new.idempotency_key is distinct from (new.request_json->>'idempotency_key')::uuid + or new.prepared_generation_id is distinct from + (new.request_json->>'prepared_generation_id')::uuid + or new.policy_sha256 is distinct from new.request_json->>'policy_sha256' + or new.default_behavior_sha256 is distinct from + new.request_json->>'default_behavior_sha256' + or new.default_input_sha256 is distinct from new.request_json->>'default_input_sha256' + or new.archive_sha256 is distinct from new.request_json->>'archive_sha256' + or new.archive_byte_count is distinct from + (new.request_json->>'archive_byte_count')::bigint + or new.semantic_manifest_sha256 is distinct from + new.request_json->>'semantic_manifest_sha256' + or new.execution_budget_ms is distinct from + (new.request_json->>'execution_budget_ms')::integer + or new.request_json->>'schema_version' is distinct from + 'workstream.selected_pre_submit_reservation.v1' + or jsonb_typeof(lineage) is distinct from 'object' + or new.request_digest is distinct from public.external_checker_registry_digest(new.request_json) + then raise exception 'selected PRE reservation lineage mismatch' using errcode='23514'; end if; + + predecessor_id := nullif(lineage->>'predecessor_submission_id','')::uuid; + predecessor_version := (lineage->>'predecessor_submission_version')::integer; + remediation_id := nullif(lineage->>'checker_remediation_manifest_id','')::uuid; + + -- Match the application owner order: TASK, assignment, predecessor, CHECKERS. + perform 1 from public.workstream_tasks t + join public.project_guides g + on g.project_id=t.project_id and g.version=t.locked_guide_version + where t.id=new.task_id and t.project_id=new.project_id + and t.assigned_to=new.actor_profile_id + and t.status=case when predecessor_id is null then 'in_progress' else 'needs_revision' end + and g.id=(lineage->>'guide_id')::uuid + and t.locked_guide_version=lineage->>'guide_version' + and t.locked_guide_source_snapshot_id=(lineage->>'source_snapshot_id')::uuid + and t.locked_guide_source_snapshot_hash=lineage->>'source_snapshot_sha256' + and t.locked_effective_project_submission_artifact_policy_id= + (lineage->>'effective_policy_id')::uuid + and t.locked_effective_project_submission_artifact_policy_hash= + lineage->>'effective_policy_sha256' + and t.locked_pre_submit_checker_policy_id=(lineage->>'pre_submit_policy_id')::uuid + and t.locked_pre_submit_checker_bundle_hash=lineage->>'pre_submit_policy_sha256' + for update of t; + if not found then + raise exception 'selected PRE reservation lineage mismatch' using errcode='23514'; + end if; + + perform 1 from public.task_assignments a + where a.id=new.assignment_id and a.task_id=new.task_id + and a.project_id=new.project_id and a.contributor_id=new.actor_profile_id + and a.status='active' and a.released_at is null + and (predecessor_id is null or a.accepted_at is not null) + for update; + if not found then + raise exception 'selected PRE reservation lineage mismatch' using errcode='23514'; + end if; + + if predecessor_id is null then + if predecessor_version is not null or remediation_id is not null + or exists(select 1 from public.submissions s where s.task_id=new.task_id) + then raise exception 'selected PRE reservation lineage mismatch' using errcode='23514'; end if; + else + if predecessor_version is null or remediation_id is null then + raise exception 'selected PRE reservation lineage mismatch' using errcode='23514'; + end if; + perform 1 from public.submissions s + where s.id=predecessor_id and s.task_id=new.task_id + and s.contributor_id=new.actor_profile_id and s.task_assignment_id=new.assignment_id + and s.version=predecessor_version + and not exists(select 1 from public.submissions successor + where successor.task_id=s.task_id and successor.version>s.version) + for update; + if not found then + raise exception 'selected PRE reservation routed cause is not current' using errcode='23514'; + end if; + + if not exists( + select 1 from public.task_post_submit_routing_manifests m + where m.id=remediation_id and m.project_id=new.project_id and m.task_id=new.task_id + and m.assignment_id=new.assignment_id and m.contributor_id=new.actor_profile_id + and m.submission_id=predecessor_id and m.submission_version=predecessor_version + and m.routing_recommendation='needs_revision' + ) then + raise exception 'selected PRE reservation routed cause is foreign' using errcode='23514'; + end if; + + perform 1 from public.checker_submission_fences f + join public.task_post_submit_routing_manifests m + on m.submission_id=f.submission_id and m.checker_run_id=f.current_run_id + where m.id=remediation_id and f.submission_id=predecessor_id + and public.task_routing_outcome_complete(m) + for update of f; + if not found then + raise exception 'selected PRE reservation routed cause is not current' using errcode='23514'; + end if; + end if; + return new; +end $$ +""") + op.execute("create trigger selected_pre_submit_run_insert before insert on public.selected_pre_submit_runs for each row execute function public.guard_selected_pre_submit_run_insert()") + op.execute(r""" create function public.selected_pre_submit_facts_digest(r public.selected_pre_submit_runs, phase text) returns text language sql immutable strict set search_path=pg_catalog,public,pg_temp as $$ select case phase diff --git a/backend/tests/conftest.py b/backend/tests/conftest.py index 7bcb6cec5..c034cff55 100644 --- a/backend/tests/conftest.py +++ b/backend/tests/conftest.py @@ -23,7 +23,7 @@ DDL_LOCK_DIRECTORY = Path("/tmp") # Match the PostgreSQL 16 engine used by Backend CI. Catalog identity rendering # differs across major versions; regenerate only after comparing actual objects. -EXPECTED_PUBLIC_SCHEMA_SHA256 = "2970241168e5b843b0526a94d32e87166c8956fbbcb9e73de2c395b2f3a154cf" +EXPECTED_PUBLIC_SCHEMA_SHA256 = "8d9ba7f3f7b7701775b23257a4eb0ceb898fa6cf6bf615dd6f694da8b7ffb1b8" PROTECTED_TEST_TABLES = ( "actor_profile_migration_state", "alembic_version", From 7d7e62284cd1e4619a8906857add91d156f9a364 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 10:21:20 +0100 Subject: [PATCH 159/283] [PILOT-04] Align selected POST delivery budgets --- backend/app/adapters/artifacts/__init__.py | 22 ++++++ backend/app/adapters/outbox/__init__.py | 14 +++- backend/app/core/config.py | 4 +- backend/app/modules/artifacts/preparation.py | 4 +- .../modules/checkers/api/external_policy.py | 21 +++++- backend/app/modules/outbox/delivery.py | 44 +++++++++--- .../tests/checkers/external/test_policy.py | 72 ++++++++++++++++++- .../evaluation_delivery/test_completion.py | 27 ++++++- docs/spec_artifact_storage_service.md | 4 +- 9 files changed, 191 insertions(+), 21 deletions(-) diff --git a/backend/app/adapters/artifacts/__init__.py b/backend/app/adapters/artifacts/__init__.py index b665ab0ff..6d65daf7f 100644 --- a/backend/app/adapters/artifacts/__init__.py +++ b/backend/app/adapters/artifacts/__init__.py @@ -575,8 +575,30 @@ async def materialize( initialize_artifact_internal_runtime, ) from app.modules.artifacts.submission_archive import SubmissionArchiveInspector + from app.modules.checkers.api.external_policy import ( + ExternalCheckerPolicyError, + selected_post_submit_execution_budget_ms, + ) + from app.modules.checkers.api.materialization import ( + PostSubmissionMaterializationFailure, + ) + from app.modules.checkers.api.selected_post_submit import ( + SelectedPostSubmissionEvaluationRequest, + ) settings = get_settings() + if isinstance(facts.request, SelectedPostSubmissionEvaluationRequest): + try: + selected_post_submit_execution_budget_ms( + facts.request.policy, + artifact_deadline_ms=int( + settings.artifact_preparation_total_deadline_seconds * 1000 + ), + ) + except ExternalCheckerPolicyError: + raise PostSubmissionMaterializationFailure( + "post_submit_material_deadline_unavailable" + ) from None await initialize_artifact_internal_runtime() with _artifact_internal_runtime() as (store, namespace): manager = create_artifact_scratch_manager(settings) diff --git a/backend/app/adapters/outbox/__init__.py b/backend/app/adapters/outbox/__init__.py index 17ba420e3..c39c7eea1 100644 --- a/backend/app/adapters/outbox/__init__.py +++ b/backend/app/adapters/outbox/__init__.py @@ -1,6 +1,6 @@ """Explicit composition of the shared delivery owner; feature registration is separate.""" -from collections.abc import Callable +from collections.abc import Callable, Mapping from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker from app.modules.authorization.api.outbox_dispatch import OutboxDispatchAuthorizationPort @@ -21,6 +21,7 @@ def outbox_delivery( authorization_factory: Callable[[AsyncSession], OutboxDispatchAuthorizationPort], registry: HandlerRegistry, options: DeliveryOptions, + event_options: Mapping[tuple[str, int], DeliveryOptions] | None = None, ) -> OutboxDelivery: """No default authority, installed handler, worker or runtime discovery.""" return OutboxDelivery( @@ -28,6 +29,7 @@ def outbox_delivery( authorization_factory=authorization_factory, registry=registry, options=options, + event_options=event_options, ) @@ -44,6 +46,10 @@ def production_outbox_delivery(session_factory): evaluation_request_handler, ) from app.modules.checkers.api.execution import COMPLETION_EVENT, REQUEST_EVENT + from app.modules.checkers.api.external_policy import ( + SELECTED_POST_DELIVERY_LEASE_SECONDS, + SELECTED_POST_HANDLER_TIMEOUT_SECONDS, + ) from app.modules.tasks.api.assignment_invalidation import ASSIGNMENT_INVALIDATION_EVENT return outbox_delivery( @@ -78,6 +84,12 @@ def production_outbox_delivery(session_factory): ] ), options=DeliveryOptions(), + event_options={ + (REQUEST_EVENT, 1): DeliveryOptions( + lease_seconds=SELECTED_POST_DELIVERY_LEASE_SECONDS, + handler_timeout_seconds=SELECTED_POST_HANDLER_TIMEOUT_SECONDS, + ) + }, ) diff --git a/backend/app/core/config.py b/backend/app/core/config.py index 6dccebbac..c0d8ee504 100644 --- a/backend/app/core/config.py +++ b/backend/app/core/config.py @@ -228,12 +228,12 @@ class Settings(BaseSettings): ge=0, ) artifact_scratch_reservation_ttl_seconds: float = Field( - default=2400.0, + default=3900.0, gt=0.0, le=86_400.0, ) artifact_preparation_total_deadline_seconds: float = Field( - default=1800.0, + default=3400.0, gt=0.0, le=7200.0, ) diff --git a/backend/app/modules/artifacts/preparation.py b/backend/app/modules/artifacts/preparation.py index 0eed9bf90..e7d13479a 100644 --- a/backend/app/modules/artifacts/preparation.py +++ b/backend/app/modules/artifacts/preparation.py @@ -297,8 +297,8 @@ class ArtifactPreparationLimits: maximum_files: int = 8 maximum_concurrency: int = 4 minimum_free_bytes: int = HARD_MAXIMUM_ARTIFACT_BYTES - reservation_ttl_seconds: float = 2400.0 - total_deadline_seconds: float = 1800.0 + reservation_ttl_seconds: float = 3900.0 + total_deadline_seconds: float = 3400.0 cleanup_margin_seconds: float = 300.0 stream_buffer_bytes: int = 1024 * 1024 maximum_source_bytes: int = HARD_MAXIMUM_ARTIFACT_BYTES diff --git a/backend/app/modules/checkers/api/external_policy.py b/backend/app/modules/checkers/api/external_policy.py index 6a1f758e3..8941b418a 100644 --- a/backend/app/modules/checkers/api/external_policy.py +++ b/backend/app/modules/checkers/api/external_policy.py @@ -25,8 +25,17 @@ WORKSTREAM_DEFAULT_EXECUTION_BUDGET_MS = 60_000 MAXIMUM_SELECTED_PRE_EXECUTION_BUDGET_MS = 7_200_000 SELECTED_POST_MATERIALIZATION_BUDGET_MS = 60_000 -MAXIMUM_SELECTED_POST_EXECUTION_BUDGET_MS = 3_600_000 +# The outbox claim is natively bounded to one hour. Keep explicit time for the +# request reader/authority prelude, execution finalization and delivery commit. +MAXIMUM_SELECTED_POST_EXECUTION_BUDGET_MS = 3_400_000 +SELECTED_POST_HANDLER_PRELUDE_MARGIN_MS = 60_000 SELECTED_POST_FINALIZATION_MARGIN_MS = 60_000 +SELECTED_POST_HANDLER_TIMEOUT_SECONDS = ( + MAXIMUM_SELECTED_POST_EXECUTION_BUDGET_MS + + SELECTED_POST_HANDLER_PRELUDE_MARGIN_MS + + SELECTED_POST_FINALIZATION_MARGIN_MS +) // 1000 +SELECTED_POST_DELIVERY_LEASE_SECONDS = 3_600 class ExternalCheckerPolicyError(ValueError): @@ -299,9 +308,15 @@ def selected_pre_submit_execution_budget_ms( def selected_post_submit_execution_budget_ms( policy: LockedExternalPostSubmitPolicy, + *, + artifact_deadline_ms: int | None = None, ) -> int: """Bound ART materialization and every ordered POST image under one lease.""" - if type(policy) is not LockedExternalPostSubmitPolicy: + if ( + type(policy) is not LockedExternalPostSubmitPolicy + or artifact_deadline_ms is not None + and (type(artifact_deadline_ms) is not int or artifact_deadline_ms <= 0) + ): raise ExternalCheckerPolicyError("selected POST execution budget is invalid") required = SELECTED_POST_MATERIALIZATION_BUDGET_MS + sum( binding.registry.resources.deadline_ms + EXTERNAL_CHECKER_EXECUTION_CLEANUP_MARGIN_MS @@ -309,4 +324,6 @@ def selected_post_submit_execution_budget_ms( ) if required > MAXIMUM_SELECTED_POST_EXECUTION_BUDGET_MS: raise ExternalCheckerPolicyError("selected POST execution exceeds durable worker deadline") + if artifact_deadline_ms is not None and required > artifact_deadline_ms: + raise ExternalCheckerPolicyError("selected POST execution exceeds ART custody deadline") return required diff --git a/backend/app/modules/outbox/delivery.py b/backend/app/modules/outbox/delivery.py index 43001db51..947952260 100644 --- a/backend/app/modules/outbox/delivery.py +++ b/backend/app/modules/outbox/delivery.py @@ -3,10 +3,11 @@ from __future__ import annotations import asyncio -from collections.abc import Callable +from collections.abc import Callable, Mapping from contextlib import asynccontextmanager from datetime import datetime, timedelta import json +from types import MappingProxyType from uuid import UUID, uuid4 from sqlalchemy.exc import SQLAlchemyError @@ -152,14 +153,27 @@ def __init__( authorization_factory: Callable[[AsyncSession], OutboxDispatchAuthorizationPort], registry: HandlerRegistry, options: DeliveryOptions, + event_options: Mapping[tuple[str, int], DeliveryOptions] | None = None, ) -> None: """Require explicit AUTH composition and bounded handler registration.""" self._sessions = session_factory self._authorization = authorization_factory self._registry = registry self._options = DeliveryOptions.model_validate(options.model_dump()) + overrides = {} + for key, value in (event_options or {}).items(): + if key not in registry.keys or type(value) is not DeliveryOptions: + raise ValueError("outbox event delivery options are invalid") + overrides[key] = DeliveryOptions.model_validate(value.model_dump()) + self._event_options = MappingProxyType(overrides) self._running_handlers: set[asyncio.Task] = set() + def _options_for(self, event_type: str, event_version: int) -> DeliveryOptions: + """Resolve one registered event's immutable limits or the shared defaults.""" + if self._registry.get(event_type, event_version) is None: + raise DeliveryUnavailable("outbox_delivery_unavailable") + return self._event_options.get((event_type, event_version), self._options) + @asynccontextmanager async def _authority(self, session, **selectors): """Conceal AUTH boundary failures without swallowing owner errors.""" @@ -195,12 +209,17 @@ async def claim(self, event_id: UUID, project_id: UUID, owner: str) -> OutboxCla async with self._sessions() as session: event = await DeliveryRepository(session).event(event_id, project_id) now = await database_time(session) + options = ( + self._options_for(event.event_type, event.event_version) + if event is not None + else self._options + ) if ( event is None or self._registry.get(event.event_type, event.event_version) is None or event.delivery_state not in ("pending", "retryable") or event.next_attempt_at > now - or event.claim_generation >= self._options.max_attempts + or event.claim_generation >= options.max_attempts ): return None claim = OutboxClaim( @@ -210,7 +229,7 @@ async def claim(self, event_id: UUID, project_id: UUID, owner: str) -> OutboxCla claim_generation=event.claim_generation + 1, claim_owner=owner, claimed_at=now, - claim_expires_at=now + timedelta(seconds=self._options.lease_seconds), + claim_expires_at=now + timedelta(seconds=options.lease_seconds), ) facts = _facts(claim, OutboxDispatchPhase.CLAIM) async with self._sessions() as session, session.begin(): @@ -309,15 +328,16 @@ async def invoke(self, claim: OutboxClaim) -> DeliveryReceipt | None: return None annotate_current_span(outbox_correlation_id=envelope.correlation_id) handler = self._registry.get(envelope.event_type, envelope.event_version) + options = self._options_for(envelope.event_type, envelope.event_version) cause = FinalizationCause.UNKNOWN task = None try: loop = asyncio.get_running_loop() - deadline = loop.time() + self._options.handler_timeout_seconds + deadline = loop.time() + options.handler_timeout_seconds task = asyncio.create_task(handler(envelope)) self._running_handlers.add(task) task.add_done_callback(self._handler_done) - done, _ = await asyncio.wait((task,), timeout=self._options.handler_timeout_seconds) + done, _ = await asyncio.wait((task,), timeout=options.handler_timeout_seconds) if done and loop.time() < deadline and not task.cancelled(): result = task.result() if type(result) is HandlerOutcome: @@ -335,15 +355,18 @@ async def finalize(self, claim: OutboxClaim, cause: FinalizationCause) -> Delive """Authorize the exact outcome; response loss replays original delivery facts.""" claim = _checked_claim(claim) async with self._sessions() as session: - attempt = await DeliveryRepository(session).attempt(claim) - if attempt is None or claim_from_attempt(attempt) != claim: + repository = DeliveryRepository(session) + event = await repository.event(claim.event_id, claim.project_id) + attempt = await repository.attempt(claim) + if event is None or attempt is None or claim_from_attempt(attempt) != claim: raise DeliveryUnavailable("outbox_delivery_unavailable") + options = self._options_for(event.event_type, event.event_version) now = await database_time(session) if attempt.stage == "completed": now = datetime.fromisoformat( json.loads(attempt.outcome_json)["receipt_completed_at"] ) - value = _outcome(claim, attempt.invoked_at, cause, now, self._options) + value = _outcome(claim, attempt.invoked_at, cause, now, options) proposed = DeliveryReceipt( claim=claim, outcome_json=_encode(value), outcome_digest=canonical_json_hash(value) ) @@ -356,7 +379,7 @@ async def finalize(self, claim: OutboxClaim, cause: FinalizationCause) -> Delive attempt.invoked_at, cause, datetime.fromisoformat(stored["receipt_completed_at"]), - self._options, + options, ) if _encode(expected) != completed.receipt.outcome_json: raise DeliveryUnavailable("outbox_delivery_unavailable") from None @@ -382,6 +405,7 @@ async def _finalize( now = await database_time(session) if event is None or attempt is None or claim_from_attempt(attempt) != claim: raise DeliveryUnavailable("outbox_delivery_unavailable") + options = self._options_for(event.event_type, event.event_version) if attempt.stage == "completed": if _receipt(claim, attempt) != receipt: raise _CompletedDuringFinalization(_receipt(claim, attempt)) @@ -397,7 +421,7 @@ async def _finalize( raise DeliveryUnavailable("outbox_delivery_unavailable") value = json.loads(receipt.outcome_json) completed = datetime.fromisoformat(value["receipt_completed_at"]) - expected = _outcome(claim, attempt.invoked_at, cause, completed, self._options) + expected = _outcome(claim, attempt.invoked_at, cause, completed, options) if ( completed > now or _encode(expected) != receipt.outcome_json diff --git a/backend/tests/checkers/external/test_policy.py b/backend/tests/checkers/external/test_policy.py index 16589bc7a..1686fcab5 100644 --- a/backend/tests/checkers/external/test_policy.py +++ b/backend/tests/checkers/external/test_policy.py @@ -23,18 +23,33 @@ from app.modules.checkers.api.external_policy import ( ExternalCheckerPolicyError, LockedWorkstreamDefault, + MAXIMUM_SELECTED_POST_EXECUTION_BUDGET_MS, + SELECTED_POST_MATERIALIZATION_BUDGET_MS, compile_external_checker_policies, + selected_post_submit_execution_budget_ms, selected_pre_submit_execution_budget_ms, ) +from app.modules.checkers.api.external import EXTERNAL_CHECKER_EXECUTION_CLEANUP_MARGIN_MS +from app.modules.artifacts.preparation import ArtifactPreparationLimits from tests.checkers.external.support import registry_spec from tests.projects.guide_compilation.helpers import result -def _entry(capability_id: str, phase: str, configuration_schema=None) -> ExternalCheckerRegistryEntry: +def _entry( + capability_id: str, + phase: str, + configuration_schema=None, + *, + deadline_ms: int | None = None, +) -> ExternalCheckerRegistryEntry: changes = {"capability_id": capability_id} if configuration_schema is not None: changes["configuration_schema"] = configuration_schema spec = registry_spec(phase).model_copy(update=changes) + if deadline_ms is not None: + spec = spec.model_copy( + update={"resources": spec.resources.model_copy(update={"deadline_ms": deadline_ms})} + ) # Revalidate after changing one digest-bound specification field. spec = type(spec).model_validate(spec.model_dump()) return ExternalCheckerRegistryEntry( @@ -203,6 +218,61 @@ async def test_selected_pre_budget_binds_ordered_deadlines_to_art_custody(): selected_pre_submit_execution_budget_ms(pre, artifact_deadline_ms=149_999) +@pytest.mark.asyncio +async def test_selected_post_maximum_fits_default_art_custody_and_rejects_overrun(): + image_deadline = ( + MAXIMUM_SELECTED_POST_EXECUTION_BUDGET_MS + - SELECTED_POST_MATERIALIZATION_BUDGET_MS + - EXTERNAL_CHECKER_EXECUTION_CLEANUP_MARGIN_MS + ) + _, policy = await compile_external_checker_policies( + _proposal(), + _Registry( + ( + _entry("acme.safe_archive", "pre_submit"), + _entry( + "acme.quality_review", + "post_submit", + deadline_ms=image_deadline, + ), + ) + ), + ) + limits = ArtifactPreparationLimits() + + assert selected_post_submit_execution_budget_ms( + policy, + artifact_deadline_ms=int(limits.total_deadline_seconds * 1000), + ) == MAXIMUM_SELECTED_POST_EXECUTION_BUDGET_MS + assert ( + limits.total_deadline_seconds + limits.cleanup_margin_seconds + < limits.reservation_ttl_seconds + ) + with pytest.raises(ExternalCheckerPolicyError, match="ART custody"): + selected_post_submit_execution_budget_ms( + policy, + artifact_deadline_ms=MAXIMUM_SELECTED_POST_EXECUTION_BUDGET_MS - 1, + ) + + too_slow = policy.model_copy( + update={ + "entries": ( + policy.entries[0].model_copy( + update={ + "registry": _entry( + "acme.quality_review", + "post_submit", + deadline_ms=image_deadline + 1, + ) + } + ), + ) + } + ) + with pytest.raises(ExternalCheckerPolicyError, match="durable worker"): + selected_post_submit_execution_budget_ms(too_slow) + + @pytest.mark.asyncio async def test_pre_configuration_is_schema_checked_and_locked_as_json(): document = { diff --git a/backend/tests/tasks/evaluation_delivery/test_completion.py b/backend/tests/tasks/evaluation_delivery/test_completion.py index c55b31ccb..d9e4ec454 100644 --- a/backend/tests/tasks/evaluation_delivery/test_completion.py +++ b/backend/tests/tasks/evaluation_delivery/test_completion.py @@ -9,6 +9,13 @@ from app.adapters.outbox import outbox_delivery, production_outbox_delivery from app.adapters.tasks import evaluation_completion_handler from app.modules.checkers.api.execution import COMPLETION_EVENT, REQUEST_EVENT +from app.modules.checkers.api.external_policy import ( + MAXIMUM_SELECTED_POST_EXECUTION_BUDGET_MS, + SELECTED_POST_DELIVERY_LEASE_SECONDS, + SELECTED_POST_FINALIZATION_MARGIN_MS, + SELECTED_POST_HANDLER_PRELUDE_MARGIN_MS, + SELECTED_POST_HANDLER_TIMEOUT_SECONDS, +) from app.modules.outbox.api import HandlerOutcome, FinalizationCause, DeliveryOptions from app.modules.outbox.registry import HandlerRegistry from app.modules.tasks.post_submit_routing.outcome import TaskPostSubmitOutcome @@ -160,7 +167,25 @@ async def test_completion_handler_committed_replay_is_exact( def test_completion_handler_is_registered_in_production_registry(): - assert (COMPLETION_EVENT, 1) in production_outbox_delivery(None)._registry.keys + delivery = production_outbox_delivery(None) + assert (COMPLETION_EVENT, 1) in delivery._registry.keys + assert delivery._options_for(COMPLETION_EVENT, 1) == DeliveryOptions() + + +def test_production_request_transport_covers_maximum_selected_execution(): + delivery = production_outbox_delivery(None) + request = delivery._options_for(REQUEST_EVENT, 1) + + assert request.handler_timeout_seconds == SELECTED_POST_HANDLER_TIMEOUT_SECONDS + assert request.lease_seconds == SELECTED_POST_DELIVERY_LEASE_SECONDS + bounded_pipeline_ms = ( + MAXIMUM_SELECTED_POST_EXECUTION_BUDGET_MS + + SELECTED_POST_HANDLER_PRELUDE_MARGIN_MS + + SELECTED_POST_FINALIZATION_MARGIN_MS + ) + assert bounded_pipeline_ms <= request.handler_timeout_seconds * 1000 + assert request.handler_timeout_seconds < request.lease_seconds <= 3600 + assert bounded_pipeline_ms < request.lease_seconds * 1000 @pytest.mark.parametrize("human", [True, False]) diff --git a/docs/spec_artifact_storage_service.md b/docs/spec_artifact_storage_service.md index b4ef29131..23b67e942 100644 --- a/docs/spec_artifact_storage_service.md +++ b/docs/spec_artifact_storage_service.md @@ -883,8 +883,8 @@ The preparation settings use the standard `WORKSTREAM_` environment prefix: | `WORKSTREAM_ARTIFACT_SCRATCH_MAXIMUM_CONCURRENCY` | `4` | Maximum concurrent preparations; cannot exceed the file limit. | | `WORKSTREAM_ARTIFACT_SCRATCH_MAXIMUM_WORKSPACE_ENTRIES` | `2000` | Maximum entries removable from one private processing workspace; it must be at least the accepted submission-ZIP entry limit. | | `WORKSTREAM_ARTIFACT_SCRATCH_MINIMUM_FREE_BYTES` | `536870912` | Free-space floor retained in addition to the next full reservation. | -| `WORKSTREAM_ARTIFACT_SCRATCH_RESERVATION_TTL_SECONDS` | `2400` | Database-independent wall-clock expiry for abandoned reservations. | -| `WORKSTREAM_ARTIFACT_PREPARATION_TOTAL_DEADLINE_SECONDS` | `1800` | Total first-pass and provider-consumption deadline. | +| `WORKSTREAM_ARTIFACT_SCRATCH_RESERVATION_TTL_SECONDS` | `3900` | Database-independent wall-clock expiry for abandoned reservations. | +| `WORKSTREAM_ARTIFACT_PREPARATION_TOTAL_DEADLINE_SECONDS` | `3400` | Total first-pass and provider-consumption deadline, aligned with the maximum selected POST execution budget. | | `WORKSTREAM_ARTIFACT_SCRATCH_CLEANUP_MARGIN_SECONDS` | `300` | Required margin between the total deadline and reservation TTL. | | `WORKSTREAM_ARTIFACT_SCRATCH_CLEANUP_INTERVAL_SECONDS` | `300` | Celery Beat cadence for the named stale-scratch cleanup task; accepted range is 1 through 86400 seconds. | | `WORKSTREAM_ARTIFACT_PENDING_WORK_SCAN_INTERVAL_SECONDS` | `60` | Celery Beat cadence for one authority-bound, database-cutoff pending-work page. | From 434b9e0d365095dc9b12722293effd1061020b60 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 10:29:26 +0100 Subject: [PATCH 160/283] [PILOT-04] Preserve delivery refusal and exact shared registry fixtures --- .../changes/pilot04-workstream-default-checker.md | 13 +++++++++++++ backend/app/modules/outbox/delivery.py | 2 -- .../projects/guide_activation/source_fixtures.py | 15 ++++++++++++++- backend/tests/selected_predecessor_fixtures.py | 3 ++- 4 files changed, 29 insertions(+), 4 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 440f844db..26678eb8e 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -318,3 +318,16 @@ The same-head native run passed the real production automatic acceptance case lineage construction. Normalize the native PostgreSQL remediation UUID to the TASK public port's Python UUID representation rather than weakening validation. Replacement proof and runtime-budget alignment remain pending. + +Runtime budget repair aligns selected POST work, ART custody and the production +request transport; only request events receive extended delivery bounds. Preserve +unknown-event refusal before invocation and authorized immutable finalization +replay by resolving bounds independently of current handler registration; the +existing claim/invocation guards still require a registered handler. Focused +unknown-registration and selected production delivery regressions are required. + +Canonical multi-project fixtures reuse only an exact already-registered immutable +checker entry via the public registry reader, asserting the full spec digest; +otherwise they publish through real Operator authority. They do not duplicate +registrations or bypass registry custody. Selected replacement test substitutions +normalize a native cause UUID at the typed fixture boundary. diff --git a/backend/app/modules/outbox/delivery.py b/backend/app/modules/outbox/delivery.py index 947952260..dec991060 100644 --- a/backend/app/modules/outbox/delivery.py +++ b/backend/app/modules/outbox/delivery.py @@ -170,8 +170,6 @@ def __init__( def _options_for(self, event_type: str, event_version: int) -> DeliveryOptions: """Resolve one registered event's immutable limits or the shared defaults.""" - if self._registry.get(event_type, event_version) is None: - raise DeliveryUnavailable("outbox_delivery_unavailable") return self._event_options.get((event_type, event_version), self._options) @asynccontextmanager diff --git a/backend/tests/projects/guide_activation/source_fixtures.py b/backend/tests/projects/guide_activation/source_fixtures.py index d357e4e43..9b09943a1 100644 --- a/backend/tests/projects/guide_activation/source_fixtures.py +++ b/backend/tests/projects/guide_activation/source_fixtures.py @@ -291,13 +291,26 @@ async def _register_external_checker_fixture(factory, spec): ExternalCheckerRegistryAuthorizationAdapter, ) from app.modules.checkers.api.external import make_external_checker_registration_request - from app.modules.checkers.external_registry import ExternalCheckerRegistryService + from app.modules.checkers.external_registry import ( + ExternalCheckerRegistryReader, ExternalCheckerRegistryService, + ) from tests.project_create_fixtures import ( grant_fixture_admin_role, seed_fixture_actor, ) async with factory() as session, session.begin(): + reader = ExternalCheckerRegistryReader(session) + existing = tuple( + entry for entry in await reader.list_entries() + if (entry.capability_id, entry.capability_version, entry.phase) + == (spec.capability_id, spec.capability_version, spec.phase) + ) + if existing: + assert len(existing) == 1 and existing[0].entry_digest == spec.spec_digest + return await reader.read_exact( + existing[0].registry_entry_id, existing[0].entry_digest, + ) profile, link = await seed_fixture_actor( session, issuer="https://external-checker-fixture.test", diff --git a/backend/tests/selected_predecessor_fixtures.py b/backend/tests/selected_predecessor_fixtures.py index 3bf7402ba..61da9ecaf 100644 --- a/backend/tests/selected_predecessor_fixtures.py +++ b/backend/tests/selected_predecessor_fixtures.py @@ -2,6 +2,7 @@ from dataclasses import replace from io import BytesIO +from uuid import UUID import json from zipfile import ZipFile @@ -122,7 +123,7 @@ async def _queued_selected_body(h, admission_id, *, cause=None) -> dict: idempotency_key=key, prepared_generation_id=new_record_id(), admission_lineage=( - replace(lineage, checker_remediation_manifest_id=cause) + replace(lineage, checker_remediation_manifest_id=UUID(str(cause))) if cause is not None else lineage ), From 2290403b68bd0ae5c3e14a2f20696a8eaf5fa558 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 10:45:04 +0100 Subject: [PATCH 161/283] [PILOT-04] Refuse unrunnable policies before approval --- .../modules/checkers/api/external_policy.py | 2 ++ .../tests/checkers/external/test_policy.py | 32 +++++++++++++++++++ .../guide_activation/source_fixtures.py | 2 +- 3 files changed, 35 insertions(+), 1 deletion(-) diff --git a/backend/app/modules/checkers/api/external_policy.py b/backend/app/modules/checkers/api/external_policy.py index 8941b418a..0cfd989f9 100644 --- a/backend/app/modules/checkers/api/external_policy.py +++ b/backend/app/modules/checkers/api/external_policy.py @@ -117,6 +117,8 @@ def validate_policy(self) -> Self: self.model_dump(mode="json", exclude={"policy_sha256"}) ): raise ExternalCheckerPolicyError("post-submit policy digest mismatch") + # Approval, admission and dispatch share this closed runnable policy. + selected_post_submit_execution_budget_ms(self) return self diff --git a/backend/tests/checkers/external/test_policy.py b/backend/tests/checkers/external/test_policy.py index 1686fcab5..bf45280ac 100644 --- a/backend/tests/checkers/external/test_policy.py +++ b/backend/tests/checkers/external/test_policy.py @@ -323,3 +323,35 @@ def test_pre_configuration_preserves_retained_empty_binding_and_rejects_duplicat duplicate = CapabilityParameter(name="threshold", value=3) with pytest.raises(ValueError, match="unique"): PreSubmissionBindingProposal.model_validate(retained | {"parameters": (duplicate, duplicate)}) + + +@pytest.mark.asyncio +@pytest.mark.parametrize("aggregate", [False, True]) +async def test_policy_compilation_refuses_unrunnable_post_images(aggregate: bool): + proposal = _proposal() + entries = [_entry("acme.safe_archive", "pre_submit")] + if aggregate: + binding = proposal.post_submit_bindings[0] + requirement = next( + item for item in proposal.requirements + if item.requirement_id == binding.requirement_id + ) + proposal = proposal.model_copy(update={ + "requirements": proposal.requirements + ( + requirement.model_copy(update={"requirement_id": "secondary_review"}), + ), + "post_submit_bindings": proposal.post_submit_bindings + ( + binding.model_copy(update={ + "requirement_id": "secondary_review", + "capability_id": "acme.secondary_review", + }), + ), + }) + entries.extend([ + _entry("acme.quality_review", "post_submit", deadline_ms=1_700_000), + _entry("acme.secondary_review", "post_submit", deadline_ms=1_700_000), + ]) + else: + entries.append(_entry("acme.quality_review", "post_submit", deadline_ms=3_600_000)) + with pytest.raises(ValueError, match="durable worker deadline"): + await compile_external_checker_policies(proposal, _Registry(entries)) diff --git a/backend/tests/projects/guide_activation/source_fixtures.py b/backend/tests/projects/guide_activation/source_fixtures.py index 9b09943a1..0fe2dac25 100644 --- a/backend/tests/projects/guide_activation/source_fixtures.py +++ b/backend/tests/projects/guide_activation/source_fixtures.py @@ -309,7 +309,7 @@ async def _register_external_checker_fixture(factory, spec): if existing: assert len(existing) == 1 and existing[0].entry_digest == spec.spec_digest return await reader.read_exact( - existing[0].registry_entry_id, existing[0].entry_digest, + UUID(str(existing[0].registry_entry_id)), existing[0].entry_digest, ) profile, link = await seed_fixture_actor( session, From 8cf1bc470b43893f5d2de35b4beccd7882a63022 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 10:16:07 +0100 Subject: [PATCH 162/283] test(pilot04): use approved external post-policy custody --- .../pilot04-workstream-default-checker.md | 29 +++++++++++++ .../authorization/post_policy/pg_support.py | 2 - .../projects/guide_activation/pg_support.py | 4 +- .../tests/projects/post_policy/test_guards.py | 10 ++--- .../projects/post_policy/test_postgresql.py | 35 ++++++++++++---- .../projects/post_policy/test_public_api.py | 11 +++-- .../projects/test_locked_policy_custody.py | 41 +++++++++++-------- 7 files changed, 92 insertions(+), 40 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 26678eb8e..864d48657 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -59,6 +59,35 @@ cleanup. ### Allowed +- Delegated TEST-only reconciliation is limited to + `tests/projects/post_policy/test_guards.py`, `test_postgresql.py`, + `test_public_api.py`, `tests/authorization/post_policy/pg_support.py`, + `tests/projects/test_locked_policy_custody.py` and the single + `activation_case` registry-spec passthrough in + `tests/projects/guide_activation/pg_support.py` (all under `backend/`). + Use the current two-argument service, saved approved external policy and + real Operator-authorized immutable registration. Preserve authority, + transaction, custody, replay, mutation and revocation assertions. Shared + `tests/checkers/post_submit/support.py` and all production files stay untouched. + Remove only mutable catalogue injection, whose owner no longer exists; + replace its purpose with exact approved-binding version/digest substitution + refusal and unchanged locked-context reads without live registry lookup. + + Purpose mapping: the obsolete `catalogue` parametrization of + `test_exact_source_and_authority_substitutions_reject_without_writes` is + removed because a mutable catalogue is no longer a service input. Its remaining + upstream/project/link/policy-hash substitutions retain their zero-write checks. + `test_post_policy_operation_preserves_finalization_without_provider_or_evaluator_calls` + now binds one genuinely registered POST entry to the approved snapshot and + refuses a substituted capability version. The old catalogue-rollout context + case is replaced by + `test_registry_substitution_blocks_activation_but_frozen_context_never_re_resolves`: + a substituted registry digest blocks activation with unchanged state; restored + identity activates; frozen and active contexts remain identical with live + registry reads forbidden. Public response comparison uses the actual saved + approved external policy. All SQL immutability, deferred receipt closure, + replay, commit rollback, revocation and HTTP admission tests remain selected. + - This record and affected current PILOT-04 architecture, roadmap and owner docs. - CHECKERS policy contracts, registry reads, default/external execution, durable attempt/result custody, post routing and composition roots. diff --git a/backend/tests/authorization/post_policy/pg_support.py b/backend/tests/authorization/post_policy/pg_support.py index 46fd772c5..07eec9e4b 100644 --- a/backend/tests/authorization/post_policy/pg_support.py +++ b/backend/tests/authorization/post_policy/pg_support.py @@ -17,7 +17,6 @@ ) from app.modules.authorization.api import ActorKind from app.modules.actors.api import ServiceIdentity -from app.modules.checkers.api.historical_post_submit import current_post_submit_catalogue from app.modules.projects.post_policy.service import PostPolicyService from app.modules.projects.api.post_policy import ( PostPolicyApproval, @@ -66,7 +65,6 @@ async def service(factory, actor): PostPolicyService( session, post_policy_authorization(session, context), - current_post_submit_catalogue(), ), request, context, diff --git a/backend/tests/projects/guide_activation/pg_support.py b/backend/tests/projects/guide_activation/pg_support.py index f58b4275c..bd7e36189 100644 --- a/backend/tests/projects/guide_activation/pg_support.py +++ b/backend/tests/projects/guide_activation/pg_support.py @@ -146,11 +146,11 @@ def activation_service(session, actor, command, grant, *, authority=True, close_ @asynccontextmanager async def activation_case( - url, *, human_review_required=True, compensated=False, contribution_awards=() + url, *, human_review_required=True, compensated=False, contribution_awards=(), post_submit_registry_spec=None ): from .source_fixtures import source_case - async with source_case(url) as (values, factory, finalization, actor, grant): + async with source_case(url, post_submit_registry_spec=post_submit_registry_spec) as (values, factory, finalization, actor, grant): await seed_selected_review_revision_inputs( factory, finalization, actor, human_review_required=human_review_required ) diff --git a/backend/tests/projects/post_policy/test_guards.py b/backend/tests/projects/post_policy/test_guards.py index c534c0ef1..4abb43339 100644 --- a/backend/tests/projects/post_policy/test_guards.py +++ b/backend/tests/projects/post_policy/test_guards.py @@ -7,7 +7,6 @@ from sqlalchemy import text from sqlalchemy.exc import DBAPIError -from app.modules.checkers.api.historical_post_submit import current_post_submit_catalogue from app.modules.projects.api.guide_proposals import GuideProposalError, GuideProposalSelection from app.modules.projects.api.post_policy import ( PostPolicyApproval, @@ -38,7 +37,7 @@ async def test_missing_approval_receipt_hits_the_specific_deferred_guard(clean_p payload = PostPolicyApproval(target=projected.target, idempotency_key=uuid4()) async with factory() as session: await session.begin() - service = PostPolicyService(session, PostAuthority(session, actor, command.project_id, grant), current_post_submit_catalogue()) + service = PostPolicyService(session, PostAuthority(session, actor, command.project_id, grant)) async def omit_only_operation(*args): # Preserve actual policy outputs and the real prepared audit decision. @@ -96,10 +95,8 @@ async def test_retained_policy_and_operation_evidence_is_immutable(clean_postgre await session.execute(text(statement)) -@pytest.mark.parametrize('change', ['upstream', 'catalogue', 'project', 'link', 'policy_hash']) +@pytest.mark.parametrize('change', ['upstream', 'project', 'link', 'policy_hash']) async def test_exact_source_and_authority_substitutions_reject_without_writes(clean_postgres_database, change): - from tests.checkers.post_submit.support import altered_catalogue - async with proposal_case(clean_postgres_database) as (values, factory, command, actor, grant): derive, projected = await prepare_post_policy(factory, command, actor, grant, service_actor(values)) payload = PostPolicyApproval(target=projected.target, idempotency_key=uuid4()) @@ -110,13 +107,12 @@ async def test_exact_source_and_authority_substitutions_reject_without_writes(cl await operate(factory, service_actor(values), command.project_id, None, 'derive', bad) else: async with factory() as session, session.begin(): - catalogue = altered_catalogue(index=8, state='disabled') if change == 'catalogue' else current_post_submit_catalogue() authority = PostAuthority(session, actor, uuid4() if change == 'project' else command.project_id, grant) caller = replace(actor, identity_link_id=uuid4()) if change == 'link' else actor if change == 'policy_hash': payload = PostPolicyApproval(target=projected.target.model_copy(update={'policy_hash': 'sha256:'+'b'*64}), idempotency_key=uuid4()) - service = PostPolicyService(session, authority, catalogue) + service = PostPolicyService(session, authority) with pytest.raises(GuideProposalError, match='authority_unavailable' if change in {'project','link'} else 'proposal_stale'): await service.approve(payload, actor=caller, request_id=uuid4()) async with factory() as session: diff --git a/backend/tests/projects/post_policy/test_postgresql.py b/backend/tests/projects/post_policy/test_postgresql.py index 64b24eb1b..c93366e45 100644 --- a/backend/tests/projects/post_policy/test_postgresql.py +++ b/backend/tests/projects/post_policy/test_postgresql.py @@ -7,12 +7,16 @@ from uuid import uuid4 +import pytest from sqlalchemy import text -from app.modules.checkers.api.historical_post_submit import current_post_submit_catalogue from app.modules.projects.api.guide_proposals import GuideProposalApproval, GuideProposalSelection from app.modules.projects.api.post_policy import PostPolicyApproval, PostPolicyDerive, PostPolicySelection from app.modules.projects.post_policy.service import PostPolicyService +from app.modules.projects.post_policy.compiler import compile_saved_post_policy +from app.modules.checkers.api.external_policy import validate_stored_external_checker_policies +from app.interfaces.project_agents import ProjectGuideCompilationResult +from tests.checkers.external.support import post_registry_spec from tests.projects.guide_compilation.helpers import service_actor from tests.projects.guide_compilation.proposals.pg_support import read_package from tests.projects.guide_compilation.proposals.test_postgresql import approve @@ -20,7 +24,7 @@ async def test_post_policy_operation_preserves_finalization_without_provider_or_evaluator_calls(clean_postgres_database, monkeypatch): - async with source_case(clean_postgres_database) as (values, factory, command, actor, grant): + async with source_case(clean_postgres_database, post_submit_registry_spec=post_registry_spec()) as (values, factory, command, actor, grant): package = await read_package(factory, command, actor, grant) upstream = await approve(factory, command, actor, grant, GuideProposalApproval(target=package.target, idempotency_key=uuid4())) @@ -44,22 +48,39 @@ async def forbidden(*args, **kwargs): receipts = [] for _ in range(2): async with factory() as session, session.begin(): - service = PostPolicyService(session, PostAuthority(session, service_actor(values), command.project_id), current_post_submit_catalogue()) + service = PostPolicyService(session, PostAuthority(session, service_actor(values), command.project_id)) receipts.append(await service.derive(payload, actor=service_actor(values), request_id=uuid4())) assert receipts[0] == receipts[1] target = receipts[0].target async with factory() as session, session.begin(): - service = PostPolicyService(session, PostAuthority(session, actor, command.project_id, grant), current_post_submit_catalogue()) + service = PostPolicyService(session, PostAuthority(session, actor, command.project_id, grant)) draft = await service.review_package(PostPolicySelection(**payload.selection.model_dump(), policy_id=target.policy_id), actor=actor, request_id=uuid4(), contribution=GuideContributionPolicyDiscovery(published_contribution_policy_port(session))) assert draft.current and draft.lifecycle_status == 'compiled' - assert draft.policy.policy_hash == target.policy_hash - assert len(draft.policy.entries) == 8 + assert draft.policy.policy_sha256 == target.policy_hash + async with factory() as session: + saved = await session.scalar(text( + "SELECT canonical_result FROM project_guide_compilations WHERE id=:id" + ), {"id": command.compilation_id}) + approved_plan = await session.scalar(text( + "SELECT effective_pre_submit_plan FROM project_guide_proposal_approvals WHERE operation_id=:id" + ), {"id": upstream.operation_id}) + policies = validate_stored_external_checker_policies(approved_plan) + assert draft.policy == policies.post_submit + assert len(draft.policy.entries) == 1 + assert draft.policy.entries[0].registry.capability_id == post_registry_spec().capability_id + saved_result = ProjectGuideCompilationResult.model_validate(saved) + changed_result = saved_result.model_copy(update={ + "post_submit_bindings": tuple(binding.model_copy(update={"capability_version": "v9.9.9"}) + for binding in saved_result.post_submit_bindings), + }) + with pytest.raises(ValueError, match="changes a required binding"): + compile_saved_post_policy(result=changed_result, policies=policies) assert draft.proposal.target == package.target approval = PostPolicyApproval(target=target, idempotency_key=uuid4()) approved = [] for _ in range(2): async with factory() as session, session.begin(): - service = PostPolicyService(session, PostAuthority(session, actor, command.project_id, grant), current_post_submit_catalogue()) + service = PostPolicyService(session, PostAuthority(session, actor, command.project_id, grant)) approved.append(await service.approve(approval, actor=actor, request_id=uuid4())) assert approved[0] == approved[1] async with factory() as session: diff --git a/backend/tests/projects/post_policy/test_public_api.py b/backend/tests/projects/post_policy/test_public_api.py index 3da228a82..3200f19ef 100644 --- a/backend/tests/projects/post_policy/test_public_api.py +++ b/backend/tests/projects/post_policy/test_public_api.py @@ -7,7 +7,7 @@ from app.main import create_app from app.modules.projects.post_policy.compiler import compile_saved_post_policy -from app.modules.checkers.api.historical_post_submit import current_post_submit_catalogue +from app.modules.checkers.api.external_policy import validate_stored_external_checker_policies from app.interfaces.project_agents import ProjectGuideCompilationResult from tests.projects.guide_compilation.proposals.pg_support import revoke_review_grant, seed_review_actor from tests.projects.guide_compilation.proposals.public_support import proposal_client, proposal_path @@ -81,12 +81,15 @@ async def test_public_policy_body_separate_approval_replay_and_revocation( assert body["target"]["upstream"]["operation_id"] == str(approval_id) async with factory() as session: saved = await session.scalar(text("SELECT canonical_result FROM project_guide_compilations WHERE id=:id"), {"id":command.compilation_id}) + approved_plan = await session.scalar(text( + "SELECT effective_pre_submit_plan FROM project_guide_proposal_approvals WHERE operation_id=:id" + ), {"id": approval_id}) expected = compile_saved_post_policy( - project_id=command.project_id, guide_version=body["target"]["proposal"]["guide_version"], - result=ProjectGuideCompilationResult.model_validate(saved), catalogue=current_post_submit_catalogue(), + result=ProjectGuideCompilationResult.model_validate(saved), + policies=validate_stored_external_checker_policies(approved_plan), ) assert body["policy"] == expected.model_dump(mode="json") - assert body["target"]["policy_hash"] == expected.policy_hash + assert body["target"]["policy_hash"] == expected.policy_sha256 assert await session.scalar(text("SELECT count(*) FROM project_post_policy_operations WHERE kind='derive'")) == 1 headers = {"Idempotency-Key": str(uuid4())} payload = {"target": body["target"]} diff --git a/backend/tests/projects/test_locked_policy_custody.py b/backend/tests/projects/test_locked_policy_custody.py index f2e1b61d3..6e47f1a58 100644 --- a/backend/tests/projects/test_locked_policy_custody.py +++ b/backend/tests/projects/test_locked_policy_custody.py @@ -204,37 +204,42 @@ async def test_context_read_does_not_allow_activated_proposal_mutations(clean_po ) -async def test_catalogue_rollout_preserves_context_but_blocks_new_activation( +async def test_registry_substitution_blocks_activation_but_frozen_context_never_re_resolves( clean_postgres_database, monkeypatch, ): import pytest from app.modules.projects.api.guide_proposals import GuideProposalError - from app.modules.projects import post_submit_policy - from app.modules.projects.post_policy import custody - from tests.checkers.post_submit.support import altered_catalogue + from app.modules.checkers.external_registry import ExternalCheckerRegistryReader + from tests.checkers.external.support import post_registry_spec from tests.projects.guide_activation.pg_support import activation_case - from tests.authorization.guide_activation.pg_support import ( - activate, activation_state, service, - ) + from tests.authorization.guide_activation.pg_support import activate, activation_state - async with activation_case(clean_postgres_database) as ( - factory, command, actor, *_ - ): - newer = altered_catalogue(index=8, state="disabled") - assert newer.manifest_sha256 != command.target.proposal.post_catalogue_manifest_hash + async with activation_case( + clean_postgres_database, post_submit_registry_spec=post_registry_spec() + ) as (factory, command, actor, *_): before = await activation_state(factory) - with pytest.raises(GuideProposalError): - async with service(factory, actor) as (_, owner, request_id, _): - owner.post_catalogue = newer - await owner.activate(command, actor=actor, request_id=request_id) + read_exact = ExternalCheckerRegistryReader.read_exact + + async def substituted(owner, *args, **kwargs): + current = await read_exact(owner, *args, **kwargs) + return current.model_copy(update={"entry_digest": "sha256:" + "b" * 64}) + + with monkeypatch.context() as patch: + patch.setattr(ExternalCheckerRegistryReader, "read_exact", substituted) + with pytest.raises(GuideProposalError, match="proposal_stale"): + await activate(factory, actor, command) assert await activation_state(factory) == before receipt = await activate(factory, actor, command) async with factory() as session, session.begin(): original = await ProjectLockedPolicyRepository(session).lock_locked_policy_context( frozen_request(receipt) ) - monkeypatch.setattr(post_submit_policy, "current_post_submit_catalogue", lambda: newer) - monkeypatch.setattr(custody, "current_post_submit_catalogue", lambda: newer) + + async def forbidden(*args, **kwargs): + raise AssertionError("locked policy context consulted live registry metadata") + + monkeypatch.setattr(ExternalCheckerRegistryReader, "read_exact", forbidden) + monkeypatch.setattr(ExternalCheckerRegistryReader, "read_identity", forbidden) async with factory() as session, session.begin(): owner = ProjectLockedPolicyRepository(session) assert await owner.lock_locked_policy_context(frozen_request(receipt)) == original From 590e1df1ec66e9aac2aa3d42d23c5bdf41ae2092 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 10:22:49 +0100 Subject: [PATCH 163/283] test(pilot04): expect canonical registry readiness refusal --- backend/tests/projects/test_locked_policy_custody.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/tests/projects/test_locked_policy_custody.py b/backend/tests/projects/test_locked_policy_custody.py index 6e47f1a58..5b304aa88 100644 --- a/backend/tests/projects/test_locked_policy_custody.py +++ b/backend/tests/projects/test_locked_policy_custody.py @@ -226,7 +226,7 @@ async def substituted(owner, *args, **kwargs): with monkeypatch.context() as patch: patch.setattr(ExternalCheckerRegistryReader, "read_exact", substituted) - with pytest.raises(GuideProposalError, match="proposal_stale"): + with pytest.raises(GuideProposalError, match="approval_blocked"): await activate(factory, actor, command) assert await activation_state(factory) == before receipt = await activate(factory, actor, command) From 72768c1065b2de1016eaaceb05bee6746b7089fc Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 10:39:32 +0100 Subject: [PATCH 164/283] docs(pilot04): record focused post-policy caller proof --- .../changes/pilot04-workstream-default-checker.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 864d48657..895688457 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -258,6 +258,20 @@ intermediate-wait regression. | Default behavior and warnings | `pytest -q backend/tests/checkers/default/test_contract.py backend/tests/checkers/default/test_execution.py backend/tests/checkers/external/test_selected_pre_submit.py -m 'not postgres_schema_contract'` | 30 passed. The manifest and executable behavior retain exactly four ordered blockers; empty summary and attestation produce warnings without changing eligibility. | Full required checks remain on the final reconciled head. | | End-to-end replacement | `run_selected_end_to_end_probe.py` through the isolated runner, `/tmp/pilot04-selected-e2e10.log` and `.json`, using platform manifest `sha256:c664d8d85d6dfcded31710223c8d91441548e5445f0aa9b59d246fc464a129ef` | PASS on PostgreSQL 16/schema 0037 with database/role/MinIO/workspace cleanup complete. Real MinIO PRE and the Rust/runc image commit one Submission, `evaluation_pending` and dispatch, then actual Submission/ART POST evidence. A secret finding leaves a separate Task `in_progress` with no Submission. Service loss retains `implementation_unavailable`; restart uses a fresh upload and independent ART verification, records a completed successor generation and commits exactly one later Submission/dispatch. | This local proof uses explicit `runc`/`docker-dev`; hosted CI must exercise its configured runtime and the final reconciled head. | + +| Delegated current post-policy callers | Exact `c1195f8b2d55bc02976efe41d6052bca8b975a66`: six focused PostgreSQL cases in `/tmp/pilot04-post-policy-c119-native-callers.log` and producer metadata `.json`; scoped Ruff and `git diff --check` | 6 passed in 104.91s, schema `0036_selected_checker_flow`, database/role cleanup complete. The registered digest substitution refuses activation with unchanged activation facts; restored registration activates, and active/frozen reads never consult registry. Public approval/replay/revocation and commit rollback, plus canonical AUTH derive/read/approve evidence pass. | Local PostgreSQL 16.15 uses an owned 512 MiB tmpfs and 256 MiB memory bound with fsync/synchronous_commit/full_page_writes enabled. This test-only proof uses local ART and scripted setup, not MinIO or runtime evaluation; final combined source and hosted CI remain separately verified. | + +The registered-one-entry projection and exact approved-binding version rejection +also passed at `397e8812c`, with that test/source blob unchanged at `c1195f8b2`. +The companion registry-refusal test initially expected `proposal_stale`; its +actual canonical readiness outcome is `approval_blocked`, corrected and verified +in the six-case proof above. Two broader selections reached their unchanged +240-second child budget (physical-disk reset IO, then a selection too large for +that focused budget); both cleaned their databases/roles and are not reported as +complete module passes. All surviving tests remain in their canonical CI lanes. +The delegated reconciliation changes no capability or public exposure, so it has +no independent roadmap change beyond the parent cutover's documented scope. + ## Reconciliation - Current-source reconciliation: implementation starts at PR538 head From 6e8edad3c78b6dc6052c676c911da3a985f678f3 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 10:48:23 +0100 Subject: [PATCH 165/283] [PILOT-04] Close pre-check policy execution budget --- .../pilot04-workstream-default-checker.md | 11 ++++++++ .../modules/checkers/api/external_policy.py | 3 +++ .../tests/checkers/external/test_policy.py | 25 +++++++++++++++++++ 3 files changed, 39 insertions(+) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 895688457..43e30bfa7 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -374,3 +374,14 @@ checker entry via the public registry reader, asserting the full spec digest; otherwise they publish through real Operator authority. They do not duplicate registrations or bypass registry custody. Selected replacement test substitutions normalize a native cause UUID at the typed fixture boundary. + +Static selected policy budgets are validated before compilation and approval. +POST rejects both a single excessive image and an excessive aggregate; PRE +rejects aggregate work beyond the platform custody ceiling. Lower deployment +limits still produce a recoverable infrastructure refusal at runtime. Focused +policy, outbox and transport verification passed 56 tests in the local locked +environment; this is not final-head full-suite CI evidence. Native 434b9e0d3 +passed replacement replay, unknown registration and automatic acceptance; its +two cause guards stopped at a native UUID fixture boundary. Normalize that +fixture identifier only, preserving the strict production registry reader. +Database, role and MinIO cleanup completed; cause-guard rerun remains pending. diff --git a/backend/app/modules/checkers/api/external_policy.py b/backend/app/modules/checkers/api/external_policy.py index 0cfd989f9..651e51f9a 100644 --- a/backend/app/modules/checkers/api/external_policy.py +++ b/backend/app/modules/checkers/api/external_policy.py @@ -100,6 +100,9 @@ def validate_policy(self) -> Self: self.model_dump(mode="json", exclude={"policy_sha256"}) ): raise ExternalCheckerPolicyError("pre-submit policy digest mismatch") + selected_pre_submit_execution_budget_ms( + self, artifact_deadline_ms=MAXIMUM_SELECTED_PRE_EXECUTION_BUDGET_MS + ) return self diff --git a/backend/tests/checkers/external/test_policy.py b/backend/tests/checkers/external/test_policy.py index bf45280ac..4893ce7e1 100644 --- a/backend/tests/checkers/external/test_policy.py +++ b/backend/tests/checkers/external/test_policy.py @@ -355,3 +355,28 @@ async def test_policy_compilation_refuses_unrunnable_post_images(aggregate: bool entries.append(_entry("acme.quality_review", "post_submit", deadline_ms=3_600_000)) with pytest.raises(ValueError, match="durable worker deadline"): await compile_external_checker_policies(proposal, _Registry(entries)) + + +@pytest.mark.asyncio +async def test_policy_compilation_refuses_pre_images_exceeding_platform_custody(): + proposal = _proposal() + binding = proposal.pre_submit_bindings[0] + requirement = proposal.requirements[0] + proposal = proposal.model_copy(update={ + "requirements": proposal.requirements + ( + requirement.model_copy(update={"requirement_id": "secondary_archive"}), + ), + "pre_submit_bindings": proposal.pre_submit_bindings + ( + binding.model_copy(update={ + "requirement_id": "secondary_archive", + "capability_id": "acme.secondary_archive", + }), + ), + }) + entries = [ + _entry("acme.safe_archive", "pre_submit", deadline_ms=3_600_000), + _entry("acme.secondary_archive", "pre_submit", deadline_ms=3_600_000), + _entry("acme.quality_review", "post_submit"), + ] + with pytest.raises(ValueError, match="ART custody deadline"): + await compile_external_checker_policies(proposal, _Registry(entries)) From 11bd7bda07a13408f9f15d68d990d3270582aa88 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 10:51:40 +0100 Subject: [PATCH 166/283] [PILOT-04] Reconcile selected successor tests and capability ledger --- .../pilot04-workstream-default-checker.md | 9 ++++ backend/tests/checkers/post_submit/support.py | 6 +++ .../test_submission_predecessor_custody.py | 4 +- docs/roadmap_status.md | 47 ++++++++++++------- 4 files changed, 46 insertions(+), 20 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 43e30bfa7..d5eb19076 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -385,3 +385,12 @@ passed replacement replay, unknown registration and automatic acceptance; its two cause guards stopped at a native UUID fixture boundary. Normalize that fixture identifier only, preserving the strict production registry reader. Database, role and MinIO cleanup completed; cause-guard rerun remains pending. + +The selected cause-guard rerun reached the intended SQL immutability denial +(SQLSTATE 55000) but exposed two superseded test assumptions: successor requests +were rebuilt with the historical DTO, and mutation refusal was caught as an +integrity violation instead of DBAPIError. Use the exact selected constructor +for selected fixtures and retain the exact 55000 assertion. No production guard +or database constraint changes are part of this test repair. Reconcile roadmap +claims to selected hidden delivery, keeping public intake and hosted isolation +proof explicitly outside the delivered surface. Final guard rerun is required. diff --git a/backend/tests/checkers/post_submit/support.py b/backend/tests/checkers/post_submit/support.py index 2b21341fe..1ac4b387e 100644 --- a/backend/tests/checkers/post_submit/support.py +++ b/backend/tests/checkers/post_submit/support.py @@ -20,6 +20,10 @@ PostSubmitPolicyEntry, ) from app.modules.checkers.api.post_submit import make_post_submit_request +from app.modules.checkers.api.selected_post_submit import ( + SelectedPostSubmissionEvaluationRequest, + make_selected_post_submit_request, +) from tests.historical_checker_metadata import historical_post_submit_catalogue HASH = "sha256:" + "a" * 64 @@ -126,4 +130,6 @@ def request(*, snapshot=None, project_id=PROJECT): def change_request(source, **changes): fields = source.model_dump(exclude={"request_sha256"}) fields.update(changes) + if type(source) is SelectedPostSubmissionEvaluationRequest: + return make_selected_post_submit_request(**fields) return make_post_submit_request(**fields) diff --git a/backend/tests/test_submission_predecessor_custody.py b/backend/tests/test_submission_predecessor_custody.py index 34391bce8..995844829 100644 --- a/backend/tests/test_submission_predecessor_custody.py +++ b/backend/tests/test_submission_predecessor_custody.py @@ -12,7 +12,7 @@ import pytest from sqlalchemy import text -from sqlalchemy.exc import IntegrityError +from sqlalchemy.exc import DBAPIError, IntegrityError from starlette.requests import Request from app.api.deps.authorization import compose_hidden_submission_creation_command @@ -651,7 +651,7 @@ async def test_sql_selected_pre_reservation_and_admission_reject_foreign_routed_ assert denied.value.orig.sqlstate == "23514" assert await _snapshot(local) == before with pytest.raises( - IntegrityError, match="selected PRE request custody is immutable" + DBAPIError, match="selected PRE request custody is immutable" ) as immutable: async with local.factory.begin() as session: await session.execute( diff --git a/docs/roadmap_status.md b/docs/roadmap_status.md index d9c17e240..ddeccddb8 100644 --- a/docs/roadmap_status.md +++ b/docs/roadmap_status.md @@ -278,9 +278,9 @@ cannot be reused as post-submission review-gate evidence. See the | Task readiness and claim | **Foundation with grant-backed manager and contributor commands** | Task records, assignments and locked work context; guide-bound ContributionPolicyVersion locked before `READY` and copied to TaskAssignment; detached project/guide display; public project-scoped ready, management and operational queues with distinct current grant authority and signed bounded live pagination; public contributor/management detail with exact project and assignment authority; separate current live work-context projections with exact receipt-selected review/revision/ContributionPolicy identities and no obsolete economic fields; explicit management/operational/audit locked-context projections using one historical resolver, with separate public manager, system-Operator and Audit Authority access; immutable contributor/management requirements using one historical translator, with public exact Contributor and Manager authority; bounded public Audit Authority lifecycle evidence with atomic project/task scoping and exact transition references; public manager create/screen/release use exact covered Project Manager authority, atomic audit and replay; claim/start/contributor context use exact-project Submitter grants; assigned context lists documents only and distinct `task.guide.read` verifies locked originals before delivery; separate manager context and system-Operator start; durable claim/start retry receipts with fresh authority and exact assignment checks; hidden exact-assignment invalidation with committed cause verification, delivery fencing, exact fixed-service authority and decision-bound immutable release evidence; atomic authority-loss publication and registered prefork delivery; PILOT-14 exposes both locked contribution types in ready rows and Contributor detail for active exact-project Submitters or Reviewers as unpaid or exact instrument/unit/quantity awards, without Finance binding facts; claim/start remain Submitter-only | Public intake cutover follows evaluation/remediation prerequisites | | Bulk task source custody | **Public backend source foundation delivered** | PILOT-02A provides covered-PM project-bound declaration, canonical 1..500-row JSON upload with exact SHA/count, fresh-authority replay, source status and independently verified download using existing ART custody; linear migration and public-route PostgreSQL/MinIO custody, rollback, concurrency and recovery tests pass | Atomic DRAFT import, separate explicit batch screen/release and CLI conversion; issue 489 remains open | | Contributor artifact preparation | **Hidden and proven** | One outer ZIP; bounded scratch inspection; canonical manifest; shared evaluation-content capacity and exact locked-policy checks before attempts or durable intent; platform and project prechecks; unchanged-work rejection; durable put intent; verification; capacity-charged ready admission; hidden final handoff validates the exact activated historical guide through owner ports | Complete the later public admission-only cutover | -| Pre-submission intake checking | **Hidden with approved-guide lineage and same-request feedback; unselected default/external components delivered** | Separate versioned pre-submission catalogue, locked effective-plan compilation, platform/project checks during continuous preparation, and one internal phase command covering execution/replay with the JSON precheck removed; the mounted authorized hidden route returns exact ordered bounded feedback for blocking findings before Submission creation while remaining absent from OpenAPI. ARCH-03D connects approved-guide lineage through the final durable handoff. PILOT-04 publishes the strict normalized external pre-submit identity, immutable authorized digest-pinned registry, unselected Rust service/SDK and ART callback grant for verified read-only material, plus one unselected versioned Workstream default checker with exactly the four approved blocking outcomes and warning-only summary/attestation absence | Bind and route every required digest-pinned project pre-image only after verified ZIP identity/manifest; compose the default checker and require all prechecks to pass before the caller-owned atomic Submission/`evaluation_pending`/initial-dispatch transaction. Work findings create no Submission and leave the task `in_progress`; infrastructure failures remain recoverable. Bind approved policies, prove F-020 recovery and public intake integration, then remove both legacy catalogues without a parallel path | +| Pre-submission intake checking | **Selected hidden flow with approved-guide lineage and bounded feedback** | One versioned Workstream default checker enforces safe ZIP/resource bounds, independently verified digest/manifest, high-confidence secret rejection and unchanged-work rejection. Missing summary/attestation produces warnings only. Approved project PRE checks are immutable digest-pinned images run by the Rust service on verified read-only ART material. Durable selected custody takes TASK before CHECKERS; only a complete pass grants admission to the existing atomic Submission transaction. Both executable catalogues are removed | Public contributor upload/finalize and CLI submit/status remain PILOT-12. Work findings create no Submission and preserve in_progress; infrastructure failures retain recoverable outcomes. Local Rust/MinIO proof uses runc/docker-dev; hosted gVisor integration and representative limits remain | | Immutable Submission creation | **Hidden foundation; public packet creation retired** | Contributor preparation authority; durable pre-submit reservation and exact completed-evidence recovery without rerunning checks; atomic admission consumption; TASK-owned admission-backed creation with exact assignment ContributionPolicyVersion, locked policy lineage and service/database checked-packet custody; fixed-service artifact binding; replay/concurrency/rollback proof | Finish downstream evaluation and the canonical public integration. The retained submission-list GET is not a usable creation POST | -| Post-submission evaluation and governed outcome | **Hidden authorized outcomes; external contract, registry and unselected runtime mechanism delivered; automatic production routing unavailable** | PILOT-04 supplies normalized external checker contracts, an immutable authorized OCI-digest registry, and an unselected Rust service/SDK with a typed Unix-socket adapter and ART callback grant, without product composition or policy authority. Exact ART input/output custody, durable current checker results, actual input/execute/finalize receipts, TASK request/source reservation and B7 hidden request delivery; 04E3A gives that hidden handler the existing Celery ART provider lease with invocation-scoped scratch; 04E2-B binds real route AUTH, source publication and complete true/false success consequences with database closure, shared audit/outbox and exact replay; B8 wires hidden completion delivery to the committed operation; 04F1 verifies current completed failure evidence and 04F2 routes exact current contributor-correctable results to `needs_revision` under both policy modes with no REV/CON effect. | Bind and execute digest-pinned external checkers with replacement proof before removing the superseded catalogue; registry and hidden runtime foundations alone do not activate execution. Complete exact-cause replacement intake and setup-fault/Operator recovery before 04E3 production registration and false-guide activation. True handoff has no REV/CON prerequisite. No public intake or live human review/revision is supplied. | +| Post-submission evaluation and governed outcome | **Selected hidden external execution and production completion routing** | Immutable approved image bindings, Rust service/SDK and typed ART callback grants; exact verified input/output custody, durable current results and phase authority. Production outbox request/completion handlers run selected images and preserve exact restart/replay. True-policy success reaches review_pending; false-policy success invokes shared authorized FinalAcceptance and atomically creates the submitter ContributionRecord and complete frozen award set. Contributor-correctable failures retain exact remediation causes; Operator retry retains fresh authority and no spent contributor round | Public intake remains PILOT-12; live human review and contributor revision surfaces remain separate. Uncovered required guide capabilities block activation; registration alone cannot repair an approved generation. True handoff has no REV/CON prerequisite. No deployed runtime or exhaustive public journey claim | | Review queue and lease | **Hidden persistence foundation** | Queue/admission idempotency and ReviewLease/preference persistence; complete unavailable REV action/principal catalogue and typed AUTH contracts; ART-07A1 metadata-only packet contract and REV-03B immutable normalized packet persistence with live ingest custody; REV-04A Review/finding/resolution and completed request storage | Future resolver proof; canonical admission from `allow_review`; claim/lease/packet authority; lease copies the Submission-stamped policy version with no CON lookup | | Review decision and revision | **Hidden acceptance core; runtime planned** | Review/revision policy identities and mutation authority, with `requires_second_review` fixed false through typed and database boundaries; REV-04A immutable Review storage; REV-04B source storage; REV-04C hidden source-neutral FinalAcceptance/TASK/CON participant; approved same-task revision-rebase semantics | ARCH-04E2-B supplies mandatory source AUTH and complete database/audit/outbox closure for hidden automated outcomes. Human decision authority/composition, revision preparation, replay and recovery remain | | Contribution and compensation truth | **Hidden shared participant plus public policy administration** | ContributionPolicyVersion persistence; lifecycle-audit participant; adapter bindings; public Finance policy administration; REV-04B shared acceptance source storage; CON-03C immutable ContributionRecord/CompensationAward storage; obsolete guide-keyed payment storage and task-local payment fields removed; CON-07 source-neutral submitter participant and complete award sets; REV-04C composes it with FinalAcceptance/TASK effects in the caller transaction; 04F2 checker remediation creates no contribution or award | ARCH-04E2-B supplies exact routing authority/evidence, complete-set database closure and audit/outbox under REV-12A4A. Hidden B8 completion delivery, 04F3 exact-cause replacement and 04F4 hidden retry are implemented; manager-visible setup-fault hold and live composition remain before production consumption. Only actual Reviews create reviewer records. Obligation/root/ordinal custody remains deferred until fulfillment activation; no public recognition or fulfillment route is live | @@ -553,7 +553,7 @@ cannot be reused as post-submission review-gate evidence. See the post-submit proposals, then projects the sufficiency and artifact-policy components and atomically finalizes the setup at draft output. A blocked guide ends at sufficiency evidence, with no policy projection. Its canonical result - retains exact supported catalogue matches and one evidence-linked engineering + retains exact registered digest-pinned image matches and one evidence-linked engineering suggestion for each required missing pre-submit or post-submit check. Fully covered projects need no suggestions. POL-05B exposes the complete POL-05A review package; AUTH-12F4 supplies exact manager authority; suggestions cannot register or activate a checker. Runtime, model/provider and instructions are independently @@ -663,8 +663,10 @@ owns implementation sequencing. The existing checker phase service supports hidden pre-submit execution/replay and hidden durable post-submit execution. Exact post-submit service authority and the hidden 04E2-B authorized outcome operation are implemented. 04F2 adds the hidden policy-independent remediation handoff, 04F3 adds -hidden exact-cause replacement intake and 04F4 adds hidden Operator retry; automatic production delivery and public -acceptance remain unavailable. +hidden exact-cause replacement intake and 04F4 adds hidden Operator retry. PILOT-04 +registers selected request and completion delivery in production composition; passing +false-policy results use the shared atomic acceptance operation. Public contributor +upload/finalize remains PILOT-12 work. Live setup does not wait for downstream task/checker execution. The [first complete contributor milestone](../.commitrail/initiatives/WS-ARCH-001/planning/PLAN.md#first-complete-contributor-milestone) @@ -727,7 +729,7 @@ The broader v0.1 sequence below retains later scope: an explicitly implemented model judge. A structural presence check cannot stand in for a required substantive quality evaluation. Unsupported required evaluators block the affected guide until implemented and included in a new - approved catalogue-bound generation. Infrastructure retries and project + approved image-bound generation. Infrastructure retries and project setup faults are not contributor failures; `allow_review` is not acceptance. **For the first false-policy acceptance path:** consume the delivered TASK 04E1A source facts through the delivered REV-04B source FK; TASK request/source-identity reservation (04E1B-A) and the hidden @@ -824,13 +826,14 @@ Production registration remains unavailable. ARCH-04B adds hidden exact Submission materialization through TASK's immutable read port and ART's consumed admission. Local/MinIO input is independently reread, verified and projected through canonical bounded scratch. ARCH-04D2 supplies exact leased input authority before and after I/O. -Public intake and automatic checker dispatch remain unavailable. +Public intake remains unavailable; selected hidden Submission creation durably +dispatches the initial post-check request. ARCH-04B2 adds hidden typed checker-output `store` and byte-free `recover(selector)` operations, per-slot preparation caps, generic put and verification reuse, and flush-only immutable verified binding. Controlled -nonempty slots prove ART mechanics only; the current structural catalogue has -zero slots. ARCH-04C supplies CHECKERS reservation/currentness; ARCH-04D2 supplies +nonempty slots originally proved ART mechanics only. The selected external +flow now verifies image-declared outputs through the same ART custody. ARCH-04C supplies CHECKERS reservation/currentness; ARCH-04D2 supplies execute/finalize authority. Output write/bind authority remains unavailable. Public intake is not activated. ## Critical Dependency Map @@ -1009,11 +1012,16 @@ proof. The [offline gVisor build spike](engineering/pilot00-gvisor-offline-build-spike.md) selects a sealed-cache Kaniko builder plus a separate gVisor oracle sandbox for PILOT-04/PILOT-06. PILOT-04 now has a normalized external request/result -contract, immutable authorized digest-pinned registry, hidden unselected Rust -service/SDK with a typed Unix-socket adapter and request-bound ART grant, and an -unselected versioned Workstream default checker with its exact four blocking -outcomes. Product runtime composition and policy routing remain absent. The spike proves only the -included small Linux fixture; +contract, immutable authorized digest-pinned registry, selected Rust service/SDK +with a typed Unix-socket adapter and request-bound ART grant, and one versioned +Workstream default checker with exactly four blocking outcomes. Both executable +catalogues are removed. Verified ZIP/default checks precede approved external PRE +images; only a complete pass permits immutable Submission creation and durable +POST dispatch. Production completion routes true-policy success to review_pending +and false-policy success through shared atomic acceptance. Default failures prevent +Submission creation; infrastructure failures retain recoverable outcomes. Local +Rust/MinIO integration evidence uses runc/docker-dev, not gVisor, and the contributor +upload/CLI surface remains PILOT-12 work. The spike proves only the included small Linux fixture; representative task sizing, hosted hardening and macOS fallback evidence remain. @@ -1082,18 +1090,21 @@ remaining trace sequence is: plus the REV-04C hidden FinalAcceptance/TASK/CON participant, support the additional false-path acceptance-source AUTH custody and activation prerequisites. Both branches have delivered request reservation `04E1B-A` and AUTH preparation `04E2-A`, followed by delivered authorized success outcomes `04E2-B` and hidden completion - delivery `04E1B-B8`. Production registration/live composition `04E3` remains pending; true + delivery `04E1B-B8`. PILOT-04 supplies selected production registration and worker + composition; true routing proceeds after its own prerequisites without shared acceptance. 04F1 supplies verified failure evidence, 04F2 supplies the hidden remediation handoff, 04F3 supplies hidden exact-cause replacement intake, and 04F4 adds hidden Operator retry. Manager-visible setup-fault hold remains. The mandatory [04D1 canonical material custody](../.commitrail/initiatives/WS-ARCH-001/WS-ARCH-001-04D1.md) closes the three-field ART database guarantee before authority activation. - ARCH-04C accepts the exact empty output set from the current structural - catalogue; nonempty 04B2 test slots do not claim a live evaluator capability. + ARCH-04C retains immutable output-set custody; selected external image outputs + use the same verified ART ownership rather than a structural catalogue. AUTH-OUTBOX-02 delivers shared live authority, phase audit custody and Celery delivery/recovery scans over CON-02B. Delivery termination is bounded by a - 300-second hard limit under prefork. + per-event hard limit under prefork: selected POST requests reserve bounded + execution and finalization time within the one-hour lease; other events keep + their existing shorter limit. ARCH-03C2 enforces a dedicated non-eager prefork delivery queue. ARCH-04E1A proves source storage and detached contracts only; its false scalar proof does not make false activation available. Automatic `04E` delivery still needs From 2d111d8c753751e89010d7a632aacecf11b68eb5 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 10:57:26 +0100 Subject: [PATCH 167/283] [PILOT-04] Align Celery process containment with checker budget --- .../changes/pilot04-workstream-default-checker.md | 11 +++++++++++ backend/app/workers/outbox_topology.py | 14 +++++++++++--- backend/tests/outbox/test_delivery_topology.py | 10 ++++++++-- backend/tests/outbox/test_worker_postgresql.py | 11 ++++++++++- .../tasks/evaluation_delivery/test_completion.py | 8 ++++++++ docs/operations_authorization_service.md | 15 ++++++++++----- 6 files changed, 58 insertions(+), 11 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index d5eb19076..72e48042c 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -89,6 +89,9 @@ cleanup. replay, commit rollback, revocation and HTTP admission tests remain selected. - This record and affected current PILOT-04 architecture, roadmap and owner docs. +- The existing OUTBOX prefork topology and its delivery task hard bound, with + topology and real process-containment regressions, to honor the selected + request budget without changing event-specific owner deadlines or selectors. - CHECKERS policy contracts, registry reads, default/external execution, durable attempt/result custody, post routing and composition roots. - ART preparation, verified-material callback, evidence, admission and @@ -394,3 +397,11 @@ for selected fixtures and retain the exact 55000 assertion. No production guard or database constraint changes are part of this test repair. Reconcile roadmap claims to selected hidden delivery, keeping public intake and hosted isolation proof explicitly outside the delivered surface. Final guard rerun is required. + +Real Celery transport must cover selected POST work, not just the asynchronous +owner timeout. Its fixed prefork hard bound is now the maximum lease plus a +60-second shutdown margin (3660 seconds), with exact task/message validation +to reject shorter or longer overrides. Per-event bounds remain selected request +3520/3600 and ordinary events 240/300. Preserve the existing scaled real-prefork +kill/reap/UNKNOWN regression while scaling both the installed test bound and its +entry guard; no production duration is shortened for verification. diff --git a/backend/app/workers/outbox_topology.py b/backend/app/workers/outbox_topology.py index c76f863e8..3f18fcf22 100644 --- a/backend/app/workers/outbox_topology.py +++ b/backend/app/workers/outbox_topology.py @@ -6,8 +6,12 @@ from celery.concurrency.prefork import TaskPool from celery.exceptions import WorkerShutdown from celery.signals import worker_init +from app.modules.checkers.api.external_policy import SELECTED_POST_DELIVERY_LEASE_SECONDS -OUTBOX_HARD_LIMIT_SECONDS = 300 +OUTBOX_PROCESS_SHUTDOWN_MARGIN_SECONDS = 60 +OUTBOX_HARD_LIMIT_SECONDS = ( + SELECTED_POST_DELIVERY_LEASE_SECONDS + OUTBOX_PROCESS_SHUTDOWN_MARGIN_SECONDS +) OUTBOX_QUEUE = "workstream.outbox" OUTBOX_DELIVERY_TASK = "workstream.outbox.deliver_event" _validated_parent: int | None = None @@ -36,6 +40,10 @@ def require_outbox_worker(task): or task.request.called_directly ): raise RuntimeError("OUTBOX delivery requires a validated prefork worker") - hard_limit = (task.request.timelimit or (None, None))[0] or task.time_limit - if type(hard_limit) not in (int, float) or not 0 < hard_limit <= OUTBOX_HARD_LIMIT_SECONDS: + message_limit = (task.request.timelimit or (None, None))[0] + if ( + type(task.time_limit) is not int or task.time_limit != OUTBOX_HARD_LIMIT_SECONDS + or message_limit is not None + and (type(message_limit) is not int or message_limit != OUTBOX_HARD_LIMIT_SECONDS) + ): raise RuntimeError("OUTBOX delivery requires a bounded hard time limit") diff --git a/backend/tests/outbox/test_delivery_topology.py b/backend/tests/outbox/test_delivery_topology.py index 13687d9a0..822c67667 100644 --- a/backend/tests/outbox/test_delivery_topology.py +++ b/backend/tests/outbox/test_delivery_topology.py @@ -68,7 +68,8 @@ def test_validated_prefork_child_enters(monkeypatch): topology.validate_outbox_worker(configured) monkeypatch.setattr(topology.os, "getppid", os.getpid) topology.require_outbox_worker(SimpleNamespace(app=configured.app, - time_limit=300, request=SimpleNamespace(is_eager=False, called_directly=False, timelimit=None))) + time_limit=topology.OUTBOX_HARD_LIMIT_SECONDS, + request=SimpleNamespace(is_eager=False, called_directly=False, timelimit=None))) def test_synchronous_task_rejects_before_sql(monkeypatch): @@ -104,7 +105,12 @@ def test_delivery_routes_to_dedicated_queue(monkeypatch): get_settings.cache_clear() -@pytest.mark.parametrize("task_limit,message_limit", [(None, None), (301, None), (300, 301)]) +@pytest.mark.parametrize("task_limit,message_limit", [ + (None, None), (300, None), (topology.OUTBOX_HARD_LIMIT_SECONDS + 1, None), + (topology.OUTBOX_HARD_LIMIT_SECONDS, 300), + (topology.OUTBOX_HARD_LIMIT_SECONDS, topology.OUTBOX_HARD_LIMIT_SECONDS + 1), + (topology.OUTBOX_HARD_LIMIT_SECONDS, 0), +]) def test_delivery_cannot_disable_or_extend_process_bound(monkeypatch, task_limit, message_limit): configured = worker() topology.validate_outbox_worker(configured) diff --git a/backend/tests/outbox/test_worker_postgresql.py b/backend/tests/outbox/test_worker_postgresql.py index df9e822b7..0b338ab68 100644 --- a/backend/tests/outbox/test_worker_postgresql.py +++ b/backend/tests/outbox/test_worker_postgresql.py @@ -244,6 +244,8 @@ async def stubborn(envelope): # prefork task hanging until the independent test watchdog detects it. if task.time_limit is not None: monkeypatch.setattr(task, "time_limit", 5) + from app.workers import outbox_topology + monkeypatch.setattr(outbox_topology, "OUTBOX_HARD_LIMIT_SECONDS", 5) monkeypatch.setenv("WORKSTREAM_ARTIFACT_STORE_BACKEND", "disabled") get_settings.cache_clear() acked = Event() @@ -319,7 +321,14 @@ def test_delivery_task_has_independent_hard_limit(worker): from app.modules.outbox.api import DeliveryOptions task = worker.deliver_event - assert task.time_limit == 300 + from app.modules.checkers.api.external_policy import ( + SELECTED_POST_DELIVERY_LEASE_SECONDS, SELECTED_POST_HANDLER_TIMEOUT_SECONDS, + ) + from app.workers.outbox_topology import OUTBOX_PROCESS_SHUTDOWN_MARGIN_SECONDS + assert task.time_limit == ( + SELECTED_POST_DELIVERY_LEASE_SECONDS + OUTBOX_PROCESS_SHUTDOWN_MARGIN_SECONDS + ) + assert task.time_limit > SELECTED_POST_HANDLER_TIMEOUT_SECONDS assert task.time_limit > DeliveryOptions().handler_timeout_seconds assert task.acks_late and task.acks_on_failure_or_timeout assert task.reject_on_worker_lost is True diff --git a/backend/tests/tasks/evaluation_delivery/test_completion.py b/backend/tests/tasks/evaluation_delivery/test_completion.py index d9e4ec454..b2d8648ad 100644 --- a/backend/tests/tasks/evaluation_delivery/test_completion.py +++ b/backend/tests/tasks/evaluation_delivery/test_completion.py @@ -173,6 +173,9 @@ def test_completion_handler_is_registered_in_production_registry(): def test_production_request_transport_covers_maximum_selected_execution(): + from app.workers.outbox import deliver_event + from app.workers.outbox_topology import OUTBOX_PROCESS_SHUTDOWN_MARGIN_SECONDS + delivery = production_outbox_delivery(None) request = delivery._options_for(REQUEST_EVENT, 1) @@ -186,6 +189,11 @@ def test_production_request_transport_covers_maximum_selected_execution(): assert bounded_pipeline_ms <= request.handler_timeout_seconds * 1000 assert request.handler_timeout_seconds < request.lease_seconds <= 3600 assert bounded_pipeline_ms < request.lease_seconds * 1000 + assert deliver_event.time_limit == ( + request.lease_seconds + OUTBOX_PROCESS_SHUTDOWN_MARGIN_SECONDS + ) + assert deliver_event.time_limit > request.handler_timeout_seconds + assert delivery._options_for(COMPLETION_EVENT, 1) == DeliveryOptions() @pytest.mark.parametrize("human", [True, False]) diff --git a/docs/operations_authorization_service.md b/docs/operations_authorization_service.md index 6b32c26e6..f0ce45220 100644 --- a/docs/operations_authorization_service.md +++ b/docs/operations_authorization_service.md @@ -1311,14 +1311,19 @@ closes SQL before publishing event/project selectors. Failed publication is rediscovered; expired claims are recovered even if their handler was removed. Each delivery phase uses fresh AUTH/PREP and retains its exact decision reference. Unknown invoked effects remain terminal for reconciliation. The production -registry contains only `TaskAssignmentAuthorityInvalidationRequested` version 1, -with its separate exact feature authority. Unregistered event types stay unclaimed. +registry contains assignment invalidation and the selected post-submit request +and completion events, each with its separate exact feature authority. +Unregistered event types stay unclaimed. Celery worker retries cover infrastructure failure with at most three retries and a 30-second exponential delay; they never authorize repeating an invocation. -Delivery requires Celery's prefork process pool. `deliver_event` has a 300-second -hard execution limit, independent of its 240-second handler timeout and covering -async shutdown as well. The prefork parent acknowledges a hard timeout instead +Delivery requires Celery's prefork process pool. `deliver_event` has an exact +3,660-second hard execution limit, covering the maximum 3,600-second delivery +lease plus a fixed 60-second process-shutdown margin. Selected post-submit +requests have a 3,520-second handler timeout; completion and assignment +invalidation retain their 240-second handler timeout and 300-second lease. +Task or broker-message overrides that change the hard limit are refused before +SQL. This process limit also contains cancellation-resistant async shutdown. The prefork parent acknowledges a hard timeout instead of requeuing that timed-out invocation. A committed UNKNOWN remains terminal; if termination interrupts finalization, the existing expired-invocation recovery records UNKNOWN without calling the handler again. Ordinary Celery worker-loss From 89df6a34aa0acc5ca5f31354dad4020004c236d0 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 11:00:05 +0100 Subject: [PATCH 168/283] [PILOT-04] Prove actual external pre-check rejection before admission --- .../pilot04-workstream-default-checker.md | 3 +++ .../checker.py | 9 +++++++- .../run_selected_end_to_end_probe.py | 23 +++++++++++++++---- 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 72e48042c..f7d999201 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -89,6 +89,9 @@ cleanup. replay, commit rollback, revocation and HTTP admission tests remain selected. - This record and affected current PILOT-04 architecture, roadmap and owner docs. +- The existing local Rust-runtime protocol fixture and selected end-to-end + probe, to distinguish actual default rejection from actual project-image + rejection and verify both leave the task in progress without a Submission. - The existing OUTBOX prefork topology and its delivery task hard bound, with topology and real process-containment regressions, to honor the selected request budget without changing event-specific owner deadlines or selectors. diff --git a/experiments/pilot04_external_checker_runtime/checker.py b/experiments/pilot04_external_checker_runtime/checker.py index 5f62735d5..b04166b6b 100644 --- a/experiments/pilot04_external_checker_runtime/checker.py +++ b/experiments/pilot04_external_checker_runtime/checker.py @@ -1,4 +1,4 @@ -"""Small protocol fixture for the local unselected external-checker probe.""" +"""Small protocol fixture for the local selected external-checker probe.""" from __future__ import annotations @@ -74,6 +74,13 @@ def main() -> int: } for item in failures ] + if Path("/work/input/project-rejected.txt").exists(): + findings.append({ + "code": "probe.project_rule_failed", + "level": "error", + "message": "The sample project rejects this fixture file.", + "path": "project-rejected.txt", + }) body = { "schema_version": "external_checker_result.v1", "request_digest": request["request_digest"], diff --git a/experiments/pilot04_external_checker_runtime/run_selected_end_to_end_probe.py b/experiments/pilot04_external_checker_runtime/run_selected_end_to_end_probe.py index 2d708ad68..34a4582af 100644 --- a/experiments/pilot04_external_checker_runtime/run_selected_end_to_end_probe.py +++ b/experiments/pilot04_external_checker_runtime/run_selected_end_to_end_probe.py @@ -152,8 +152,8 @@ async def _prepare(fixture, settings, request): ).prepare(request) -async def _prove_work_failure(fixture, settings) -> dict[str, object]: - """A default-check failure leaves a separate Task in progress.""" +async def _prove_work_failure(fixture, settings, *, external=False) -> dict[str, object]: + """Either actual default or project-image failure prevents admission.""" task_id, assignment_id = new_record_id(), new_record_id() params = { "task": str(task_id), @@ -163,6 +163,12 @@ async def _prove_work_failure(fixture, settings) -> dict[str, object]: } async with fixture.engine.begin() as connection: await seed_started_task_for_artifact_test(connection, params) + data = _secret_archive(fixture.data) + if external: + output = BytesIO(fixture.data) + with ZipFile(output, "a") as archive: + archive.writestr("project-rejected.txt", b"sample project rejection\n") + data = output.getvalue() request = SubmissionBundlePreparationRequest( actor=ActorIdentityFacts( fixture.actor_context.actor_profile_id, @@ -178,7 +184,7 @@ async def _prove_work_failure(fixture, settings) -> dict[str, object]: summary=fixture.creation_request.summary, contributor_attestation=fixture.creation_request.contributor_attestation, media_type="application/zip", - byte_source=byte_source(_secret_archive(fixture.data)), + byte_source=byte_source(data), ) try: await _prepare(fixture, settings, request) @@ -188,8 +194,15 @@ async def _prove_work_failure(fixture, settings) -> dict[str, object]: for check in error.facts.workstream_default.checks if check.failure_code is not None ) + if external: + if codes or len(error.facts.external_members) != 1: + raise RuntimeError("project failure did not follow passing defaults") + result = error.facts.external_members[0].result + codes = tuple(item.code for item in result.findings) + if result.verdict != "failed" or codes != ("probe.project_rule_failed",): + raise RuntimeError("project image did not return its exact failure") else: - raise RuntimeError("secret-bearing input unexpectedly passed selected PRE") + raise RuntimeError("rejected input unexpectedly passed selected PRE") async with fixture.factory() as session: task = await session.get(WorkstreamTask, str(task_id)) submissions = await session.scalar(select(func.count()).select_from(Submission)) @@ -566,6 +579,7 @@ async def run( if not workspace_cleanup: raise RuntimeError("selected checker workspace cleanup is incomplete") work_failure = await _prove_work_failure(fixture, settings) + external_pre_failure = await _prove_work_failure(fixture, settings, external=True) infrastructure_recovery = await _prove_infrastructure_recovery( fixture, settings, @@ -589,6 +603,7 @@ async def run( "submission_count": submission_count, "workspace_cleanup": workspace_cleanup, "work_failure": work_failure, + "external_pre_failure": external_pre_failure, "infrastructure_recovery": infrastructure_recovery, "minio_bucket": bucket, } From 893fe95da6d5bb5d990108cf9aa91ef10ac7cb6f Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 11:03:37 +0100 Subject: [PATCH 169/283] [PILOT-04] Clarify selected delivery and remaining public surfaces --- README.md | 21 ++++++++++++------- .../README.md | 11 ++++++++++ 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 1ec640254..8fdc9dc14 100644 --- a/README.md +++ b/README.md @@ -177,8 +177,11 @@ durable post-submit execution and unfinished-attempt recovery. ARCH-04D2 supplie exact service authority. ARCH-04E1A adds immutable route-neutral TASK source storage, detached source facts and accepted-effects contracts. B6 commits each new hidden Submission with its initial checker reservation and outbox request; -automatic production delivery, routing and acceptance remain unavailable; hidden -authorized outcomes are implemented. Project-guide ingestion stores original documents, +selected production request/completion delivery now runs digest-pinned external +images after the four Workstream defaults and approved external PRE checks. +Passing true-policy results reach `review_pending`; eligible false-policy results +invoke shared authorized acceptance atomically. Public contributor intake and +false-guide activation remain separate pilot work. Project-guide ingestion stores original documents, records immutable metadata and provides authorized exact-file reads to the unified setup agent. Accepted originals are PDF, DOCX, PPTX and byte-preserved UTF-8 Markdown (`.md`); HTML and documentation sites are not guide inputs. Guide @@ -796,8 +799,8 @@ ARCH-03A completes the existing internal PROJECTS context port. New work selects one active activated guide; existing work resolves its exact frozen guide and policy selectors, including after a successor or contribution-policy retirement. The result includes the saved activation receipt, both checker-policy bodies, -artifact/effective policy, review/revision semantics and recorded catalogue -identities. It never substitutes current policies or reruns inference. CP08 uses +artifact/effective policy, review/revision semantics and exact approved external +image bindings. Retained earlier contexts preserve their immutable identities. It never substitutes current policies or reruns inference. CP08 uses that port in the existing TASK writers: screening stamps the activated contribution policy, claim copies it to the assignment, and hidden Submission creation copies the assignment's exact stamp. PostgreSQL rejects mismatched or replaced stamps. @@ -842,12 +845,14 @@ input with scoped async file access and cleanup. ARCH-04B2 adds hidden typed checker-output storage, byte-free recovery and flush-only verified binding over the generic ART put/verification path. ARCH-04C supplies hidden durable execution, exact request/execution-lease custody, immutable member results and atomic completion events. -The structural catalogue produces no output files, so output write/bind authority -remains unavailable. ARCH-04D1 validates retained terminal material against canonical +Selected image execution retains normalized bounded JSON results. Checker file +output write/bind authority remains unavailable; neither executable catalogue +remains in the live flow. ARCH-04D1 validates retained terminal material against canonical ART lineage. ARCH-04D2 supplies fixed-service input, execute and finalize authority, with PostgreSQL enforcement of exact execution/finalization receipts. ARCH-04E1A -adds immutable source storage and detached contracts only. Automatic dispatch, -production routing and public acceptance remain ARCH-04E work. The hidden +adds immutable source storage and detached contracts. PILOT-04 composes selected +hidden dispatch and production routing; public contributor intake and supported +false-guide activation remain separate pilot work. The hidden [ARCH-04E2-B operation](.commitrail/initiatives/WS-ARCH-001/WS-ARCH-001-04E2B.md) consumes canonical fixed-router authorization and commits the actual receipt with its exact source and complete consequence. Locked true moves TASK to diff --git a/experiments/pilot04_external_checker_runtime/README.md b/experiments/pilot04_external_checker_runtime/README.md index 0f5ed85b9..8f94b4c24 100644 --- a/experiments/pilot04_external_checker_runtime/README.md +++ b/experiments/pilot04_external_checker_runtime/README.md @@ -21,3 +21,14 @@ archive through the callback-scoped POST grant, and requires the normalized result, isolation receipt, database finalization, and workspace cleanup. The database must be disposable and independently cleaned by the caller; the probe does not create or drop it. + +`run_selected_end_to_end_probe.py` exercises PostgreSQL and MinIO through +selected PRE admission, immutable Submission/initial dispatch and production +request/completion handlers. It requires default-secret rejection and an actual +external PRE image rejection to preserve `in_progress` with no new Submission. +The latter uses `project-rejected.txt` as a fixture project rule, implemented +only inside the image. It also tests unavailable-service recovery through fresh +verified bytes and restarted completion delivery with exact replay. This hidden +owner drill does not provide public contributor upload/CLI, false-guide +activation or hosted gVisor deployment proof. Run it through the isolated-test +runner so owned database, role and MinIO cleanup are checked. From 644b5feee7b5a6054f8a7f2431ba80eb520afc73 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 11:03:02 +0100 Subject: [PATCH 170/283] docs(pilot04): reconcile selected hidden checker capability claims --- .../pilot04-workstream-default-checker.md | 19 + docs/architecture_checker_framework.md | 452 ++++++------------ ...014_external_service_adapter_convention.md | 11 +- docs/roadmap_status.md | 67 +-- 4 files changed, 207 insertions(+), 342 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index f7d999201..63156a527 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -59,6 +59,18 @@ cleanup. ### Allowed +- Bounded current-document reconciliation covers `docs/roadmap_status.md`, + `docs/architecture_checker_framework.md` and + `docs/decision_0014_external_service_adapter_convention.md`. Describe selected + hidden PRE/POST and production request/completion composition, distinguish + retained predecessor contracts from removed executable catalogues, preserve + the four default blockers and warning-only summary/attestation, and retain + PILOT-08 false-guide activation and PILOT-12 public intake as remaining work. + Generated output-file authority is still deny-only; normalized JSON result + custody does not prove ART file outputs. Local runc/docker-dev proof is not + deployed or gVisor proof. Worker transport/budget code and + `docs/operations_authorization_service.md` remain lead-owned. + - Delegated TEST-only reconciliation is limited to `tests/projects/post_policy/test_guards.py`, `test_postgresql.py`, `test_public_api.py`, `tests/authorization/post_policy/pg_support.py`, @@ -408,3 +420,10 @@ to reject shorter or longer overrides. Per-event bounds remain selected request 3520/3600 and ordinary events 240/300. Preserve the existing scaled real-prefork kill/reap/UNKNOWN regression while scaling both the installed test bound and its entry guard; no production duration is shortened for verification. + +Current-document reconciliation distinguishes selected hidden production +composition from public intake and false-guide activation. Immutable predecessor +contracts are retained provenance, not executable catalogue fallback. Source +inspection confirms output-file storage/binding is deny-only while selected +images produce closed JSON results. This editorial repair adds no runtime +proof; the lead owns final-head native cause guards, worker timing and hosted CI. diff --git a/docs/architecture_checker_framework.md b/docs/architecture_checker_framework.md index e8dcb93e7..a401a7e72 100644 --- a/docs/architecture_checker_framework.md +++ b/docs/architecture_checker_framework.md @@ -45,72 +45,21 @@ It is either `completed`, with closed findings and a passed/failed verdict, or `infrastructure_failed`, with one of the existing capacity, deadline, material, implementation or invalid-output codes. Missing images, crashes and malformed or oversized output cannot become a silent pass. This contract and the -immutable registry are available to later owner operations; no external -launcher, routing path or execution factory is installed yet. - -The following catalogue contracts remain the currently executing behavior -until the clean cutover replaces them. They are not alternate external wire -formats. - -The following illustrative provenance envelope uses a pre-submission catalogue -`v1` definition; it is not a universal serialized result schema. The -[current post-submit contract](#current-post-submit-contract) uses -`PostSubmitMemberResult` with schema `post_submit_structural_result` and its -separate bounded fields. - -Illustrative pre-submission provenance envelope: - -```json -{ - "definition": { - "dispatch_authority": "pre_submission_catalogue", - "definition_id": "policy.submission_packet.validate", - "definition_version": "v1", - "public_name": "check_submission_packet", - "source": "locked_project_policy" - }, - "policy_trace": { - "effective_plan_hash": "sha256:<64 lowercase hex>", - "rule_instance_id": "sha256:<64 lowercase hex>", - "locked_policy_hash": "sha256:<64 lowercase hex>" - }, - "status": "passed", - "severity": "info", - "code": "submission_packet_complete", - "message": "Submission packet is complete.", - "suggested_fix": null, - "evidence": [], - "metadata": {} -} -``` - -`definition` and `policy_trace` are typed provenance, not arbitrary metadata. -The discriminating `dispatch_authority` gives `definition_id/version` exact -meaning: for `pre_submission_catalogue` they are the stable catalogue -definition ID/version, while the effective plan separately binds the top-level -catalogue ID/version and manifest hash; for `durable_checker_registry` they are -the registered durable checker ID/version. -For Workstream defaults, `source=workstream_default` and policy-only fields may -be null under the closed schema. Serialization preserves this exact nesting. -Persistence uses explicit authority-neutral columns or schema-validated typed -JSON fields for every member; none may be stored only inside open-ended -`metadata`. - -Status: +immutable registry are consumed by selected hidden PRE/POST owners through an +explicit Rust service adapter. Production request/completion handlers are +registered; public contributor intake remains PILOT-12 work. -- passed -- warning -- failed +The following catalogue envelope documents retained pre-cutover evidence only. +Both executable catalogues and their runtime factories are removed. New requests +use the selected default-plus-external PRE contract and selected external POST +contract; retained business-version facts are not alternate execution paths. -Severity: +Retained predecessor rows preserve their original typed provenance and exact +business-version digests. Historical decoders validate those stored facts; they +do not reconstruct executable catalogue factories or dispatch new work. New +external results use the normalized contracts above. -- info -- low -- medium -- high -- critical - -## External Checker Registry And Current Catalogues +## External Checker Registry And Selected Policies The immutable external registry publishes one capability/version/phase with an exact OCI `sha256` digest, bounded configuration/input/output JSON Schemas and @@ -123,22 +72,16 @@ schema, request and entry digest while denying update, delete and truncate. Registry metadata grants no policy selection, activation, execution or routing authority. Consumers read an exact registry ID and digest; there is no "latest" lookup and no registry-driven Python plugin or callable discovery. -The registry supports both `pre_submit` and `post_submit`, but no external -execution is wired in this foundation. - -Until the replacement proof and clean cutover, the single versioned -`PreSubmissionCheckerCatalogue` remains the pre-submit dispatch authority and -the current process-wide post-submit catalogue remains the post-submit dispatch -authority. They do not execute registry entries in parallel. - -The current hidden catalogue implementation is process-wide and immutable. -Deployment configuration may name disabled stable definition IDs only at startup. Unknown -or duplicate IDs, invalid dependencies/order, unknown capabilities, and unsafe -disabled behavior fail startup validation. The pure effective-plan compiler -binds project, guide version, source snapshot, effective policy, pre-submit -policy, catalogue manifest, availability state, ordered definition/configuration -hashes, and deterministic rule-instance identities. It does not read artifacts -or invoke either pre-submit or durable checkers. +The registry supports both `pre_submit` and `post_submit`. Registration alone +grants no execution; selected owners execute only exact approved image bindings +with fresh phase authority and ART-verified material. + +The trusted compiler binds approved requirement identities to exact immutable +registry entries, image/configuration/schema digests and ordered PRE/POST +policies. PRE includes the single versioned Workstream default. No executable +pre-submit or post-submit catalogue remains, and no registry-driven Python +implementation discovery is allowed. Retained catalogue identities remain +immutable provenance for earlier records; they do not select new execution. External registry fields include: @@ -152,21 +95,25 @@ External registry fields include: decision receipt. Capability names must not drift between project guides, approved policy -bindings, registry entries and checker results. Later policy work must bind the +bindings, registry entries and checker results. Approved policies bind the exact digest, configuration and schema identities; registration alone changes -no locked task. +no locked task or approved guide generation. -## Current post-submit contract +## Retained post-submit contract -CHECKERS owns one immutable initial-v0.1 catalogue, one implementation per -checker ID, and closed evaluation-request/result contracts. PROJECTS uses that -same catalogue to compile one canonical policy body. Active PROJECTS, TASKS and -CHECKERS consumers validate that body and its exact hash; persisted required, +This section describes immutable pre-cutover policy/result evidence, not new +compilation or execution. New POST requests carry `LockedExternalPostSubmitPolicy` +and `SelectedPostSubmissionEvaluationRequest`; their results retain every +required image and exact observed isolation facts. + +The former CHECKERS implementation owned one immutable initial-v0.1 catalogue, one implementation per +checker ID, and closed evaluation-request/result contracts. PROJECTS used that +same catalogue to compile the retained canonical policy body. Retained-evidence readers validate that body and its exact hash; persisted required, warning and blocking summaries must agree with it. Unsupported development bodies reject without translation or an alternate reader. -The eight mandatory structural defaults and the selectable -`check_acceptance_criteria_present` have conformance fixtures. Criteria presence +The retained structural identities included eight mandatory defaults and +selectable `check_acceptance_criteria_present`; these are not current executors. Criteria presence does not prove that work satisfies the criteria. Unsupported substantive automation remains a capability gap; an explicitly approved `human_review` disposition remains valid without a checker binding. @@ -181,7 +128,9 @@ checked by the owning services. Structural consistency grants no authorization. The canonical `policy_hash` binds ordered entries, configuration and exact catalogue/implementation identities. Domain project policy versions record changes to project rules; they do not select obsolete software implementations. -ARCH-04C implements hidden phase execution; ARCH-04D2 supplies exact service authority. No public execution route or dispatcher is activated. +These earlier component proofs supplied hidden execution and phase authority; +PILOT-04 separately installs selected production delivery without a public +execution route. POL-04B connects unified guide setup; POL-05B and POL-06B expose separate pre-submit and post-submit policy approvals. @@ -194,9 +143,8 @@ split attempts. Replay returns the original identity; it cannot restore an old request as current. Execution claims a PostgreSQL-timed execution lease and releases all locks and prepared authority before materialization or evaluator work. -The existing in-process post-submit structural-handler registry evaluates exactly -the compiled entries against ART-verified material; it is distinct from the new -external-image metadata registry. Finalization consumes separate action-specific authority, +Selected POST execution runs every approved digest-pinned image against +ART-verified immutable Submission material through the Rust service. Finalization consumes separate action-specific authority, checks the current fence and unexpired lease, and commits complete ordered closed members, terminal result and shared-outbox completion together. Expired-lease recovery retains the attempt; terminal infrastructure failures never restart or @@ -210,24 +158,25 @@ I/O. Execute/finalize receipts are bound to the persisted phase facts by Postgre terminal replay validates both original receipts without appending new evidence. No new Celery task or public execution endpoint exists. ARCH-04E/B8 recheck currentness when consuming a completion event and apply the locked ReviewPolicy; -their hidden handlers remain unregistered. CHECKERS never accepts a contribution +their selected hidden handlers are registered in production composition. CHECKERS never accepts a contribution or mutates TASK state. Migration 0008 refuses retained checker history before changing schema rather than inventing request lineage or deleting data. ## Blocking Policy -The current catalogue behavior remains: - -- critical- and high-severity `failed` results block human review -- medium-severity `failed` result creates reviewer warning -- low-severity `failed` result creates informational note +Selected PRE requires the Workstream default and every required external image +to pass. Selected POST derives `needs_revision` from a failed required image and +`allow_review` from a complete passing set; TASK applies the locked review mode. +The old severity lists belong only to retained structural evidence. -Approved machine policies can declare stricter blocking behavior. `SubmissionArtifactPolicy` and generated project `PreSubmitCheckerPolicy` govern pre-submit artifact rules. `PostSubmitCheckerPolicy` governs durable post-submit checker blocking. +Approved project images enforce their exact required checks. Artifact custody +cannot be weakened by project configuration, and a failed required image cannot +be reclassified into a pass through an administrative grant. Project policy cannot weaken Workstream default submission artifact rules. Workstream defaults are applied before project policy. A project policy that attempts to require a forbidden artifact, remove hash requirements, allow credential-bearing storage references, or downgrade blocking defaults is a project setup defect. -The clean-cutover target has one versioned Workstream default checker with +The selected hidden flow has one versioned Workstream default checker with exactly four blocking behaviors: 1. safely open exactly one ZIP within platform size limits, rejecting @@ -240,11 +189,11 @@ exactly four blocking behaviors: Missing summary or attestation produces warnings only. Required-file, project size and forbidden-file rules belong to digest-pinned external project images. -The default checker, ART custody and project images must replace every required -outcome before either current catalogue is removed. Human reviewers continue +The default checker, ART custody and approved project images replace the removed +executable catalogues. Human reviewers continue to own final quality judgment. -The unselected `workstream.default` v1 component implements this closed result +The selected `workstream.default` v1 component implements this closed result boundary. It consumes detached ART/TASK custody facts and reads verified bytes only through the existing CHECKERS-owned callback-scoped material capability; it receives no path or storage authority and introduces no CHECKERS-to-ART @@ -255,7 +204,8 @@ unsafe contributor ZIPs are bounded work findings, while storage integrity, inspection timeout, stale predecessor and mixed-custody failures remain recoverable infrastructure outcomes. The unchanged-work check compares the canonical predecessor only when its locked task-rules digest is still current. -This component has no active caller yet and does not alter either catalogue. +The selected PRE owner calls this component before required project images; +both executable catalogues are removed. The clean-cutover intake order is fixed. ART receives the ZIP, computes its SHA-256, verifies the stored bytes, safely opens it within platform limits and @@ -278,7 +228,7 @@ The target launcher and checker integration use the agreed Rust service and SDK. Registered OCI images are not thereby required to be written in Rust; their execution identity is the approved digest, schemas and resource limits. The hidden runtime mechanism now supplies the strict Rust SDK and long-lived -service plus an unselected typed Python Unix-socket adapter. ART can issue one +service plus an explicitly composed typed Python Unix-socket adapter. ART can issue one opaque request-bound grant only inside the existing pre-admission prepared-ZIP callback; the service independently verifies its sealed file/directory manifest and exact private-root location before a read-only mount. The service accepts @@ -287,103 +237,32 @@ and config image ID all match, and owns no-network, non-root, capability-free, read-only sandbox launch, bounded output/deadline handling and cleanup. Hosted readiness requires `runsc`; local `runc` is reported as `docker-dev`. -This hidden mechanism is not selected by either current catalogue and stores no -run state. Policy binding, caller-owned phase authority/currentness, durable -attempt and isolation receipts, composition of the unselected default checker, -project-image routing, F-020 and public intake remain required before cutover. -The replacement must remove both current pre- and post-submit catalogues after -end-to-end replacement proof. It must not retain a legacy/new parallel path, -weaken caller-owned atomicity or bypass phase identity and currentness checks. +The Rust launcher owns sandbox execution; durable CHECKERS owners retain +approved policy binding, phase authority/currentness, attempts, results and +isolation receipts. F-020 requires corrected approved generation after missing +capability registration; registration alone never clears the old warning. +Production completion routes true-policy success to review_pending and eligible +locked false-policy success through shared acceptance. Public false-guide +activation remains PILOT-08 work; public intake remains PILOT-12 work. Local +Rust/MinIO proof uses runc/docker-dev and makes no deployed or gVisor claim. ## Current Required Core Checkers Pending Removal -The names below describe the current catalogue pending replacement; they do -not expand the four future Workstream defaults. - -### check_policy_context_present - -Ensures the task has locked guide, checker, review, and revision policy context. -Award eligibility is locked on TaskAssignment for the attempt, stamped on the -immutable Submission, and copied from that Submission to ReviewLease. It is not -checker-policy context. - -### check_submission_packet - -Ensures submission has summary, output reference, and package/evidence where required. - -### check_evidence_present - -Ensures accepted work can be audited. - -### check_evidence_integrity - -Ensures the submission packet records content hashes for uploaded artifacts and that checker runs use those exact hashes. - -### check_acceptance_criteria_present - -Ensures a task has rubric or acceptance criteria. - -### check_required_files - -Validates required submission artifacts from the locked project pre-submit -checker policy. - -### check_forbidden_files - -Blocks known forbidden artifacts, secrets, private keys, copied internal data, or artifacts forbidden by the locked project pre-submit checker policy. - -Default forbidden patterns include: - -- private keys -- API tokens -- `.env` -- copied confidential client/source files -- generated low-quality helper artifacts banned by project submission artifact policy -- files not allowed in the submission packet - -### check_confidentiality_attestation - -Ensures the contributor explicitly attests that the submission does not contain prohibited client data, private source material, credentials, or copied platform artifacts. - -### check_low_quality_generated_artifacts - -Flags repeated low-quality generated patterns banned by project submission artifact policy, such as generic helper files, hidden-test leakage patterns, fabricated model files, placeholder evidence, or boilerplate reports that do not prove task-specific work. - -This mandatory default emits a medium-severity warning for placeholder signals. -It cannot be removed or reclassified as a project-selected entry. Project -blocking severities govern whether that warning requires contributor revision; -only `check_acceptance_criteria_present` is selectable. - -Revision closure, task lifecycle movement, task readiness, and pre-review routing are enforced as lifecycle guards in v0.1. They must not be configured as checker policy names until a registered checker exists for that contract. - -The pre-review gate is a checker execution phase. The persisted task status during this phase is `evaluation_pending`. - ## Gate Mapping -Project activation gate: - -- `check_policy_context_present` -- project-specific guide completeness checks - -Task screening gate: - -- `check_policy_context_present` -- `check_acceptance_criteria_present` -- task lifecycle transition guards - -Submission quality gate: +- Project activation validates approved source/policy identities and exact + registry digests; missing required capability coverage blocks activation. +- TASK screening and release retain their canonical locked-context and lifecycle + guards; registry publication alone grants no Task transition authority. +- Selected PRE runs the four Workstream defaults and all required project images + before caller-owned immutable Submission creation. +- Selected POST consumes committed Submission custody and produces durable + evidence. TASK's authorized completion operation alone changes lifecycle state + or invokes shared acceptance. -- `check_submission_packet` -- `check_evidence_present` -- `check_evidence_integrity` -- `check_required_files` -- `check_forbidden_files` -- `check_confidentiality_attestation` -- `check_low_quality_generated_artifacts` - -Pre-review gate phase: - -- project-configured registered checkers run against the locked submission and policy context +Revision closure and task lifecycle movement remain owner guards, not generated +checker names. Public false-policy guide activation is still blocked pending +PILOT-08, and public contributor intake remains PILOT-12 work. ## Submission Artifact Policy And Pre-Submit Generation @@ -418,9 +297,9 @@ policy. Workstream default submission artifact rules require: -- summary +- summary metadata, with absence warning-only - one outer ZIP whose exact identity and semantic manifest are generated by ART -- contributor attestation +- contributor attestation metadata, with absence warning-only - safe relative artifact paths - production artifact hashes shaped as `sha256:<64 lowercase hex>` - pre-cutover only: validated caller-supplied storage references and manifest; @@ -439,15 +318,16 @@ Workstream default submission artifact rules require: advisory or locked project-specific unless an exact generic custody risk is proven -The hidden pre-submit executor consumes one exact effective plan under ART -scratch custody. It validates the commitment, inspection, semantic manifest and -change-gate facts and returns bounded entry results. ART owns the immutable -pre-submit evidence; these results are separate from post-submit CheckerRuns. +The selected hidden PRE owner consumes one exact approved policy under ART +scratch custody. It validates commitment, inspection, semantic manifest and +change-gate facts and returns bounded default/external results. CHECKERS retains +immutable selected run/evidence custody; ART owns verified bytes and admission. +PRE results remain separate from post-submit CheckerRuns. -POL-07B composes exactly two internal commands, `evaluate_pre_submission` and +The earlier POL-07B phase facade composes two internal commands, `evaluate_pre_submission` and `evaluate_post_submission`. Hidden preparation calls the pre command once after reservation commits, including completed replay. The composition passes the -same opaque reservation to the same ART evidence owner; it clears the consumed +same opaque reservation through canonical selected custody; it clears the consumed prepared authorization and opens no transaction before ART's existing executor obtains fresh authority. Replay returns ART's canonical result unchanged. @@ -465,7 +345,7 @@ deny-only. Controlled nonempty slots prove ART mechanics only. ARCH-04C supports that exact empty output set and owns durable execution. ARCH-04D2 supplies input, execute and finalize authority; ARCH-04E/B8 supply the hidden routing operation and completion handler, and 04F2 supplies its remediation branch. Production -registration remains pending. A returned evaluation value is not a stored current +request/completion registration is supplied by PILOT-04. A returned evaluation value is not a stored current result or acceptance. Retained run and submission history now use canonical AUTH and separate fixed contributor/manager projections. The alternate execution service and Celery worker are @@ -517,48 +397,20 @@ Pre-submit results do not create durable `CheckerRun` records, do not move a task to `review_pending`, and do not return review decision values: `accept`, `needs_revision`, or `reject`. -The unified `ProjectGuideCompilationAgent` proposes the artifact-intake -contract alongside sufficiency and both checker-stage bindings in one result. -It does not produce unrestricted checker code. Workstream's trusted -checker compiler builds and validates the project checker specification during -setup, then persists deterministic project-level checker logic using approved -primitives such as: - -- `validate_submission_packet` -- `enforce_storage_scheme` -- `require_manifest_field` -- `verify_hash` -- `require_file` -- `require_minimum_evidence` -- `forbid_artifact` -- `require_attestation` -- `limit_file_size` -- `limit_package_size` -- `limit_archive_size` -- `limit_archive_entries` -- `require_packaging` -- `warn_low_quality_generated_artifact` - -`limit_package_size` evaluates total expanded bytes from ART's verified manifest, -not compressed upload size. `limit_archive_size` separately evaluates the entire -compressed ZIP's verified `ArtifactCommitment.byte_count`, including archive -metadata, not the sum of compressed member sizes. It is an optional strict -positive byte limit; null adds no project limit. `limit_archive_entries` evaluates that manifest's -normalized outer ZIP entry count, including explicit and implied parent -directories. Omitting a ZIP directory record cannot evade this limit. Nested archives count as -files; this rule does not recursively unpack them. Project count is an optional -strict positive integer; null adds no project limit. All three rules preserve ART's -independent platform safety ceilings and block intake through the existing -effective-plan result, without creating acceptance or exposing hidden routes. - -`warn_low_quality_generated_artifact` is warning-only. The trusted compiler -rejects checker specifications that escalate that primitive to blocking. - -Project-specific executable checker code is a future extension path, not the -default. That extension path must require static validation, generated tests, -sandboxed execution, no network, no shell, no secrets, no database access, -covered Project Manager approval of the exact code hash after those checks -pass, and a locked code hash. +The unified `ProjectGuideCompilationAgent` proposes artifact intake, sufficiency +and both checker-stage bindings in one constrained result. It proposes no +unrestricted executable code. The trusted compiler resolves each required +project check to an immutable Operator-registered image, validates bounded typed +configuration against that entry's schema, and locks its exact digest and order. +An unsupported required automated check blocks the guide; a presence check cannot +stand in for a substantive evaluator. The removed primitive catalogue is not an +alternate compiler or runtime path. + +Project-specific file/count/size/evidence requirements belong to these approved +external checks. Workstream's independent ZIP/resource and credential safety +bounds remain mandatory regardless of project configuration. Generated checker +implementations remain later development work; registering an implemented image +is distinct from asking a setup agent to generate or run contributor evaluation. Pre-submit checks are authoritative for intake. Post-submit runs supply the current evaluation evidence for TASK's locked-policy routing, not acceptance @@ -573,8 +425,7 @@ effective intake policy and compiled pre-submit policy; a separate operation then deterministically projects the same result's post-submit component. It does not resume finalized setup or invoke `PostSubmitCheckerPolicyDerivationAgent`. -Bindings select only implemented definitions/configurations from the exact -CHECKERS-owned catalogue snapshot and trace to the guide's requirement inventory. +Bindings select exact registered image/configuration/schema identities and trace to the guide's requirement inventory. All pre/post capability gaps block under the current compilation schema. Ordinary warnings may be acknowledged; unsupported automation cannot be silently reclassified as human review. Explicit approved `human_review` requirements @@ -584,8 +435,8 @@ acceptance both reject any applicable approved `human_review` disposition. Passing every executable check cannot discharge that separate requirement. The unified output is a constrained proposal. Workstream's trusted compiler owns the -canonical `PostSubmitCheckerPolicy.policy_body`, hash, default checker list, -and execution order. Runtime checker execution loads the locked compiled +canonical `PostSubmitCheckerPolicy.policy_body`, hash and ordered external +bindings. Workstream defaults belong to PRE, not a duplicated POST list. Runtime checker execution loads the locked compiled policy; it does not call the setup derivation agent to judge a contributor submission. A model-based runtime evaluator would be a separate supported, registered checker, not an automatic consequence of this setup flow. @@ -603,7 +454,9 @@ The first two gates replace external origin qualification and task ingestion for ## Project-Specific Checkers -Each project can register specialized checkers. +A system-scoped Operator registers specialized image implementations. Covered +Project Managers approve exact project bindings; a project grant alone grants +no registry publication authority. Examples: @@ -622,32 +475,19 @@ Examples: ## Post-Submit Compiler Boundary `PostSubmitCheckerPolicy` is produced by Workstream's trusted post-submit -compiler from a constrained specification. The compiler owns the canonical +compiler by projecting the exact approved external POST policy. The compiler owns the canonical runtime body and hash. Setup agents may propose registered checker names and routing classifications, but they do not produce executable runtime code and they do not decide submission outcomes at runtime. -The compiler always includes the platform default durable checkers in -`default_checkers` and `execution_checkers`: - -- `check_submission_packet` -- `check_policy_context_present` -- `check_evidence_present` -- `check_evidence_integrity` -- `check_required_files` -- `check_forbidden_files` -- `check_confidentiality_attestation` -- `check_low_quality_generated_artifacts` - -Default-only projects are valid. The single compiled body stores ordered -entries; default, required, warning and execution lists are derived from them. -Project selections cannot remove, rename, reorder or reclassify mandatory -defaults. Only registered selectable entries may be added. Unknown or -conflicting selections reject before persistence. +Retained pre-cutover bodies preserve their original ordered structural entries, +classification lists and hashes for exact historical decoding. -Platform blocking severities are `critical` and `high`. Project policy may add -stricter blocking severities, but it cannot remove those platform blocking -severities. +Those bodies are retained provenance only. New POST bodies contain the exact +approved external entries and `policy_sha256`; an empty approved POST binding +set is valid. Saved requirement, capability/version, stage and configuration +substitution rejects before projection. All required image results are consumed +by the selected outcome owner, without runtime catalogue lookup. ## Checker Run Flow — Target Contract @@ -659,14 +499,14 @@ invocation, recovers B6's exact request and fences both execution and terminal replay/publication. B8 delivers the hidden completion handler, and ARCH-04F2 extends its existing TASK/AUTH outcome operation so an exact current contributor-correctable result routes to `needs_revision` under either locked -ReviewPolicy mode. Both handlers remain unregistered; automatic production -delivery is unavailable. Known missing or corrupt input after ART authorization records a +ReviewPolicy mode. Selected request and completion handlers are registered in +production composition, with exact invocation authority and replay custody. Known missing or corrupt input after ART authorization records a terminal infrastructure failure only after cleanup and fresh finalization authorization; it does not route the task. Exact replay does not reread storage. Denied material access and unexpected failures remain nonterminal. ARCH-04F adds -replacement intake and authorized recovery after the delivered hidden -remediation handoff; those remaining boundaries gate public intake and enabling -the false-policy acceptance path. The true `allow_review` route may ship first. +implemented hidden exact-cause replacement intake and reason-bound Operator +retry after the remediation handoff. Public intake and false-policy guide +activation remain separate prerequisites for the complete public journey. ARCH-04B hidden input and ARCH-04B2 hidden output custody are delivered with output-file authority unavailable; exact input authority is implemented. The flow below is not a claim that the complete journey is live in production. @@ -681,11 +521,11 @@ Draft packet -> automatically lock submission -> queue automatic pre-review CheckerRun -> validate locked PostSubmitCheckerPolicy id/version/hash/body --> execute locked PostSubmitCheckerPolicy execution_checkers +-> execute every exact locked external POST image -> store CheckerResult records -> calculate blocking status --> commit final CheckerRun result/recommendation, required verified output bindings and completion event --> TASK consumes the current result: publish allow_review manifest/current pointer and review_pending atomically when eligible +-> commit final CheckerRun result/recommendation, normalized JSON evidence and completion event +-> TASK consumes the current result: true -> review_pending; eligible locked false -> shared FinalAcceptance/TASK/CON/awards atomically -> TASK projects an exact current contributor-fixable failure as needs_revision with the retained manifest recommendation and no Review -> project/setup faults remain internal task_setup_blocked, never contributor blame -> if checker infrastructure fails: keep in checker retry handling @@ -694,8 +534,7 @@ Draft packet The checker run must bind to one immutable submission version. If the contributor uploads a replacement file, the platform creates a new submission version and reruns checks. `evaluation_pending` is the persisted state while post-submit checker execution -or infrastructure retry is active. After checker results, immutable output/log -artifact bindings, and completion facts commit atomically, the TASK-owned +or infrastructure retry is active. After checker results, normalized JSON evidence and completion facts commit atomically, the TASK-owned handler performs the routes above through its own transaction and authority: passing work moves to `review_pending`, while contributor-fixable blocking failures may move to `needs_revision`. The routing @@ -717,14 +556,15 @@ Submission/result/manifest/receipt lineage, and creates no Review, FinalAcceptance, ContributionRecord or award in either ReviewPolicy mode. Exact replay returns the retained outcome without repeating effects. Contributors continue to receive only the existing bounded checker-history projection; no new -public API is added. Replacement intake, setup-fault and Operator recovery, -production composition and public intake remain required before public cutover. +public API is added. Exact-cause replacement and Operator retry are implemented hidden owners; +manager-visible setup-fault hold and public intake remain before public cutover; selected production +composition is implemented. The direct CHECKERS-to-TASK mutation, fabricated system actor and alternate -Celery gate are removed. Hidden durable execution and exact service authority are implemented; automatic -routing remains unregistered. ARCH-04E2-B supplies the hidden authorized +Celery gate are removed. Hidden durable execution and exact service authority are implemented; selected automatic +request/completion delivery is registered. ARCH-04E2-B supplies the hidden authorized outcome operation; B8 supplies hidden completion delivery; ARCH-04F2 extends -that operation with remediation. Live composition and the remaining 04F -replacement/recovery boundaries remain pending. +that operation with remediation. Manager-visible setup-fault hold, public intake and public false-guide activation +remain pending. `review_pending` marks readiness for the separately owned WS-REV lifecycle. WS-REV alone creates `ReviewPacketManifest`, review queues, reviewer leases, @@ -739,10 +579,10 @@ and there is no Review or review decision ID. Human review can also produce If a checker crashes or cannot run because of platform infrastructure, the checker run remains failed as an infrastructure failure and the task does not -move to human review. The planned retry contract requires Operator +move to human review. The implemented hidden retry contract requires Operator `operations.checker.retry`, a reason, a new attempt/supersession record, and -append-only audit evidence. That action is currently unavailable; no public -retry or repair route survives the alternate execution removal. +append-only audit evidence. That action is available only through the canonical hidden recovery owner; +no public retry or repair route is added. This terminal retry is distinct from transport redelivery or recovery of an unfinished provider call. In-flight recovery retains its logical attempt and @@ -806,8 +646,8 @@ locked post-submit policy body, or hidden task setup details. ARCH-04C retains closed, ordered post-submit checker identity and implementation version, status, code, failure category, severity and the bounded counter fields of `PostSubmitMemberResult`. It also retains exact request/result generation and -digests, locked policy lineage and verified material custody. Current structural -handlers emit empty counters. Explanations and suggested fixes in history are +digests, locked policy lineage and verified material custody. Retained structural +results have empty counters; selected image results use their closed JSON schema. Explanations and suggested fixes in history are derived deterministically from the closed code; raw handler messages and arbitrary metadata are not retained. @@ -834,15 +674,14 @@ ARCH-04C adds neither full-log reads nor retry/repair controls. ## Recovery, Not Checker Override -`operations.submission_gate.repair` and `operations.checker.retry` are planned, -unavailable actions. The following describes their required future authority -and evidence contract, not existing callable recovery routes. +`operations.checker.retry` has a hidden reason-bound Operator owner with fresh +authority and immutable attempt/audit custody. `operations.submission_gate.repair` +remains unavailable. Neither grants a public override or bypasses checker results. Critical- and high-severity checker failures cannot be converted into review readiness by an administrative grant. A covered Project Manager may repair task -setup under `project.task.manage`. Future Operator submission-gate repair and -checker retry must be limited to the registered recovery purpose once their -canonical owner implementation and AUTH activation are delivered. +setup under `project.task.manage`. Future Operator submission-gate repair and current hidden checker retry must +remain limited to their exact registered recovery purposes. Recovery requires: @@ -947,23 +786,24 @@ No manual execution endpoint accompanies these reads. See the ### Shared evaluation content capacity -ARCH-04E1B-B5 provides `PostSubmissionEvaluationContent` for both preparation and -later identified requests. It enforces the existing locked catalogue, policy +The retained ARCH-04E1B-B5 contract provided `PostSubmissionEvaluationContent` +for pre-cutover preparation and later identified requests. Its retained value type validates the original catalogue/policy consistency and structural field limits, plus 1 MiB minus a 1,024-byte reserve for the finite request identity envelope. The full request retains its 1 MiB limit and canonical digest. Catalogue and policy identities are unchanged. -The typed adapter projects every verified file and only required evidence with +The removed preparation adapter projected every verified file and only required evidence with matching verified `evidence/{key}` files. Missing criteria remain empty text for the existing post-submit checker. This check does not execute evaluators or supply authority. See [the ART admission boundary](spec_artifact_storage_service.md#evaluation-content-capacity-before-durable-admission) -for timing and cleanup. ARCH-04E1B-B6 reuses this projection with actual record +for historical timing and cleanup. ARCH-04E1B-B6 used that projection with actual record identities and reserves generation one through the required TASK guard in the Submission transaction. The same commit retains exact creation/binding AUTH receipts and a bounded `PostSubmissionEvaluationRequested` outbox event. Select-only creation replay checks the original request and event without -changing the current-generation fence. Request/completion handlers remain -unregistered; this stored intent alone does not invoke checker execution or accept work. +changing the current-generation fence. PILOT-04 replaces that preparation projection with selected external policy +content and registers selected request/completion handlers. Stored intent alone +still confers no execution or acceptance authority. Preparation has no stored Submission to observe and never replaces the TASK evaluation guard. diff --git a/docs/decision_0014_external_service_adapter_convention.md b/docs/decision_0014_external_service_adapter_convention.md index 078378f18..10bc7fe7c 100644 --- a/docs/decision_0014_external_service_adapter_convention.md +++ b/docs/decision_0014_external_service_adapter_convention.md @@ -38,7 +38,7 @@ ExternalServiceAdapter |- IdentityIssuerVerifier |- ProjectGuideAgentRuntime |- ArtifactStore -`- ExternalCheckerExecutionAdapter (hidden, unselected Unix-socket runtime) +`- ExternalCheckerExecutionAdapter (selected hidden Unix-socket runtime) ``` Concrete implementations satisfy explicit capability ports: @@ -60,10 +60,11 @@ The checker capability publishes a normalized pre/post request/result contract, an immutable digest-pinned metadata registry, and a hidden typed Unix-socket adapter for its trusted Rust node service. The registry remains data, not an adapter factory: it cannot select Python code, discover plugins, grant execution -authority or construct a transport. The adapter factory is instance-local and -unselected; no product composition root or checker caller installs it yet. -Later cutover must preserve CHECKERS request/lease/result ownership and ART -material custody when it adds that explicit composition. +authority or construct a transport. The adapter factory is instance-local and explicitly installed by the selected +hidden CHECKERS composition. Durable PRE/POST owners retain request, lease and +result custody, while ART owns verified material and callback-scoped grants. +Production request/completion registration does not expose public intake. +Local integration uses runc/docker-dev; hosted gVisor proof remains separate. The Rust service alone owns container-engine access. Python sends an opaque, request-bound callback grant issued from ART's existing pre-admission scratch diff --git a/docs/roadmap_status.md b/docs/roadmap_status.md index ddeccddb8..769715445 100644 --- a/docs/roadmap_status.md +++ b/docs/roadmap_status.md @@ -53,8 +53,9 @@ outside v0.1. ## Status Vocabulary -The automated-acceptance branch is a **planned** v0.1 -requirement, not a live capability. The existing versioned ReviewPolicy now +The complete public automated-acceptance journey is a **planned** v0.1 +requirement. Selected hidden completion supports the false-policy outcome; +public false-policy guide activation remains blocked pending PILOT-08. The existing versioned ReviewPolicy now persists the setting: `human_review_required: bool = true`. True requires human review after required checks pass; false leads to authorized FinalAcceptance and submitter contribution without a reviewer contribution. It requires explicit locked project policy, @@ -74,8 +75,8 @@ belongs to later fulfillment activation. The setting is configurable through the existing authorized policy writer; creation defaults true and omitted replacements inherit the predecessor. -Versioned hashing preserves old policy hashes and locks. False remains blocked -by the current activation service. See the [implementation record](../.commitrail/changes/pre-review-plan-reconciliation.md#delivered-policy-setting-implementation). Enabling false follows shared final-acceptance, +Versioned hashing preserves old policy hashes and locks. Public false-policy guide activation remains blocked +by the current activation service pending PILOT-08. See the [implementation record](../.commitrail/changes/pre-review-plan-reconciliation.md#delivered-policy-setting-implementation). Enabling false follows shared final-acceptance, TASK effects, exact AUTH/source custody and routing proof, not live human-review infrastructure. The separate `requires_second_review` field is [fixed to false](../.commitrail/changes/enforce-requires-second-review-false.md) at typed input, immutable lineage and PostgreSQL boundaries. Retained true facts @@ -116,7 +117,7 @@ contributor-correctable result through the existing TASK/AUTH operation to `needs_revision` under either locked ReviewPolicy mode. 04F3 adds hidden exact-cause replacement intake through the canonical ART/TASK writer, preserving the predecessor, locked policy and checker source while atomically creating the -successor Submission and evaluation request. ARCH-04F4 adds hidden reason-bound Operator retry for an exact current terminal `infrastructure_failed` run through the existing CHECKERS coordinator and request handler, with immutable source, AUTH/audit/outbox custody and fresh-authorized historical replay. Manager-visible setup-fault hold remains. Production registration remains unavailable, and no public API is added. +successor Submission and evaluation request. ARCH-04F4 adds hidden reason-bound Operator retry for an exact current terminal `infrastructure_failed` run through the existing CHECKERS coordinator and request handler, with immutable source, AUTH/audit/outbox custody and fresh-authorized historical replay. Manager-visible setup-fault hold remains. PILOT-04 registers selected request and completion handlers in production composition; no public intake API is added. Exact assignment-invalidation authority, atomic originating publication and production delivery with enforced prefork topology are implemented. Manager task @@ -147,7 +148,7 @@ contracts. Required success branches on the locked ReviewPolicy: the hidden operation stages the TASK human-review handoff for true and shared authorized acceptance without a human Review for false. These internal outcomes have transaction and database proof; B8 supplies hidden completion delivery, and -guide activation still rejects false until its runtime prerequisites are met. ART-07A1 supplies metadata-only reviewer packet types, with no resolver or byte +public guide activation still rejects false pending PILOT-08. ART-07A1 supplies metadata-only reviewer packet types, with no resolver or byte authority. REV-03B packets and REV-04A immutable Review source storage are delivered; REV-04B shared acceptance storage, CON-03C contribution/award storage, REV-12A1 disabled controller/fence mechanics and CON-07 hidden source-neutral submitter participation with complete frozen award sets are delivered. [REV-04C](../.commitrail/initiatives/WS-REV-001/WS-REV-001-04C.md) adds one hidden source-neutral participant that stages @@ -165,7 +166,7 @@ actual receipt custody with `checker_remediation`: TASK moves from creates no Review, FinalAcceptance, ContributionRecord or award under either ReviewPolicy mode. 04F3 admits a changed full ZIP from that exact current authorized cause under either mode, with no failure economics or human Review. -04F4 adds a separate hidden Operator retry for known terminal infrastructure failure; it creates no Review, acceptance, contribution or award. Manager-visible setup-fault hold, production registration and false-guide activation remain unavailable. Human review/revision, conditional fulfillment, operations and +04F4 adds a separate hidden Operator retry for known terminal infrastructure failure; it creates no Review, acceptance, contribution or award. Manager-visible setup-fault hold and false-guide activation remain unavailable; selected production request/completion composition is implemented. Human review/revision, conditional fulfillment, operations and release proof remain later v0.1 work. The [independent MCP package](../mcp_server/README.md) implements nine self-service @@ -248,8 +249,8 @@ implementation and policy binding and is not claimed live here. | Stage | Purpose and examples | Policy and execution boundary | Outcome | | --- | --- | --- | --- | -| Pre-submission intake checks | Is this package acceptable to submit? Check completeness, required/forbidden files, evidence integrity, and configured intake-quality rules. | The locked `PreSubmitCheckerPolicy` and effective artifact policy drive the pre-submission catalogue during continuous artifact preparation, before a Submission exists. | Blocking failures return correction feedback and prevent Submission creation. Passing intake does not prove the task is accepted or ready for review. | -| Post-submission evaluation | Does the submitted work meet the configured task/project checks? Evaluate the exact stored work and evidence under the locked requirements. | The Submission-stamped `PostSubmitCheckerPolicy` drives the current in-process structural-handler registry and durable `CheckerRun` execution after immutable Submission creation; this path is distinct from the new external-image metadata registry. Only supported, registered checks execute. 04F1 verifies current completed failure evidence through the same CHECKERS port. | Persist current evidence. The hidden authorized operation publishes exact source custody. `allow_review` branches on locked ReviewPolicy: true moves TASK to `review_pending`; false invokes shared acceptance under TASK authority. Exact current `needs_revision` moves TASK to contributor remediation under either mode without REV/CON effects. CHECKERS never writes TASK state or acceptance itself. B8 supplies hidden completion delivery; automatic production registration remains pending. | +| Pre-submission intake checks | Is this package acceptable to submit? Check completeness, required/forbidden files, evidence integrity, and configured intake-quality rules. | The locked selected PRE policy runs the single Workstream default followed by every required digest-pinned project image on ART-verified material, before a Submission exists. | Blocking failures return correction feedback and prevent Submission creation. Passing intake does not prove the task is accepted or ready for review. | +| Post-submission evaluation | Does the submitted work meet the configured task/project checks? Evaluate the exact stored work and evidence under the locked requirements. | The Submission-stamped external POST policy drives approved digest-pinned images through the Rust service and durable `CheckerRun` ownership after immutable Submission creation. Only supported, registered checks execute. 04F1 verifies current completed failure evidence through the same CHECKERS port. | Persist current evidence. The hidden authorized operation publishes exact source custody. `allow_review` branches on locked ReviewPolicy: true moves TASK to `review_pending`; false invokes shared acceptance under TASK authority. Exact current `needs_revision` moves TASK to contributor remediation under either mode without REV/CON effects. CHECKERS never writes TASK state or acceptance itself. B8 supplies completion custody; PILOT-04 registers selected request/completion production delivery. | The unified guide agent proposes both sets of policy bindings in one setup result. Trusted compilation, validation, and the governing approval path turn @@ -280,10 +281,10 @@ cannot be reused as post-submission review-gate evidence. See the | Contributor artifact preparation | **Hidden and proven** | One outer ZIP; bounded scratch inspection; canonical manifest; shared evaluation-content capacity and exact locked-policy checks before attempts or durable intent; platform and project prechecks; unchanged-work rejection; durable put intent; verification; capacity-charged ready admission; hidden final handoff validates the exact activated historical guide through owner ports | Complete the later public admission-only cutover | | Pre-submission intake checking | **Selected hidden flow with approved-guide lineage and bounded feedback** | One versioned Workstream default checker enforces safe ZIP/resource bounds, independently verified digest/manifest, high-confidence secret rejection and unchanged-work rejection. Missing summary/attestation produces warnings only. Approved project PRE checks are immutable digest-pinned images run by the Rust service on verified read-only ART material. Durable selected custody takes TASK before CHECKERS; only a complete pass grants admission to the existing atomic Submission transaction. Both executable catalogues are removed | Public contributor upload/finalize and CLI submit/status remain PILOT-12. Work findings create no Submission and preserve in_progress; infrastructure failures retain recoverable outcomes. Local Rust/MinIO proof uses runc/docker-dev; hosted gVisor integration and representative limits remain | | Immutable Submission creation | **Hidden foundation; public packet creation retired** | Contributor preparation authority; durable pre-submit reservation and exact completed-evidence recovery without rerunning checks; atomic admission consumption; TASK-owned admission-backed creation with exact assignment ContributionPolicyVersion, locked policy lineage and service/database checked-packet custody; fixed-service artifact binding; replay/concurrency/rollback proof | Finish downstream evaluation and the canonical public integration. The retained submission-list GET is not a usable creation POST | -| Post-submission evaluation and governed outcome | **Selected hidden external execution and production completion routing** | Immutable approved image bindings, Rust service/SDK and typed ART callback grants; exact verified input/output custody, durable current results and phase authority. Production outbox request/completion handlers run selected images and preserve exact restart/replay. True-policy success reaches review_pending; false-policy success invokes shared authorized FinalAcceptance and atomically creates the submitter ContributionRecord and complete frozen award set. Contributor-correctable failures retain exact remediation causes; Operator retry retains fresh authority and no spent contributor round | Public intake remains PILOT-12; live human review and contributor revision surfaces remain separate. Uncovered required guide capabilities block activation; registration alone cannot repair an approved generation. True handoff has no REV/CON prerequisite. No deployed runtime or exhaustive public journey claim | +| Post-submission evaluation and governed outcome | **Selected hidden external execution and production completion routing** | Immutable approved image bindings, Rust service/SDK and typed ART callback grants; exact verified input custody, bounded normalized JSON results and phase authority. Production outbox request/completion handlers run selected images and preserve exact restart/replay. True-policy success reaches review_pending; false-policy success invokes shared authorized FinalAcceptance and atomically creates the submitter ContributionRecord and complete frozen award set. Contributor-correctable failures retain exact remediation causes; Operator retry retains fresh authority and no spent contributor round | Public intake remains PILOT-12; live human review and contributor revision surfaces remain separate. Uncovered required guide capabilities block activation; registration alone cannot repair an approved generation. True handoff has no REV/CON prerequisite. No deployed runtime or exhaustive public journey claim | | Review queue and lease | **Hidden persistence foundation** | Queue/admission idempotency and ReviewLease/preference persistence; complete unavailable REV action/principal catalogue and typed AUTH contracts; ART-07A1 metadata-only packet contract and REV-03B immutable normalized packet persistence with live ingest custody; REV-04A Review/finding/resolution and completed request storage | Future resolver proof; canonical admission from `allow_review`; claim/lease/packet authority; lease copies the Submission-stamped policy version with no CON lookup | | Review decision and revision | **Hidden acceptance core; runtime planned** | Review/revision policy identities and mutation authority, with `requires_second_review` fixed false through typed and database boundaries; REV-04A immutable Review storage; REV-04B source storage; REV-04C hidden source-neutral FinalAcceptance/TASK/CON participant; approved same-task revision-rebase semantics | ARCH-04E2-B supplies mandatory source AUTH and complete database/audit/outbox closure for hidden automated outcomes. Human decision authority/composition, revision preparation, replay and recovery remain | -| Contribution and compensation truth | **Hidden shared participant plus public policy administration** | ContributionPolicyVersion persistence; lifecycle-audit participant; adapter bindings; public Finance policy administration; REV-04B shared acceptance source storage; CON-03C immutable ContributionRecord/CompensationAward storage; obsolete guide-keyed payment storage and task-local payment fields removed; CON-07 source-neutral submitter participant and complete award sets; REV-04C composes it with FinalAcceptance/TASK effects in the caller transaction; 04F2 checker remediation creates no contribution or award | ARCH-04E2-B supplies exact routing authority/evidence, complete-set database closure and audit/outbox under REV-12A4A. Hidden B8 completion delivery, 04F3 exact-cause replacement and 04F4 hidden retry are implemented; manager-visible setup-fault hold and live composition remain before production consumption. Only actual Reviews create reviewer records. Obligation/root/ordinal custody remains deferred until fulfillment activation; no public recognition or fulfillment route is live | +| Contribution and compensation truth | **Hidden shared participant plus public policy administration** | ContributionPolicyVersion persistence; lifecycle-audit participant; adapter bindings; public Finance policy administration; REV-04B shared acceptance source storage; CON-03C immutable ContributionRecord/CompensationAward storage; obsolete guide-keyed payment storage and task-local payment fields removed; CON-07 source-neutral submitter participant and complete award sets; REV-04C composes it with FinalAcceptance/TASK effects in the caller transaction; 04F2 checker remediation creates no contribution or award | ARCH-04E2-B supplies exact routing authority/evidence, complete-set database closure and audit/outbox under REV-12A4A. Selected production request/completion delivery, 04F3 exact-cause replacement and 04F4 hidden retry are implemented; manager-visible setup-fault hold and the complete public journey remain. Only actual Reviews create reviewer records. Obligation/root/ordinal custody remains deferred until fulfillment activation; no public recognition or fulfillment route is live | | Contribution evidence reads | **Public bounded backend reads** | PILOT-10A exposes current human self-read and one-project JSON/CSV export for covering Project Managers or exact-project Finance Authorities; one fresh repeatable-read response with one narrowly bounded serialization-conflict retry and fresh authority, complete zero/one/two immutable awards, exact decimals, recorded-time filters and formula-neutralized CSV; 1,000-contribution maximum refuses excess without truncation | CLI consumption and stable fixed-membership paginated list remain separate; no recognition mutation, fulfillment, payout or deployed-service claim | | Fulfillment, reconciliation, and audit | **Planned** | Shared audit foundations, provider-neutral adapter convention, AUTH-OUTBOX-02 live dispatcher authority, retained phase audit decisions, Celery delivery/recovery scans and CON-02B custody | Feature-specific handlers and authority, conditional award fulfillment, callbacks, idempotent recovery, reconciliation, bounded operational reads, and release controls | | Runtime diagnostics | **Implemented foundation** | Closed structured logging, explicit API/Celery tracing, bounded metrics, safe correlation and optional typed OTLP export | Restrict broker publishers; configure and secure collector/log access, egress, encryption and finite deletion; prove diagnostics during the release drill; no deployed monitoring claim | @@ -821,7 +822,7 @@ ARCH-04D2 supplies exact service authority; 04E/B8 supply hidden authorized routing and completion delivery, 04F2 supplies the hidden remediation branch, 04F3 supplies exact-cause hidden replacement intake, and 04F4 supplies hidden Operator retry of terminal infrastructure failure. -Production registration remains unavailable. +PILOT-04 registers the selected request and completion handlers in production composition; this does not expose public intake. ARCH-04B adds hidden exact Submission materialization through TASK's immutable read port and ART's consumed admission. Local/MinIO input is independently reread, @@ -832,9 +833,10 @@ dispatches the initial post-check request. ARCH-04B2 adds hidden typed checker-output `store` and byte-free `recover(selector)` operations, per-slot preparation caps, generic put and verification reuse, and flush-only immutable verified binding. Controlled -nonempty slots originally proved ART mechanics only. The selected external -flow now verifies image-declared outputs through the same ART custody. ARCH-04C supplies CHECKERS reservation/currentness; ARCH-04D2 supplies -execute/finalize authority. Output write/bind authority remains unavailable. Public intake is not activated. +nonempty slots originally proved ART mechanics only. Selected external +images return bounded schema-validated JSON results; generated output-file +write/binding authority remains unavailable. ARCH-04C supplies CHECKERS reservation/currentness; ARCH-04D2 supplies +execute/finalize authority. Public intake is not activated. ## Critical Dependency Map @@ -876,7 +878,7 @@ Delivered foundations (not a claim of full public integration) ARCH-04E1B-B1 ordered reservation/current reads + admission INSERTs (no activation) ARCH-04E1B-B2 exact source proposal + B3 ZIP metadata + B4 checked packet custody + B5 bounded evaluation content ARCH-04E1B-B6 atomic Submission/dispatch + exact AUTH receipts + replay (no delivery/publication authority) - ARCH-04E1B-B7 hidden request delivery (unregistered) + ARCH-04E1B-B7 original hidden request-delivery foundation REV-12A4A scoped Operator transitions + immutable AUTH/history custody + current-generation gates PILOT-02A public canonical JSON source custody + authorized replay + PostgreSQL/MinIO recovery proof @@ -889,7 +891,9 @@ Delivered foundations (not a claim of full public integration) ARCH-04F2 exact current checker remediation through TASK/AUTH under both policy modes ARCH-04F3 hidden exact-cause replacement through canonical ART/TASK intake and writer ARCH-04F4 hidden reason-bound Operator retry through CHECKERS/AUTH + existing request handler - ARCH-04E3A hidden ART Celery child lease + per-invocation scratch; no production registration + ARCH-04E3A hidden ART Celery child lease + per-invocation scratch + PILOT-04 selected default + exact external PRE/POST images; both catalogues removed + production request/completion handlers -> true review_pending or hidden false acceptance PILOT-10A public bounded evidence reads over existing immutable CON/awards active human self or covering PM / exact-project Finance -> JSON or CSV @@ -899,9 +903,9 @@ Remaining integration PILOT-02 separately scoped atomic DRAFT import -> explicit batch screen/release Manager-visible setup-fault hold: retain Submission/locked rules, no contributor penalty (changing submitted-task rules remains deferred) - -> 04E3 live composition and false-policy readiness + -> PILOT-08 false-policy guide activation readiness -> public initial/checker-remediation intake and immutable admitted Submission cutover - -> automatically consume the durable current result + -> public trigger for the implemented selected completion outcomes | +-- contributor-correctable failure -> TASK needs_revision (no REV/CON) | -> hidden exact-cause replacement intake; setup-fault hold pending @@ -968,8 +972,9 @@ v0.1 is not ready until all of the following are true: success consequences under that manifest. B8 completion delivery is implemented; 04F2 adds exact checker remediation with zero REV/CON effects. 04F3 adds hidden exact-cause replacement intake and 04F4 hidden Operator retry. - Manager-visible setup-fault hold and live - composition remain before production shared acceptance. + Selected production completion already invokes shared acceptance for eligible + locked false-policy facts. Manager-visible setup-fault hold, PILOT-08 false-policy + guide activation and the complete public journey remain. Conditional awards remain atomic. Fulfillment obligation/root/ordinal storage and real cutoff/drain proof are required when payment fulfillment is enabled, not before the first contribution path. No fabricated observation or @@ -1107,9 +1112,9 @@ remaining trace sequence is: their existing shorter limit. ARCH-03C2 enforces a dedicated non-eager prefork delivery queue. ARCH-04E1A proves source storage and detached contracts only; its false scalar - proof does not make false activation available. Automatic `04E` delivery still needs - production registration and live composition of the implemented authorized - checker-routing handler; the installed assignment handler does not provide them. + proof does not make false activation available. PILOT-04 separately installs + selected request/completion production composition; public false-guide + activation remains PILOT-08 work. The true handoff does not require REV or fulfillment. TASK request/source-identity reservation `04E1B-A`, hidden AUTH preparation `04E2-A`, CON-07 participation and REV-04C hidden FinalAcceptance/TASK/CON @@ -1117,7 +1122,7 @@ remaining trace sequence is: closure and atomic success outcomes. B8 supplies hidden completion delivery; 04F2 extends the same operation with exact checker remediation under both policy modes. 04F3 adds hidden replacement intake and 04F4 hidden Operator retry; - manager-visible setup-fault hold and live integration `04E3` remain. A dispatcher + manager-visible setup-fault hold and the complete public intake journey remain. A dispatcher cannot authorize TASK or CHECKERS mutations. Remaining `04F` owns the authorized manager-visible setup-fault hold before public cutover. This hold retains the Submission and locked rules without contributor penalty. The remaining recovery work @@ -1145,20 +1150,20 @@ ARCH-04E1B-B3 proof: [verified ZIP metadata custody](../.commitrail/initiatives/ ARCH-04E1B-B6 proof: [atomic Submission, exact receipts and initial request custody](../.commitrail/initiatives/WS-ARCH-001/WS-ARCH-001-04E1BB6.md). -ARCH-04E1B-B7 proof: [hidden request delivery and invocation custody](../.commitrail/initiatives/WS-ARCH-001/WS-ARCH-001-04E1BB7.md). B8 supplies hidden completion routing; production registration and public intake remain unavailable. +ARCH-04E1B-B7 proof: [hidden request delivery and invocation custody](../.commitrail/initiatives/WS-ARCH-001/WS-ARCH-001-04E1BB7.md). B8 supplied hidden completion routing; PILOT-04 adds selected production composition, while public intake remains unavailable. -REV-12A4A proof: [scoped lifecycle control and payment-delivery deferral](../.commitrail/initiatives/WS-REV-001/WS-REV-001-12A4A.md). ARCH-04E2-B supplies exact source receipts; B8 completion delivery, the 04F2 zero-REV/CON remediation handoff, 04F3 hidden replacement intake and 04F4 hidden Operator retry are implemented. Manager-visible setup-fault hold and production activation remain required. +REV-12A4A proof: [scoped lifecycle control and payment-delivery deferral](../.commitrail/initiatives/WS-REV-001/WS-REV-001-12A4A.md). ARCH-04E2-B supplies exact source receipts; B8 completion delivery, the 04F2 zero-REV/CON remediation handoff, 04F3 hidden replacement intake and 04F4 hidden Operator retry are implemented. Manager-visible setup-fault hold, false-guide activation and the complete public journey remain required. -ARCH-04E2-B proof: [hidden authorized outcome custody](../.commitrail/initiatives/WS-ARCH-001/WS-ARCH-001-04E2B.md). B8 supplies hidden completion delivery; production registration and false-guide activation remain unavailable. +ARCH-04E2-B proof: [hidden authorized outcome custody](../.commitrail/initiatives/WS-ARCH-001/WS-ARCH-001-04E2B.md). B8 supplies hidden completion delivery; selected production composition is implemented, while false-guide activation remains unavailable. -ARCH-04E1B-B8 proof: [hidden completion delivery](../.commitrail/initiatives/WS-ARCH-001/WS-ARCH-001-04E1BB8.md). Both policy branches commit before acknowledgment; closed UNKNOWN invocations never automatically repeat effects. Production registration remains unavailable. +ARCH-04E1B-B8 proof: [hidden completion delivery](../.commitrail/initiatives/WS-ARCH-001/WS-ARCH-001-04E1BB8.md). Both policy branches commit before acknowledgment; closed UNKNOWN invocations never automatically repeat effects. PILOT-04 adds selected production request/completion composition; no public intake is supplied. ARCH-04F1 proof: [verified checker failure evidence](../.commitrail/initiatives/WS-ARCH-001/WS-ARCH-001-04F1.md). The existing completion read returns exact stored completed results and distinguishes contributor/setup failures; no failure routing, replacement intake or recovery authority is activated. ARCH-04F2 delivered boundary: [authorized checker remediation handoff](../.commitrail/initiatives/WS-ARCH-001/WS-ARCH-001-04F2.md). The existing hidden TASK/AUTH operation retains the exact current recommendation, manifest and actual decision receipt while moving TASK to `needs_revision` under either policy mode. It creates no Review, FinalAcceptance, contribution or award and adds no public API or production registration. 04F3 supplies hidden replacement intake and 04F4 hidden Operator retry; manager-visible setup-fault hold and the live drill remain. -ARCH-04F3 intended merged boundary: [exact-cause checker-remediation replacement](../.commitrail/initiatives/WS-ARCH-001/WS-ARCH-001-04F3.md). Existing hidden ART intake and TASK creation admit a changed full ZIP only from the exact current authorized remediation source under either policy mode. The successor Submission, binding, AUTH decisions and generation-one request commit atomically; old evidence stays immutable. Uncaused `revision` runtime/replay is removed, and migration `0034_checker_remediation_replacement` refuses retained unprovable revision rows without deleting them. 04F4 adds hidden terminal-failure Operator retry; manager-visible setup-fault hold, production registration, public intake and the live drill remain. +ARCH-04F3 intended merged boundary: [exact-cause checker-remediation replacement](../.commitrail/initiatives/WS-ARCH-001/WS-ARCH-001-04F3.md). Existing hidden ART intake and TASK creation admit a changed full ZIP only from the exact current authorized remediation source under either policy mode. The successor Submission, binding, AUTH decisions and generation-one request commit atomically; old evidence stays immutable. Uncaused `revision` runtime/replay is removed, and migration `0034_checker_remediation_replacement` refuses retained unprovable revision rows without deleting them. 04F4 adds hidden terminal-failure Operator retry; manager-visible setup-fault hold, public intake and the complete public drill remain. ARCH-04F4 intended merged boundary: [hidden Operator checker retry](../.commitrail/initiatives/WS-ARCH-001/WS-ARCH-001-04F4.md). An active system Operator can request a reason-bound new CHECKERS generation only for the exact current terminal `infrastructure_failed` run. The existing coordinator and request handler retain a new immutable retry receipt, AUTH decision, audit and request event while preserving the failed run; fresh-authorized same-key replay validates historical ownership and the original closure without creating another run. No public route, production registration, setup-fault hold or contributor penalty is supplied by this chunk. -ARCH-04E3A proof: [hidden invocation-scoped ART materialization](../.commitrail/initiatives/WS-ARCH-001/WS-ARCH-001-04E3A.md) leases the existing Celery child provider and closes bounded scratch for hidden request delivery. Production registration remains unavailable. +ARCH-04E3A proof: [hidden invocation-scoped ART materialization](../.commitrail/initiatives/WS-ARCH-001/WS-ARCH-001-04E3A.md) leases the existing Celery child provider and closes bounded scratch for hidden request delivery. PILOT-04 adds selected production request/completion composition; no public intake is supplied. From c0ffb0f47b0db0a4af7c264e2801392b68dcb9dd Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 11:05:47 +0100 Subject: [PATCH 171/283] [PILOT-04] Record repaired flow and exact worker bounds --- .../changes/pilot04-workstream-default-checker.md | 14 ++++++++++++++ docs/roadmap_status.md | 7 ++++--- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 63156a527..755736162 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -427,3 +427,17 @@ contracts are retained provenance, not executable catalogue fallback. Source inspection confirms output-file storage/binding is deny-only while selected images produce closed JSON results. This editorial repair adds no runtime proof; the lead owns final-head native cause guards, worker timing and hosted CI. + +Final repaired native evidence: cause-substitution and intermediate TASK-lock +wait controls passed 3 tests in 186.12s at 11bd7bda0. Real prefork kill/reap, +UNKNOWN persistence and independent hard-limit checks passed 2 tests in 25.81s +at 2d111d8c7; topology and transport controls passed 24 tests in 3.65s. Owned +database, role and MinIO cleanup completed for both native runs. The selected +Rust/MinIO probe at 89df6a34a passed actual default and external PRE rejection +without a new Submission, passing PRE-to-Submission/dispatch-to-POST/completion +to review_pending, fresh completion restart/replay, and unavailable-service +recovery through fresh verified bytes. Image platform manifest is +sha256:c2d957341116c2324299461598330bf93937786c30658a4b71ef9392e9b78278. +Its runtime is local runc/docker-dev, not hosted gVisor. Database, role, object +store and scratch cleanup passed. Later documentation commits change no product +code from that tested head. Full final-head hosted CI remains required. diff --git a/docs/roadmap_status.md b/docs/roadmap_status.md index 769715445..53ca77476 100644 --- a/docs/roadmap_status.md +++ b/docs/roadmap_status.md @@ -1107,9 +1107,10 @@ remaining trace sequence is: use the same verified ART ownership rather than a structural catalogue. AUTH-OUTBOX-02 delivers shared live authority, phase audit custody and Celery delivery/recovery scans over CON-02B. Delivery termination is bounded by a - per-event hard limit under prefork: selected POST requests reserve bounded - execution and finalization time within the one-hour lease; other events keep - their existing shorter limit. + fixed 3,660-second prefork process hard limit. Selected POST requests have + a 3,520-second handler timeout and 3,600-second lease; completion/invalidation + retain their 240-second handler timeout and 300-second lease. Exact task and + message bounds prevent either truncating approved work or extending shutdown. ARCH-03C2 enforces a dedicated non-eager prefork delivery queue. ARCH-04E1A proves source storage and detached contracts only; its false scalar proof does not make false activation available. PILOT-04 separately installs From 3fde44797607d4c187dc62f93876e6ae70d5c555 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 11:12:46 +0100 Subject: [PATCH 172/283] [PILOT-04] Repair fresh CI wording and identical Redis source --- .../changes/pilot04-workstream-default-checker.md | 12 ++++++++++++ .github/workflows/backend.yml | 4 ++-- docs/roadmap_status.md | 2 +- scripts/test_lightweight_agent_gates.py | 4 ++-- 4 files changed, 17 insertions(+), 5 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 755736162..237b95393 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -107,6 +107,9 @@ cleanup. - The existing OUTBOX prefork topology and its delivery task hard bound, with topology and real process-containment regressions, to honor the selected request budget without changing event-specific owner deadlines or selectors. +- The backend CI Redis service source and its exact structural regression, + preserving the official image digest, service count, ports and health checks + while repairing a reproduced registry quota failure before test checkout. - CHECKERS policy contracts, registry reads, default/external execution, durable attempt/result custody, post routing and composition roots. - ART preparation, verified-material callback, evidence, admission and @@ -441,3 +444,12 @@ sha256:c2d957341116c2324299461598330bf93937786c30658a4b71ef9392e9b78278. Its runtime is local runc/docker-dev, not hosted gVisor. Database, role, object store and scratch cleanup passed. Later documentation commits change no product code from that tested head. Full final-head hosted CI remains required. + +Fresh hosted CI at c0ffb0f47 found one current-roadmap vocabulary violation +(corrected to Celery composition) and two lanes failed before checkout on an +anonymous public-ECR Redis Data limit exceeded response. Use the identical +official Redis OCI index from Docker Hub instead: independently fetched bytes +hash to the same pinned 520775a41a63e77e06c73e35d2fd9cc15921a609516818796b4ecbb813078bc7. +Only the two registry prefixes and exact structural expectation change; all +services, digest, health checks, test selection and caps remain unchanged. +New-source CI verification is required; those failed lanes ran no tests. diff --git a/.github/workflows/backend.yml b/.github/workflows/backend.yml index 30db53de5..78151c8af 100644 --- a/.github/workflows/backend.yml +++ b/.github/workflows/backend.yml @@ -214,7 +214,7 @@ jobs: services: redis: - image: public.ecr.aws/docker/library/redis:7-alpine@sha256:520775a41a63e77e06c73e35d2fd9cc15921a609516818796b4ecbb813078bc7 + image: docker.io/library/redis:7-alpine@sha256:520775a41a63e77e06c73e35d2fd9cc15921a609516818796b4ecbb813078bc7 ports: - 6380:6379 options: >- @@ -388,7 +388,7 @@ jobs: services: redis: - image: public.ecr.aws/docker/library/redis:7-alpine@sha256:520775a41a63e77e06c73e35d2fd9cc15921a609516818796b4ecbb813078bc7 + image: docker.io/library/redis:7-alpine@sha256:520775a41a63e77e06c73e35d2fd9cc15921a609516818796b4ecbb813078bc7 ports: - 6380:6379 options: >- diff --git a/docs/roadmap_status.md b/docs/roadmap_status.md index 53ca77476..8e40131de 100644 --- a/docs/roadmap_status.md +++ b/docs/roadmap_status.md @@ -1095,7 +1095,7 @@ remaining trace sequence is: plus the REV-04C hidden FinalAcceptance/TASK/CON participant, support the additional false-path acceptance-source AUTH custody and activation prerequisites. Both branches have delivered request reservation `04E1B-A` and AUTH preparation `04E2-A`, followed by delivered authorized success outcomes `04E2-B` and hidden completion - delivery `04E1B-B8`. PILOT-04 supplies selected production registration and worker + delivery `04E1B-B8`. PILOT-04 supplies selected production registration and Celery composition; true routing proceeds after its own prerequisites without shared acceptance. 04F1 supplies verified failure evidence, 04F2 supplies the hidden remediation diff --git a/scripts/test_lightweight_agent_gates.py b/scripts/test_lightweight_agent_gates.py index 770696d30..2153912b9 100644 --- a/scripts/test_lightweight_agent_gates.py +++ b/scripts/test_lightweight_agent_gates.py @@ -22,13 +22,13 @@ class LightweightAgentGateTests(unittest.TestCase): """Keep the retained checks executable and cover their core parsing rules.""" - def test_backend_redis_services_use_the_exact_official_mirror_image(self) -> None: + def test_backend_redis_services_use_the_exact_official_image(self) -> None: workflow = Path(".github/workflows/backend.yml").read_text(encoding="utf-8") images = re.findall(r"(?m)^ redis:\n image: (\S+)$", workflow) self.assertEqual( images, [ - "public.ecr.aws/docker/library/redis:7-alpine@sha256:" + "docker.io/library/redis:7-alpine@sha256:" "520775a41a63e77e06c73e35d2fd9cc15921a609516818796b4ecbb813078bc7" ] * 2, From 3c4ce2fb6f2a037971eebde50f714f50e77ce7b0 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 11:29:40 +0100 Subject: [PATCH 173/283] fix(cli): decode selected checker policies --- .../pilot04-workstream-default-checker.md | 19 ++ cli/internal/api/guide_post_policy.go | 179 +++++++++++++----- .../test_guide_post_policy_http.py | 164 +++++++++------- .../test_guide_post_policy_public_api.py | 30 ++- 4 files changed, 277 insertions(+), 115 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 237b95393..b62c6a9a0 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -132,6 +132,11 @@ cleanup. tests after replacement proof. - Focused contract, AUTH, custody, replay, concurrency, failure, service, public API, CLI, PostgreSQL and MinIO tests and their exact CI ownership. +- The existing CLI post-policy read DTO and its HTTP/public-socket contract + tests. Replace the removed catalogue-policy decoder with the one closed + `external_post_submit_policy.v1` response; preserve selectors, fresh read + authority, raw output, denial handling and transport failure semantics. No + legacy-response fallback or command-surface change is allowed. ### Not allowed @@ -453,3 +458,17 @@ hash to the same pinned 520775a41a63e77e06c73e35d2fd9cc15921a609516818796b4ecbb8 Only the two registry prefixes and exact structural expectation change; all services, digest, health checks, test selection and caps remain unchanged. New-source CI verification is required; those failed lanes ran no tests. + +Fresh CLI public-contract CI then reached the current backend successfully but +rejected its selected external POST policy locally as `invalid_api_response`. +The CLI still decoded the removed catalogue schema. The bounded caller repair +uses a strict closed external-policy/registry DTO, rejects the historical active +catalogue shape and retains the existing public authority, replay and transport +controls. Focused Go packages and five HTTP contract tests pass. The strengthened +real PostgreSQL public-socket node publishes a genuine Operator-authorized POST +registry entry, derives one nonempty locked binding and passes in 96.64 seconds +at code/test head `84087f49245482ecf775a6d68dc83a849f9ebe0a`, schema head +`0036_selected_checker_flow`, with complete isolated database/role cleanup. It +uses the actual current backend JSON rather than a copied nested fixture. This +record-only descendant changes no tested CLI or test bytes. The prior hosted +143-pass/one-fail run is retained as the failing-before discriminator. diff --git a/cli/internal/api/guide_post_policy.go b/cli/internal/api/guide_post_policy.go index e8e7d4083..ff684936f 100644 --- a/cli/internal/api/guide_post_policy.go +++ b/cli/internal/api/guide_post_policy.go @@ -3,18 +3,21 @@ package api import ( "context" "encoding/json" + jsonv2 "encoding/json/v2" "errors" "math/big" "net/http" "net/url" "regexp" "slices" + "strings" + "unicode/utf8" ) // GuidePostPolicy is an observation of one retained policy, not readiness or authority. type GuidePostPolicy struct { Target PostPolicyTarget `json:"target"` - Policy CompiledPostPolicy `json:"policy"` + Policy ExternalPostPolicy `json:"policy"` Proposal GuideProposal `json:"proposal"` ActivationContext GuideActivationContext `json:"activation_context"` LifecycleStatus string `json:"lifecycle_status"` @@ -33,25 +36,49 @@ type PostPolicyTarget struct { PredecessorPolicyID *string `json:"predecessor_policy_id"` } -type CompiledPostPolicy struct { - SchemaVersion string `json:"schema_version"` - CompilerVersion string `json:"compiler_version"` - ProjectID string `json:"project_id"` - GuideVersion string `json:"guide_version"` - CatalogueID string `json:"catalogue_id"` - CatalogueSourceVersion string `json:"catalogue_source_version"` - CatalogueSchemaVersion string `json:"catalogue_schema_version"` - CatalogueManifestHash string `json:"catalogue_manifest_sha256"` - Entries []PostPolicyEntry `json:"entries"` - BlockingSeverities []string `json:"blocking_severities"` +type ExternalPostPolicy struct { + SchemaVersion string `json:"schema_version"` + Entries []ExternalCheckerBinding `json:"entries"` + PolicyHash string `json:"policy_sha256"` } -type PostPolicyEntry struct { - CheckerID string `json:"checker_id"` - DefinitionVersion string `json:"definition_version"` - ImplementationVersion string `json:"implementation_version"` - Classification string `json:"classification"` - Configuration json.RawMessage `json:"configuration"` +type ExternalCheckerBinding struct { + RequirementID string `json:"requirement_id"` + Stage string `json:"stage"` + Registry ExternalCheckerRegistryEntry `json:"registry"` + Configuration json.RawMessage `json:"configuration"` + ConfigurationHash string `json:"configuration_sha256"` +} + +type ExternalCheckerRegistryEntry struct { + CapabilityID string `json:"capability_id"` + CapabilityVersion string `json:"capability_version"` + Phase string `json:"phase"` + ImageDigest string `json:"image_digest"` + ConfigurationSchema ExternalCheckerSchema `json:"configuration_schema"` + InputSchema ExternalCheckerSchema `json:"input_schema"` + OutputSchema ExternalCheckerSchema `json:"output_schema"` + Resources ExternalCheckerResourceLimits `json:"resources"` + RegistryEntryID string `json:"registry_entry_id"` + EntryDigest string `json:"entry_digest"` + RegistrationOperationID string `json:"registration_operation_id"` + RegisteredByActorProfileID string `json:"registered_by_actor_profile_id"` + AuthorizationDecisionEventID string `json:"authorization_decision_event_id"` + CreatedAt string `json:"created_at"` +} + +type ExternalCheckerSchema struct { + SchemaID string `json:"schema_id"` + SchemaVersion string `json:"schema_version"` + Document json.RawMessage `json:"document"` + SchemaHash string `json:"schema_sha256"` +} + +type ExternalCheckerResourceLimits struct { + CPUMillis *big.Int `json:"cpu_millis"` + MemoryBytes *big.Int `json:"memory_bytes"` + DeadlineMillis *big.Int `json:"deadline_ms"` + MaximumOutputBytes *big.Int `json:"maximum_output_bytes"` } type GuideActivationContext struct { @@ -106,7 +133,7 @@ func (c *Client) GuidePostPolicy(ctx context.Context, project, guide, compilatio } proposal, err := decodeGuideProposal(fields["proposal"], project, guide, compilation) if err != nil || validatePostTarget(fields["target"], &value.Target, proposal.Value, policy) != nil || - validateCompiledPostPolicy(fields["policy"], &value.Policy, value.Target.Proposal) != nil || + validateExternalPostPolicy(fields["policy"], &value.Policy, value.Target.PolicyHash) != nil || validateActivationContext(fields["activation_context"], &value.ActivationContext) != nil { return result, &Failure{Code: "invalid_api_response"} } @@ -184,45 +211,101 @@ func sameNullableText(a, b *string) bool { } var postPolicyIdentifier = regexp.MustCompile(`^[a-z][a-z0-9_.-]{0,99}$`) +var postPolicySchemaVersion = regexp.MustCompile(`^[a-z0-9][a-z0-9_.-]{0,49}$`) -func validateCompiledPostPolicy(raw json.RawMessage, value *CompiledPostPolicy, target ProposalTarget) error { - // Public schema defaults are wire values, not a local compiler implementation. - *value = CompiledPostPolicy{SchemaVersion: "post_submit_checker_policy", CompilerVersion: "workstream-post-submit-compiler", - CatalogueID: "workstream.post_submission_checkers", CatalogueSourceVersion: "v0.1", CatalogueSchemaVersion: "post_submission_checker_capability_projection"} - fields, err := contextObject(raw, value, []string{"project_id", "guide_version", "catalogue_manifest_sha256", "entries", "blocking_severities"}, []string{"blocking_severities"}) - if err != nil || value.SchemaVersion != "post_submit_checker_policy" || value.CompilerVersion != "workstream-post-submit-compiler" || - value.CatalogueID != "workstream.post_submission_checkers" || value.CatalogueSourceVersion != "v0.1" || value.CatalogueSchemaVersion != "post_submission_checker_capability_projection" || - !sameUUID(value.ProjectID, target.ProjectID) || value.GuideVersion != target.GuideVersion || - value.CatalogueID != target.PostCatalogueID || value.CatalogueSourceVersion != target.PostCatalogueVersion || - value.CatalogueSchemaVersion != target.PostCatalogueSchemaVersion || value.CatalogueManifestHash != target.PostCatalogueManifestHash || - len(value.Entries) < 1 || len(value.Entries) > 9 || len(value.BlockingSeverities) < 2 || len(value.BlockingSeverities) > 5 { - return errors.New("invalid compiled post-policy") +func validateExternalPostPolicy(raw json.RawMessage, value *ExternalPostPolicy, targetHash string) error { + fields, err := contextObject(raw, value, []string{"schema_version", "entries", "policy_sha256"}, nil) + if err != nil || value.SchemaVersion != "external_post_submit_policy.v1" || + !contextPolicyDigest.MatchString(value.PolicyHash) || value.PolicyHash != targetHash { + return errors.New("invalid external post-policy") } var entries []json.RawMessage - if json.Unmarshal(fields["entries"], &entries) != nil { - return errors.New("invalid entries") + if jsonv2.Unmarshal(fields["entries"], &entries) != nil || entries == nil || len(entries) != len(value.Entries) { + return errors.New("invalid external post-policy entries") } - seen := make(map[string]bool, len(value.Entries)) + var previous [3]string for i := range value.Entries { entry := &value.Entries[i] - _, err := contextObject(entries[i], entry, []string{"checker_id", "definition_version", "implementation_version", "classification", "configuration"}, nil) - var configuration struct{} - if err != nil || seen[entry.CheckerID] || !postPolicyIdentifier.MatchString(entry.CheckerID) || !postPolicyIdentifier.MatchString(entry.ImplementationVersion) || - entry.DefinitionVersion != "v0.1" || !slices.Contains([]string{"platform_default", "project_required", "project_warning"}, entry.Classification) || - decode(entry.Configuration, &configuration, nil, nil) != nil { - return errors.New("invalid policy entry") + if validateExternalCheckerBinding(entries[i], entry) != nil { + return errors.New("invalid external checker binding") } - seen[entry.CheckerID] = true + identity := [3]string{entry.RequirementID, entry.Registry.CapabilityID, entry.Registry.CapabilityVersion} + if i > 0 && compareCheckerBindingIdentity(identity, previous) <= 0 { + return errors.New("external checker bindings are not canonical") + } + previous = identity } - // These are public response invariants, not local catalogue evaluation. - canonical := make([]string, 0, 5) - for _, severity := range []string{"critical", "high", "medium", "low", "info"} { - if slices.Contains(value.BlockingSeverities, severity) { - canonical = append(canonical, severity) + return nil +} + +func compareCheckerBindingIdentity(left, right [3]string) int { + for i := range left { + if comparison := strings.Compare(left[i], right[i]); comparison != 0 { + return comparison } } - if !slices.Contains(canonical, "critical") || !slices.Contains(canonical, "high") || !slices.Equal(canonical, value.BlockingSeverities) { - return errors.New("invalid blocking severities") + return 0 +} + +func validateExternalCheckerBinding(raw json.RawMessage, value *ExternalCheckerBinding) error { + fields, err := contextObject(raw, value, []string{"requirement_id", "stage", "registry", "configuration", "configuration_sha256"}, nil) + if err != nil || utf8.RuneCountInString(value.RequirementID) < 1 || utf8.RuneCountInString(value.RequirementID) > 100 || value.Stage != "post_submit" || + !contextPolicyDigest.MatchString(value.ConfigurationHash) || validateJSONObject(value.Configuration) != nil || + validateExternalCheckerRegistry(fields["registry"], &value.Registry) != nil || value.Registry.Phase != value.Stage { + return errors.New("invalid external checker binding") + } + return nil +} + +func validateExternalCheckerRegistry(raw json.RawMessage, value *ExternalCheckerRegistryEntry) error { + fields, err := contextObject(raw, value, []string{ + "capability_id", "capability_version", "phase", "image_digest", "configuration_schema", "input_schema", "output_schema", "resources", + "registry_entry_id", "entry_digest", "registration_operation_id", "registered_by_actor_profile_id", "authorization_decision_event_id", "created_at", + }, nil) + if err != nil || !postPolicyIdentifier.MatchString(value.CapabilityID) || !postPolicySchemaVersion.MatchString(value.CapabilityVersion) || + value.Phase != "post_submit" || !contextPolicyDigest.MatchString(value.ImageDigest) || !contextPolicyDigest.MatchString(value.EntryDigest) || + !validUUID(value.RegistryEntryID) || !validUUID(value.RegistrationOperationID) || !validUUID(value.RegisteredByActorProfileID) || + !validUUID(value.AuthorizationDecisionEventID) || !validTime(value.CreatedAt) || + validateExternalCheckerSchema(fields["configuration_schema"], &value.ConfigurationSchema, "") != nil || + validateExternalCheckerSchema(fields["input_schema"], &value.InputSchema, "external_checker_post_submit_input") != nil || + validateExternalCheckerSchema(fields["output_schema"], &value.OutputSchema, "external_checker_result") != nil || + validateExternalCheckerResources(fields["resources"], &value.Resources) != nil { + return errors.New("invalid external checker registry entry") + } + identity, valid := uuidIdentity(value.RegistryEntryID) + if !valid || identity[6]>>4 != 7 || identity[8]&0xc0 != 0x80 { + return errors.New("invalid external checker registry identity") + } + return nil +} + +func validateExternalCheckerSchema(raw json.RawMessage, value *ExternalCheckerSchema, requiredID string) error { + _, err := contextObject(raw, value, []string{"schema_id", "schema_version", "document", "schema_sha256"}, nil) + if err != nil || !postPolicyIdentifier.MatchString(value.SchemaID) || !postPolicySchemaVersion.MatchString(value.SchemaVersion) || + (requiredID != "" && value.SchemaID != requiredID) || !contextPolicyDigest.MatchString(value.SchemaHash) || + validateJSONObject(value.Document) != nil { + return errors.New("invalid external checker schema") + } + return nil +} + +func validateExternalCheckerResources(raw json.RawMessage, value *ExternalCheckerResourceLimits) error { + _, err := contextObject(raw, value, []string{"cpu_millis", "memory_bytes", "deadline_ms", "maximum_output_bytes"}, nil) + if err != nil || !boundedInteger(value.CPUMillis, 100, 64_000) || !boundedInteger(value.MemoryBytes, 16*1024*1024, 64*1024*1024*1024) || + !boundedInteger(value.DeadlineMillis, 100, 3_600_000) || !boundedInteger(value.MaximumOutputBytes, 256, 65_536) { + return errors.New("invalid external checker resources") + } + return nil +} + +func boundedInteger(value *big.Int, minimum, maximum int64) bool { + return value != nil && value.IsInt64() && value.Int64() >= minimum && value.Int64() <= maximum +} + +func validateJSONObject(raw json.RawMessage) error { + var value map[string]json.RawMessage + if err := jsonv2.Unmarshal(raw, &value); err != nil || value == nil { + return errors.New("invalid JSON object") } return nil } diff --git a/cli/tests/integration/test_guide_post_policy_http.py b/cli/tests/integration/test_guide_post_policy_http.py index 48e771071..b747d3921 100644 --- a/cli/tests/integration/test_guide_post_policy_http.py +++ b/cli/tests/integration/test_guide_post_policy_http.py @@ -15,6 +15,45 @@ LARGE = 9223372036854775808 +def schema(schema_id): + return { + "schema_id": schema_id, + "schema_version": "v1", + "document": {"type": "object", "additionalProperties": False}, + "schema_sha256": HASH, + } + + +def binding(requirement_id="quality_review", capability_id="acme.quality_review"): + return { + "requirement_id": requirement_id, + "stage": "post_submit", + "registry": { + "capability_id": capability_id, + "capability_version": "v1.2.3", + "phase": "post_submit", + "image_digest": HASH, + "configuration_schema": schema(f"{capability_id}.configuration"), + "input_schema": schema("external_checker_post_submit_input"), + "output_schema": schema("external_checker_result"), + "resources": { + "cpu_millis": 500, + "memory_bytes": 128 * 1024 * 1024, + "deadline_ms": 30_000, + "maximum_output_bytes": 32_768, + }, + "registry_entry_id": POLICY, + "entry_digest": HASH, + "registration_operation_id": OTHER, + "registered_by_actor_profile_id": GUIDE, + "authorization_decision_event_id": SETUP, + "created_at": "2026-10-12T08:30:00Z", + }, + "configuration": {}, + "configuration_sha256": HASH, + } + + def package(): source = proposal() source["target"].update( @@ -40,26 +79,9 @@ def package(): "predecessor_policy_id": None, }, "policy": { - "schema_version": "post_submit_checker_policy", - "compiler_version": "workstream-post-submit-compiler", - "project_id": PROJECT, - "guide_version": source["target"]["guide_version"], - "catalogue_id": source["target"]["post_catalogue_id"], - "catalogue_source_version": "v0.1", - "catalogue_schema_version": source["target"][ - "post_catalogue_schema_version" - ], - "catalogue_manifest_sha256": HASH, - "entries": [ - { - "checker_id": "content_required", - "definition_version": "v0.1", - "implementation_version": "content_required", - "classification": "platform_default", - "configuration": {}, - } - ], - "blocking_severities": ["critical", "high"], + "schema_version": "external_post_submit_policy.v1", + "entries": [binding()], + "policy_sha256": HASH, }, "proposal": source, "activation_context": { @@ -119,18 +141,6 @@ def test_post_policy_exact_read_history_defaults_and_terminal_safety(cli): historical["proposal"].update(current=False, post_submit_policy_id=None) historical["target"]["predecessor_policy_id"] = GUIDE bodies.append(historical) - defaults = deepcopy(historical) - for key in ( - "schema_version", - "compiler_version", - "catalogue_id", - "catalogue_source_version", - "catalogue_schema_version", - ): - del defaults["policy"][key] - del defaults["correction"]["status"] - del defaults["target"]["predecessor_policy_id"] - bodies.append(defaults) for value in bodies: response["body"] = json.dumps(value).encode() result = invoke(cli, origin) @@ -166,33 +176,39 @@ def test_post_policy_rejects_valid_uuid_selected_policy_substitution(cli): assert len(requests) == 1 -def test_post_policy_rejects_duplicate_checkers_and_noncanonical_severity_floor(cli): +def test_post_policy_rejects_removed_catalogue_shape_and_noncanonical_bindings(cli): with http_fixture() as (origin, response, requests): value = package() - value["policy"]["blocking_severities"] = [ - "critical", - "high", - "medium", - "low", - "info", - ] + value["policy"]["entries"] = [] response["body"] = json.dumps(value).encode() assert invoke(cli, origin).returncode == 0 duplicate = package() duplicate["policy"]["entries"] *= 2 response["body"] = json.dumps(duplicate).encode() assert_failure(invoke(cli, origin), "invalid_api_response") - for severities in ( - ["low", "info"], - ["high", "critical"], - ["critical", "high", "high"], - ["critical", "high", "unknown"], - ): - value = package() - value["policy"]["blocking_severities"] = severities - response["body"] = json.dumps(value).encode() - assert_failure(invoke(cli, origin), "invalid_api_response") - assert len(requests) == 6 + unordered = package() + unordered["policy"]["entries"] = [ + binding("z_review", "z.review"), + binding("a_review", "a.review"), + ] + response["body"] = json.dumps(unordered).encode() + assert_failure(invoke(cli, origin), "invalid_api_response") + removed = package() + removed["policy"] = { + "schema_version": "post_submit_checker_policy", + "compiler_version": "workstream-post-submit-compiler", + "project_id": PROJECT, + "guide_version": "v1", + "catalogue_id": "workstream.post_submission_checkers", + "catalogue_source_version": "v0.1", + "catalogue_schema_version": "post_submission_checker_capability_projection", + "catalogue_manifest_sha256": HASH, + "entries": [], + "blocking_severities": ["critical", "high"], + } + response["body"] = json.dumps(removed).encode() + assert_failure(invoke(cli, origin), "invalid_api_response") + assert len(requests) == 4 def test_post_policy_rejects_incomplete_malformed_and_cross_resource_packages(cli): @@ -205,23 +221,21 @@ def test_post_policy_rejects_incomplete_malformed_and_cross_resource_packages(cl (("target", "policy_hash"), "bad"), (("target", "upstream", "acknowledged_warning_hashes"), [None]), (("target", "proposal", "setup_generation"), 0), - (("policy", "project_id"), OTHER), - (("policy", "guide_version"), "wrong"), - (("policy", "catalogue_manifest_sha256"), "sha256:" + "b" * 64), + (("policy", "policy_sha256"), "sha256:" + "b" * 64), (("policy", "entries"), [None]), + (("policy", "entries", 0, "stage"), "pre_submit"), + (("policy", "entries", 0, "configuration"), []), + (("policy", "entries", 0, "configuration_sha256"), "bad"), + (("policy", "entries", 0, "registry", "phase"), "pre_submit"), ( - ("policy", "entries"), - [ - { - "checker_id": "a", - "definition_version": "v0.1", - "implementation_version": "a", - "classification": "platform_default", - "configuration": {"unexpected": True}, - } - ], + ("policy", "entries", 0, "registry", "registry_entry_id"), + "550e8400-e29b-41d4-a716-446655440000", ), - (("policy", "blocking_severities"), [None, "high"]), + (("policy", "entries", 0, "registry", "created_at"), "not-a-time"), + (("policy", "entries", 0, "registry", "input_schema", "schema_id"), "wrong"), + (("policy", "entries", 0, "registry", "output_schema", "document"), []), + (("policy", "entries", 0, "registry", "resources", "cpu_millis"), 99), + (("policy", "entries", 0, "registry", "resources", "deadline_ms"), True), (("policy", "schema_version"), None), (("activation_context", "guide_mutation_generation"), True), ( @@ -262,9 +276,27 @@ def test_post_policy_rejects_incomplete_malformed_and_cross_resource_packages(cl del value[field] response["body"] = json.dumps(value).encode() assert_failure(invoke(cli, origin), "invalid_api_response") + for path, field in ( + (("policy",), "policy_sha256"), + (("policy", "entries", 0), "configuration_sha256"), + (("policy", "entries", 0, "registry"), "entry_digest"), + (("policy", "entries", 0, "registry", "input_schema"), "document"), + (("policy", "entries", 0, "registry", "resources"), "deadline_ms"), + ): + value = package() + node = value + for key in path: + node = node[key] + del node[field] + response["body"] = json.dumps(value).encode() + assert_failure(invoke(cli, origin), "invalid_api_response") for path in ( ("target",), ("policy",), + ("policy", "entries", 0), + ("policy", "entries", 0, "registry"), + ("policy", "entries", 0, "registry", "input_schema"), + ("policy", "entries", 0, "registry", "resources"), ("activation_context",), ("proposal",), ("proposal", "target"), @@ -282,7 +314,7 @@ def test_post_policy_rejects_incomplete_malformed_and_cross_resource_packages(cl .encode() ) assert_failure(invoke(cli, origin), "invalid_api_response") - assert len(requests) == len(mutations) + len(package()) + 6 + assert len(requests) == len(mutations) + len(package()) + 15 def test_post_policy_local_selectors_and_transport_fail_closed(cli): diff --git a/cli/tests/integration/test_guide_post_policy_public_api.py b/cli/tests/integration/test_guide_post_policy_public_api.py index 73785b09f..50e147985 100644 --- a/cli/tests/integration/test_guide_post_policy_public_api.py +++ b/cli/tests/integration/test_guide_post_policy_public_api.py @@ -31,6 +31,7 @@ ) from tests.projects.guide_activation.source_fixtures import source_case # noqa: E402 from tests.projects.guide_compilation.proposals.pg_support import seed_review_actor # noqa: E402 +from tests.checkers.external.support import post_registry_spec # noqa: E402 @pytest.mark.asyncio @@ -55,7 +56,10 @@ def token(actor): ) # Canonical retained source/compilation prerequisites, not a provider-inference claim. - async with source_case(clean_postgres_database) as ( + async with source_case( + clean_postgres_database, + post_submit_registry_spec=post_registry_spec(), + ) as ( _, factory, command, @@ -195,6 +199,30 @@ async def unchanged(expected_operations): assert response.status_code == 200, response.text compiled = success(read(policy_id)) assert compiled == response.json() + assert compiled["policy"]["schema_version"] == ( + "external_post_submit_policy.v1" + ) + assert compiled["policy"]["policy_sha256"] == ( + compiled["target"]["policy_hash"] + ) + assert len(compiled["policy"]["entries"]) == 1 + selected = compiled["policy"]["entries"][0] + assert ( + selected["stage"] + == selected["registry"]["phase"] + == "post_submit" + ) + assert selected["registry"]["input_schema"]["schema_id"] == ( + "external_checker_post_submit_input" + ) + assert selected["registry"]["output_schema"]["schema_id"] == ( + "external_checker_result" + ) + assert not { + "catalogue_id", + "catalogue_source_version", + "blocking_severities", + } & compiled["policy"].keys() assert ( compiled["lifecycle_status"] == "compiled" and compiled["current"] is True From 4a860a766ce258544dd4e014c165cbac020b1317 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 11:23:45 +0100 Subject: [PATCH 174/283] test(pilot04): package authority contracts and capture selected PRE enums --- .../pilot04-workstream-default-checker.md | 19 +++++++++++++++++++ .../post_submit_routing/__init__.py | 1 + .../authorization/pre_submit/__init__.py | 1 + mcp_server/contracts/actor_get.json | 5 +++-- mcp_server/contracts/admin_roles_list.json | 6 ++++-- .../contracts/authorization_context_get.json | 6 ++++-- mcp_server/contracts/permissions_list.json | 8 +++++--- 7 files changed, 37 insertions(+), 9 deletions(-) create mode 100644 backend/tests/authorization/post_submit_routing/__init__.py create mode 100644 backend/tests/authorization/pre_submit/__init__.py diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index b62c6a9a0..ffffa9cdb 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -59,6 +59,25 @@ cleanup. ### Allowed +- The bounded CI collection/selected-contract repair permits only additive + package markers `backend/tests/authorization/pre_submit/__init__.py` and + `backend/tests/authorization/post_submit_routing/__init__.py`, plus the exact + affected `mcp_server/contracts/{authorization_context_get,permissions_list, + admin_roles_list,actor_get}.json` snapshots and + this record. No production, CLI, migration, workflow, pytest import mode, + collection selection, canonical runner or test assertion changes are allowed. + Both AUTH directories sit under the existing packaged `tests.authorization` + owner and have colliding flat `test_contracts` names; package-qualified imports + must retain every original node. Reuse the selected-fragment canonical capture + functions, change only the demonstrated selected PRE ActionId/PermissionId additions, + ServiceIdentity addition, dependent permission count, hashes and source + provenance. Preserve all nine operations and the other five snapshot files + byte-for-byte, including their captured source and hash. No MCP tool is added. + Acceptance is fresh complete canonical backend collection with every node + assigned once across all ten declared lanes, plus real backend OpenAPI drift + checks and a deliberately wrong-schema negative that still fails. This repair + makes no database/runtime or hosted green claim. + - Bounded current-document reconciliation covers `docs/roadmap_status.md`, `docs/architecture_checker_framework.md` and `docs/decision_0014_external_service_adapter_convention.md`. Describe selected diff --git a/backend/tests/authorization/post_submit_routing/__init__.py b/backend/tests/authorization/post_submit_routing/__init__.py new file mode 100644 index 000000000..1ccdb3f3a --- /dev/null +++ b/backend/tests/authorization/post_submit_routing/__init__.py @@ -0,0 +1 @@ +"""Exact post-submit routing authority contract tests.""" diff --git a/backend/tests/authorization/pre_submit/__init__.py b/backend/tests/authorization/pre_submit/__init__.py new file mode 100644 index 000000000..a4c68eeaa --- /dev/null +++ b/backend/tests/authorization/pre_submit/__init__.py @@ -0,0 +1 @@ +"""Selected PRE authority contract tests.""" diff --git a/mcp_server/contracts/actor_get.json b/mcp_server/contracts/actor_get.json index 9352adef0..50533da2e 100644 --- a/mcp_server/contracts/actor_get.json +++ b/mcp_server/contracts/actor_get.json @@ -1,5 +1,5 @@ { - "canonical_sha256": "083310034d72651d6936c869f0888d8c871330d3d8e3d2f3b7cb88f40edb0a76", + "canonical_sha256": "7c526951dbaa08ff77173242ded4bc94b51376dca6bf7dd447d29764f08188e0", "components": { "schemas": { "ActorProfileAdminResponse": { @@ -223,6 +223,7 @@ "workstream.artifact.checker_output", "workstream.task.assignment_reconciler", "workstream.task.post_submit_router", + "workstream.checker.pre_submit", "workstream.checker.post_submit", "workstream.outbox.dispatcher", "workstream.project.setup", @@ -504,7 +505,7 @@ "schema_version": 1, "source": { "action_id": "actor.profile.read", - "backend_git_sha": "2134c7be05d10c381649872d423e957f9c18caff", + "backend_git_sha": "3fde44797607d4c187dc62f93876e6ae70d5c555", "method": "GET", "openapi_version": "3.1.0", "path": "/api/v1/actors/{actor_profile_id}" diff --git a/mcp_server/contracts/admin_roles_list.json b/mcp_server/contracts/admin_roles_list.json index 83757d472..d2a684389 100644 --- a/mcp_server/contracts/admin_roles_list.json +++ b/mcp_server/contracts/admin_roles_list.json @@ -1,5 +1,5 @@ { - "canonical_sha256": "a59d6648dfb3bf4f4acc3f04c153e26cdfb950d3d1a0075a177611d3e2d9a4ef", + "canonical_sha256": "c6bc364e9aa3565a4bd7d026f2fa6625aed883e6c302118d18be8ace871e8546", "components": { "schemas": { "AdminRole": { @@ -150,6 +150,8 @@ "actor.identity_link.reactivate", "task.assignment.authority_reconcile", "task.post_submit.route", + "checker.pre_submit.execute", + "checker.pre_submit.finalize", "checker.post_submit.execute", "checker.post_submit.finalize", "outbox.dispatch", @@ -426,7 +428,7 @@ "schema_version": 1, "source": { "action_id": "authorization.admin_role_definitions.read", - "backend_git_sha": "2134c7be05d10c381649872d423e957f9c18caff", + "backend_git_sha": "3fde44797607d4c187dc62f93876e6ae70d5c555", "method": "GET", "openapi_version": "3.1.0", "path": "/api/v1/authorization/admin-role-definitions" diff --git a/mcp_server/contracts/authorization_context_get.json b/mcp_server/contracts/authorization_context_get.json index 72c26ce8f..82a1a5ab6 100644 --- a/mcp_server/contracts/authorization_context_get.json +++ b/mcp_server/contracts/authorization_context_get.json @@ -1,5 +1,5 @@ { - "canonical_sha256": "d49f96eb6f6b2731b8b18ca023676402dfe7b0236e1615586839c3326b109316", + "canonical_sha256": "bb2a74e3a63afd3ec11b3a971d1d4b607acbb44a03b78946046c0c9c8cdacfe0", "components": { "schemas": { "ActionId": { @@ -50,6 +50,8 @@ "actor.identity_link.reactivate", "task.assignment.authority_reconcile", "task.post_submit.route", + "checker.pre_submit.execute", + "checker.pre_submit.finalize", "checker.post_submit.execute", "checker.post_submit.finalize", "outbox.dispatch", @@ -541,7 +543,7 @@ "schema_version": 1, "source": { "action_id": "actor.authorization_context.read", - "backend_git_sha": "e8d5983e8fcd83980c709a4a2d7c3469a936e11b", + "backend_git_sha": "3fde44797607d4c187dc62f93876e6ae70d5c555", "method": "GET", "openapi_version": "3.1.0", "path": "/api/v1/actors/me/authorization-context" diff --git a/mcp_server/contracts/permissions_list.json b/mcp_server/contracts/permissions_list.json index d14c4c10b..6e37720a8 100644 --- a/mcp_server/contracts/permissions_list.json +++ b/mcp_server/contracts/permissions_list.json @@ -1,5 +1,5 @@ { - "canonical_sha256": "610114e15ba7a4204cd3df81ea15455e1060e82d49d70ff491e344b518c61be3", + "canonical_sha256": "77afba28dc3d6793ab29cd4b1514dd82cdfb90c65f2e007df9411700d7247b47", "components": { "schemas": { "ApiError": { @@ -87,7 +87,7 @@ "type": "array" }, "total": { - "const": 78, + "const": 80, "title": "Total", "type": "integer" } @@ -113,6 +113,8 @@ "actor.identity_link.reactivate", "task.assignment.authority_reconcile", "task.post_submit.route", + "checker.pre_submit.execute", + "checker.pre_submit.finalize", "checker.post_submit.execute", "checker.post_submit.finalize", "outbox.dispatch", @@ -389,7 +391,7 @@ "schema_version": 1, "source": { "action_id": "authorization.permission_catalogue.read", - "backend_git_sha": "2134c7be05d10c381649872d423e957f9c18caff", + "backend_git_sha": "3fde44797607d4c187dc62f93876e6ae70d5c555", "method": "GET", "openapi_version": "3.1.0", "path": "/api/v1/authorization/permissions" From e7f73a78e69a23e20c6529458fac1aecc0cb451b Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 11:36:34 +0100 Subject: [PATCH 175/283] docs(pilot04): record complete collection and MCP drift proof --- .../pilot04-workstream-default-checker.md | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index ffffa9cdb..d205b4e80 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -491,3 +491,26 @@ at code/test head `84087f49245482ecf775a6d68dc83a849f9ebe0a`, schema head uses the actual current backend JSON rather than a copied nested fixture. This record-only descendant changes no tested CLI or test bytes. The prior hosted 143-pass/one-fail run is retained as the failing-before discriminator. + +At clean `a9547a49b42c246d355b818e63c68ed85fa6270a`, the unchanged canonical +`run_test_lanes.py --collect-only` collected 8,887 unique nodes in 228.06 seconds, +with zero deselections and complete, nonoverlapping assignment to all ten lanes. +Both namespaced AUTH families are retained: three selected PRE contracts and +96 post-submit-routing nodes. Producer manifest and per-lane inventories are in +`/tmp/pilot04-a954-collection-canonical/`; raw collection output is +`/tmp/pilot04-a954-collection-canonical.log`, with generated metadata in +`/tmp/pilot04-a954-collection-metadata.json`. This is collection proof, not +backend test execution or lane-runtime evidence. + +All eleven MCP selected-fragment tests passed in 37.93 seconds against a fresh +backend OpenAPI command. A deliberately added counterfeit ActionId produced the +intended one drift-check failure with ten other checks passing in 1.24 seconds. +Logs are `/tmp/pilot04-a954-mcp-current-canonical.log` and +`/tmp/pilot04-a954-mcp-wrong-enum.log`. Canonical capture is from backend source +`3fde44797607d4c187dc62f93876e6ae70d5c555`; this repair leaves that backend code +unchanged. The local contract tests reuse the existing MCP 2.2.0 environment, +with the backend command in the locked backend environment; hosted SDK/wire and +full required CI proof remain separate. Five unaffected snapshot files retain +exact bytes, source and hashes; all nine operations are unchanged. Initial +harness setup failures (invalid output-parent layout and an incompatible backend +MCP SDK for test conftest) are retained in raw logs and are not test results. From 94e4700bb73ef5f4292685195e2ac3ae20ff3535 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 12:01:52 +0100 Subject: [PATCH 176/283] [PILOT-04] Apply public CLI regression formatting --- .../pilot04-workstream-default-checker.md | 4 ++++ .../test_guide_post_policy_public_api.py | 22 ++++++++++--------- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index d205b4e80..ca484fa91 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -514,3 +514,7 @@ full required CI proof remain separate. Five unaffected snapshot files retain exact bytes, source and hashes; all nine operations are unchanged. Initial harness setup failures (invalid output-parent layout and an incompatible backend MCP SDK for test conftest) are retained in raw logs and are not test results. + +Hosted e7 CLI checks found one formatting-only failure in the public policy +regression. Apply the repository formatter; Python AST equality before/after +confirms no test behavior change, preserving the native 8408 producer proof. diff --git a/cli/tests/integration/test_guide_post_policy_public_api.py b/cli/tests/integration/test_guide_post_policy_public_api.py index 50e147985..0e14b8c68 100644 --- a/cli/tests/integration/test_guide_post_policy_public_api.py +++ b/cli/tests/integration/test_guide_post_policy_public_api.py @@ -202,15 +202,14 @@ async def unchanged(expected_operations): assert compiled["policy"]["schema_version"] == ( "external_post_submit_policy.v1" ) - assert compiled["policy"]["policy_sha256"] == ( - compiled["target"]["policy_hash"] + assert ( + compiled["policy"]["policy_sha256"] + == (compiled["target"]["policy_hash"]) ) assert len(compiled["policy"]["entries"]) == 1 selected = compiled["policy"]["entries"][0] assert ( - selected["stage"] - == selected["registry"]["phase"] - == "post_submit" + selected["stage"] == selected["registry"]["phase"] == "post_submit" ) assert selected["registry"]["input_schema"]["schema_id"] == ( "external_checker_post_submit_input" @@ -218,11 +217,14 @@ async def unchanged(expected_operations): assert selected["registry"]["output_schema"]["schema_id"] == ( "external_checker_result" ) - assert not { - "catalogue_id", - "catalogue_source_version", - "blocking_severities", - } & compiled["policy"].keys() + assert ( + not { + "catalogue_id", + "catalogue_source_version", + "blocking_severities", + } + & compiled["policy"].keys() + ) assert ( compiled["lifecycle_status"] == "compiled" and compiled["current"] is True From b63b36347c5400fce11b4638cd235efb095333a7 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 12:00:28 +0100 Subject: [PATCH 177/283] Defer optional external checker runtime --- .../pilot04-workstream-default-checker.md | 18 +++ backend/app/adapters/checkers/__init__.py | 65 ++++++-- .../tests/checkers/external/test_runtime.py | 23 ++- .../external/test_selected_pre_submit.py | 152 +++++++++++++----- .../evaluation_delivery/test_completion.py | 11 +- 5 files changed, 211 insertions(+), 58 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index ca484fa91..39be2f296 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -151,6 +151,13 @@ cleanup. tests after replacement proof. - Focused contract, AUTH, custody, replay, concurrency, failure, service, public API, CLI, PostgreSQL and MinIO tests and their exact CI ownership. +- The CHECKERS composition adapter and existing selected PRE/POST composition + tests may defer the fixed Unix provider until a locked external entry is + actually invoked. A default-only PRE policy and an empty POST policy require + no Rust-service configuration; a nonempty policy with absent configuration + must become the existing recoverable `implementation_unavailable` outcome + after durable reservation. Partial configuration remains invalid. No second + provider, fallback executor, alternate result or lifecycle path is allowed. - The existing CLI post-policy read DTO and its HTTP/public-socket contract tests. Replace the removed catalogue-policy decoder with the one closed `external_post_submit_policy.v1` response; preserve selectors, fresh read @@ -518,3 +525,14 @@ MCP SDK for test conftest) are retained in raw logs and are not test results. Hosted e7 CLI checks found one formatting-only failure in the public policy regression. Apply the repository formatter; Python AST equality before/after confirms no test behavior change, preserving the native 8408 producer proof. + +The fixed Unix checker provider is now resolved only when a locked external +entry executes. Nineteen focused runtime and selected-PRE tests pass: an empty +PRE policy runs the actual verified-archive default with no grant or provider +construction, while a nonempty policy with absent settings opens its ART grant +and returns the existing recoverable `implementation_unavailable` category. +The production empty-POST request/completion route also passes against real +PostgreSQL with absent service settings, zero persisted external members and +complete database/role cleanup (`/tmp/pilot04-optional-runtime-post.log` and +`.json`). Strict partial-setting validation and the sole fixed provider remain +unchanged. Full final-head hosted CI remains required. diff --git a/backend/app/adapters/checkers/__init__.py b/backend/app/adapters/checkers/__init__.py index c0fa82c1d..07cfd8b17 100644 --- a/backend/app/adapters/checkers/__init__.py +++ b/backend/app/adapters/checkers/__init__.py @@ -5,7 +5,17 @@ EXTERNAL_CHECKER_PROVIDER_KEY, UnixSocketExternalCheckerAdapter, ) -from app.interfaces.external_services import ExternalServiceAdapterFactory +from app.interfaces.external_checker_execution import ( + ExternalCheckerExecutionAdapter, + ExternalCheckerExecutionResponse, + ExternalCheckerMaterialGrant, + ExternalCheckerServiceHealth, +) +from app.interfaces.external_services import ( + ExternalServiceAdapterFactory, + ExternalServiceAdapterIdentity, + ExternalServiceUnavailableError, +) from app.modules.tasks.api import TaskSubmissionContextFacts from app.modules.checkers.api.external_policy import LockedExternalPostSubmitPolicy @@ -22,6 +32,7 @@ from app.modules.checkers.api.external import ( ExternalCheckerCapabilityDefinition, ExternalCheckerCapabilityProjection, + ExternalCheckerExecutionRequest, PreSubmitExternalCheckerIdentity, PreSubmitExternalCheckerMaterial, external_checker_json_hash, @@ -63,21 +74,55 @@ def configured_external_checker_execution_factory(settings): ) -def configured_external_checker_execution(settings): - """Create the sole configured Rust-service adapter for selected execution.""" - return configured_external_checker_execution_factory(settings).create( - EXTERNAL_CHECKER_PROVIDER_KEY - ) +class _ConfiguredExternalCheckerExecution: + """Resolve the fixed Rust provider only when a locked image is invoked.""" + + def __init__(self, settings) -> None: + self._settings = settings + self._identity = ExternalServiceAdapterIdentity( + EXTERNAL_CHECKER_CAPABILITY_KEY, + EXTERNAL_CHECKER_PROVIDER_KEY, + ) + + @property + def identity(self) -> ExternalServiceAdapterIdentity: + """Expose the sole provider identity without constructing its transport.""" + return self._identity + + def _resolve(self) -> ExternalCheckerExecutionAdapter: + """Create the fixed provider or report absent runtime configuration.""" + if ( + self._settings.external_checker_service_socket is None + and self._settings.external_checker_material_root is None + ): + raise ExternalServiceUnavailableError(self._identity) + return configured_external_checker_execution_factory(self._settings).create( + EXTERNAL_CHECKER_PROVIDER_KEY + ) + + async def execute( + self, + request: ExternalCheckerExecutionRequest, + grant: ExternalCheckerMaterialGrant, + ) -> ExternalCheckerExecutionResponse: + """Resolve and invoke the sole provider for one selected binding.""" + return await self._resolve().execute(request, grant) + + async def health(self) -> ExternalCheckerServiceHealth: + """Resolve the sole provider before checking runtime readiness.""" + return await self._resolve().health() + + +def configured_external_checker_execution(settings) -> ExternalCheckerExecutionAdapter: + """Create the lazy fixed-provider adapter for selected execution.""" + return _ConfiguredExternalCheckerExecution(settings) def selected_pre_submit_checker_execution(*, settings, archive_inspector): """Compose the sole selected PRE runtime from the configured Rust service.""" - execution = configured_external_checker_execution_factory(settings).create( - EXTERNAL_CHECKER_PROVIDER_KEY - ) return SelectedPreSubmitCheckerExecutionAdapter( archive_inspector=archive_inspector, - external_execution=execution, + external_execution=configured_external_checker_execution(settings), ) diff --git a/backend/tests/checkers/external/test_runtime.py b/backend/tests/checkers/external/test_runtime.py index eb5c4f484..0e4498b07 100644 --- a/backend/tests/checkers/external/test_runtime.py +++ b/backend/tests/checkers/external/test_runtime.py @@ -15,7 +15,14 @@ import pytest from pydantic import ValidationError -from app.adapters.checkers import external_checker_execution_factory +from app.adapters.checkers import ( + configured_external_checker_execution, + external_checker_execution_factory, +) +from app.adapters.checkers.external_service import ( + EXTERNAL_CHECKER_CAPABILITY_KEY, + EXTERNAL_CHECKER_PROVIDER_KEY, +) from app.core.config import Settings from app.interfaces.external_checker_execution import ( ExternalCheckerIsolationReceipt, @@ -139,6 +146,20 @@ def test_external_service_settings_share_the_art_scratch_root(tmp_path: Path): ) +@pytest.mark.asyncio +async def test_configured_execution_defers_absent_fixed_provider_until_invocation(): + adapter = configured_external_checker_execution(Settings()) + + assert adapter.identity.capability_key == EXTERNAL_CHECKER_CAPABILITY_KEY + assert adapter.identity.provider_key == EXTERNAL_CHECKER_PROVIDER_KEY + with pytest.raises(ExternalServiceUnavailableError) as invocation: + await adapter.execute(_request(), object()) + assert invocation.value.identity == adapter.identity + with pytest.raises(ExternalServiceUnavailableError) as health: + await adapter.health() + assert health.value.identity == adapter.identity + + def test_service_runtime_files_stay_outside_art_scratch_custody(tmp_path: Path): """A live or crashed service cannot poison ART's closed root layout.""" scratch = tmp_path / "scratch" diff --git a/backend/tests/checkers/external/test_selected_pre_submit.py b/backend/tests/checkers/external/test_selected_pre_submit.py index 1d195dd58..db1afba90 100644 --- a/backend/tests/checkers/external/test_selected_pre_submit.py +++ b/backend/tests/checkers/external/test_selected_pre_submit.py @@ -14,6 +14,8 @@ import zipfile import pytest +from app.adapters.checkers import configured_external_checker_execution +from app.core.config import Settings from app.core.hashing import canonical_json_hash from app.core.identifiers import new_record_id from app.interfaces.external_checker_execution import ( @@ -46,6 +48,7 @@ from app.modules.checkers.api.selected_pre_submit import ( SelectedPreSubmitAdmissionLineage, SelectedPreSubmitLeaseFacts, + SelectedPreSubmitInfrastructureUnavailable, SelectedPreSubmitReservationFacts, SelectedPreSubmitTerminalFacts, ) @@ -358,6 +361,20 @@ def _policy() -> LockedExternalPreSubmitPolicy: ) +def _empty_policy() -> LockedExternalPreSubmitPolicy: + default = LockedWorkstreamDefault() + body = { + "schema_version": "external_pre_submit_policy.v1", + "workstream_default": default.model_dump(mode="json"), + "entries": [], + } + return LockedExternalPreSubmitPolicy( + workstream_default=default, + entries=(), + policy_sha256=canonical_json_hash(body), + ) + + def _policies() -> LockedExternalCheckerPolicies: pre = _policy() post_body = { @@ -439,6 +456,52 @@ async def execute(self, request, _grant): ) +def _execution_context(request, policy): + identity = PreSubmitExternalCheckerIdentity( + project_id=request.effective_plan.lineage.project_id, + task_id=request.task_id, + assignment_id=request.assignment_id, + prepared_generation_id=request.prepared_artifact.generation_id, + attempt_id=new_record_id(), + attempt_request_digest=SHA, + effective_plan_sha256=policy.policy_sha256, + ) + material = PreSubmitExternalCheckerMaterial( + role="submission_archive", + prepared_generation_id=identity.prepared_generation_id, + attempt_id=identity.attempt_id, + attempt_request_digest=identity.attempt_request_digest, + archive_sha256=request.prepared_artifact.commitment.sha256, + archive_byte_count=request.prepared_artifact.commitment.byte_count, + semantic_manifest_sha256=request.manifest.sha256, + media_type="application/zip", + ) + entries = tuple( + SubmissionMaterialEntry( + item.normalized_path, + item.entry_type.value, + item.byte_count, + item.sha256, + item.executable, + ) + for item in request.manifest.entries + ) + default_input = WorkstreamDefaultCheckerInput( + archive_sha256=material.archive_sha256, + archive_byte_count=material.archive_byte_count, + archive_media_type=material.media_type, + semantic_manifest_sha256=material.semantic_manifest_sha256, + entries=entries, + predecessor=None, + predecessor_exists=False, + current_predecessor=None, + current_rules_sha256=request.effective_plan.lineage.pre_submit_policy_bundle_hash, + predecessor_rules_sha256=None, + packet=SubmissionPacketView(summary="", contributor_attestation=""), + ) + return identity, material, default_input + + def _assert_terminal_round_trip(identity, policy, default_input, material, result) -> None: now = datetime.now(UTC) reservation = SelectedPreSubmitReservationFacts( @@ -491,48 +554,7 @@ async def test_selected_pre_runs_default_then_locked_external_image( ) -> None: request, inspector, manager, preparation, _catalogue = await _request(tmp_path) policy = _policy() - identity = PreSubmitExternalCheckerIdentity( - project_id=request.effective_plan.lineage.project_id, - task_id=request.task_id, - assignment_id=request.assignment_id, - prepared_generation_id=request.prepared_artifact.generation_id, - attempt_id=new_record_id(), - attempt_request_digest=SHA, - effective_plan_sha256=policy.policy_sha256, - ) - material = PreSubmitExternalCheckerMaterial( - role="submission_archive", - prepared_generation_id=identity.prepared_generation_id, - attempt_id=identity.attempt_id, - attempt_request_digest=identity.attempt_request_digest, - archive_sha256=request.prepared_artifact.commitment.sha256, - archive_byte_count=request.prepared_artifact.commitment.byte_count, - semantic_manifest_sha256=request.manifest.sha256, - media_type="application/zip", - ) - entries = tuple( - SubmissionMaterialEntry( - item.normalized_path, - item.entry_type.value, - item.byte_count, - item.sha256, - item.executable, - ) - for item in request.manifest.entries - ) - default_input = WorkstreamDefaultCheckerInput( - archive_sha256=material.archive_sha256, - archive_byte_count=material.archive_byte_count, - archive_media_type=material.media_type, - semantic_manifest_sha256=material.semantic_manifest_sha256, - entries=entries, - predecessor=None, - predecessor_exists=False, - current_predecessor=None, - current_rules_sha256=request.effective_plan.lineage.pre_submit_policy_bundle_hash, - predecessor_rules_sha256=None, - packet=SubmissionPacketView(summary="", contributor_attestation=""), - ) + identity, material, default_input = _execution_context(request, policy) grants, execution = _GrantIssuer(), _Execution(verdict) processor = SelectedPreSubmitProcessor( archive_inspector=inspector, @@ -568,6 +590,52 @@ async def test_selected_pre_runs_default_then_locked_external_image( manager.close() +@pytest.mark.asyncio +@pytest.mark.parametrize("external", [False, True]) +async def test_selected_pre_only_requires_runtime_for_locked_external_images( + tmp_path, external: bool +) -> None: + request, inspector, manager, preparation, _catalogue = await _request(tmp_path) + policy = _policy() if external else _empty_policy() + identity, material, default_input = _execution_context(request, policy) + grants = _GrantIssuer() + processor = SelectedPreSubmitProcessor( + archive_inspector=inspector, + inspection=request.inspection, + policy=policy, + default_input=default_input, + identity=identity, + material=material, + grants=grants, + execution=configured_external_checker_execution(Settings()), + ) + try: + if external: + with pytest.raises(SelectedPreSubmitInfrastructureUnavailable) as failure: + await preparation._process_prepared_submission( + request.prepared_artifact, + processor, + reserved_bytes=request.manifest.total_expanded_bytes, + maximum_entries=request.manifest.entry_count, + ) + assert failure.value.code == "implementation_unavailable" + assert len(grants.requests) == 1 + else: + result = await preparation._process_prepared_submission( + request.prepared_artifact, + processor, + reserved_bytes=request.manifest.total_expanded_bytes, + maximum_entries=request.manifest.entry_count, + ) + assert result.eligible is True + assert result.required_external_count == 0 + assert result.external_members == () + assert grants.requests == [] + finally: + await request.prepared_artifact.close() + manager.close() + + @pytest.mark.asyncio @pytest.mark.parametrize("replacement", [False, True]) async def test_selected_pre_terminal_publishes_self_contained_ready_admission( diff --git a/backend/tests/tasks/evaluation_delivery/test_completion.py b/backend/tests/tasks/evaluation_delivery/test_completion.py index b2d8648ad..18f1a7eeb 100644 --- a/backend/tests/tasks/evaluation_delivery/test_completion.py +++ b/backend/tests/tasks/evaluation_delivery/test_completion.py @@ -224,12 +224,12 @@ async def test_production_registry_delivers_request_then_completion_exactly_once assert accepted.rowcount == 1 await provision_router(h.factory) await delivery_fixture(h) - # This fixture has no external POST bindings; use the real configured - # adapter without requiring an unused service to run. Actual image - # execution is covered by the production Rust/MinIO probe. + # An empty locked POST policy completes without constructing or + # contacting the external service. Actual image execution is covered + # by the production Rust/MinIO probe. settings = h.settings.model_copy(update={ - "external_checker_service_socket": tmp_path / "checker.sock", - "external_checker_material_root": h.scratch, + "external_checker_service_socket": None, + "external_checker_material_root": None, }) monkeypatch.setattr("app.core.config.get_settings", lambda: settings) monkeypatch.setattr( @@ -251,6 +251,7 @@ async def test_production_registry_delivers_request_then_completion_exactly_once assert outcome(request_receipt)["delivery_state"] == "acknowledged", outcome(request_receipt) completed = await state(h) assert completed["run"]["status"] == "completed" + assert completed["members"] == 0 completion_event_id = completed["run"]["completion_event_id"] assert completion_event_id is not None From 318aa5ebe131b0e045adf32eaa2c63ac22a55e3d Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 11:57:40 +0100 Subject: [PATCH 178/283] test(pilot04): align permission fixture and identical Postgres source --- .../pilot04-workstream-default-checker.md | 18 ++++++++++++++++++ .github/workflows/backend.yml | 4 ++-- .github/workflows/cli.yml | 2 +- .github/workflows/mcp.yml | 2 +- mcp_server/tests/test_access_reads.py | 2 +- 5 files changed, 23 insertions(+), 5 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 39be2f296..b514e1f03 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -59,6 +59,24 @@ cleanup. ### Allowed +- The bounded permission-fixture/PostgreSQL CI provider repair permits only + `mcp_server/tests/test_access_reads.py`'s representative permission response + total (78 to the current exact 80), four exact PostgreSQL image source + prefixes in `.github/workflows/backend.yml` (two), + `.github/workflows/cli.yml` (one) and `.github/workflows/mcp.yml` (one), + and this record. Preserve every assertion, negative/schema constant, SDK + lock, fixture identity, test selector, service count, PostgreSQL 16 version, + OCI digest, health check, resource bound, job dependency and required check. + No backend product, migration or CLI product/test source may change. The + previous invalid-total negative remains invalid; no dynamic total fallback + or schema broadening is allowed. Independently fetched Docker Hub OCI index + bytes must match pinned `33f923b05f64ca54ac4401c01126a6b92afe839a0aa0a52bc5aeb5cc958e5f20`. + Acceptance is the complete existing MCP package selection, retaining and + identifying its two baseline environment-gated skips, including declarative + schema/wire and authority-revocation cases; existing lightweight workflow + controls and exact provider-only structural comparison must pass. Local + MCP 2.2 evidence is separate from hosted SDK/wire proof. + - The bounded CI collection/selected-contract repair permits only additive package markers `backend/tests/authorization/pre_submit/__init__.py` and `backend/tests/authorization/post_submit_routing/__init__.py`, plus the exact diff --git a/.github/workflows/backend.yml b/.github/workflows/backend.yml index 78151c8af..f8e55a01d 100644 --- a/.github/workflows/backend.yml +++ b/.github/workflows/backend.yml @@ -223,7 +223,7 @@ jobs: --health-timeout 5s --health-retries 10 postgres: - image: public.ecr.aws/docker/library/postgres:16@sha256:33f923b05f64ca54ac4401c01126a6b92afe839a0aa0a52bc5aeb5cc958e5f20 + image: docker.io/library/postgres:16@sha256:33f923b05f64ca54ac4401c01126a6b92afe839a0aa0a52bc5aeb5cc958e5f20 env: POSTGRES_DB: workstream_test POSTGRES_USER: workstream @@ -397,7 +397,7 @@ jobs: --health-timeout 5s --health-retries 10 postgres: - image: public.ecr.aws/docker/library/postgres:16@sha256:33f923b05f64ca54ac4401c01126a6b92afe839a0aa0a52bc5aeb5cc958e5f20 + image: docker.io/library/postgres:16@sha256:33f923b05f64ca54ac4401c01126a6b92afe839a0aa0a52bc5aeb5cc958e5f20 env: POSTGRES_DB: workstream_test POSTGRES_USER: workstream diff --git a/.github/workflows/cli.yml b/.github/workflows/cli.yml index 5d9c6f8a5..ce711759a 100644 --- a/.github/workflows/cli.yml +++ b/.github/workflows/cli.yml @@ -12,7 +12,7 @@ jobs: timeout-minutes: 15 services: postgres: - image: public.ecr.aws/docker/library/postgres:16@sha256:33f923b05f64ca54ac4401c01126a6b92afe839a0aa0a52bc5aeb5cc958e5f20 + image: docker.io/library/postgres:16@sha256:33f923b05f64ca54ac4401c01126a6b92afe839a0aa0a52bc5aeb5cc958e5f20 env: POSTGRES_DB: postgres POSTGRES_USER: workstream diff --git a/.github/workflows/mcp.yml b/.github/workflows/mcp.yml index becb87c7c..d292fac45 100644 --- a/.github/workflows/mcp.yml +++ b/.github/workflows/mcp.yml @@ -103,7 +103,7 @@ jobs: services: postgres: - image: public.ecr.aws/docker/library/postgres:16@sha256:33f923b05f64ca54ac4401c01126a6b92afe839a0aa0a52bc5aeb5cc958e5f20 + image: docker.io/library/postgres:16@sha256:33f923b05f64ca54ac4401c01126a6b92afe839a0aa0a52bc5aeb5cc958e5f20 env: POSTGRES_DB: workstream_test POSTGRES_USER: workstream diff --git a/mcp_server/tests/test_access_reads.py b/mcp_server/tests/test_access_reads.py index 0f4873cfa..deae42527 100644 --- a/mcp_server/tests/test_access_reads.py +++ b/mcp_server/tests/test_access_reads.py @@ -52,7 +52,7 @@ def _arguments(name: str) -> dict[str, Any]: def _response(name: str) -> dict[str, Any]: # Representative entries use the backend's frozen catalogue totals. if name == "workstream_permissions_list": - return {"items": [{"permission_id": "actor.profile.read_any"}], "total": 78} + return {"items": [{"permission_id": "actor.profile.read_any"}], "total": 80} if name == "workstream_admin_roles_list": return { "items": [ From 9afcd4e4bbc08c66dc3686f4498e810323b1f055 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 12:01:34 +0100 Subject: [PATCH 179/283] docs(pilot04): record MCP package and Postgres provider proof --- .../pilot04-workstream-default-checker.md | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index b514e1f03..0b630084b 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -554,3 +554,25 @@ PostgreSQL with absent service settings, zero persisted external members and complete database/role cleanup (`/tmp/pilot04-optional-runtime-post.log` and `.json`). Strict partial-setting validation and the sole fixed provider remain unchanged. Full final-head hosted CI remains required. + +At clean `769d117a7230af053ac7ff63c52f6b35b674c21b`, the entire existing MCP +package selection passed 367 tests in 47.56 seconds using the existing local +MCP 2.2.0 environment. Its two baseline environment-gated skips remain exactly +the fresh backend OpenAPI comparison and clean-wheel independence proof; each +has a separate required hosted invocation. Declarative schemas, exact GET wire, +projection, invalid response and post-revocation controls execute in this suite. +The old invalid-total negative is unchanged; the representative positive fixture +alone now matches the backend's exact 80. Raw output is +`/tmp/pilot04-permission-pg-mcp-package.log`. This is not hosted SDK 2.3 wire or +container/build proof. + +Existing lightweight workflow controls passed all 20 tests in 2.309 seconds +(`/tmp/pilot04-permission-pg-lightweight.log`). Independently fetched official +Docker Hub PostgreSQL 16 OCI index bytes are 10,237 bytes and hash exactly to +`33f923b05f64ca54ac4401c01126a6b92afe839a0aa0a52bc5aeb5cc958e5f20` +(`/tmp/pilot04-postgres-33f923-dockerhub-manifest.json`). Reversing only the four +provider-prefix replacements yields byte-identical original workflow text: +backend two services, CLI one and MCP one. All version/digest, health, PostgreSQL +configuration, resource bounds, job dependencies and required checks are retained. +No container or image layers were provisioned for this source repair. Actual +new-source hosted service startup, SDK/wire, build and full CI remain required. From 953e9f9ab452f982160ff12d1d8ca8794e4564bf Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 12:07:27 +0100 Subject: [PATCH 180/283] [PILOT-04] Clarify optional runtime and remove stale catalogue heading --- README.md | 4 ++++ backend/app/adapters/checkers/__init__.py | 6 +++--- docs/architecture_checker_framework.md | 5 +++-- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 8fdc9dc14..b3f8060af 100644 --- a/README.md +++ b/README.md @@ -187,6 +187,10 @@ unified setup agent. Accepted originals are PDF, DOCX, PPTX and byte-preserved UTF-8 Markdown (`.md`); HTML and documentation sites are not guide inputs. Guide metadata in PostgreSQL also holds at least one required task example; the agent assesses the examples with the uploaded guide documents. + +Default-only projects need no external-service configuration. The fixed Rust +provider is resolved only when a required project image executes; missing +configuration for that image produces recoverable infrastructure evidence. Findings and policy proposals retain document-access evidence. [ART-07A1](.commitrail/initiatives/WS-ART-001/WS-ART-001-07A1.md) provides strict diff --git a/backend/app/adapters/checkers/__init__.py b/backend/app/adapters/checkers/__init__.py index 07cfd8b17..1f2b5445e 100644 --- a/backend/app/adapters/checkers/__init__.py +++ b/backend/app/adapters/checkers/__init__.py @@ -47,7 +47,7 @@ def external_checker_execution_factory( *, socket_path: Path, timeout_seconds: float ) -> ExternalServiceAdapterFactory[UnixSocketExternalCheckerAdapter]: - """Compose the unselected instance-local external checker adapter factory.""" + """Compose the sole instance-local external checker adapter factory.""" factory = ExternalServiceAdapterFactory[UnixSocketExternalCheckerAdapter]( EXTERNAL_CHECKER_CAPABILITY_KEY ) @@ -62,7 +62,7 @@ def external_checker_execution_factory( def configured_external_checker_execution_factory(settings): - """Map validated settings into the unselected explicit adapter factory.""" + """Map configured image-execution settings into the sole adapter factory.""" if ( settings.external_checker_service_socket is None or settings.external_checker_material_root is None @@ -119,7 +119,7 @@ def configured_external_checker_execution(settings) -> ExternalCheckerExecutionA def selected_pre_submit_checker_execution(*, settings, archive_inspector): - """Compose the sole selected PRE runtime from the configured Rust service.""" + """Compose default/PRE checking with deferred project-image transport.""" return SelectedPreSubmitCheckerExecutionAdapter( archive_inspector=archive_inspector, external_execution=configured_external_checker_execution(settings), diff --git a/docs/architecture_checker_framework.md b/docs/architecture_checker_framework.md index a401a7e72..54fae520f 100644 --- a/docs/architecture_checker_framework.md +++ b/docs/architecture_checker_framework.md @@ -246,8 +246,6 @@ locked false-policy success through shared acceptance. Public false-guide activation remains PILOT-08 work; public intake remains PILOT-12 work. Local Rust/MinIO proof uses runc/docker-dev and makes no deployed or gVisor claim. -## Current Required Core Checkers Pending Removal - ## Gate Mapping - Project activation validates approved source/policy identities and exact @@ -256,6 +254,9 @@ Rust/MinIO proof uses runc/docker-dev and makes no deployed or gVisor claim. guards; registry publication alone grants no Task transition authority. - Selected PRE runs the four Workstream defaults and all required project images before caller-owned immutable Submission creation. +- Valid empty image bindings require no external-service configuration. The + fixed Unix provider is resolved only when an image executes; missing required + runtime configuration yields recoverable `implementation_unavailable` evidence. - Selected POST consumes committed Submission custody and produces durable evidence. TASK's authorized completion operation alone changes lifecycle state or invokes shared acceptance. From 2f1f469306a49ccb11e34bd93c8dbaaa0f891eb5 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 12:18:10 +0100 Subject: [PATCH 181/283] [PILOT-04] Reconcile delivery docs and bind final native evidence --- .../changes/pilot04-workstream-default-checker.md | 11 +++++++++++ README.md | 13 ++++++++----- docs/roadmap_status.md | 2 +- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 0b630084b..96de68f33 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -576,3 +576,14 @@ backend two services, CLI one and MCP one. All version/digest, health, PostgreSQ configuration, resource bounds, job dependencies and required checks are retained. No container or image layers were provisioned for this source repair. Actual new-source hosted service startup, SDK/wire, build and full CI remain required. + +Refreshed frozen-head native evidence at 953e9f9ab452f982160ff12d1d8ca8794e4564bf: +production empty POST with absent external settings passed 1 test in 49.19s. +This supersedes the earlier optional-runtime sidecar whose recorded HEAD was +e7 while the author tested uncommitted changes; do not attribute that earlier +run to the later frozen commit. The configured Rust/MinIO flow also passed at +953 with the same c2d957 platform image: default and external PRE rejection, +passing atomic Submission/dispatch through POST and completion to review_pending, +restart/replay and unavailable-service recovery via fresh verified bytes. Both +isolated runners record schema0036 and completed DB/role/MinIO cleanup; runtime +remains local runc/docker-dev. Later README/roadmap reconciliation is prose-only. diff --git a/README.md b/README.md index b3f8060af..f8f50c5e5 100644 --- a/README.md +++ b/README.md @@ -457,8 +457,9 @@ AUTH/PREP decisions for claim, invocation and finalization. AUTH-OUTBOX-02 binds those decisions to immutable delivery receipts and supplies Celery delivery and bounded recovery scans. ARCH-03C2 registers exact assignment invalidation, with atomic publication from supported authority mutations and separate fixed -feature authority. The authorized checker request and completion handlers are -implemented but unregistered; production registration and live composition remain. +feature authority. The selected checker request and completion handlers are +registered in production composition; public contributor intake remains PILOT-12 +work. Registration does not establish deployed sandbox readiness. Delivery consumes `workstream.outbox` only under a validated non-eager prefork Celery process; other queues can use their appropriate execution pool. @@ -753,10 +754,12 @@ canonical evidence ownership. The obsolete checker worker, manual execution and submission-finalize repair routes are removed. `evaluate_post_submission` now uses hidden durable execution with exact ARCH-04D2 service authority. ARCH-04E1A retains route-neutral source evidence. REV-04C uses its bounded exact-source -verifier and hidden FinalAcceptance/TASK/CON participant, while no general -routing publication writer/reader or current pointer exists. B7 implements hidden +verifier and hidden FinalAcceptance/TASK/CON participant. The authorized TASK +outcome owner publishes exact routing sources under CHECKERS current-run custody. +B7 implements hidden request delivery with invocation fencing. B8 adds hidden completion routing with commit-before-ACK. Production -registration remains ARCH-04E3 work. +request/completion registration is supplied by the selected PILOT-04 composition; +public contributor intake remains PILOT-12 work. Submission and checker history use live exact-project Submitter authority for the original contributor. Separate `/projects/{project_id}` reads require a covering Project Manager grant and expose fixed management fields. Token roles confer no diff --git a/docs/roadmap_status.md b/docs/roadmap_status.md index 8e40131de..e05606802 100644 --- a/docs/roadmap_status.md +++ b/docs/roadmap_status.md @@ -288,7 +288,7 @@ cannot be reused as post-submission review-gate evidence. See the | Contribution evidence reads | **Public bounded backend reads** | PILOT-10A exposes current human self-read and one-project JSON/CSV export for covering Project Managers or exact-project Finance Authorities; one fresh repeatable-read response with one narrowly bounded serialization-conflict retry and fresh authority, complete zero/one/two immutable awards, exact decimals, recorded-time filters and formula-neutralized CSV; 1,000-contribution maximum refuses excess without truncation | CLI consumption and stable fixed-membership paginated list remain separate; no recognition mutation, fulfillment, payout or deployed-service claim | | Fulfillment, reconciliation, and audit | **Planned** | Shared audit foundations, provider-neutral adapter convention, AUTH-OUTBOX-02 live dispatcher authority, retained phase audit decisions, Celery delivery/recovery scans and CON-02B custody | Feature-specific handlers and authority, conditional award fulfillment, callbacks, idempotent recovery, reconciliation, bounded operational reads, and release controls | | Runtime diagnostics | **Implemented foundation** | Closed structured logging, explicit API/Celery tracing, bounded metrics, safe correlation and optional typed OTLP export | Restrict broker publishers; configure and secure collector/log access, egress, encryption and finite deletion; prove diagnostics during the release drill; no deployed monitoring claim | -| Frontend and pilot | **Local runtime foundation; product pilot planned** | Checkout-isolated Docker Compose API, prefork Celery process, beat, PostgreSQL, Redis and MinIO stack with local Flow-HMAC identities, existing authority bootstrap/grants, configurable loopback ports and project-scoped state; a pinned offline sample image build and separate oracle were proved under gVisor; React + Vite + TypeScript stack decision | Implement the external launcher/checker images and benchmark a representative task before choosing production limits; complete provider-backed guide compilation and activated-guide scoped task-denial proof on the base stack, implement only stable backed frontend surfaces, run the real internal pilot, repair findings, and complete release drills; Docker Desktop/macOS runtime proof remains | +| Frontend and pilot | **Local runtime foundation; product pilot planned** | Checkout-isolated Docker Compose API, prefork Celery process, beat, PostgreSQL, Redis and MinIO stack with local Flow-HMAC identities, existing authority bootstrap/grants, configurable loopback ports and project-scoped state; a pinned offline sample image build and separate oracle were proved under gVisor; React + Vite + TypeScript stack decision | Benchmark representative project checker images and prove hosted isolation before choosing production limits; complete provider-backed guide compilation and activated-guide scoped task-denial proof on the base stack, implement only stable backed frontend surfaces, run the real internal pilot, repair findings, and complete release drills; Docker Desktop/macOS runtime proof remains | ## What Has Been Completed From 71c066074cdc8ab5b1277181ce96a92cc16f36c6 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 12:28:48 +0100 Subject: [PATCH 182/283] [PILOT-04] Reconcile exact administrative permission count --- .../pilot04-admin-permission-fixture.md | 28 +++++++++++++++++++ .../test_admin_reads_postgresql.py | 2 +- 2 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 .commitrail/changes/pilot04-admin-permission-fixture.md diff --git a/.commitrail/changes/pilot04-admin-permission-fixture.md b/.commitrail/changes/pilot04-admin-permission-fixture.md new file mode 100644 index 000000000..2e63ad9c9 --- /dev/null +++ b/.commitrail/changes/pilot04-admin-permission-fixture.md @@ -0,0 +1,28 @@ +# [PILOT-04] Reconcile the administrative permission read fixture + +- Initiative: None +- Durable disposition: Planned +- Intended merge outcome: Administrative read coverage expects the two selected PRE permissions already owned by the current AUTH catalogue. + +## Intent and scope + +The hosted administrative read test still expects 78 permissions, while the +selected PRE execute/finalize contract makes the exact public total 80. +Allowed files are this record and +`backend/tests/authorization/admin_access/test_admin_reads_postgresql.py`. +Change only the expected permission total. Preserve role definitions, authority, +observation and response assertions. No production, migration, workflow, policy, +test selection or catalogue implementation changes are permitted. + +## Acceptance and verification + +Both parameterized administrative catalogue reads pass against real PostgreSQL. +The old permission expectation fails against the same public response. Run Ruff +and whitespace checks. This is a low-risk fixture reconciliation within PR #538; +the lead reviews the exact diff and native evidence. Human review should confirm +the total corresponds to the selected PRE permissions and no assertion is lost. + +## Roadmap + +No capability changes: this corrects a fixture for the existing selected AUTH +contract, so no additional roadmap edit is needed. diff --git a/backend/tests/authorization/admin_access/test_admin_reads_postgresql.py b/backend/tests/authorization/admin_access/test_admin_reads_postgresql.py index bd16dc0e9..dc89a6405 100644 --- a/backend/tests/authorization/admin_access/test_admin_reads_postgresql.py +++ b/backend/tests/authorization/admin_access/test_admin_reads_postgresql.py @@ -183,7 +183,7 @@ async def test_missing_admin_target_has_concealed_response_and_no_success_effect assert await authority_snapshot() == before -@pytest.mark.parametrize("surface,total", [("permissions", 78), ("admin-role-definitions", 5)]) +@pytest.mark.parametrize("surface,total", [("permissions", 80), ("admin-role-definitions", 5)]) async def test_admin_catalogue_read_returns_public_definitions( admin_access: AdminAccess, surface: str, From bb9b6a0aa91ae57d4be2ce285d6345c873074599 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 12:29:48 +0100 Subject: [PATCH 183/283] [PILOT-04] Keep the fixture scope in its existing change record --- .../pilot04-admin-permission-fixture.md | 28 ------------------- .../pilot04-workstream-default-checker.md | 10 +++++++ 2 files changed, 10 insertions(+), 28 deletions(-) delete mode 100644 .commitrail/changes/pilot04-admin-permission-fixture.md diff --git a/.commitrail/changes/pilot04-admin-permission-fixture.md b/.commitrail/changes/pilot04-admin-permission-fixture.md deleted file mode 100644 index 2e63ad9c9..000000000 --- a/.commitrail/changes/pilot04-admin-permission-fixture.md +++ /dev/null @@ -1,28 +0,0 @@ -# [PILOT-04] Reconcile the administrative permission read fixture - -- Initiative: None -- Durable disposition: Planned -- Intended merge outcome: Administrative read coverage expects the two selected PRE permissions already owned by the current AUTH catalogue. - -## Intent and scope - -The hosted administrative read test still expects 78 permissions, while the -selected PRE execute/finalize contract makes the exact public total 80. -Allowed files are this record and -`backend/tests/authorization/admin_access/test_admin_reads_postgresql.py`. -Change only the expected permission total. Preserve role definitions, authority, -observation and response assertions. No production, migration, workflow, policy, -test selection or catalogue implementation changes are permitted. - -## Acceptance and verification - -Both parameterized administrative catalogue reads pass against real PostgreSQL. -The old permission expectation fails against the same public response. Run Ruff -and whitespace checks. This is a low-risk fixture reconciliation within PR #538; -the lead reviews the exact diff and native evidence. Human review should confirm -the total corresponds to the selected PRE permissions and no assertion is lost. - -## Roadmap - -No capability changes: this corrects a fixture for the existing selected AUTH -contract, so no additional roadmap edit is needed. diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 96de68f33..6abaab3c7 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -59,6 +59,16 @@ cleanup. ### Allowed +- Administrative permission-read fixture reconciliation permits only + `backend/tests/authorization/admin_access/test_admin_reads_postgresql.py` + and this record. Replace the obsolete exact permission total 78 with 80, + reflecting the selected PRE execute/finalize permissions. Preserve role, + response, authority and observation assertions. No product, migration, + workflow, test selection or implementation change is permitted. Acceptance + is both existing public administrative reads on real PostgreSQL, plus Ruff + and whitespace checks. The low-risk review checks the exact diff and native + evidence. This fixture correction has no additional roadmap impact. + - The bounded permission-fixture/PostgreSQL CI provider repair permits only `mcp_server/tests/test_access_reads.py`'s representative permission response total (78 to the current exact 80), four exact PostgreSQL image source From 1e5147d2ef3fd80ac3339c5251727fb721679cc3 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 12:46:34 +0100 Subject: [PATCH 184/283] Fix correction dispatch registry read transaction --- .../changes/pilot04-workstream-default-checker.md | 11 +++++++++++ backend/app/api/deps/guide_proposals.py | 3 ++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 6abaab3c7..516894219 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -597,3 +597,14 @@ passing atomic Submission/dispatch through POST and completion to review_pending restart/replay and unavailable-service recovery via fresh verified bytes. Both isolated runners record schema0036 and completed DB/role/MinIO cleanup; runtime remains local runc/docker-dev. Later README/roadmap reconciliation is prose-only. + +Correction dispatch loads the immutable checker projection in its own explicit +root after capturing AUTH context and ending identity reads. Its product request +still starts in a fresh transaction and rechecks current manager authority before +committing or publishing. The former dependency assumed identity resolution had +left a root open: a valid detached identity and fresh request session raised +`ExternalCheckerRegistryUnavailable` before reaching either admission or denial. +The existing public manager-handoff regression reproduces that failure at +`2f1f46930` in 23.18 seconds with isolated schema `0036` and cleanup complete; +the targeted trace locates the missing registry-read transaction. Final proof +uses the normal public owner, with diagnostic exception capture removed. diff --git a/backend/app/api/deps/guide_proposals.py b/backend/app/api/deps/guide_proposals.py index 01d84448f..d07fc718b 100644 --- a/backend/app/api/deps/guide_proposals.py +++ b/backend/app/api/deps/guide_proposals.py @@ -87,10 +87,11 @@ async def get_correction_dispatch( actor = await get_authorization_actor_identity(resolved) async with prepared_authorization_service(request, resolved, session) as prepared: - capabilities = await external_checker_capability_projection(session) # Capture the immutable AUTH context before rollback expires the ORM # identity rows; dispatch still owns a fresh product transaction. await session.rollback() + async with session.begin(): + capabilities = await external_checker_capability_projection(session) yield CorrectionDispatchRequest( project_guide_correction_dispatch( session, From 6db700cb21201efbbcf79c700ae100149cc20639 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 12:47:04 +0100 Subject: [PATCH 185/283] [PILOT-04] Remove catalogue policy custody fallbacks --- .../pilot04-workstream-default-checker.md | 12 +++ .../modules/projects/post_policy/custody.py | 80 ++++--------------- 2 files changed, 28 insertions(+), 64 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 516894219..4c29b1719 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -59,6 +59,18 @@ cleanup. ### Allowed +- Project POST-policy custody accepts only the locked external-image policy. + This repair permits `backend/app/modules/projects/post_policy/custody.py` + and this record: remove the obsolete catalogue union, read fallback and + activation fallback while retaining exact operation receipts, sidecar hashes, + authority, lineage and caller-owned transactions. No stored row deletion, + migration, alternate decoder, deployment or merge is authorized by this + scope. Native current-policy public reads/approval/replay/revocation and + activation controls, Ruff and relevant owner checks verify the removal. + The lead independently inspects the final diff; affected architecture and + authority reviewers replay the combined candidate. Risk is L1 because + policy custody remains fail-closed and governs activation. + - Administrative permission-read fixture reconciliation permits only `backend/tests/authorization/admin_access/test_admin_reads_postgresql.py` and this record. Replace the obsolete exact permission total 78 with 80, diff --git a/backend/app/modules/projects/post_policy/custody.py b/backend/app/modules/projects/post_policy/custody.py index 3b5e9d84f..3ba2b7fd1 100644 --- a/backend/app/modules/projects/post_policy/custody.py +++ b/backend/app/modules/projects/post_policy/custody.py @@ -6,10 +6,6 @@ from sqlalchemy import select from app.core.hashing import canonical_json_hash -from app.modules.checkers.api.historical_post_submit import ( - CompiledPostSubmitPolicy, - parse_locked_post_submit_policy, -) from app.modules.checkers.api.external_policy import ( LockedExternalPostSubmitPolicy, validate_stored_external_post_policy, @@ -32,7 +28,7 @@ class PostPolicyCustody: """One policy and its exact immutable receipts; no current-successor substitution.""" target: PostPolicyTarget - compiled: CompiledPostSubmitPolicy | LockedExternalPostSubmitPolicy + compiled: LockedExternalPostSubmitPolicy projection: PostPolicyOperation approval: PostPolicyOperation | None correction: PostPolicyOperation | None @@ -130,40 +126,14 @@ async def load_post_policy_custody(session, policy) -> PostPolicyCustody: if projection is None or policy.projection_operation_id != projection.operation_id: raise GuideProposalError("proposal_unavailable") target = operation_receipt(projection).target - if policy.policy_body.get("schema_version") == "external_post_submit_policy.v1": - compiled = validate_stored_external_post_policy(policy.policy_body) - if ( - compiled.policy_sha256 != policy.policy_hash - or policy.required_checkers - != [item.registry.capability_id for item in compiled.entries] - or policy.warning_checkers != [] - or policy.blocking_severities != ["critical", "high"] - ): - raise GuideProposalError("proposal_unavailable") - else: - compiled = parse_locked_post_submit_policy( - policy.policy_body, - project_id=policy.project_id, - guide_version=policy.guide_version, - policy_hash=policy.policy_hash or "", - ) - if ( - compiled.catalogue_id, - compiled.catalogue_source_version, - compiled.catalogue_schema_version, - compiled.catalogue_manifest_sha256, - ) != ( - target.proposal.post_catalogue_id, - target.proposal.post_catalogue_version, - target.proposal.post_catalogue_schema_version, - target.proposal.post_catalogue_manifest_hash, - ): - raise GuideProposalError("proposal_unavailable") - compiled.validate_sidecars( - required_checkers=policy.required_checkers, - warning_checkers=policy.warning_checkers, - blocking_severities=policy.blocking_severities, - ) + compiled = validate_stored_external_post_policy(policy.policy_body) + if ( + compiled.policy_sha256 != policy.policy_hash + or policy.required_checkers != [item.registry.capability_id for item in compiled.entries] + or policy.warning_checkers != [] + or policy.blocking_severities != ["critical", "high"] + ): + raise GuideProposalError("proposal_unavailable") expected = { "project_id": str(target.proposal.project_id), "guide_id": str(target.proposal.guide_id), @@ -293,32 +263,14 @@ def validate_activation_post_policy( ): raise ValueError("post-submit checker approval custody is required") try: + parsed = validate_stored_external_post_policy(post_submit_checker_policy.policy_body) if ( - post_submit_checker_policy.policy_body.get("schema_version") - == "external_post_submit_policy.v1" + parsed.policy_sha256 != post_submit_checker_policy.policy_hash + or post_submit_checker_policy.required_checkers + != [item.registry.capability_id for item in parsed.entries] + or post_submit_checker_policy.warning_checkers != [] + or post_submit_checker_policy.blocking_severities != ["critical", "high"] ): - parsed = validate_stored_external_post_policy( - post_submit_checker_policy.policy_body - ) - if ( - parsed.policy_sha256 != post_submit_checker_policy.policy_hash - or post_submit_checker_policy.required_checkers - != [item.registry.capability_id for item in parsed.entries] - or post_submit_checker_policy.warning_checkers != [] - or post_submit_checker_policy.blocking_severities != ["critical", "high"] - ): - raise ValueError("selected post policy sidecars differ") - else: - parsed = parse_locked_post_submit_policy( - post_submit_checker_policy.policy_body, - project_id=post_submit_checker_policy.project_id, - guide_version=post_submit_checker_policy.guide_version, - policy_hash=post_submit_checker_policy.policy_hash or "", - ) - parsed.validate_sidecars( - required_checkers=post_submit_checker_policy.required_checkers, - warning_checkers=post_submit_checker_policy.warning_checkers, - blocking_severities=post_submit_checker_policy.blocking_severities, - ) + raise ValueError("external post policy sidecars differ") except ValueError as exc: raise ValueError("post-submit checker policy hash is invalid") from exc From 5ac55bde25e8162b70b78b24d6406fa576b8bd34 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 12:55:58 +0100 Subject: [PATCH 186/283] Remove legacy checker execution branches --- .../pilot04-workstream-default-checker.md | 21 ++++++ backend/app/modules/checkers/api/__init__.py | 36 ++-------- .../modules/checkers/api/canonical_values.py | 52 ++++++++++++++ .../checkers/api/evaluation_contract.py | 29 +++----- backend/app/modules/checkers/api/execution.py | 46 ++++++------- .../modules/checkers/api/materialization.py | 4 +- .../modules/checkers/api/output_custody.py | 10 +-- .../checkers/api/pre_submit_material.py | 36 ++++++++++ .../checkers/api/selected_post_submit.py | 38 +++++++++-- backend/app/modules/checkers/checker_retry.py | 7 +- backend/app/modules/checkers/execution.py | 32 +++------ .../checkers/execution_coordination.py | 34 ++-------- .../modules/checkers/execution_repository.py | 68 ++++++------------- .../app/modules/checkers/execution_results.py | 48 ++----------- .../post_submit_routing/evaluation_guard.py | 58 +++++++--------- .../external/test_selected_post_submit.py | 13 ++++ .../guide_activation/test_admission.py | 3 - .../test_capability_growth_postgresql.py | 4 +- .../test_live_cutover_postgresql.py | 34 +++++----- backend/tests/retained_material_fixtures.py | 5 +- 20 files changed, 295 insertions(+), 283 deletions(-) create mode 100644 backend/app/modules/checkers/api/canonical_values.py create mode 100644 backend/app/modules/checkers/api/pre_submit_material.py diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 4c29b1719..81c75be21 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -203,6 +203,27 @@ cleanup. `external_post_submit_policy.v1` response; preserve selectors, fresh read authority, raw output, denial handling and transport failure semantics. No legacy-response fallback or command-surface change is allowed. +- Bounded hosted-suite reconciliation may update + `backend/tests/retained_material_fixtures.py`, + `backend/tests/projects/guide_compilation/test_capability_growth_postgresql.py`, + `backend/tests/projects/guide_compilation/test_live_cutover_postgresql.py`, + `backend/tests/projects/guide_activation/test_admission.py`, and the existing + Retained-material callers + must use the current typed TASK submission-context port; worker tests must + await the current async composition helper; activation admission tests use + the current constructor. Historical migration fixtures may preserve raw rows + and predecessor shapes, but cannot reconstruct an executable catalogue DTO + or feed retained rows into the current scheduler. +- The selected-only contract cleanup may update CHECKERS public API value types, + execution, result classification, repository, coordination and retry owners, + plus `backend/app/modules/tasks/post_submit_routing/evaluation_guard.py` and + focused selected-flow tests. The current boundary accepts only the selected + external request/result schemas. Stored historical rows remain immutable and + readable as raw history, but cannot acquire a lease, execute, retry, finalize + or publish a completion. Selected replay compares the same exact TASK owner + projection and full locked selected-policy body as initial reservation. + TASK, assignment and Submission lock order, terminal eligibility, denial + semantics and persisted historical facts remain unchanged. ### Not allowed diff --git a/backend/app/modules/checkers/api/__init__.py b/backend/app/modules/checkers/api/__init__.py index aded93225..f2f695c19 100644 --- a/backend/app/modules/checkers/api/__init__.py +++ b/backend/app/modules/checkers/api/__init__.py @@ -29,7 +29,6 @@ make_external_checker_registration_request, ) from app.modules.checkers.api.pre_submit import ( - ALLOWED_PRE_SUBMIT_STORAGE_SCHEMES, EffectivePreSubmissionExecutionPlan, EffectivePreSubmissionPlanEntry, EffectivePreSubmissionPlanError, @@ -40,9 +39,12 @@ PreSubmissionExecutionFacts, PreSubmissionInfrastructureUnavailableError, PRE_SUBMISSION_RESULT_METADATA_KEYS, - SubmissionPacketView, validate_pre_submission_execution_facts, ) +from app.modules.checkers.api.pre_submit_material import ( + ALLOWED_PRE_SUBMIT_STORAGE_SCHEMES, + SubmissionPacketView, +) from app.modules.checkers.api.selected_pre_submit import ( ExternalPreSubmitIsolationFacts, ExternalPreSubmitMemberFacts, @@ -70,29 +72,8 @@ "SelectedPreSubmitInfrastructureUnavailable", ) -from app.modules.checkers.api.historical_post_submit import ( - CompiledPostSubmitPolicy, - EmptyPostSubmitConfiguration, - PostSubmitCatalogue, - PostSubmitDefinition, - PostSubmitPolicyEntry, -) -from app.modules.checkers.api.post_submit import ( - ExpectedPostSubmitContext, - ObservedPostSubmitContext, - PostSubmissionEvaluationContent, - make_post_submit_request, - PostSubmissionEvaluationRequest, - PostSubmissionEvaluationResult, - PostSubmissionExecutionPort, - PostSubmissionStructuralInput, - PostSubmitCurrentResultReference, - PostSubmitEvidenceEntry, - PostSubmitManifestEntry, - PostSubmitMemberResult, - PostSubmitPolicyInputs, -) from app.modules.checkers.api.selected_post_submit import ( + SelectedPostSubmitCurrentResultReference, SelectedPostSubmissionContent, SelectedPostSubmissionEvaluationRequest, SelectedPostSubmissionEvaluationResult, @@ -103,12 +84,7 @@ ) __all__ += ( - "CompiledPostSubmitPolicy", "EmptyPostSubmitConfiguration", "PostSubmitCatalogue", - "PostSubmitDefinition", "PostSubmitPolicyEntry", "ExpectedPostSubmitContext", - "ObservedPostSubmitContext", "PostSubmissionEvaluationContent", "make_post_submit_request", "PostSubmissionEvaluationRequest", "PostSubmissionEvaluationResult", - "PostSubmissionExecutionPort", "PostSubmissionStructuralInput", - "PostSubmitCurrentResultReference", "PostSubmitEvidenceEntry", "PostSubmitManifestEntry", - "PostSubmitMemberResult", "PostSubmitPolicyInputs", + "SelectedPostSubmitCurrentResultReference", "SelectedPostSubmissionContent", "SelectedPostSubmissionEvaluationRequest", "SelectedPostSubmissionEvaluationResult", "SelectedPostSubmitExecutionFacts", "SelectedPostSubmitLockedContext", "make_selected_post_submit_request", diff --git a/backend/app/modules/checkers/api/canonical_values.py b/backend/app/modules/checkers/api/canonical_values.py new file mode 100644 index 000000000..0d3bd1ada --- /dev/null +++ b/backend/app/modules/checkers/api/canonical_values.py @@ -0,0 +1,52 @@ +"""Canonical bounded scalar values shared by the selected checker flow.""" + +from __future__ import annotations + +import json +from typing import Annotated +from uuid import UUID + +from pydantic import BaseModel, ConfigDict, Field, StrictInt, StrictStr + +Sha256 = Annotated[StrictStr, Field(pattern=r"^sha256:[0-9a-f]{64}$")] +Identifier = Annotated[ + StrictStr, Field(min_length=1, max_length=100, pattern=r"^[a-z][a-z0-9_.-]*$") +] +VersionNumber = Annotated[StrictInt, Field(ge=1, le=2_147_483_647)] +GuideVersion = Annotated[StrictStr, Field(min_length=1, max_length=50, pattern=r"\S")] +ResourceId = Annotated[UUID, Field(strict=True)] +ByteCount = Annotated[StrictInt, Field(ge=0, le=9_223_372_036_854_775_807)] + + +class CheckerValue(BaseModel): + """Reject unknown fields and revalidate previously constructed instances.""" + + model_config = ConfigDict(extra="forbid", frozen=True, revalidate_instances="always") + + +def canonical_checker_bytes( + value: CheckerValue, + *, + exclude: set[str] | None = None, + include: set[str] | None = None, +) -> bytes: + """Use the canonical hash encoding for bounded serialized facts.""" + return json.dumps( + value.model_dump(mode="json", exclude=exclude, include=include), + sort_keys=True, + separators=(",", ":"), + ensure_ascii=False, + allow_nan=False, + ).encode("utf-8") + + +__all__ = ( + "ByteCount", + "CheckerValue", + "GuideVersion", + "Identifier", + "ResourceId", + "Sha256", + "VersionNumber", + "canonical_checker_bytes", +) diff --git a/backend/app/modules/checkers/api/evaluation_contract.py b/backend/app/modules/checkers/api/evaluation_contract.py index b82e20385..f08c6e17c 100644 --- a/backend/app/modules/checkers/api/evaluation_contract.py +++ b/backend/app/modules/checkers/api/evaluation_contract.py @@ -1,51 +1,40 @@ -"""Closed active and retained POST envelopes for the single execution owner.""" +"""Closed selected POST envelopes for the single execution owner.""" from __future__ import annotations -from typing import Annotated, TypeAlias +from typing import TypeAlias -from pydantic import Field, TypeAdapter - -from app.modules.checkers.api.post_submit import ( - PostSubmissionEvaluationRequest, - PostSubmissionEvaluationResult, -) +from pydantic import TypeAdapter from app.modules.checkers.api.selected_post_submit import ( SelectedPostSubmissionEvaluationRequest, SelectedPostSubmissionEvaluationResult, ) -PostSubmissionExecutionRequest: TypeAlias = Annotated[ - PostSubmissionEvaluationRequest | SelectedPostSubmissionEvaluationRequest, - Field(discriminator="schema_version"), -] -PostSubmissionExecutionResult: TypeAlias = Annotated[ - PostSubmissionEvaluationResult | SelectedPostSubmissionEvaluationResult, - Field(discriminator="schema_version"), -] +PostSubmissionExecutionRequest: TypeAlias = SelectedPostSubmissionEvaluationRequest +PostSubmissionExecutionResult: TypeAlias = SelectedPostSubmissionEvaluationResult _REQUEST = TypeAdapter(PostSubmissionExecutionRequest) _RESULT = TypeAdapter(PostSubmissionExecutionResult) def validate_execution_request(value: object) -> PostSubmissionExecutionRequest: - """Validate the selected writer or a retained legacy request by schema.""" + """Validate the only executable POST request schema.""" return _REQUEST.validate_python(value) def validate_stored_execution_request(value: str) -> PostSubmissionExecutionRequest: - """Decode retained canonical JSON using strict models' JSON boundary.""" + """Decode selected canonical JSON using the strict model boundary.""" return _REQUEST.validate_json(value) def validate_execution_result(value: object) -> PostSubmissionExecutionResult: - """Validate the selected writer or a retained legacy result by schema.""" + """Validate the only executable POST result schema.""" return _RESULT.validate_python(value) def validate_stored_execution_result(value: str) -> PostSubmissionExecutionResult: - """Decode retained canonical result JSON through strict models' JSON boundary.""" + """Decode selected canonical result JSON through the strict model boundary.""" return _RESULT.validate_json(value) diff --git a/backend/app/modules/checkers/api/execution.py b/backend/app/modules/checkers/api/execution.py index 5428f0155..60b4dd540 100644 --- a/backend/app/modules/checkers/api/execution.py +++ b/backend/app/modules/checkers/api/execution.py @@ -15,9 +15,9 @@ PostSubmissionExecutionRequest, PostSubmissionExecutionResult, ) -from app.modules.checkers.api.post_submit import PostSubmitCurrentResultReference -from app.modules.checkers.api.historical_post_submit import ( - PostSubmitValue, +from app.modules.checkers.api.selected_post_submit import SelectedPostSubmitCurrentResultReference +from app.modules.checkers.api.canonical_values import ( + CheckerValue, ResourceId, Sha256, VersionNumber, @@ -35,7 +35,7 @@ class CheckerRequestConflict(CheckerExecutionUnavailable): """A request key or generation already belongs to different facts.""" -class CheckerRetryCommand(PostSubmitValue): +class CheckerRetryCommand(CheckerValue): """Operator's exact source, reason and replay key; no caller-selected successor.""" source_run_id: ResourceId @@ -50,7 +50,7 @@ def nonblank_reason(cls, value: str) -> str: return value -class CheckerRetrySource(PostSubmitValue): +class CheckerRetrySource(CheckerValue): """Stored immutable failed-run tuple presented to AUTH before supersession.""" project_id: ResourceId @@ -68,7 +68,7 @@ class CheckerRetrySource(PostSubmitValue): failure_code: str = Field(min_length=1, max_length=100) -class CheckerRetryPreparation(PostSubmitValue): +class CheckerRetryPreparation(CheckerValue): """Stable actor/request/source identity bound before AUTH grants are locked.""" actor_profile_id: ResourceId @@ -84,7 +84,7 @@ def nonblank_reason(cls, value: str) -> str: return value -class CheckerRetrySuccessor(PostSubmitValue): +class CheckerRetrySuccessor(CheckerValue): """Actual coordinator and participant identities appended in one transaction.""" request_id: ResourceId @@ -96,7 +96,7 @@ class CheckerRetrySuccessor(PostSubmitValue): audit_event_id: ResourceId -class CheckerRetryResult(PostSubmitValue): +class CheckerRetryResult(CheckerValue): """Retained receipt identities returned on new request or authorized replay.""" receipt_id: ResourceId @@ -105,7 +105,7 @@ class CheckerRetryResult(PostSubmitValue): authorization_decision_id: ResourceId -class CheckerRetryEventExpectation(PostSubmitValue): +class CheckerRetryEventExpectation(CheckerValue): """Immutable retry event facts for exact TASK delivery comparison.""" event_type: str @@ -119,14 +119,14 @@ class CheckerRetryEventExpectation(PostSubmitValue): payload_digest: Sha256 -class CheckerRetryDelivery(PostSubmitValue): +class CheckerRetryDelivery(CheckerValue): """CHECKERS-owned committed source and exact event for the single TASK handler.""" request: PostSubmissionExecutionRequest expected_event: CheckerRetryEventExpectation -class CheckerRetryAuthorityReceipt(PostSubmitValue): +class CheckerRetryAuthorityReceipt(CheckerValue): """AUTH's consumed exact resource, used only in the caller transaction.""" actor_profile_id: ResourceId @@ -170,7 +170,7 @@ async def record( ... -class EvaluationReservation(PostSubmitValue): +class EvaluationReservation(CheckerValue): """Stable request, attempt and result identities reserved together.""" request_id: ResourceId @@ -180,14 +180,14 @@ class EvaluationReservation(PostSubmitValue): evaluation_generation: VersionNumber -class ReservedEvaluation(PostSubmitValue): +class ReservedEvaluation(CheckerValue): """Exact retained request and identities, without a currentness assertion.""" request: PostSubmissionExecutionRequest reservation: EvaluationReservation -class ExecutionLease(PostSubmitValue): +class ExecutionLease(CheckerValue): """Database-timed generation granting temporary use of one reserved attempt.""" reservation: EvaluationReservation @@ -196,14 +196,14 @@ class ExecutionLease(PostSubmitValue): expires_at: AwareDatetime -class ExecuteFacts(PostSubmitValue): +class ExecuteFacts(CheckerValue): """Exact request and lease consumed by execution authority.""" request: PostSubmissionExecutionRequest lease: ExecutionLease -class VerifiedMaterialFacts(PostSubmitValue): +class VerifiedMaterialFacts(CheckerValue): """ART-verified byte and lineage facts required for completed results.""" submission_id: ResourceId @@ -292,14 +292,14 @@ def execution_authority_digest(facts: ExecuteFacts | FinalizeAuthorityFacts) -> return canonical_json_hash(execution_authority_values(facts)) -class ExecuteEvidence(PostSubmitValue): +class ExecuteEvidence(CheckerValue): """Opaque action-specific receipt; real AUTH custody is installed by 04D.""" evidence_id: ResourceId facts_digest: Sha256 -class FinalizeEvidence(PostSubmitValue): +class FinalizeEvidence(CheckerValue): """Nominally distinct from execute evidence, even for the same run.""" evidence_id: ResourceId @@ -370,10 +370,10 @@ def prepare_finalization( ... -class CompletedEvaluation(PostSubmitValue): +class CompletedEvaluation(CheckerValue): """Fresh owner projection; the consumer must keep the caller transaction open.""" - reference: PostSubmitCurrentResultReference + reference: SelectedPostSubmitCurrentResultReference routing_recommendation: Literal["allow_review", "needs_revision", "task_setup_blocked"] result: PostSubmissionExecutionResult @@ -430,20 +430,20 @@ async def read_current_result( ... -class EvaluationCompletion(PostSubmitValue): +class EvaluationCompletion(CheckerValue): """Bounded publication facts, never perpetual authority or private packet data.""" project_id: ResourceId task_id: ResourceId submission_id: ResourceId - reference: PostSubmitCurrentResultReference + reference: SelectedPostSubmitCurrentResultReference routing_recommendation: Literal["allow_review", "needs_revision", "task_setup_blocked"] output_binding_ids: tuple[ResourceId, ...] = Field(max_length=0) execute_evidence_id: ResourceId finalize_evidence_id: ResourceId -class VerifiedEvaluationCompletion(PostSubmitValue): +class VerifiedEvaluationCompletion(CheckerValue): """Current owner-verified completion and retained material, never routing authority.""" completion: EvaluationCompletion diff --git a/backend/app/modules/checkers/api/materialization.py b/backend/app/modules/checkers/api/materialization.py index 00097ce30..d6246febf 100644 --- a/backend/app/modules/checkers/api/materialization.py +++ b/backend/app/modules/checkers/api/materialization.py @@ -9,7 +9,7 @@ from app.core.hashing import canonical_json_hash from app.modules.checkers.api.execution import ExecuteFacts, execution_authority_digest, VerifiedMaterialFacts from app.modules.checkers.api.material import SubmissionMaterialEntry -from app.modules.checkers.api.historical_post_submit import PostSubmitValue, ResourceId, Sha256, VersionNumber +from app.modules.checkers.api.canonical_values import CheckerValue, ResourceId, Sha256, VersionNumber from app.modules.checkers.api.evaluation_contract import ( PostSubmissionExecutionRequest, @@ -29,7 +29,7 @@ class PostSubmissionMaterializationFailure(RuntimeError): """Retain a known post-authorization material failure after successful cleanup.""" -class MaterializationFacts(PostSubmitValue): +class MaterializationFacts(CheckerValue): """Exact selected ancestry without provider coordinates or scratch authority.""" execution: ExecuteFacts diff --git a/backend/app/modules/checkers/api/output_custody.py b/backend/app/modules/checkers/api/output_custody.py index 288cd509c..c0a8fcc9b 100644 --- a/backend/app/modules/checkers/api/output_custody.py +++ b/backend/app/modules/checkers/api/output_custody.py @@ -8,9 +8,9 @@ from pydantic import Field, StrictInt, model_validator from app.modules.checkers.api.evaluation_contract import PostSubmissionExecutionRequest -from app.modules.checkers.api.historical_post_submit import ( +from app.modules.checkers.api.canonical_values import ( + CheckerValue, Identifier, - PostSubmitValue, ResourceId, VersionNumber, ) @@ -20,7 +20,7 @@ class CheckerOutputUnavailable(RuntimeError): """Conceal missing, stale or unauthorized checker output custody.""" -class CheckerOutputSelector(PostSubmitValue): +class CheckerOutputSelector(CheckerValue): """Select exact immutable evaluation and the caller's claimed execution lease.""" evaluation: PostSubmissionExecutionRequest @@ -30,7 +30,7 @@ class CheckerOutputSelector(PostSubmitValue): slot_key: Identifier -class CheckerOutputSlot(PostSubmitValue): +class CheckerOutputSlot(CheckerValue): """One globally unique run slot issued by CHECKERS, not by a contributor.""" key: Identifier @@ -38,7 +38,7 @@ class CheckerOutputSlot(PostSubmitValue): maximum_bytes: Annotated[StrictInt, Field(ge=1, le=536_870_912)] -class CheckerOutputReservation(PostSubmitValue): +class CheckerOutputReservation(CheckerValue): """Detached owner facts, never a substitute for fresh action authority.""" evaluation: PostSubmissionExecutionRequest diff --git a/backend/app/modules/checkers/api/pre_submit_material.py b/backend/app/modules/checkers/api/pre_submit_material.py new file mode 100644 index 000000000..fc189cdb3 --- /dev/null +++ b/backend/app/modules/checkers/api/pre_submit_material.py @@ -0,0 +1,36 @@ +"""Neutral contributor packet facts used by the selected PRE flow.""" + +from __future__ import annotations + +from dataclasses import dataclass + +from app.core.hashing import canonical_json_hash + + +ALLOWED_PRE_SUBMIT_STORAGE_SCHEMES = frozenset({"local", "s3"}) + + +@dataclass(frozen=True, slots=True) +class SubmissionPacketView: + """Bounded optional text accompanying server-owned verified ZIP facts.""" + + summary: str + contributor_attestation: str + + def __post_init__(self) -> None: + for value in (self.summary, self.contributor_attestation): + if type(value) is not str or len(value.encode("utf-8")) > 64 * 1024: + raise ValueError("submission packet text is invalid") + + @property + def sha256(self) -> str: + """Commit to the same exact text at preparation and Submission creation.""" + return canonical_json_hash( + { + "summary": self.summary, + "contributor_attestation": self.contributor_attestation, + } + ) + + +__all__ = ("ALLOWED_PRE_SUBMIT_STORAGE_SCHEMES", "SubmissionPacketView") diff --git a/backend/app/modules/checkers/api/selected_post_submit.py b/backend/app/modules/checkers/api/selected_post_submit.py index 6fee3771e..32fe5ab10 100644 --- a/backend/app/modules/checkers/api/selected_post_submit.py +++ b/backend/app/modules/checkers/api/selected_post_submit.py @@ -11,16 +11,16 @@ from app.core.hashing import canonical_json_hash from app.modules.checkers.api.external import ExternalCheckerExecutionResult from app.modules.checkers.api.external_policy import LockedExternalPostSubmitPolicy -from app.modules.checkers.api.historical_post_submit import ( +from app.modules.checkers.api.canonical_values import ( ByteCount, - PostSubmitValue, + CheckerValue, ResourceId, Sha256, VersionNumber, ) -class SelectedPostSubmitLockedContext(PostSubmitValue): +class SelectedPostSubmitLockedContext(CheckerValue): """Exact TASK and selected-policy lineage carried by a new Submission.""" guide_version: str = Field(min_length=1, max_length=50) @@ -42,7 +42,7 @@ class SelectedPostSubmitLockedContext(PostSubmitValue): revision_hash: Sha256 -class SelectedPostSubmissionContent(PostSubmitValue): +class SelectedPostSubmissionContent(CheckerValue): """Approved POST image policy plus the exact locked TASK context.""" project_id: ResourceId @@ -196,7 +196,7 @@ def result_digest(self) -> str: return canonical_json_hash(self.canonical_body()) -class SelectedPostSubmissionEvaluationResult(PostSubmitValue): +class SelectedPostSubmissionEvaluationResult(CheckerValue): """Durable selected POST evidence envelope with no acceptance authority.""" schema_version: Literal["workstream.selected_post_submit_result.v1"] = ( @@ -256,6 +256,33 @@ def validate_request( raise ValueError("selected POST result request mismatch") +class SelectedPostSubmitCurrentResultReference(CheckerValue): + """Owner-issued reference to one completed selected POST result.""" + + schema_version: Literal["workstream.selected_post_submit_current_result.v1"] = ( + "workstream.selected_post_submit_current_result.v1" + ) + request_id: ResourceId + request_digest: Sha256 + attempt_id: ResourceId + evaluation_generation: VersionNumber + result_id: ResourceId + result_digest: Sha256 + + def validate_result(self, result: object) -> None: + """Match exact completed selected result identity.""" + reference = SelectedPostSubmitCurrentResultReference.model_validate(self) + selected = SelectedPostSubmissionEvaluationResult.model_validate(result) + names = ( + "request_id", "request_digest", "attempt_id", + "evaluation_generation", "result_id", "result_digest", + ) + if selected.outcome != "completed" or any( + getattr(reference, key) != getattr(selected, key) for key in names + ): + raise ValueError("selected POST current reference result mismatch") + + def make_selected_post_submit_result( **fields: object, ) -> SelectedPostSubmissionEvaluationResult: @@ -292,6 +319,7 @@ def __init__(self, code: str) -> None: "ExternalPostSubmitIsolationFacts", "ExternalPostSubmitMemberFacts", "SelectedPostSubmitExecutionFacts", + "SelectedPostSubmitCurrentResultReference", "SelectedPostSubmitInfrastructureUnavailable", "SelectedPostSubmitLockedContext", "SelectedPostSubmissionContent", diff --git a/backend/app/modules/checkers/checker_retry.py b/backend/app/modules/checkers/checker_retry.py index 4963f59ea..9130241c7 100644 --- a/backend/app/modules/checkers/checker_retry.py +++ b/backend/app/modules/checkers/checker_retry.py @@ -18,10 +18,7 @@ CheckerRetrySuccessor, EvaluationTaskGuard, ) from app.modules.checkers.api.evaluation_contract import PostSubmissionExecutionRequest -from app.modules.checkers.api.selected_post_submit import ( - SelectedPostSubmissionEvaluationRequest, - make_selected_post_submit_request, -) +from app.modules.checkers.api.selected_post_submit import make_selected_post_submit_request from app.modules.checkers.execution_coordination import EvaluationCoordinator from app.modules.checkers.execution_repository import ( require_transaction, stored_request, stored_result, @@ -164,8 +161,6 @@ async def retry(self, command: CheckerRetryCommand) -> CheckerRetryResult: raise CheckerExecutionUnavailable("checker_retry_source_unavailable") if existing is not None: return await self._replay(command, existing, source) - if not isinstance(source_request, SelectedPostSubmissionEvaluationRequest): - raise CheckerExecutionUnavailable("checker_retry_policy_unavailable") preparation = CheckerRetryPreparation( actor_profile_id=self._actor_profile_id, request_key=command.request_key, reason=command.reason, source=source, diff --git a/backend/app/modules/checkers/execution.py b/backend/app/modules/checkers/execution.py index 87cd2e20f..b5f5edc45 100644 --- a/backend/app/modules/checkers/execution.py +++ b/backend/app/modules/checkers/execution.py @@ -27,7 +27,6 @@ PreparedFinalization, VerifiedMaterialFacts, ) -from app.modules.checkers.api.post_submit import PostSubmitCurrentResultReference from app.modules.checkers.api.evaluation_contract import ( PostSubmissionExecutionRequest, PostSubmissionExecutionResult, @@ -39,6 +38,7 @@ selected_post_submit_execution_budget_ms, ) from app.modules.checkers.api.selected_post_submit import ( + SelectedPostSubmitCurrentResultReference, SelectedPostSubmissionEvaluationRequest, SelectedPostSubmitInfrastructureUnavailable, make_selected_post_submit_result, @@ -47,7 +47,7 @@ SelectedPostSubmitProcessor, ) from app.interfaces.external_checker_execution import ExternalCheckerExecutionAdapter -from app.modules.checkers.api.historical_post_submit import canonical_post_submit_bytes +from app.modules.checkers.api.canonical_values import canonical_checker_bytes from app.modules.checkers.execution_repository import ( ExecutionRepository, reservation, @@ -160,16 +160,12 @@ def __init__( @staticmethod def _execution_budget_seconds(request: PostSubmissionExecutionRequest) -> int: - if isinstance(request, SelectedPostSubmissionEvaluationRequest): - return math.ceil(selected_post_submit_execution_budget_ms(request.policy) / 1000) - return EXECUTION_TIMEOUT_SECONDS + return math.ceil(selected_post_submit_execution_budget_ms(request.policy) / 1000) def _consumer(self, request, lease): - if isinstance(request, SelectedPostSubmissionEvaluationRequest): - if self._selected_execution is None: - raise CheckerExecutionUnavailable("checker_external_execution_unavailable") - return _SelectedExternalConsumer(self._selected_execution, lease) - raise CheckerExecutionUnavailable("checker_legacy_execution_retired") + if self._selected_execution is None: + raise CheckerExecutionUnavailable("checker_external_execution_unavailable") + return _SelectedExternalConsumer(self._selected_execution, lease) async def _claim(self, request): """Authorize replay or acquire the next database-timed lease atomically.""" @@ -200,16 +196,12 @@ async def _claim(self, request): ), output_binding_ids=(), ) - if not isinstance(request, SelectedPostSubmissionEvaluationRequest): - raise CheckerExecutionUnavailable("checker_legacy_execution_retired") now = await repo.now() if run.status == "running" and run.worker_lease_expires_at > now: raise CheckerExecutionUnavailable("checker_execution_lease_unavailable") execution_seconds = self._execution_budget_seconds(request) - lease_seconds = ( - execution_seconds + math.ceil(SELECTED_POST_FINALIZATION_MARGIN_MS / 1000) - if isinstance(request, SelectedPostSubmissionEvaluationRequest) - else LEASE_SECONDS + lease_seconds = execution_seconds + math.ceil( + SELECTED_POST_FINALIZATION_MARGIN_MS / 1000 ) lease = ExecutionLease( reservation=reservation(run), @@ -236,8 +228,6 @@ async def evaluate_post_submission( lease, replay = await self._claim(request) if replay is not None: return await self.finalize(replay) - if not isinstance(request, SelectedPostSubmissionEvaluationRequest): - raise CheckerExecutionUnavailable("checker_legacy_execution_retired") material = None input_materialization_evidence_id = None try: @@ -349,9 +339,9 @@ async def finalize(self, facts: FinalizeFacts) -> PostSubmissionExecutionResult: completed_at = await repo.now() await repo.write_members(run, result) if result.outcome == "completed": - reference = PostSubmitCurrentResultReference( + reference = SelectedPostSubmitCurrentResultReference( **result.model_dump( - include=set(PostSubmitCurrentResultReference.model_fields) + include=set(SelectedPostSubmitCurrentResultReference.model_fields) - {"schema_version"} ) ) @@ -379,7 +369,7 @@ async def finalize(self, facts: FinalizeFacts) -> PostSubmissionExecutionResult: ) ) run.completion_event_id = appended.event_id - run.result_json = canonical_post_submit_bytes( + run.result_json = canonical_checker_bytes( result, exclude={"result_digest"} ).decode("utf-8") run.result_digest = result.result_digest diff --git a/backend/app/modules/checkers/execution_coordination.py b/backend/app/modules/checkers/execution_coordination.py index a38bbc4cf..70c7a76a7 100644 --- a/backend/app/modules/checkers/execution_coordination.py +++ b/backend/app/modules/checkers/execution_coordination.py @@ -24,9 +24,8 @@ PostSubmissionExecutionRequest, validate_execution_request, ) -from app.modules.checkers.api.post_submit import PostSubmitCurrentResultReference from app.modules.checkers.api.selected_post_submit import ( - SelectedPostSubmissionEvaluationRequest, + SelectedPostSubmitCurrentResultReference, ) from app.modules.checkers.api.output_custody import ( CheckerOutputReservation, @@ -112,7 +111,6 @@ async def _reserve_after_task_lock( if request.evaluation_generation != expected: raise CheckerRequestConflict("checker_generation_conflict") context = request.expected_context - selected = isinstance(request, SelectedPostSubmissionEvaluationRequest) run = CheckerRun( id=str(new_record_id()), project_id=str(request.project_id), @@ -132,31 +130,13 @@ async def _reserve_after_task_lock( worker_lease_generation=0, supersedes_checker_run_id=prior.id if prior else None, locked_guide_version=context.guide_version, - locked_post_submit_checker_policy_id=str( - context.retained_catalogue_policy_id - if selected - else context.post_policy_id - ), + locked_post_submit_checker_policy_id=str(context.retained_catalogue_policy_id), locked_post_submit_checker_policy_version=( context.retained_catalogue_policy_version - if selected - else context.post_policy_version - ), - locked_post_submit_checker_policy_hash=( - context.retained_catalogue_policy_hash - if selected - else context.post_policy_hash - ), - selected_post_submit_policy_sha256=( - request.policy.policy_sha256 - if selected - else None - ), - selected_post_submit_policy_body=( - request.policy.model_dump(mode="json") - if selected - else None ), + locked_post_submit_checker_policy_hash=context.retained_catalogue_policy_hash, + selected_post_submit_policy_sha256=request.policy.policy_sha256, + selected_post_submit_policy_body=request.policy.model_dump(mode="json"), locked_review_policy_id=str(context.review_policy_id), locked_review_policy_generation=context.review_generation, locked_review_policy_hash=context.review_hash, @@ -256,9 +236,9 @@ async def read_current_result( if run.status != "completed": raise CheckerExecutionUnavailable("checker_current_result_unavailable") result = stored_result(run) - reference = PostSubmitCurrentResultReference( + reference = SelectedPostSubmitCurrentResultReference( **result.model_dump( - include=set(PostSubmitCurrentResultReference.model_fields) - {"schema_version"} + include=set(SelectedPostSubmitCurrentResultReference.model_fields) - {"schema_version"} ) ) reference.validate_result(result) diff --git a/backend/app/modules/checkers/execution_repository.py b/backend/app/modules/checkers/execution_repository.py index febed0ef5..fdcd59dab 100644 --- a/backend/app/modules/checkers/execution_repository.py +++ b/backend/app/modules/checkers/execution_repository.py @@ -19,10 +19,7 @@ validate_stored_execution_request, validate_stored_execution_result, ) -from app.modules.checkers.api.selected_post_submit import ( - SelectedPostSubmissionEvaluationResult, -) -from app.modules.checkers.api.historical_post_submit import canonical_post_submit_bytes +from app.modules.checkers.api.canonical_values import canonical_checker_bytes from app.modules.checkers.models import CheckerResult, CheckerRun, CheckerSubmissionFence @@ -34,7 +31,7 @@ def require_transaction(session: AsyncSession) -> None: def request_text(request: PostSubmissionExecutionRequest) -> str: """Serialize canonical request facts without the separately stored digest.""" - return canonical_post_submit_bytes(request, exclude={"request_sha256"}).decode("utf-8") + return canonical_checker_bytes(request, exclude={"request_sha256"}).decode("utf-8") def reservation(run: CheckerRun) -> EvaluationReservation: @@ -147,55 +144,30 @@ async def require_lease( async def write_members(self, run: CheckerRun, result: PostSubmissionExecutionResult) -> None: """Flush ordered closed results under the locked running parent.""" - if isinstance(result, SelectedPostSubmissionEvaluationResult): - for member in result.execution.external_members if result.execution else (): - self.session.add( - CheckerResult( - id=str(new_record_id()), - checker_run_id=run.id, - task_id=run.task_id, - submission_id=run.submission_id, - member_order=member.order, - checker_name=member.requirement_id, - definition_version=member.result.schema_version, - implementation_version=member.registry_entry_digest, - status=member.result.verdict or "infrastructure_failed", - code=( - "passed" - if member.result.verdict == "passed" - else member.result.findings[0].code - if member.result.findings - else "invalid_output" - ), - failure_category=( - "none" if member.result.verdict == "passed" else "submission_structure" - ), - severity=( - "info" - if member.result.verdict == "passed" - else "error" - ), - counters=[], - ) - ) - await self.session.flush() - return - for order, member in enumerate(result.member_results): + for member in result.execution.external_members if result.execution else (): self.session.add( CheckerResult( id=str(new_record_id()), checker_run_id=run.id, task_id=run.task_id, submission_id=run.submission_id, - member_order=order, - checker_name=member.checker_id, - definition_version=member.definition_version, - implementation_version=member.implementation_version, - status=member.status, - code=member.code, - failure_category=member.failure_category, - severity=member.severity, - counters=[item.model_dump(mode="json") for item in member.counters], + member_order=member.order, + checker_name=member.requirement_id, + definition_version=member.result.schema_version, + implementation_version=member.registry_entry_digest, + status=member.result.verdict or "infrastructure_failed", + code=( + "passed" + if member.result.verdict == "passed" + else member.result.findings[0].code + if member.result.findings + else "invalid_output" + ), + failure_category=( + "none" if member.result.verdict == "passed" else "submission_structure" + ), + severity=("info" if member.result.verdict == "passed" else "error"), + counters=[], ) ) await self.session.flush() diff --git a/backend/app/modules/checkers/execution_results.py b/backend/app/modules/checkers/execution_results.py index 87549cb6c..ed657a715 100644 --- a/backend/app/modules/checkers/execution_results.py +++ b/backend/app/modules/checkers/execution_results.py @@ -2,18 +2,10 @@ from dataclasses import dataclass -from app.modules.checkers.api.post_submit import ( - PostSubmissionEvaluationRequest, - PostSubmissionEvaluationResult, -) from app.modules.checkers.api.evaluation_contract import ( PostSubmissionExecutionRequest, PostSubmissionExecutionResult, ) -from app.modules.checkers.api.selected_post_submit import ( - SelectedPostSubmissionEvaluationRequest, - SelectedPostSubmissionEvaluationResult, -) @dataclass(frozen=True, slots=True) @@ -34,40 +26,14 @@ def classify_result( result.validate_request(request) if result.outcome == "infrastructure_failed": return ResultClassification("not_evaluated", 0, 0, 0, 0) - if isinstance(request, SelectedPostSubmissionEvaluationRequest) and isinstance( - result, SelectedPostSubmissionEvaluationResult - ): - members = result.execution.external_members if result.execution else () - failed = sum(member.result.verdict == "failed" for member in members) - return ResultClassification( - "needs_revision" if failed else "allow_review", - sum(member.result.verdict == "passed" for member in members), - 0, - failed, - failed, - ) - if not isinstance(request, PostSubmissionEvaluationRequest) or not isinstance( - result, PostSubmissionEvaluationResult - ): - raise ValueError("post-submit request and result schemas differ") - members = result.member_results - blocking = tuple( - m - for m in members - if m.status != "passed" and m.severity in request.policy.blocking_severities - ) - if any(m.failure_category == "task_configuration" for m in blocking): - routing = "task_setup_blocked" - elif blocking: - routing = "needs_revision" - else: - routing = "allow_review" + members = result.execution.external_members if result.execution else () + failed = sum(member.result.verdict == "failed" for member in members) return ResultClassification( - routing, - sum(m.status == "passed" for m in members), - sum(m.status == "warning" for m in members), - sum(m.status == "failed" for m in members), - len(blocking), + "needs_revision" if failed else "allow_review", + sum(member.result.verdict == "passed" for member in members), + 0, + failed, + failed, ) diff --git a/backend/app/modules/tasks/post_submit_routing/evaluation_guard.py b/backend/app/modules/tasks/post_submit_routing/evaluation_guard.py index 29c8bb731..20cd7c73c 100644 --- a/backend/app/modules/tasks/post_submit_routing/evaluation_guard.py +++ b/backend/app/modules/tasks/post_submit_routing/evaluation_guard.py @@ -7,14 +7,35 @@ from app.modules.checkers.api.execution import CheckerExecutionUnavailable from app.modules.checkers.api.evaluation_contract import PostSubmissionExecutionRequest -from app.modules.checkers.api.selected_post_submit import ( - SelectedPostSubmissionEvaluationRequest, -) from app.modules.tasks.api.submitted_bundle import SubmittedBundleRequest, SubmittedBundleUnavailable from app.modules.tasks.repository import TaskRepository from app.modules.tasks.submitted_bundle import SubmittedBundleReader +def _context_matches(request: PostSubmissionExecutionRequest, context: object) -> bool: + """Compare selected request lineage with exact retained TASK facts.""" + observed = asdict(context) + return request.expected_context.model_dump() == { + "guide_version": observed["guide_version"], + "source_id": observed["source_id"], + "source_hash": observed["source_hash"], + "effective_policy_id": observed["effective_policy_id"], + "effective_policy_hash": observed["effective_policy_hash"], + "pre_policy_id": observed["pre_policy_id"], + "pre_policy_hash": observed["pre_policy_hash"], + "retained_catalogue_policy_id": observed["post_policy_id"], + "retained_catalogue_policy_version": observed["post_policy_version"], + "retained_catalogue_policy_hash": observed["post_policy_hash"], + "selected_post_policy_hash": observed["selected_post_policy_hash"], + "review_policy_id": observed["review_policy_id"], + "review_generation": observed["review_generation"], + "review_hash": observed["review_hash"], + "revision_policy_id": observed["revision_policy_id"], + "revision_generation": observed["revision_generation"], + "revision_hash": observed["revision_hash"], + } and observed["selected_post_policy_body"] == request.policy.model_dump(mode="json") + + class TaskEvaluationGuard: """Lock current TASK scope without granting execution or changing product state.""" @@ -49,40 +70,13 @@ async def lock_evaluation_scope(self, request: PostSubmissionExecutionRequest) - )) except SubmittedBundleUnavailable: raise CheckerExecutionUnavailable("checker_reservation_scope_unavailable") from None - observed = asdict(facts.context) - expected = request.expected_context.model_dump() - context_matches = expected == { - name: observed[name] for name in expected if name in observed - } - if isinstance(request, SelectedPostSubmissionEvaluationRequest): - context_matches = expected == { - "guide_version": observed["guide_version"], - "source_id": observed["source_id"], - "source_hash": observed["source_hash"], - "effective_policy_id": observed["effective_policy_id"], - "effective_policy_hash": observed["effective_policy_hash"], - "pre_policy_id": observed["pre_policy_id"], - "pre_policy_hash": observed["pre_policy_hash"], - "retained_catalogue_policy_id": observed["post_policy_id"], - "retained_catalogue_policy_version": observed["post_policy_version"], - "retained_catalogue_policy_hash": observed["post_policy_hash"], - "selected_post_policy_hash": observed["selected_post_policy_hash"], - "review_policy_id": observed["review_policy_id"], - "review_generation": observed["review_generation"], - "review_hash": observed["review_hash"], - "revision_policy_id": observed["revision_policy_id"], - "revision_generation": observed["revision_generation"], - "revision_hash": observed["revision_hash"], - } and observed["selected_post_policy_body"] == request.policy.model_dump( - mode="json" - ) if not ( facts.assignment_id == request.assignment_id and facts.submission_version == request.submission_version and facts.contributor_id == UUID(assignment.contributor_id) and facts.binding_id == request.binding_id and facts.content_id == request.content_id - and context_matches + and _context_matches(request, facts.context) ): raise CheckerExecutionUnavailable("checker_reservation_scope_unavailable") if task.status in {"accepted", "rejected"}: @@ -133,6 +127,6 @@ async def lock_retry_replay_scope(self, request: PostSubmissionExecutionRequest) and facts.contributor_id == UUID(assignment.contributor_id) and facts.binding_id == request.binding_id and facts.content_id == request.content_id - and asdict(facts.context) == request.expected_context.model_dump() + and _context_matches(request, facts.context) ): raise CheckerExecutionUnavailable("checker_retry_replay_unavailable") diff --git a/backend/tests/checkers/external/test_selected_post_submit.py b/backend/tests/checkers/external/test_selected_post_submit.py index fc6e56644..7a6cfb56a 100644 --- a/backend/tests/checkers/external/test_selected_post_submit.py +++ b/backend/tests/checkers/external/test_selected_post_submit.py @@ -30,6 +30,7 @@ from app.modules.checkers.api.evaluation_contract import ( validate_execution_request, validate_execution_result, + validate_stored_execution_request, validate_stored_execution_result, ) from app.modules.checkers.api.execution import EvaluationReservation, ExecutionLease @@ -353,6 +354,18 @@ async def test_selected_scheduler_consumer_derives_exact_envelope(outcome, expec assert type(validate_stored_execution_result(json.dumps(stored))) is type(result) +def test_execution_boundary_rejects_removed_catalogue_request_schema() -> None: + """Retained catalogue-shaped facts cannot enter the active scheduler.""" + removed = { + "schema_version": "post_submit_evaluation_request", + "evaluation_request_id": str(new_record_id()), + } + with pytest.raises(ValueError): + validate_execution_request(removed) + with pytest.raises(ValueError): + validate_stored_execution_request(json.dumps(removed)) + + def test_selected_post_content_uses_selected_digest_not_catalogue_hash() -> None: policy = _policy() locked = SimpleNamespace( diff --git a/backend/tests/projects/guide_activation/test_admission.py b/backend/tests/projects/guide_activation/test_admission.py index 07e7c8c1c..329bec9ef 100644 --- a/backend/tests/projects/guide_activation/test_admission.py +++ b/backend/tests/projects/guide_activation/test_admission.py @@ -43,9 +43,6 @@ async def lock_activation_scope(self, locator): service = GuideActivationService( session, contribution=None, - planner=None, - pre_catalogue=None, - post_catalogue=None, authorization=Authority(), ) with pytest.raises(GuideProposalError, match="authority_unavailable"): diff --git a/backend/tests/projects/guide_compilation/test_capability_growth_postgresql.py b/backend/tests/projects/guide_compilation/test_capability_growth_postgresql.py index d70a85aae..cd8144c3b 100644 --- a/backend/tests/projects/guide_compilation/test_capability_growth_postgresql.py +++ b/backend/tests/projects/guide_compilation/test_capability_growth_postgresql.py @@ -52,7 +52,7 @@ async def compile_project_guide(self, context, capabilities): runtime.outcome = growth_report() monkeypatch.setattr(worker, "create_project_guide_runtime", lambda configuration: runtime) monkeypatch.setattr(worker, "project_guide_runtime_configuration", lambda settings: runtime_configuration()) - first = await worker._coordinator(factory).run(delivery) + first = await (await worker._coordinator(factory)).run(delivery) assert first["status"] == ("compilation_invalid_terminal" if oversized else "sufficiency_blocked") if oversized: assert first["error_code"] == "schema_invalid" @@ -86,7 +86,7 @@ def forbidden(*args): monkeypatch.setattr(worker, "create_project_guide_runtime", forbidden) monkeypatch.setattr(worker, "project_guide_runtime_configuration", forbidden) - assert await worker._coordinator(factory).run(delivery) == first + assert await (await worker._coordinator(factory)).run(delivery) == first assert runtime.calls == 1 async with factory() as session: assert await session.scalar(text("select count(*) from audit_events")) == before diff --git a/backend/tests/projects/guide_compilation/test_live_cutover_postgresql.py b/backend/tests/projects/guide_compilation/test_live_cutover_postgresql.py index 531d6d7f1..62c00f18d 100644 --- a/backend/tests/projects/guide_compilation/test_live_cutover_postgresql.py +++ b/backend/tests/projects/guide_compilation/test_live_cutover_postgresql.py @@ -94,7 +94,7 @@ async def test_pending_exact_delivery_compiles_once_and_replays_finalization( monkeypatch.setattr( worker, "project_guide_runtime_configuration", lambda settings: runtime_configuration() ) - coordinator = worker._coordinator(factory) + coordinator = await worker._coordinator(factory) first = await coordinator.run(delivery) assert first["status"] == ( "sufficiency_blocked" if status == "guide_blocked" else "policy_draft_ready" @@ -141,7 +141,7 @@ def forbidden(*args): monkeypatch.setattr(worker, "create_project_guide_runtime", forbidden) monkeypatch.setattr(worker, "project_guide_runtime_configuration", forbidden) - replay = await worker._coordinator(factory).run(delivery) + replay = await (await worker._coordinator(factory)).run(delivery) assert replay == first assert runtime.calls == 1 async with factory() as session: @@ -157,7 +157,7 @@ def forbidden(*args): from app.modules.projects.api import ProjectGuideSetupFinalizationError with pytest.raises(ProjectGuideSetupFinalizationError) as denied: - await worker._coordinator(factory).run(delivery) + await (await worker._coordinator(factory)).run(delivery) assert denied.value.code == "service_authority_denied" assert runtime.calls == 1 @@ -188,7 +188,7 @@ def forbidden(*args): async with factory() as session: before = await session.scalar(text("select count(*) from audit_events")) with pytest.raises(ProjectGuideCompilationDeliveryError, match="^stale compilation delivery$"): - await worker._coordinator(factory).run(changed) + await (await worker._coordinator(factory)).run(changed) async with factory() as session: assert await session.scalar(text("select count(*) from audit_events")) == before for table in [ @@ -229,7 +229,7 @@ async def test_invalid_or_uncertain_attempt_reports_durable_diagnostics_without_ monkeypatch.setattr( worker, "project_guide_runtime_configuration", lambda settings: runtime_configuration() ) - coordinator = worker._coordinator(factory) + coordinator = await worker._coordinator(factory) # Beat selects the exact delivery before terminal provider custody exists. await _select_stale_delivery(factory, delivery) first = await coordinator.run(delivery) @@ -300,7 +300,7 @@ async def test_finalized_receipt_excludes_every_recovery_shape(automatic_source, worker, "project_guide_runtime_configuration", lambda settings: runtime_configuration() ) await _select_stale_delivery(factory, delivery) - receipt = await worker._coordinator(factory).run(delivery) + receipt = await (await worker._coordinator(factory)).run(delivery) assert receipt["status"] == "policy_draft_ready" async with factory() as session: evidence = await session.scalar( @@ -432,7 +432,7 @@ async def dispatch(): publisher = asyncio.create_task(dispatch()) try: assert await asyncio.to_thread(published.wait, 10) - receipt = await worker._coordinator(factory).run(delivery) + receipt = await (await worker._coordinator(factory)).run(delivery) assert receipt["status"] == "policy_draft_ready" async with factory() as session: before = await session.scalar( @@ -475,7 +475,7 @@ async def test_phase_crash_recovers_same_attempt_without_reinference( monkeypatch.setattr( worker, "project_guide_runtime_configuration", lambda settings: runtime_configuration() ) - coordinator = worker._coordinator(factory) + coordinator = await worker._coordinator(factory) projections = coordinator._projections class Crash(Exception): @@ -572,7 +572,7 @@ async def test_each_phase_rechecks_service_authority_and_restoration_reuses_atte monkeypatch.setattr( worker, "project_guide_runtime_configuration", lambda settings: runtime_configuration() ) - coordinator = worker._coordinator(factory) + coordinator = await worker._coordinator(factory) async def revoke(): async with factory() as session, session.begin(): @@ -673,17 +673,19 @@ async def blocked_provider(context, capabilities): monkeypatch.setattr( worker, "project_guide_runtime_configuration", lambda settings: runtime_configuration() ) - first = asyncio.create_task(worker._coordinator(factory).run(delivery)) + first = asyncio.create_task((await worker._coordinator(factory)).run(delivery)) try: await asyncio.wait_for(entered.wait(), timeout=20) - duplicate = await asyncio.wait_for(worker._coordinator(factory).run(delivery), timeout=20) + duplicate = await asyncio.wait_for( + (await worker._coordinator(factory)).run(delivery), timeout=20 + ) assert duplicate["error_code"] == "provider_outcome_unresolved" finally: release.set() receipt = await asyncio.wait_for(first, timeout=30) assert receipt["status"] == "policy_draft_ready" assert runtime.calls == 1 - assert await worker._coordinator(factory).run(delivery) == receipt + assert await (await worker._coordinator(factory)).run(delivery) == receipt async with factory() as session: for table in [ "project_guide_compilation_attempts", @@ -727,7 +729,7 @@ def forbidden(*args): monkeypatch.setattr(worker, "create_project_guide_runtime", forbidden) monkeypatch.setattr(worker, "project_guide_runtime_configuration", forbidden) with pytest.raises(ProjectGuideCompilationDeliveryError): - await worker._coordinator(factory).run(delivery) + await (await worker._coordinator(factory)).run(delivery) async with factory() as session: for table in ( "project_guide_compilation_request_operations", @@ -757,7 +759,7 @@ def unavailable(settings): monkeypatch.setattr(worker, "project_guide_runtime_configuration", unavailable) for _ in range(4): with pytest.raises(ValueError, match="missing runtime configuration"): - await worker._coordinator(factory).run(delivery) + await (await worker._coordinator(factory)).run(delivery) async with factory() as session: assert ( await session.scalar(text("select count(*) from project_guide_compilation_attempts")) @@ -769,9 +771,9 @@ def unavailable(settings): worker, "project_guide_runtime_configuration", lambda settings: runtime_configuration() ) monkeypatch.setattr(worker, "create_project_guide_runtime", lambda configuration: runtime) - first = await worker._coordinator(factory).run(delivery) + first = await (await worker._coordinator(factory)).run(delivery) assert first["status"] == "policy_draft_ready" - assert await worker._coordinator(factory).run(delivery) == first + assert await (await worker._coordinator(factory)).run(delivery) == first assert runtime.calls == 1 assert delivery.source_snapshot_id not in await _published_continuation_snapshots(factory) diff --git a/backend/tests/retained_material_fixtures.py b/backend/tests/retained_material_fixtures.py index 8b161f610..a050e0377 100644 --- a/backend/tests/retained_material_fixtures.py +++ b/backend/tests/retained_material_fixtures.py @@ -18,6 +18,7 @@ SelectedPreSubmitCheckerExecutionAdapter, selected_pre_submit_coordinator, ) +from app.adapters.tasks import task_submission_context_port from app.core.identifiers import new_record_id from app.interfaces.artifacts import ( ArtifactObjectHead, @@ -57,7 +58,6 @@ from app.modules.actors.api import ServiceIdentity from app.modules.projects.locked_policy_repository import ProjectLockedPolicyRepository from app.modules.projects.models import EffectiveProjectSubmissionArtifactPolicy -from app.modules.tasks.repository import TaskRepository from tests.test_artifact_admission import _AllowArtifactAuthority, _context, _settings from tests.test_checker_materialization import _limits from tests.checkers.execution.support import provision_post_submit_service @@ -248,7 +248,8 @@ async def retained_admission( request_id=request.request_id, correlation_id=request.correlation_id, ) - tasks, projects = TaskRepository(session), ProjectLockedPolicyRepository(session) + tasks = task_submission_context_port(session) + projects = ProjectLockedPolicyRepository(session) preparation = ArtifactPreparationService(manager) inspector = SubmissionArchiveInspector(SubmissionArchiveLimits()) materialization = PreparedBundleMaterializationService( From cb6f95e1199ca46f16b7aa9bea90a5af38325675 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 12:59:06 +0100 Subject: [PATCH 187/283] Align selected checker composition contracts --- backend/app/adapters/checkers/__init__.py | 9 +++++---- backend/app/modules/checkers/api/selected_post_submit.py | 4 ++-- backend/app/modules/checkers/default_checker.py | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/backend/app/adapters/checkers/__init__.py b/backend/app/adapters/checkers/__init__.py index 1f2b5445e..4d6cd10d2 100644 --- a/backend/app/adapters/checkers/__init__.py +++ b/backend/app/adapters/checkers/__init__.py @@ -28,7 +28,6 @@ from typing import Any, Protocol from pathlib import Path -from app.modules.checkers.api import PreSubmissionInfrastructureUnavailableError from app.modules.checkers.api.external import ( ExternalCheckerCapabilityDefinition, ExternalCheckerCapabilityProjection, @@ -42,6 +41,9 @@ WORKSTREAM_DEFAULT_CHECKER_VERSION, ) from app.modules.checkers.selected_pre_submit_execution import SelectedPreSubmitProcessor +from app.modules.checkers.api.selected_pre_submit import ( + SelectedPreSubmitInfrastructureUnavailable, +) def external_checker_execution_factory( @@ -190,7 +192,6 @@ def selected_pre_submit_coordinator(session): class _ExecutionRequest(Protocol): - plan: Any project_id: Any task_id: Any assignment_id: Any @@ -224,8 +225,8 @@ def build(self, request: _ExecutionRequest) -> SelectedPreSubmitProcessor: or attempt_request_digest is None or grants is None ): - raise PreSubmissionInfrastructureUnavailableError( - "external_pre_submit_context_unavailable" + raise SelectedPreSubmitInfrastructureUnavailable( + "material_unavailable" ) identity = PreSubmitExternalCheckerIdentity( project_id=request.project_id, diff --git a/backend/app/modules/checkers/api/selected_post_submit.py b/backend/app/modules/checkers/api/selected_post_submit.py index 32fe5ab10..997f45b35 100644 --- a/backend/app/modules/checkers/api/selected_post_submit.py +++ b/backend/app/modules/checkers/api/selected_post_submit.py @@ -259,8 +259,8 @@ def validate_request( class SelectedPostSubmitCurrentResultReference(CheckerValue): """Owner-issued reference to one completed selected POST result.""" - schema_version: Literal["workstream.selected_post_submit_current_result.v1"] = ( - "workstream.selected_post_submit_current_result.v1" + schema_version: Literal["post_submit_current_result_reference"] = ( + "post_submit_current_result_reference" ) request_id: ResourceId request_digest: Sha256 diff --git a/backend/app/modules/checkers/default_checker.py b/backend/app/modules/checkers/default_checker.py index c8c866e93..848effd22 100644 --- a/backend/app/modules/checkers/default_checker.py +++ b/backend/app/modules/checkers/default_checker.py @@ -22,7 +22,7 @@ SubmissionMaterialEntry, SubmissionMaterialView, ) -from app.modules.checkers.api.pre_submit import SubmissionPacketView +from app.modules.checkers.api.pre_submit_material import SubmissionPacketView _CONTRIBUTOR_ARCHIVE_FAILURES = frozenset( From d5a0574cd118a30c097e7061b6ce04d7ead42d74 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 13:01:31 +0100 Subject: [PATCH 188/283] Remove obsolete TASK and ART checker execution paths --- .../pilot04-workstream-default-checker.md | 23 + backend/app/adapters/artifacts/__init__.py | 74 +- backend/app/adapters/tasks/__init__.py | 34 +- .../artifacts/api/submission_preparation.py | 13 +- .../artifacts/post_submit_materialization.py | 24 +- .../artifacts/post_submit_selection.py | 100 +- .../modules/artifacts/pre_submit_attempts.py | 388 -------- .../modules/artifacts/pre_submit_evidence.py | 877 ------------------ backend/app/modules/artifacts/repository.py | 21 - backend/app/modules/artifacts/schemas.py | 14 +- .../selected_pre_submit_admission.py | 4 +- backend/app/modules/artifacts/service.py | 320 +------ .../modules/artifacts/submission_admission.py | 469 ++-------- .../modules/artifacts/submission_bindings.py | 71 +- .../modules/artifacts/submission_custody.py | 35 +- .../modules/artifacts/submission_manifest.py | 11 +- .../artifacts/submission_materialization.py | 458 +-------- backend/app/modules/tasks/repository.py | 23 +- backend/app/modules/tasks/service.py | 39 +- .../modules/tasks/submission_composition.py | 25 +- .../modules/tasks/submission_participants.py | 29 +- 21 files changed, 288 insertions(+), 2764 deletions(-) delete mode 100644 backend/app/modules/artifacts/pre_submit_attempts.py delete mode 100644 backend/app/modules/artifacts/pre_submit_evidence.py diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 81c75be21..2f72be98c 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -641,3 +641,26 @@ The existing public manager-handoff regression reproduces that failure at `2f1f46930` in 23.18 seconds with isolated schema `0036` and cleanup complete; the targeted trace locates the missing registry-read transaction. Final proof uses the normal public owner, with diagnostic exception capture removed. + + +### TASK/ART single execution flow cleanup + +The current TASK and ART consumers now accept only the closed external POST policy +and selected PRE run custody. TASK admission/replay no longer decodes catalogue +checker content, and ART material selection requires selected PRE admission and the +exact submitted external policy. ART removed its obsolete PRE evidence writer, +invocation store, phase wrapper, old capability issuance, and durable publication +and replay branches. Immutable historical models and columns remain retained; +these are not executable checker contracts. + +The selected PRE materializer still requires the committed lease, callback-scoped +genuine ART grant, exact generation/manifest/bytes and default input digest before +execution. The mounted failed-PRE projection accepts only selected execution facts +and retains the existing sanitized default and external findings. The existing +AUTH protocol fields remain stable, but runtime submission admission rejects an +old evidence-set lineage. No migration or catalogue fallback is added. + +Validation at this source checkpoint: TASK/ART Ruff and Python compilation pass; +current owner/DTO imports pass. Native and broader current-flow checks remain +required after the CHECKERS composition and selected fixture repairs are combined. +This checkpoint does not claim hosted suite readiness. diff --git a/backend/app/adapters/artifacts/__init__.py b/backend/app/adapters/artifacts/__init__.py index 6d65daf7f..9b335da35 100644 --- a/backend/app/adapters/artifacts/__init__.py +++ b/backend/app/adapters/artifacts/__init__.py @@ -61,54 +61,6 @@ from app.modules.tasks.api.guide_documents import TaskGuideDocumentsPort -from app.modules.artifacts.api import SubmissionBundlePreparationRequest -from app.modules.artifacts.pre_submit_evidence import PreSubmitEvidencePersistenceResult -from app.modules.artifacts.submission_materialization import ( - PreparedBundleMaterializationRequest, - PreparedBundlePreSubmitEvidenceService, -) -from app.modules.checkers.api.post_submit import ( - PostSubmissionEvaluationRequest, - PostSubmissionEvaluationResult, - PostSubmissionExecutionPort, -) - - -class CheckerPhaseService: - """One command per phase, composed from the canonical ART and CHECKER owners.""" - - def __init__( - self, *, pre_submission: PreparedBundlePreSubmitEvidenceService, - post_submission: PostSubmissionExecutionPort, - ) -> None: - self._pre_submission = pre_submission - self._post_submission = post_submission - - async def evaluate_pre_submission( - self, request: PreparedBundleMaterializationRequest, reservation: object, *, - preparation_request: SubmissionBundlePreparationRequest, - ) -> PreSubmitEvidencePersistenceResult: - """Finish ART's committed selection, preserving its exact canonical result.""" - if request.prepared_authorization is not None: - raise ValueError("pre_submission_phase_requires_consumed_authorization") - if isinstance(reservation, PreSubmitEvidencePersistenceResult): - return reservation - return await self._pre_submission.execute_reserved( - request, reservation, preparation_request=preparation_request, - ) - - async def evaluate_post_submission( - self, request: PostSubmissionEvaluationRequest, - ) -> PostSubmissionEvaluationResult: - """Delegate the closed post contract; production execution remains unavailable.""" - request = PostSubmissionEvaluationRequest.model_validate(request) - result = PostSubmissionEvaluationResult.model_validate( - await self._post_submission.evaluate_post_submission(request) - ) - result.validate_request(request) - return result - - async def get_submission_bundle_preparation_actor( actor: Annotated[ ActorIdentityFacts, @@ -582,23 +534,19 @@ async def materialize( from app.modules.checkers.api.materialization import ( PostSubmissionMaterializationFailure, ) - from app.modules.checkers.api.selected_post_submit import ( - SelectedPostSubmissionEvaluationRequest, - ) settings = get_settings() - if isinstance(facts.request, SelectedPostSubmissionEvaluationRequest): - try: - selected_post_submit_execution_budget_ms( - facts.request.policy, - artifact_deadline_ms=int( - settings.artifact_preparation_total_deadline_seconds * 1000 - ), - ) - except ExternalCheckerPolicyError: - raise PostSubmissionMaterializationFailure( - "post_submit_material_deadline_unavailable" - ) from None + try: + selected_post_submit_execution_budget_ms( + facts.request.policy, + artifact_deadline_ms=int( + settings.artifact_preparation_total_deadline_seconds * 1000 + ), + ) + except ExternalCheckerPolicyError: + raise PostSubmissionMaterializationFailure( + "post_submit_material_deadline_unavailable" + ) from None await initialize_artifact_internal_runtime() with _artifact_internal_runtime() as (store, namespace): manager = create_artifact_scratch_manager(settings) diff --git a/backend/app/adapters/tasks/__init__.py b/backend/app/adapters/tasks/__init__.py index 6cb52b8af..482bb4924 100644 --- a/backend/app/adapters/tasks/__init__.py +++ b/backend/app/adapters/tasks/__init__.py @@ -215,19 +215,16 @@ async def consume( else None ) if selected_post_policy is None: - raise RuntimeError("legacy checker admission cannot create a submission") + raise RuntimeError("external checker admission policy is unavailable") return SubmissionArtifactAdmissionResult( binding_id=result.binding_id, content_id=result.content_id, binding_decision_id=result.binding_decision_id, archive_sha256=result.material.archive_sha256, byte_count=result.material.archive_byte_count, - evaluation_content=None, selected_post_submit_policy=selected_post_policy, - selected_evaluation_content=( - selected_submission_evaluation_content(request.task_context, selected_post_policy) - if selected_post_policy is not None - else None + selected_evaluation_content=selected_submission_evaluation_content( + request.task_context, selected_post_policy ), ) @@ -258,12 +255,8 @@ async def read_consumed( validate_stored_external_post_policy, ) - selected_post_policy = ( - validate_stored_external_post_policy( - result.selected_post_submit_policy_body - ) - if result.selected_post_submit_policy_body is not None - else None + selected_post_policy = validate_stored_external_post_policy( + result.selected_post_submit_policy_body ) return SubmissionArtifactBindingFacts( binding_id=result.binding_id, @@ -271,12 +264,8 @@ async def read_consumed( binding_decision_id=result.binding_decision_id, archive_sha256=result.material.archive_sha256, byte_count=result.material.archive_byte_count, - selected_evaluation_content=( - selected_submission_evaluation_content( - request.task_context, selected_post_policy - ) - if selected_post_policy is not None - else None + selected_evaluation_content=selected_submission_evaluation_content( + request.task_context, selected_post_policy ), ) @@ -363,17 +352,10 @@ def evaluation_request_handler(*, sessions, materialization): ) from app.adapters.outbox import committed_invocation_reader from app.core.config import get_settings - from app.modules.checkers.api.selected_post_submit import ( - SelectedPostSubmissionEvaluationRequest, - ) from app.modules.tasks.evaluation_delivery import EvaluationRequestHandler def executor(envelope, request): - selected_execution = ( - configured_external_checker_execution(get_settings()) - if isinstance(request, SelectedPostSubmissionEvaluationRequest) - else None - ) + selected_execution = configured_external_checker_execution(get_settings()) return delivery_bound_post_submission_executor( sessions=sessions, materialization=materialization, diff --git a/backend/app/modules/artifacts/api/submission_preparation.py b/backend/app/modules/artifacts/api/submission_preparation.py index 55a79e081..b2a1ad20a 100644 --- a/backend/app/modules/artifacts/api/submission_preparation.py +++ b/backend/app/modules/artifacts/api/submission_preparation.py @@ -3,13 +3,12 @@ from __future__ import annotations from collections.abc import AsyncIterable -from dataclasses import asdict, dataclass +from dataclasses import dataclass from enum import StrEnum from typing import Protocol from uuid import UUID from app.modules.authorization.api import ActorIdentityFacts -from app.modules.checkers.api import PreSubmissionExecutionFacts from app.modules.checkers.api.selected_pre_submit import SelectedPreSubmitExecutionFacts @@ -22,12 +21,9 @@ class SubmissionBundlePreparationCheckFailed(SubmissionBundlePreparationRejected def __init__( self, - facts: PreSubmissionExecutionFacts | SelectedPreSubmitExecutionFacts, + facts: SelectedPreSubmitExecutionFacts, ) -> None: - if type(facts) not in { - PreSubmissionExecutionFacts, - SelectedPreSubmitExecutionFacts, - }: + if type(facts) is not SelectedPreSubmitExecutionFacts: raise TypeError("pre-submission feedback facts are invalid") if facts.eligible is not False: raise ValueError("blocked pre-submission facts require eligible false") @@ -36,9 +32,6 @@ def __init__( def public_results(self) -> list[dict[str, object]]: """Return sanitized ordered work findings without execution authority.""" - if type(self.facts) is PreSubmissionExecutionFacts: - return [asdict(entry) for entry in self.facts.entries] - assert type(self.facts) is SelectedPreSubmitExecutionFacts default = self.facts.workstream_default results: list[dict[str, object]] = [ { diff --git a/backend/app/modules/artifacts/post_submit_materialization.py b/backend/app/modules/artifacts/post_submit_materialization.py index 79f9e7722..cd7caa939 100644 --- a/backend/app/modules/artifacts/post_submit_materialization.py +++ b/backend/app/modules/artifacts/post_submit_materialization.py @@ -27,17 +27,13 @@ ) from app.modules.artifacts.service import ArtifactStorageNamespaceError, ArtifactStorageNamespaceSpec from app.modules.artifacts.submission_archive import ( - SealedSubmissionTree, SubmissionArchiveInspector, SubmissionArchiveEntryType, - SubmissionArchiveRejectedError, + SealedSubmissionTree, SubmissionArchiveInspector, SubmissionArchiveRejectedError, ) from app.modules.artifacts.submission_manifest import build_submission_manifest from app.modules.checkers.api.evaluation_contract import ( PostSubmissionExecutionResult, validate_execution_result, ) -from app.modules.checkers.api.selected_post_submit import ( - SelectedPostSubmissionEvaluationRequest, -) from app.modules.checkers.api.execution import ( ExecuteFacts, CurrentExecutionPort, VerifiedMaterialFacts, CheckerExecutionUnavailable, ) @@ -328,23 +324,7 @@ async def materialize( ) inspection = await prepared.inspect(self._inspector) manifest = build_submission_manifest(inspection) - expected_files = tuple((entry.normalized_path, entry.sha256, entry.byte_count) - for entry in manifest.entries - if entry.entry_type is SubmissionArchiveEntryType.FILE) - supplied_files = ( - expected_files - if isinstance(request, SelectedPostSubmissionEvaluationRequest) - else tuple( - sorted( - (entry.artifact, entry.hash, entry.size_bytes) - for entry in request.structural_input.manifest - ) - ) - ) - if ( - manifest.sha256 != selected.semantic_manifest_sha256 - or supplied_files != expected_files - ): + if manifest.sha256 != selected.semantic_manifest_sha256: raise PostSubmissionMaterializationFailure("post_submit_material_manifest_mismatch") materialization_facts = self._authority_facts(facts, selected) evaluation = await self._preparation._process_prepared_submission( diff --git a/backend/app/modules/artifacts/post_submit_selection.py b/backend/app/modules/artifacts/post_submit_selection.py index da5728dcb..bc3d24ab4 100644 --- a/backend/app/modules/artifacts/post_submit_selection.py +++ b/backend/app/modules/artifacts/post_submit_selection.py @@ -1,6 +1,6 @@ """ART-owned exact admitted-material selection, without provider I/O or locks.""" -from dataclasses import asdict, dataclass +from dataclasses import dataclass from uuid import UUID from sqlalchemy import select @@ -10,7 +10,7 @@ from app.modules.checkers.api.materialization import PostSubmissionMaterializationUnavailable from app.modules.artifacts.models import ( ArtifactBinding, ArtifactContent, ArtifactReplica, ArtifactStorageNamespace, - ArtifactVerificationJob, ArtifactVerificationReceipt, PreSubmitEvidenceSet, + ArtifactVerificationJob, ArtifactVerificationReceipt, SubmissionBundleAdmission, ) from app.modules.artifacts.service import ( @@ -21,9 +21,6 @@ from app.modules.checkers.api.evaluation_contract import ( PostSubmissionExecutionRequest, ) -from app.modules.checkers.api.selected_post_submit import ( - SelectedPostSubmissionEvaluationRequest, -) from app.modules.tasks.api.submitted_bundle import ( SubmittedBundleFacts, SubmittedBundlePort, SubmittedBundleRequest, ) @@ -59,38 +56,33 @@ async def select_post_submission_material( facts = await tasks.read(SubmittedBundleRequest( project_id=request.project_id, task_id=request.task_id, submission_id=request.submission_id, )) - selected_request = isinstance(request, SelectedPostSubmissionEvaluationRequest) context = facts.context context_matches = ( - ( - context.guide_version == request.expected_context.guide_version - and context.source_id == request.expected_context.source_id - and context.source_hash == request.expected_context.source_hash - and context.effective_policy_id - == request.expected_context.effective_policy_id - and context.effective_policy_hash - == request.expected_context.effective_policy_hash - and context.pre_policy_id == request.expected_context.pre_policy_id - and context.pre_policy_hash == request.expected_context.pre_policy_hash - and context.post_policy_id - == request.expected_context.retained_catalogue_policy_id - and context.post_policy_version - == request.expected_context.retained_catalogue_policy_version - and context.post_policy_hash - == request.expected_context.retained_catalogue_policy_hash - and context.selected_post_policy_hash - == request.expected_context.selected_post_policy_hash - and context.selected_post_policy_body == request.policy.model_dump(mode="json") - and context.review_policy_id == request.expected_context.review_policy_id - and context.review_generation == request.expected_context.review_generation - and context.review_hash == request.expected_context.review_hash - and context.revision_policy_id == request.expected_context.revision_policy_id - and context.revision_generation - == request.expected_context.revision_generation - and context.revision_hash == request.expected_context.revision_hash - ) - if selected_request - else asdict(context) == request.expected_context.model_dump() + context.guide_version == request.expected_context.guide_version + and context.source_id == request.expected_context.source_id + and context.source_hash == request.expected_context.source_hash + and context.effective_policy_id + == request.expected_context.effective_policy_id + and context.effective_policy_hash + == request.expected_context.effective_policy_hash + and context.pre_policy_id == request.expected_context.pre_policy_id + and context.pre_policy_hash == request.expected_context.pre_policy_hash + and context.post_policy_id + == request.expected_context.retained_catalogue_policy_id + and context.post_policy_version + == request.expected_context.retained_catalogue_policy_version + and context.post_policy_hash + == request.expected_context.retained_catalogue_policy_hash + and context.selected_post_policy_hash + == request.expected_context.selected_post_policy_hash + and context.selected_post_policy_body == request.policy.model_dump(mode="json") + and context.review_policy_id == request.expected_context.review_policy_id + and context.review_generation == request.expected_context.review_generation + and context.review_hash == request.expected_context.review_hash + and context.revision_policy_id == request.expected_context.revision_policy_id + and context.revision_generation + == request.expected_context.revision_generation + and context.revision_hash == request.expected_context.revision_hash ) if ( facts.status != "submitted" @@ -99,19 +91,13 @@ async def select_post_submission_material( request.project_id, request.task_id, request.assignment_id, request.submission_id, request.submission_version, request.binding_id, request.content_id) or not context_matches - or ( - not selected_request - and asdict(facts.context) - != request.structural_input.observed_context.model_dump() - ) ): raise PostSubmissionMaterializationUnavailable("post_submit_material_identity_mismatch") row = (await session.execute( - select(SubmissionBundleAdmission, PreSubmitEvidenceSet, ArtifactBinding, + select(SubmissionBundleAdmission, ArtifactBinding, ArtifactContent, ArtifactReplica, ArtifactVerificationReceipt, ArtifactVerificationJob, ArtifactStorageNamespace) .select_from(SubmissionBundleAdmission) - .outerjoin(PreSubmitEvidenceSet, PreSubmitEvidenceSet.id == SubmissionBundleAdmission.pre_submit_evidence_set_id) .join(ArtifactBinding, ArtifactBinding.id == str(facts.binding_id)) .join(ArtifactContent, ArtifactContent.id == SubmissionBundleAdmission.artifact_content_id) .join(ArtifactReplica, ArtifactReplica.id == SubmissionBundleAdmission.verified_replica_id) @@ -125,18 +111,17 @@ async def select_post_submission_material( )).one_or_none() if row is None: raise PostSubmissionMaterializationUnavailable("post_submit_material_unavailable") - admission, evidence, binding, content, replica, receipt, job, persisted = row + admission, binding, content, replica, receipt, job, persisted = row selected_lineage = ( - evidence is None - and admission.selected_pre_submit_run_id is not None + admission.selected_pre_submit_run_id is not None and admission.pre_submit_evidence_set_id is None and admission.selected_post_submit_policy_sha256 == request.policy.policy_sha256 and admission.selected_post_submit_policy_body == request.policy.model_dump(mode="json") - ) if selected_request else evidence is not None + ) if not ( - SubmissionAdmissionConsumptionService._art_lineage_is_intact(admission, evidence, content) + SubmissionAdmissionConsumptionService._art_lineage_is_intact(admission, content) and admission.status == "consumed" and admission.consumed_by_submission_id == str(facts.submission_id) and admission.consumed_by_submission_version == facts.submission_version @@ -153,24 +138,7 @@ async def select_post_submission_material( and selected_lineage and content.media_type == "application/zip" and content.sha256 == request.content_sha256 - and ( - selected_request - or content.sha256 == request.structural_input.package_hash - ) and content.byte_count == request.byte_count - and ( - selected_request - or ( - evidence.guide_version == context.guide_version - and evidence.source_snapshot_id == str(context.source_id) - and evidence.source_snapshot_sha256 == context.source_hash - and evidence.effective_policy_id == str(context.effective_policy_id) - and evidence.locked_artifact_policy_sha256 - == context.effective_policy_hash - and evidence.pre_submit_policy_id == str(context.pre_policy_id) - and evidence.locked_checker_policy_sha256 == context.pre_policy_hash - ) - ) and replica.content_id == content.id and (replica.verification_state, replica.availability_state, replica.integrity_state) == ("verified", "available", "valid") @@ -189,9 +157,7 @@ async def select_post_submission_material( raise PostSubmissionMaterializationUnavailable("post_submit_material_identity_mismatch") return PostSubmissionMaterialSelection( submission=facts, - evidence_id=UUID( - evidence.id if evidence is not None else admission.selected_pre_submit_run_id - ), + evidence_id=UUID(admission.selected_pre_submit_run_id), replica_id=UUID(replica.id), verification_receipt_id=UUID(receipt.id), verification_job_id=UUID(job.id), verification_generation=receipt.execution_generation, diff --git a/backend/app/modules/artifacts/pre_submit_attempts.py b/backend/app/modules/artifacts/pre_submit_attempts.py deleted file mode 100644 index 22fe00254..000000000 --- a/backend/app/modules/artifacts/pre_submit_attempts.py +++ /dev/null @@ -1,388 +0,0 @@ -"""ART invocation custody; completed outcomes live only in canonical evidence.""" - -from __future__ import annotations - -from typing import TYPE_CHECKING -from dataclasses import asdict, dataclass, replace -from uuid import UUID, uuid4 -from app.core.identifiers import new_record_id - -from sqlalchemy import select, update -from sqlalchemy.dialects.postgresql import insert -from sqlalchemy.ext.asyncio import AsyncSession - -from app.core.hashing import canonical_json_hash -from app.modules.artifacts.submission_manifest import SubmissionManifest -from app.modules.artifacts.models import ( - PreSubmitEvidenceResult, - PreSubmitEvidenceSet, - PreSubmitExecutionAttempt, -) -from app.modules.artifacts.pre_submit_evidence import ( - PersistedPreSubmitEvidence, - PreSubmitEvidenceConflict, - PreSubmitEvidenceContext, - PreSubmitEvidencePersistenceResult, - PreSubmitExecutionCustody, - PreSubmitExecutionResult, - _PreSubmitEvidenceRepository, - _validate_execution, - pre_submit_failure_audit_payload, -) -from app.modules.checkers.api import ( - EffectivePreSubmissionExecutionPlan, - SubmissionPacketView, - PreSubmissionExecutionEntryFacts, - PreSubmissionExecutionFacts, -) - -if TYPE_CHECKING: - from app.modules.artifacts.submission_materialization import ( - PreparedBundleMaterializationRequest, - ) - from app.modules.artifacts.pre_submit_evidence import PreSubmitEvidencePersistenceRequest - - -def logical_request( - context: PreSubmitEvidenceContext, - plan: EffectivePreSubmissionExecutionPlan, - packet: SubmissionPacketView, -) -> dict[str, object]: - """Hash logical input without substituting a retry generation for original custody.""" - if canonical_json_hash(plan.as_dict()) != plan.plan_sha256: - raise PreSubmitEvidenceConflict("pre_submit_attempt_plan_invalid") - values = { - key: str(value) if isinstance(value, UUID) else value - for key, value in asdict(context).items() - if key != "prepared_generation_id" - } - return { - **values, - "effective_plan_sha256": plan.plan_sha256, - "packet_sha256": packet.sha256, - } - - -@dataclass(frozen=True, slots=True) -class _Reservation: - attempt_id: UUID - claim_nonce: UUID - request_digest: str - request: PreparedBundleMaterializationRequest - - -class PreSubmitAttemptClaim: - """A single original invocation, minted only after its reservation commits.""" - - __slots__ = ( - "attempt_id", - "request_digest", - "_nonce", - "_request", - "_started", - "_execution", - "_session", - ) - - def __init__(self, *args: object, **kwargs: object) -> None: - """Reject caller-created invocation authority.""" - raise TypeError("pre-submit claims are issued by ART") - - def __reduce__(self): - """Keep the winning invocation bound to this process and session.""" - raise TypeError("pre-submit claims cannot be serialized") - - @property - def packet_sha256(self) -> str: - """Capture the packet actually passed to this claim's checker invocation.""" - return self._request.packet.sha256 - - async def _reserved( - self, - session: AsyncSession, - *, - lock: bool = False, - ) -> PreSubmitExecutionAttempt: - """Check committed invocation facts in the issuing root session.""" - if ( - session is not self._session - or not session.in_transaction() - or session.in_nested_transaction() - ): - raise PreSubmitEvidenceConflict("pre_submit_attempt_claim_invalid") - statement = ( - select(PreSubmitExecutionAttempt) - .where( - PreSubmitExecutionAttempt.id == str(self.attempt_id), - ) - .execution_options(populate_existing=True) - ) - if lock: - statement = statement.with_for_update() - row = await session.scalar(statement) - if ( - row is None - or row.status != "reserved" - or row.evidence_set_id is not None - or row.claim_nonce != str(self._nonce) - or row.request_digest != self.request_digest - or row.prepared_generation_id != str(self._request.prepared_artifact.generation_id) - ): - raise PreSubmitEvidenceConflict("pre_submit_attempt_claim_invalid") - return row - - async def consume( - self, - session: AsyncSession, - request: PreparedBundleMaterializationRequest, - ) -> None: - """Fence direct materializer calls before constructing the CHECKER processor.""" - if self._started or replace(request, prepared_authorization=None) != self._request: - raise PreSubmitEvidenceConflict("pre_submit_attempt_claim_invalid") - self._started = True - await self._reserved(session) - - def require_execution( - self, - session: AsyncSession, - request: PreparedBundleMaterializationRequest, - ) -> None: - """Require the committed claim outside a database transaction.""" - if ( - session is not self._session - or session.in_transaction() - or not self._started - or self._execution is not None - or replace(request, prepared_authorization=None) != self._request - ): - raise PreSubmitEvidenceConflict("pre_submit_attempt_claim_invalid") - - def finish(self, execution: PreSubmitExecutionResult) -> None: - """Retain the exact owner-issued result object for final persistence.""" - if not self._started or self._execution is not None: - raise PreSubmitEvidenceConflict("pre_submit_attempt_claim_invalid") - self._execution = execution - - async def validate_completion( - self, - session: AsyncSession, - request: PreSubmitEvidencePersistenceRequest, - ) -> None: - """A UUID or copied result cannot stand in for the winning invocation.""" - if not self._started or self._execution is not request.execution: - raise PreSubmitEvidenceConflict("pre_submit_attempt_execution_invalid") - await self._reserved(session, lock=True) - - async def complete(self, session: AsyncSession, evidence_id: UUID) -> None: - """Link evidence atomically; deferred database guards verify both directions.""" - result = await session.execute( - update(PreSubmitExecutionAttempt) - .where( - PreSubmitExecutionAttempt.id == str(self.attempt_id), - PreSubmitExecutionAttempt.claim_nonce == str(self._nonce), - PreSubmitExecutionAttempt.status == "reserved", - ) - .values(status="completed", evidence_set_id=str(evidence_id)) - ) - if result.rowcount != 1: - raise PreSubmitEvidenceConflict("pre_submit_attempt_completion_conflict") - - -class PreSubmitAttemptStore: - """Own reservation issuance and verified reads of canonical ART results.""" - - def __init__(self, session: AsyncSession) -> None: - """Bind issuance to one transaction-owning ART request.""" - self._session = session - self._pending: _Reservation | None = None - - async def reserve( - self, - *, - context: PreSubmitEvidenceContext, - plan: EffectivePreSubmissionExecutionPlan, - packet: SubmissionPacketView, - idempotency_key: UUID, - request: PreparedBundleMaterializationRequest, - ) -> _Reservation | PreSubmitExecutionAttempt: - """Reserve after authorization; an existing unresolved attempt cannot execute.""" - if not self._session.in_transaction() or self._session.in_nested_transaction(): - raise RuntimeError("pre-submit reservation requires one root transaction") - body = logical_request(context, plan, packet) - digest = canonical_json_hash(body) - attempt_id = new_record_id() - nonce = uuid4() - inserted = await self._session.scalar( - insert(PreSubmitExecutionAttempt) - .values( - id=str(attempt_id), - idempotency_key=str(idempotency_key), - actor_profile_id=str(context.actor_profile_id), - identity_link_id=str(context.identity_link_id), - task_id=str(context.task_id), - assignment_id=str(context.assignment_id), - prepared_generation_id=str(context.prepared_generation_id), - claim_nonce=str(nonce), - request_json=body, - request_digest=digest, - status="reserved", - ) - .on_conflict_do_nothing(index_elements=["actor_profile_id", "idempotency_key"]) - .returning(PreSubmitExecutionAttempt.id) - ) - if inserted is not None: - self._pending = _Reservation( - attempt_id, nonce, digest, replace(request, prepared_authorization=None) - ) - return self._pending - row = await self._session.scalar( - select(PreSubmitExecutionAttempt) - .where( - PreSubmitExecutionAttempt.actor_profile_id == str(context.actor_profile_id), - PreSubmitExecutionAttempt.idempotency_key == str(idempotency_key), - ) - .execution_options(populate_existing=True) - ) - if row is None or row.request_digest != digest or row.request_json != body: - raise PreSubmitEvidenceConflict("pre_submit_attempt_request_conflict") - if row.status != "completed": - raise PreSubmitEvidenceConflict("pre_submit_attempt_outcome_unresolved") - return row - - async def committed_claim(self, reservation: object) -> PreSubmitAttemptClaim: - """Mint only after a successful commit, with a new transaction visibility check.""" - if ( - self._session.in_transaction() - or type(reservation) is not _Reservation - or reservation is not self._pending - ): - raise PreSubmitEvidenceConflict("pre_submit_attempt_not_committed") - self._pending = None - async with self._session.begin(): - row = await self._session.get( - PreSubmitExecutionAttempt, str(reservation.attempt_id), populate_existing=True - ) - if ( - row is None - or row.claim_nonce != str(reservation.claim_nonce) - or row.request_digest != reservation.request_digest - or row.status != "reserved" - ): - raise PreSubmitEvidenceConflict("pre_submit_attempt_not_committed") - claim = object.__new__(PreSubmitAttemptClaim) - claim.attempt_id = reservation.attempt_id - claim.request_digest = reservation.request_digest - claim._nonce = reservation.claim_nonce - claim._request = reservation.request - claim._started = False - claim._execution = None - claim._session = self._session - return claim - - async def read_completed( - self, - *, - row: PreSubmitExecutionAttempt, - context: PreSubmitEvidenceContext, - plan: EffectivePreSubmissionExecutionPlan, - ) -> PreSubmitEvidencePersistenceResult: - """Return original evidence after caller revalidates original fixed-service facts.""" - evidence = await self._session.get( - PreSubmitEvidenceSet, row.evidence_set_id, populate_existing=True - ) - if ( - evidence is None - or row.status != "completed" - or evidence.attempt_id != row.id - or evidence.attempt_request_digest != row.request_digest - or evidence.packet_sha256 is None - or evidence.packet_sha256 != row.request_json.get("packet_sha256") - ): - raise PreSubmitEvidenceConflict("pre_submit_attempt_evidence_invalid") - try: - SubmissionManifest.from_dict( - evidence.semantic_manifest_body, sha256=evidence.semantic_manifest_sha256, - ) - except (TypeError, ValueError) as exc: - raise PreSubmitEvidenceConflict("pre_submit_attempt_manifest_invalid") from exc - rows = tuple( - ( - await self._session.scalars( - select(PreSubmitEvidenceResult) - .where( - PreSubmitEvidenceResult.evidence_set_id == evidence.id, - ) - .order_by(PreSubmitEvidenceResult.result_order) - ) - ).all() - ) - if len(rows) != len(plan.entries) or any( - r.metadata_json is None or r.checker_order is None for r in rows - ): - raise PreSubmitEvidenceConflict("pre_submit_attempt_result_unavailable") - execution = PreSubmitExecutionResult( - custody=PreSubmitExecutionCustody( - prepared_generation_id=UUID(row.prepared_generation_id), - archive_sha256=evidence.archive_sha256, - archive_byte_count=evidence.archive_byte_count, - semantic_manifest_sha256=evidence.semantic_manifest_sha256, - storage_scheme=evidence.storage_scheme, - ), - checker_facts=PreSubmissionExecutionFacts( - plan_sha256=evidence.effective_plan_sha256, - eligible=evidence.eligible, - entries=tuple( - PreSubmissionExecutionEntryFacts( - dispatch_authority=r.dispatch_authority, - definition_id=r.definition_id, - definition_version=r.definition_version, - public_name=r.public_name, - policy_source=r.source, - effective_plan_sha256=r.effective_plan_sha256, - rule_instance_id=r.rule_instance_id, - locked_policy_sha256=r.locked_policy_sha256, - phase=r.phase, - order=r.checker_order, - classification=r.classification, - severity=r.severity, - checker_execution_status=r.status, - failure_code=r.failure_code, - message_code=r.message_code, - metadata=tuple(tuple(item) for item in r.metadata_json), - ) - for r in rows - ), - ), - ) - _validate_execution(plan, execution) - original = replace(context, prepared_generation_id=UUID(row.prepared_generation_id)) - identity = original.operation_identity( - effective_plan_sha256=plan.plan_sha256, - attempt_id=UUID(row.id), - attempt_request_digest=row.request_digest, - ) - expected = _PreSubmitEvidenceRepository._set_values(original, plan, execution, identity) - if any(getattr(evidence, name) != value for name, value in expected.items()): - raise PreSubmitEvidenceConflict("pre_submit_attempt_result_digest_invalid") - for ordinal, (member, entry) in enumerate(zip(rows, execution.entries, strict=True)): - values = _PreSubmitEvidenceRepository._result_values( - ordinal, entry, plan.entries[ordinal].result_schema - ) - if any(getattr(member, name) != value for name, value in values.items()): - raise PreSubmitEvidenceConflict("pre_submit_attempt_member_invalid") - reference = PersistedPreSubmitEvidence(UUID(evidence.id), identity, True) - failure_audit = ( - None - if execution.eligible - else pre_submit_failure_audit_payload( - actor_profile_id=original.actor_profile_id, - project_id=original.project_id, - task_id=original.task_id, - prepared_generation_id=original.prepared_generation_id, - evidence=reference, - execution=execution, - catalogue_id=plan.catalogue_id, - catalogue_version=plan.catalogue_version, - ) - ) - return PreSubmitEvidencePersistenceResult(reference, None, failure_audit, execution) diff --git a/backend/app/modules/artifacts/pre_submit_evidence.py b/backend/app/modules/artifacts/pre_submit_evidence.py deleted file mode 100644 index ac235a0ee..000000000 --- a/backend/app/modules/artifacts/pre_submit_evidence.py +++ /dev/null @@ -1,877 +0,0 @@ -"""Immutable persistence for one exact effective pre-submit execution.""" - -from __future__ import annotations - -from dataclasses import asdict, dataclass, field -from typing import TYPE_CHECKING -import threading -from uuid import NAMESPACE_URL, UUID, uuid5 -from app.core.identifiers import new_record_id - -from sqlalchemy.dialects.postgresql import insert -from sqlalchemy.ext.asyncio import AsyncSession - -from app.core.hashing import canonical_json_hash -from app.modules.artifacts.models import PreSubmitEvidenceResult, PreSubmitEvidenceSet -from app.modules.artifacts.sources import ArtifactCommitment -from app.modules.artifacts.submission_manifest import SubmissionManifest -from app.modules.checkers.api import ( - ALLOWED_PRE_SUBMIT_STORAGE_SCHEMES, - EffectivePreSubmissionExecutionPlan, - PreSubmissionExecutionEntryFacts, - PreSubmissionExecutionFacts, - PreSubmissionInfrastructureUnavailableError, - validate_pre_submission_execution_facts, -) -from app.modules.projects.api import ( - ProjectLockedPolicyContextPort, - ProjectLockedPolicyContextRequest, - ProjectLockedPolicyContextUnavailable, -) -from app.modules.tasks.api import ( - TaskSubmissionContextFacts, - TaskSubmissionContextPort, - TaskSubmissionContextRequest, - TaskSubmissionContextUnavailable, -) - -if TYPE_CHECKING: - from app.modules.artifacts.pre_submit_attempts import PreSubmitAttemptClaim - - -def validate_predecessor_lineage( - task_context: TaskSubmissionContextFacts, - *, - predecessor_submission_id: UUID | None, - predecessor_submission_version: int | None, - checker_remediation_manifest_id: UUID | None, -) -> None: - """Require the post-byte predecessor to equal the initially checked version.""" - predecessor = task_context.predecessor - if ( - (predecessor is None) != (predecessor_submission_id is None) - or predecessor is not None - and ( - predecessor.submission_id != predecessor_submission_id - or predecessor.version != predecessor_submission_version - ) - or task_context.checker_remediation_manifest_id != checker_remediation_manifest_id - ): - raise PreSubmitEvidenceConflict("pre_submit_locked_context_changed") - - -@dataclass(frozen=True, slots=True) -class PreSubmitExecutionCustody: - """ART-owned custody observed around one CHECKER execution.""" - - prepared_generation_id: UUID - archive_sha256: str - archive_byte_count: int - semantic_manifest_sha256: str - storage_scheme: str - - -@dataclass(frozen=True, slots=True) -class PreSubmitExecutionResult: - """ART custody combined with dependency-safe CHECKER result facts.""" - - custody: PreSubmitExecutionCustody - checker_facts: PreSubmissionExecutionFacts - - @property - def plan_sha256(self) -> str: - return self.checker_facts.plan_sha256 - - @property - def eligible(self) -> bool: - return self.checker_facts.eligible - - @property - def entries(self) -> tuple[PreSubmissionExecutionEntryFacts, ...]: - return self.checker_facts.entries - - -class PreSubmitEvidenceConflict(RuntimeError): - """Reject reuse of one operation identity with different server-owned facts.""" - - -@dataclass(frozen=True, slots=True) -class PreSubmitEvidenceContext: - """Exact locked facts revalidated by the transaction-owning caller.""" - - actor_profile_id: UUID - identity_link_id: UUID - project_id: UUID - task_id: UUID - assignment_id: UUID - predecessor_submission_id: UUID | None - predecessor_submission_version: int | None - checker_remediation_manifest_id: UUID | None = field(default=None, kw_only=True) - prepared_generation_id: UUID - archive_sha256: str - archive_byte_count: int - semantic_manifest_id: UUID - semantic_manifest_sha256: str - guide_id: UUID - guide_version: str - source_snapshot_id: UUID - source_snapshot_sha256: str - locked_guide_sha256: str - effective_policy_id: UUID - locked_artifact_policy_sha256: str - pre_submit_policy_id: UUID - locked_checker_policy_sha256: str - catalogue_id: str - catalogue_version: str - catalogue_manifest_sha256: str - storage_scheme: str - - def __post_init__(self) -> None: - identifiers = ( - self.actor_profile_id, - self.identity_link_id, - self.project_id, - self.task_id, - self.assignment_id, - self.prepared_generation_id, - self.semantic_manifest_id, - self.guide_id, - self.source_snapshot_id, - self.effective_policy_id, - self.pre_submit_policy_id, - ) - if any(type(value) is not UUID for value in identifiers) or ( - self.predecessor_submission_id is not None - and not isinstance(self.predecessor_submission_id, UUID) - ) or ( - self.checker_remediation_manifest_id is not None - and not isinstance(self.checker_remediation_manifest_id, UUID) - ): - raise ValueError("pre-submit evidence identity is invalid") - if type(self.archive_byte_count) is not int or self.archive_byte_count < 0: - raise ValueError("pre-submit evidence archive size is invalid") - if (self.predecessor_submission_id is None) != ( - self.predecessor_submission_version is None - ) or ( - self.predecessor_submission_version is not None - and ( - type(self.predecessor_submission_version) is not int - or self.predecessor_submission_version < 1 - ) - ): - raise ValueError("pre-submit evidence predecessor lineage is invalid") - if (self.predecessor_submission_id is None) != ( - self.checker_remediation_manifest_id is None - ): - raise ValueError("pre-submit evidence remediation source is invalid") - for digest in ( - self.archive_sha256, - self.semantic_manifest_sha256, - self.locked_guide_sha256, - self.source_snapshot_sha256, - self.locked_artifact_policy_sha256, - self.locked_checker_policy_sha256, - self.catalogue_manifest_sha256, - ): - ArtifactCommitment.validate_sha256(digest) - if any( - type(value) is not str or not value - for value in ( - self.guide_version, - self.catalogue_id, - self.catalogue_version, - self.storage_scheme, - ) - ): - raise ValueError("pre-submit evidence catalogue identity is invalid") - if self.storage_scheme not in ALLOWED_PRE_SUBMIT_STORAGE_SCHEMES: - raise ValueError("pre-submit evidence storage scheme is invalid") - - def operation_identity( - self, *, effective_plan_sha256: str, attempt_id: UUID, attempt_request_digest: str - ) -> str: - """Derive the sole replay namespace from every custody and policy fact.""" - return canonical_json_hash( - { - "domain": "workstream.pre_submit_evidence_operation.v1", - **{ - key: str(value) if isinstance(value, UUID) else value - for key, value in asdict(self).items() - if key != "checker_remediation_manifest_id" or value is not None - }, - "effective_plan_sha256": effective_plan_sha256, - "attempt_id": str(attempt_id), - "attempt_request_digest": attempt_request_digest, - } - ) - - -@dataclass(frozen=True, slots=True) -class PersistedPreSubmitEvidence: - evidence_set_id: UUID - operation_identity: str - replayed: bool - - -@dataclass(frozen=True, slots=True) -class PreSubmitEvidenceInput: - """Exact custody and plan facts resolved before and after execution.""" - - actor_profile_id: UUID - identity_link_id: UUID - task_id: UUID - assignment_id: UUID - predecessor_submission_id: UUID | None - expected_predecessor_submission_version: int | None - expected_checker_remediation_manifest_id: UUID | None = field(default=None, kw_only=True) - prepared_generation_id: UUID - archive_sha256: str - archive_byte_count: int - semantic_manifest_sha256: str - plan: EffectivePreSubmissionExecutionPlan - - -@dataclass(frozen=True, slots=True) -class PreSubmitEvidencePersistenceRequest(PreSubmitEvidenceInput): - """Persist only the execution issued by the committed ART attempt claim.""" - - execution: PreSubmitExecutionResult - attempt: PreSubmitAttemptClaim - manifest: SubmissionManifest - - -@dataclass(frozen=True, slots=True) -class PreSubmitEvidencePersistenceResult: - """Durable evidence identity plus optional process-local pass capability.""" - - evidence: PersistedPreSubmitEvidence - pass_capability: PreSubmitPassCapability | None - failure_audit: dict[str, object] | None - execution: PreSubmitExecutionResult - - -def pre_submit_failure_audit_payload( - *, - actor_profile_id: UUID, - project_id: UUID, - task_id: UUID, - prepared_generation_id: UUID, - evidence: PersistedPreSubmitEvidence, - execution: PreSubmitExecutionResult, - catalogue_id: str, - catalogue_version: str, -) -> dict[str, object]: - """Return the sole bounded, path-free audit projection for a blocked attempt.""" - if execution.eligible: - raise ValueError("passing pre-submit execution has no failure audit projection") - counts = {"failed": 0, "warning": 0, "not_run": 0} - categories: set[str] = set() - failure_codes: set[str] = set() - result_outcomes: list[dict[str, str]] = [] - for result in execution.entries: - result_outcomes.append( - { - "definition_id": result.definition_id, - "definition_version": result.definition_version, - "status": result.checker_execution_status, - "message_code": result.message_code, - } - ) - if result.checker_execution_status == "failed": - counts["failed"] += 1 - categories.add(result.classification) - if result.failure_code is not None: - failure_codes.add(result.failure_code) - elif result.checker_execution_status == "warning": - counts["warning"] += 1 - elif result.checker_execution_status == "dependency_not_run": - counts["not_run"] += 1 - return { - "event_type": "pre_submission_check_failed", - "actor_profile_id": str(actor_profile_id), - "project_id": str(project_id), - "task_id": str(task_id), - "preparation_attempt_id": str(prepared_generation_id), - "pre_submit_evidence_set_id": str(evidence.evidence_set_id), - "effective_plan_sha256": execution.plan_sha256, - "terminal_status": "blocked", - "catalogue_id": catalogue_id, - "catalogue_version": catalogue_version, - "failed_count": counts["failed"], - "warning_count": counts["warning"], - "not_run_count": counts["not_run"], - "failure_categories": sorted(categories), - "failure_codes": sorted(failure_codes), - "result_outcomes": result_outcomes, - "outcome_code": "pre_submission_checker_failed", - } - - -def semantic_manifest_identity(semantic_manifest_sha256: str) -> UUID: - """Derive one provider-neutral identity from the canonical manifest digest.""" - ArtifactCommitment.validate_sha256(semantic_manifest_sha256) - return uuid5( - NAMESPACE_URL, - f"workstream:submission-semantic-manifest:v1:{semantic_manifest_sha256}", - ) - - -def _validate_execution( - plan: EffectivePreSubmissionExecutionPlan, - execution: PreSubmitExecutionResult, -) -> None: - """Reject custody or CHECKER facts not bound to the exact immutable plan.""" - custody = execution.custody - try: - ArtifactCommitment.validate_sha256(custody.archive_sha256) - ArtifactCommitment.validate_sha256(custody.semantic_manifest_sha256) - except ValueError as exc: - raise PreSubmitEvidenceConflict("pre_submission_result_context_invalid") from exc - if ( - type(custody.prepared_generation_id) is not UUID - or type(custody.archive_byte_count) is not int - or custody.archive_byte_count < 0 - or custody.storage_scheme not in ALLOWED_PRE_SUBMIT_STORAGE_SCHEMES - or type(execution.eligible) is not bool - or execution.plan_sha256 != plan.plan_sha256 - or len(execution.entries) != len(plan.entries) - ): - raise PreSubmitEvidenceConflict("pre_submission_result_context_invalid") - try: - validate_pre_submission_execution_facts( - plan, - PreSubmissionExecutionFacts( - plan_sha256=execution.plan_sha256, - eligible=execution.eligible, - entries=execution.entries, - ), - ) - except PreSubmissionInfrastructureUnavailableError as exc: - raise PreSubmitEvidenceConflict( - "pre_submission_result_context_invalid" - ) from exc - - -_PRE_SUBMIT_PASS_CAPABILITY_SEAL = object() - - -class PreSubmitPassCapability: - """Single-use process-local proof for immediate 04C continuation only.""" - - __slots__ = ( - "_consumed", - "_binding", - "_lock", - "_owner", - "_seal", - "evidence_set_id", - "prepared_generation_id", - "predecessor_submission_id", - "checker_remediation_manifest_id", - "effective_plan_sha256", - "archive_sha256", - "semantic_manifest_sha256", - "storage_scheme", - ) - - def __init__(self, *_: object, **__: object) -> None: - """Reject direct construction outside the evidence service.""" - raise TypeError("PreSubmitPassCapability can only be created by pre-submit evidence") - - @classmethod - def _from_evidence_service( - cls, - *, - owner: PreSubmitEvidenceService, - binding: object, - evidence_set_id: UUID, - prepared_generation_id: UUID, - predecessor_submission_id: UUID | None, - checker_remediation_manifest_id: UUID | None, - effective_plan_sha256: str, - archive_sha256: str, - semantic_manifest_sha256: str, - storage_scheme: str, - ) -> PreSubmitPassCapability: - """Mint only from the service that persisted fresh passing evidence.""" - if type(owner) is not PreSubmitEvidenceService or not owner._claims_pass_binding(binding): - raise TypeError("PreSubmitPassCapability can only be created by pre-submit evidence") - capability = object.__new__(cls) - capability._owner = owner - capability._binding = binding - capability.evidence_set_id = evidence_set_id - capability.prepared_generation_id = prepared_generation_id - capability.predecessor_submission_id = predecessor_submission_id - capability.checker_remediation_manifest_id = checker_remediation_manifest_id - capability.effective_plan_sha256 = effective_plan_sha256 - capability.archive_sha256 = archive_sha256 - capability.semantic_manifest_sha256 = semantic_manifest_sha256 - capability.storage_scheme = storage_scheme - capability._consumed = False - capability._lock = threading.Lock() - capability._seal = _PRE_SUBMIT_PASS_CAPABILITY_SEAL - return capability - - def consume( - self, - *, - prepared_generation_id: UUID, - predecessor_submission_id: UUID | None, - checker_remediation_manifest_id: UUID | None, - effective_plan_sha256: str, - archive_sha256: str, - semantic_manifest_sha256: str, - storage_scheme: str, - ) -> UUID: - """Consume once only when the immediate continuation facts still match.""" - with self._lock: - if ( - self._seal is not _PRE_SUBMIT_PASS_CAPABILITY_SEAL - or self._consumed - or ( - prepared_generation_id != self.prepared_generation_id - or predecessor_submission_id != self.predecessor_submission_id - or checker_remediation_manifest_id != self.checker_remediation_manifest_id - or effective_plan_sha256 != self.effective_plan_sha256 - or archive_sha256 != self.archive_sha256 - or semantic_manifest_sha256 != self.semantic_manifest_sha256 - or storage_scheme != self.storage_scheme - ) - ): - raise PreSubmitEvidenceConflict("pre_submit_pass_capability_invalid") - if not self._owner._consume_pass_binding(self._binding): - raise PreSubmitEvidenceConflict("pre_submit_pass_capability_invalid") - self._consumed = True - return self.evidence_set_id - - def _assert_live_prepared_custody( - self, - *, - prepared_generation_id: UUID, - archive_sha256: str, - ) -> None: - """Fail before handoff when this capability is spent or for other bytes.""" - with self._lock: - if ( - self._seal is not _PRE_SUBMIT_PASS_CAPABILITY_SEAL - or self._consumed - or not self._owner._claims_pass_binding(self._binding) - or prepared_generation_id != self.prepared_generation_id - or archive_sha256 != self.archive_sha256 - ): - raise PreSubmitEvidenceConflict("pre_submit_pass_capability_invalid") - - -class _PreSubmitEvidenceRepository: - """Insert or replay one immutable evidence set in the caller transaction.""" - - def __init__( - self, - session: AsyncSession, - *, - task_contexts: TaskSubmissionContextPort, - project_contexts: ProjectLockedPolicyContextPort, - ) -> None: - self._session = session - self._task_contexts = task_contexts - self._project_contexts = project_contexts - - async def persist( - self, - *, - context: PreSubmitEvidenceContext, - plan: EffectivePreSubmissionExecutionPlan, - execution: PreSubmitExecutionResult, - attempt_id: UUID, - attempt_request_digest: str, - packet_sha256: str, - manifest: SubmissionManifest, - ) -> PersistedPreSubmitEvidence: - """Write the winning attempt's result once; the attempt owner handles replay.""" - transaction = self._session.sync_session.get_transaction() - if ( - transaction is None - or not transaction.is_active - or self._session.in_nested_transaction() - ): - raise RuntimeError("pre-submit evidence requires one root transaction") - _validate_execution(plan, execution) - operation_identity = context.operation_identity( - effective_plan_sha256=execution.plan_sha256, attempt_id=attempt_id, - attempt_request_digest=attempt_request_digest, - ) - values = self._set_values(context, plan, execution, operation_identity) - ArtifactCommitment.validate_sha256(packet_sha256) - values.update(attempt_id=str(attempt_id), attempt_request_digest=attempt_request_digest, - packet_sha256=packet_sha256, - semantic_manifest_body=SubmissionManifest.from_dict( - manifest.as_dict(), sha256=context.semantic_manifest_sha256, - ).as_dict()) - evidence_set_id = new_record_id() - await self._session.execute( - insert(PreSubmitEvidenceSet).values(id=str(evidence_set_id), **values) - ) - for result_order, (plan_entry, result) in enumerate( - zip(plan.entries, execution.entries, strict=True) - ): - self._session.add( - PreSubmitEvidenceResult( - id=str(new_record_id()), - evidence_set_id=str(evidence_set_id), - **self._result_values(result_order, result, plan_entry.result_schema), - ) - ) - await self._session.flush() - return PersistedPreSubmitEvidence( - evidence_set_id=evidence_set_id, - operation_identity=operation_identity, - replayed=False, - ) - - @staticmethod - def _result_values( - result_order: int, - result: PreSubmissionExecutionEntryFacts, - schema_version: str, - ) -> dict[str, object]: - return { - "result_order": result_order, - "checker_order": result.order, - "metadata_json": [list(item) for item in result.metadata], - "schema_version": schema_version, - "dispatch_authority": result.dispatch_authority, - "definition_id": result.definition_id, - "definition_version": result.definition_version, - "public_name": result.public_name, - "source": result.policy_source, - "phase": result.phase, - "classification": result.classification, - "severity": result.severity, - "status": result.checker_execution_status, - "failure_code": result.failure_code, - "message_code": result.message_code, - "effective_plan_sha256": result.effective_plan_sha256, - "rule_instance_id": result.rule_instance_id, - "locked_policy_sha256": result.locked_policy_sha256, - } - - @staticmethod - def _set_values( - context: PreSubmitEvidenceContext, - plan: EffectivePreSubmissionExecutionPlan, - execution: PreSubmitExecutionResult, - operation_identity: str, - ) -> dict[str, object]: - values = { - key: str(value) if isinstance(value, UUID) else value - for key, value in asdict(context).items() - } - values["checker_remediation_manifest_id"] = context.checker_remediation_manifest_id - values = { - "operation_identity": operation_identity, - **values, - "effective_plan_sha256": execution.plan_sha256, - "terminal_status": "passed" if execution.eligible else "blocked", - "eligible": execution.eligible, - "result_count": len(execution.entries), - "result_manifest_sha256": canonical_json_hash( - { - "schema_version": "pre_submit_evidence_result_manifest.v1", - "entries": [ - { - "schema_version": plan_entry.result_schema, - "dispatch_authority": result.dispatch_authority, - "definition_id": result.definition_id, - "definition_version": result.definition_version, - "public_name": result.public_name, - "policy_source": result.policy_source, - "effective_plan_sha256": result.effective_plan_sha256, - "rule_instance_id": result.rule_instance_id, - "locked_policy_sha256": result.locked_policy_sha256, - "phase": result.phase, - "order": result.order, - "classification": result.classification, - "severity": result.severity, - "status": result.checker_execution_status, - "failure_code": result.failure_code, - "message_code": result.message_code, - "metadata": [list(item) for item in result.metadata], - } - for plan_entry, result in zip( - plan.entries, execution.entries, strict=True - ) - ], - } - ), - } - values["locked_policy_context_hash"] = canonical_json_hash( - { - "guide_id": values["guide_id"], - "guide_version": values["guide_version"], - "source_snapshot_id": values["source_snapshot_id"], - "source_snapshot_sha256": values["source_snapshot_sha256"], - "locked_guide_sha256": values["locked_guide_sha256"], - "effective_policy_id": values["effective_policy_id"], - "locked_artifact_policy_sha256": values["locked_artifact_policy_sha256"], - "pre_submit_policy_id": values["pre_submit_policy_id"], - "locked_checker_policy_sha256": values["locked_checker_policy_sha256"], - "effective_plan_sha256": values["effective_plan_sha256"], - } - ) - return values - - -class PreSubmitEvidenceService: - """Revalidate locked state and persist evidence in one caller transaction.""" - - def __init__( - self, - session: AsyncSession, - *, - task_contexts: TaskSubmissionContextPort, - project_contexts: ProjectLockedPolicyContextPort, - ) -> None: - self._session = session - self._task_contexts = task_contexts - self._project_contexts = project_contexts - self._repository = _PreSubmitEvidenceRepository( - session, - task_contexts=task_contexts, - project_contexts=project_contexts, - ) - self._live_pass_bindings: set[object] = set() - - def _claims_pass_binding(self, binding: object) -> bool: - """Recognize only an issuance registered by this live service instance.""" - return binding in getattr(self, "_live_pass_bindings", set()) - - def _consume_pass_binding(self, binding: object) -> bool: - """Retire one process-local issuance binding exactly once.""" - if binding not in self._live_pass_bindings: - return False - self._live_pass_bindings.remove(binding) - return True - - def _mint_pass_capability( - self, - *, - evidence_set_id: UUID, - prepared_generation_id: UUID, - predecessor_submission_id: UUID | None, - checker_remediation_manifest_id: UUID | None, - effective_plan_sha256: str, - archive_sha256: str, - semantic_manifest_sha256: str, - storage_scheme: str, - ) -> PreSubmitPassCapability: - """Register one unguessable issuance after fresh passing persistence.""" - binding = object() - self._live_pass_bindings.add(binding) - try: - return PreSubmitPassCapability._from_evidence_service( - owner=self, - binding=binding, - evidence_set_id=evidence_set_id, - prepared_generation_id=prepared_generation_id, - predecessor_submission_id=predecessor_submission_id, - checker_remediation_manifest_id=checker_remediation_manifest_id, - effective_plan_sha256=effective_plan_sha256, - archive_sha256=archive_sha256, - semantic_manifest_sha256=semantic_manifest_sha256, - storage_scheme=storage_scheme, - ) - except BaseException: - self._live_pass_bindings.discard(binding) - raise - - async def persist( - self, request: PreSubmitEvidencePersistenceRequest - ) -> PreSubmitEvidencePersistenceResult: - """Persist only when the post-execution database lineage remains exact.""" - transaction = self._session.sync_session.get_transaction() - if ( - transaction is None - or not transaction.is_active - or self._session.in_nested_transaction() - ): - raise RuntimeError("pre-submit evidence requires one root transaction") - _validate_execution(request.plan, request.execution) - custody = request.execution.custody - if type(request.manifest) is not SubmissionManifest: - raise PreSubmitEvidenceConflict("pre_submit_manifest_invalid") - try: - SubmissionManifest.from_dict( - request.manifest.as_dict(), sha256=request.semantic_manifest_sha256, - ) - except (TypeError, ValueError) as exc: - raise PreSubmitEvidenceConflict("pre_submit_manifest_invalid") from exc - if ( - request.prepared_generation_id != custody.prepared_generation_id - or request.archive_sha256 != custody.archive_sha256 - or request.archive_byte_count != custody.archive_byte_count - or request.semantic_manifest_sha256 != custody.semantic_manifest_sha256 - ): - raise PreSubmitEvidenceConflict("pre_submit_execution_custody_changed") - context = await self.lock_context(request, storage_scheme=custody.storage_scheme) - from app.modules.artifacts.pre_submit_attempts import PreSubmitAttemptClaim - - if type(request.attempt) is not PreSubmitAttemptClaim: - raise PreSubmitEvidenceConflict("pre_submit_attempt_claim_invalid") - await request.attempt.validate_completion(self._session, request) - evidence = await self._repository.persist( - context=context, - plan=request.plan, - execution=request.execution, - attempt_id=request.attempt.attempt_id, - attempt_request_digest=request.attempt.request_digest, - packet_sha256=request.attempt.packet_sha256, - manifest=request.manifest, - ) - await request.attempt.complete(self._session, evidence.evidence_set_id) - pass_capability = ( - self._mint_pass_capability( - evidence_set_id=evidence.evidence_set_id, - prepared_generation_id=request.prepared_generation_id, - predecessor_submission_id=request.predecessor_submission_id, - checker_remediation_manifest_id=request.expected_checker_remediation_manifest_id, - effective_plan_sha256=request.plan.plan_sha256, - archive_sha256=custody.archive_sha256, - semantic_manifest_sha256=custody.semantic_manifest_sha256, - storage_scheme=custody.storage_scheme, - ) - if request.execution.eligible - else None - ) - failure_audit = ( - None - if request.execution.eligible - else pre_submit_failure_audit_payload( - actor_profile_id=request.actor_profile_id, - project_id=context.project_id, - task_id=request.task_id, - prepared_generation_id=request.prepared_generation_id, - evidence=evidence, - execution=request.execution, - catalogue_id=request.plan.catalogue_id, - catalogue_version=request.plan.catalogue_version, - ) - ) - return PreSubmitEvidencePersistenceResult( - evidence=evidence, - pass_capability=pass_capability, - failure_audit=failure_audit, - execution=request.execution, - ) - - async def lock_context( - self, request: PreSubmitEvidenceInput, *, storage_scheme: str - ) -> PreSubmitEvidenceContext: - """Relock exact lineage when authority locks are already held by the workflow.""" - task_context = await self.lock_task_context(request) - return await self.lock_project_context( - request, task_context=task_context, storage_scheme=storage_scheme, - ) - - async def lock_task_context( - self, request: PreSubmitEvidenceInput, - ) -> TaskSubmissionContextFacts: - """Acquire TASK custody before the workflow locks contributor identity.""" - try: - task_context = await self._task_contexts.lock_submission_context( - TaskSubmissionContextRequest( - task_id=request.task_id, - assignment_id=request.assignment_id, - contributor_id=request.actor_profile_id, - predecessor_submission_id=request.predecessor_submission_id, - ) - ) - except TaskSubmissionContextUnavailable as exc: - raise PreSubmitEvidenceConflict("pre_submit_locked_context_changed") from exc - return task_context - - async def lock_project_context( - self, request: PreSubmitEvidenceInput, *, - task_context: TaskSubmissionContextFacts, storage_scheme: str, - ) -> PreSubmitEvidenceContext: - """Lock PROJECT and validate lineage after TASK and actor identity are held.""" - try: - references = task_context.locked_project_context - project_context = await self._project_contexts.lock_locked_policy_context( - ProjectLockedPolicyContextRequest( - project_id=references.project_id, - guide_version=references.guide_version, - source_snapshot_id=references.source_snapshot_id, - source_snapshot_hash=references.source_snapshot_hash, - effective_policy_id=references.effective_policy_id, - effective_policy_hash=references.effective_policy_hash, - pre_submit_policy_id=references.pre_submit_policy_id, - pre_submit_policy_bundle_hash=references.pre_submit_policy_bundle_hash, - ) - ) - except ProjectLockedPolicyContextUnavailable as exc: - raise PreSubmitEvidenceConflict("pre_submit_locked_context_changed") from exc - validate_predecessor_lineage( - task_context, - predecessor_submission_id=request.predecessor_submission_id, - predecessor_submission_version=( - request.expected_predecessor_submission_version - ), - checker_remediation_manifest_id=request.expected_checker_remediation_manifest_id, - ) - lineage = request.plan.lineage - if ( - task_context.contributor_id != request.actor_profile_id - or project_context.project_id != lineage.project_id - or project_context.guide_id != lineage.guide_id - or project_context.guide_version != lineage.guide_version - or project_context.source_snapshot_id != lineage.source_snapshot_id - or project_context.source_snapshot_hash != lineage.source_snapshot_hash - or project_context.effective_policy_id != lineage.effective_policy_id - or project_context.effective_policy_hash != lineage.effective_policy_hash - or project_context.pre_submit_policy_id != lineage.pre_submit_policy_id - or project_context.pre_submit_policy_bundle_hash - != lineage.pre_submit_policy_bundle_hash - ): - raise PreSubmitEvidenceConflict("pre_submit_locked_context_changed") - locked_guide_sha256 = canonical_json_hash( - { - "domain": "workstream.locked_task_guide.v1", - "project_id": str(project_context.project_id), - "guide_id": str(project_context.guide_id), - "guide_version": project_context.guide_version, - "source_snapshot_id": str(project_context.source_snapshot_id), - "source_snapshot_sha256": project_context.source_snapshot_hash, - } - ) - return PreSubmitEvidenceContext( - actor_profile_id=request.actor_profile_id, - identity_link_id=request.identity_link_id, - project_id=project_context.project_id, - task_id=request.task_id, - assignment_id=request.assignment_id, - predecessor_submission_id=request.predecessor_submission_id, - predecessor_submission_version=( - task_context.predecessor.version - if task_context.predecessor is not None - else None - ), - checker_remediation_manifest_id=task_context.checker_remediation_manifest_id, - prepared_generation_id=request.prepared_generation_id, - archive_sha256=request.archive_sha256, - archive_byte_count=request.archive_byte_count, - semantic_manifest_id=semantic_manifest_identity(request.semantic_manifest_sha256), - semantic_manifest_sha256=request.semantic_manifest_sha256, - guide_id=project_context.guide_id, - guide_version=project_context.guide_version, - source_snapshot_id=project_context.source_snapshot_id, - source_snapshot_sha256=project_context.source_snapshot_hash, - locked_guide_sha256=locked_guide_sha256, - effective_policy_id=project_context.effective_policy_id, - locked_artifact_policy_sha256=project_context.effective_policy_hash, - pre_submit_policy_id=project_context.pre_submit_policy_id, - locked_checker_policy_sha256=project_context.pre_submit_policy_bundle_hash, - catalogue_id=request.plan.catalogue_id, - catalogue_version=request.plan.catalogue_version, - catalogue_manifest_sha256=request.plan.catalogue_manifest_sha256, - storage_scheme=storage_scheme, - ) diff --git a/backend/app/modules/artifacts/repository.py b/backend/app/modules/artifacts/repository.py index 1088210d2..b5f0c9827 100644 --- a/backend/app/modules/artifacts/repository.py +++ b/backend/app/modules/artifacts/repository.py @@ -18,7 +18,6 @@ ArtifactBinding, ArtifactContent, ArtifactOperationReceipt, - PreSubmitEvidenceSet, ArtifactPutAttempt, ArtifactPutAttemptCharge, ArtifactPutObservationReceipt, @@ -295,26 +294,6 @@ async def get_put_attempt_by_operation( ) ) - async def lock_pre_submit_evidence_set( - self, evidence_set_id: str - ) -> PreSubmitEvidenceSet | None: - """Lock one immutable passing evidence identity for durable continuation.""" - return await self._session.scalar( - select(PreSubmitEvidenceSet) - .where(PreSubmitEvidenceSet.id == evidence_set_id) - .with_for_update(key_share=True) - .execution_options(populate_existing=True) - ) - - async def get_submission_bundle_intent_by_evidence( - self, evidence_set_id: str - ) -> SubmissionBundleDurableIntent | None: - """Load the one durable intent already created from an evidence set.""" - return await self._session.scalar( - select(SubmissionBundleDurableIntent).where( - SubmissionBundleDurableIntent.pre_submit_evidence_set_id == evidence_set_id - ) - ) async def get_submission_bundle_intent_by_selected_run( self, run_id: str diff --git a/backend/app/modules/artifacts/schemas.py b/backend/app/modules/artifacts/schemas.py index c20924ee2..c064f4fef 100644 --- a/backend/app/modules/artifacts/schemas.py +++ b/backend/app/modules/artifacts/schemas.py @@ -107,10 +107,9 @@ class SubmissionBundleArtifactAdmissionRequest: def __post_init__(self) -> None: if ( - (self.pre_submit_evidence_set_id is None) - == (self.selected_pre_submit_run_id is None) - or (self.selected_pre_submit_run_id is None) - != (self.selected_terminal_digest is None) + self.pre_submit_evidence_set_id is not None + or self.selected_pre_submit_run_id is None + or self.selected_terminal_digest is None or ( self.selected_terminal_digest is not None and ( @@ -235,10 +234,9 @@ class SubmissionBundleDurableIntentAuthorityFacts: def __post_init__(self) -> None: if ( - (self.pre_submit_evidence_set_id is None) - == (self.selected_pre_submit_run_id is None) - or (self.selected_pre_submit_run_id is None) - != (self.selected_terminal_digest is None) + self.pre_submit_evidence_set_id is not None + or self.selected_pre_submit_run_id is None + or self.selected_terminal_digest is None ): raise ValueError("submission bundle authority lineage is invalid") diff --git a/backend/app/modules/artifacts/selected_pre_submit_admission.py b/backend/app/modules/artifacts/selected_pre_submit_admission.py index 64f9769cd..e6d7a631c 100644 --- a/backend/app/modules/artifacts/selected_pre_submit_admission.py +++ b/backend/app/modules/artifacts/selected_pre_submit_admission.py @@ -7,9 +7,9 @@ from app.core.hashing import canonical_json_hash from app.modules.artifacts.sources import ArtifactCommitment -from app.modules.artifacts.pre_submit_evidence import semantic_manifest_identity from app.modules.artifacts.submission_manifest import ( SubmissionCanonicalPredecessor, + semantic_manifest_identity, SubmissionChangeGateResult, SubmissionManifest, bind_submission_change, @@ -26,7 +26,7 @@ LockedExternalPreSubmitPolicy, ) from app.modules.checkers.api.materialization import SubmissionMaterialEntry -from app.modules.checkers.api.pre_submit import SubmissionPacketView +from app.modules.checkers.api.pre_submit_material import SubmissionPacketView from app.modules.checkers.api.selected_pre_submit import ( SelectedPreSubmitAdmissionLineage, SelectedPreSubmitReservationFacts, diff --git a/backend/app/modules/artifacts/service.py b/backend/app/modules/artifacts/service.py index e1902a9ce..c4fed2406 100644 --- a/backend/app/modules/artifacts/service.py +++ b/backend/app/modules/artifacts/service.py @@ -63,7 +63,6 @@ ArtifactStorageNamespace, ArtifactVerificationJob, ArtifactVerificationReceipt, - PreSubmitEvidenceSet, SubmissionBundleDurableIntent, ) from app.modules.artifacts.metrics import ( @@ -2040,22 +2039,6 @@ async def admit( authority_facts, operation_identity=replay_attempt.operation_identity, ) - if not request.custody.is_selected: - consumed_evidence_id = request.custody.pass_capability.consume( - prepared_generation_id=authority_facts.prepared_generation_id, - predecessor_submission_id=authority_facts.predecessor_submission_id, - checker_remediation_manifest_id=( - authority_facts.checker_remediation_manifest_id - ), - effective_plan_sha256=authority_facts.effective_plan_sha256, - archive_sha256=authority_facts.archive_sha256, - semantic_manifest_sha256=authority_facts.semantic_manifest_sha256, - storage_scheme=authority_facts.storage_scheme, - ) - if consumed_evidence_id != authority_facts.pre_submit_evidence_set_id: - raise ArtifactAdmissionRelationshipError( - "submission bundle pass capability evidence changed" - ) prepared_authorization = await submission_prepared_authorization.prepare_final( facts=authority_facts ) @@ -2132,18 +2115,9 @@ async def admit( counter.scope_type, counter.counted_bytes, counter.limit_bytes ) if replay is not None: - if ( - facts.pre_submit_evidence_set_id is not None - or facts.selected_pre_submit_run_id is not None - ): - intent = ( - await self._repo.get_submission_bundle_intent_by_evidence( - facts.pre_submit_evidence_set_id - ) - if facts.pre_submit_evidence_set_id is not None - else await self._repo.get_submission_bundle_intent_by_selected_run( - facts.selected_pre_submit_run_id or "" - ) + if facts.selected_pre_submit_run_id is not None: + intent = await self._repo.get_submission_bundle_intent_by_selected_run( + facts.selected_pre_submit_run_id ) if intent is None or intent.put_attempt_id != replay.id: raise ArtifactAdmissionConfigurationError( @@ -2195,14 +2169,10 @@ async def admit( terminal_at=None, ) await self._repo.add_put_attempt(attempt, charges) - if ( - facts.pre_submit_evidence_set_id is not None - or facts.selected_pre_submit_run_id is not None - ): + if facts.selected_pre_submit_run_id is not None: selected_request = ( request.custody.selected_reservation if type(request) is SubmissionBundleArtifactAdmissionRequest - and request.custody.is_selected else None ) await self._repo.add_submission_bundle_intent( @@ -2398,48 +2368,18 @@ async def _submission_bundle_replay_attempt( raise ArtifactAdmissionRelationshipError( "submission bundle replay intent is unavailable" ) - if request.custody.is_selected: - reservation = request.custody.selected_reservation - attempt = await self._repo.lock_put_attempt(intent.put_attempt_id) - if ( - attempt is None - or intent.selected_pre_submit_run_id != str(reservation.attempt_id) - or intent.pre_submit_evidence_set_id is not None - or intent.selected_request_json != reservation.canonical_body() - or intent.selected_request_digest != reservation.request_digest - or intent.selected_terminal_json - != request.custody.selected_terminal_body - or intent.selected_terminal_digest - != request.custody.selected_terminal_digest - or attempt.producer_request_type != "submission_bundle" - or attempt.status - not in { - "prepared", - "acknowledgement_unknown", - "absent_replay_required", - "object_confirmed", - } - or attempt.sha256 != current.archive_sha256 - or attempt.byte_count != current.archive_byte_count - or attempt.media_type != current.media_type - ): - raise ArtifactAdmissionRelationshipError( - "selected submission bundle replay intent does not match custody" - ) - return attempt - if intent.pre_submit_evidence_set_id is None: - raise ArtifactAdmissionRelationshipError( - "submission bundle replay intent is unavailable" - ) - prior = await self._repo.lock_pre_submit_evidence_set(intent.pre_submit_evidence_set_id) - fresh = await self._repo.lock_pre_submit_evidence_set( - str(current.pre_submit_evidence_set_id) - ) + reservation = request.custody.selected_reservation attempt = await self._repo.lock_put_attempt(intent.put_attempt_id) if ( - prior is None - or fresh is None - or attempt is None + attempt is None + or intent.selected_pre_submit_run_id != str(reservation.attempt_id) + or intent.pre_submit_evidence_set_id is not None + or intent.selected_request_json != reservation.canonical_body() + or intent.selected_request_digest != reservation.request_digest + or intent.selected_terminal_json + != request.custody.selected_terminal_body + or intent.selected_terminal_digest + != request.custody.selected_terminal_digest or attempt.producer_request_type != "submission_bundle" or attempt.status not in { @@ -2451,248 +2391,24 @@ async def _submission_bundle_replay_attempt( or attempt.sha256 != current.archive_sha256 or attempt.byte_count != current.archive_byte_count or attempt.media_type != current.media_type - or self._submission_replay_lineage(prior) != self._submission_replay_lineage(fresh) - or ( - prior.actor_profile_id, - prior.identity_link_id, - prior.project_id, - prior.task_id, - prior.assignment_id, - prior.predecessor_submission_id, - prior.predecessor_submission_version, - prior.checker_remediation_manifest_id, - prior.guide_id, - prior.guide_version, - prior.source_snapshot_id, - prior.source_snapshot_sha256, - prior.locked_artifact_policy_sha256, - prior.locked_checker_policy_sha256, - prior.effective_plan_sha256, - prior.semantic_manifest_sha256, - prior.archive_sha256, - prior.archive_byte_count, - prior.storage_scheme, - ) - != ( - str(current.actor_profile_id), - str(current.identity_link_id), - str(current.project_id), - str(current.task_id), - str(current.assignment_id), - str(current.predecessor_submission_id) - if current.predecessor_submission_id is not None - else None, - current.predecessor_submission_version, - current.checker_remediation_manifest_id, - str(current.guide_id), - current.guide_version, - str(current.source_snapshot_id), - current.source_snapshot_sha256, - current.effective_policy_sha256, - current.pre_submit_policy_sha256, - current.effective_plan_sha256, - current.semantic_manifest_sha256, - current.archive_sha256, - current.archive_byte_count, - current.storage_scheme, - ) ): raise ArtifactAdmissionRelationshipError( - "submission bundle replay intent does not match fresh custody" + "selected submission bundle replay intent does not match custody" ) return attempt - @staticmethod - def _submission_replay_lineage(evidence: PreSubmitEvidenceSet) -> tuple[object, ...]: - """Return every publication-relevant evidence fact except fresh issuance identity.""" - return ( - evidence.actor_profile_id, - evidence.identity_link_id, - evidence.project_id, - evidence.task_id, - evidence.assignment_id, - evidence.predecessor_submission_id, - evidence.predecessor_submission_version, - evidence.checker_remediation_manifest_id, - evidence.archive_sha256, - evidence.archive_byte_count, - evidence.semantic_manifest_id, - evidence.semantic_manifest_sha256, - evidence.guide_id, - evidence.guide_version, - evidence.source_snapshot_id, - evidence.source_snapshot_sha256, - evidence.locked_guide_sha256, - evidence.effective_policy_id, - evidence.locked_artifact_policy_sha256, - evidence.pre_submit_policy_id, - evidence.locked_checker_policy_sha256, - evidence.effective_plan_sha256, - evidence.catalogue_id, - evidence.catalogue_version, - evidence.catalogue_manifest_sha256, - evidence.storage_scheme, - evidence.terminal_status, - evidence.eligible, - evidence.result_count, - evidence.result_manifest_sha256, - ) - async def _submission_bundle_facts( self, request: SubmissionBundleArtifactAdmissionRequest, *, task_contexts: TaskSubmissionContextPort, project_contexts: ProjectLockedPolicyContextPort, ) -> tuple[SubmissionBundleDurableIntentAuthorityFacts, _AdmissionFacts]: - """Lock exact passing evidence and current TASK-owned lineage.""" - from app.modules.artifacts.pre_submit_evidence import PreSubmitPassCapability + """Revalidate the sole external PRE custody under current owner locks.""" from app.modules.artifacts.submission_custody import SubmissionBundlePreparedCustody if type(request.custody) is not SubmissionBundlePreparedCustody: raise ArtifactAuthorityDeniedError("submission bundle prepared custody is unavailable") - if request.custody.is_selected: - return await self._selected_submission_bundle_facts( - request, - task_contexts=task_contexts, - project_contexts=project_contexts, - ) - pass_capability = request.custody.pass_capability - if type(pass_capability) is not PreSubmitPassCapability: - raise ArtifactAuthorityDeniedError("submission bundle pass capability is unavailable") - evidence = await self._repo.lock_pre_submit_evidence_set( - str(request.pre_submit_evidence_set_id) - ) - commitment = request.source.commitment - if ( - evidence is None - or evidence.terminal_status != "passed" - or not evidence.eligible - or evidence.prepared_generation_id != str(request.custody.prepared_generation_id) - or evidence.archive_sha256 != commitment.sha256 - or evidence.archive_byte_count != commitment.byte_count - or commitment.media_type != "application/zip" - or evidence.predecessor_submission_id - != ( - str(pass_capability.predecessor_submission_id) - if pass_capability.predecessor_submission_id is not None - else None - ) - or evidence.checker_remediation_manifest_id - != pass_capability.checker_remediation_manifest_id - or evidence.effective_plan_sha256 != pass_capability.effective_plan_sha256 - or evidence.semantic_manifest_sha256 != pass_capability.semantic_manifest_sha256 - or evidence.storage_scheme != pass_capability.storage_scheme - ): - raise ArtifactAdmissionRelationshipError( - "submission bundle passing evidence is unavailable" - ) - try: - task = await task_contexts.lock_submission_context( - TaskSubmissionContextRequest( - task_id=UUID(evidence.task_id), - assignment_id=UUID(evidence.assignment_id), - contributor_id=UUID(evidence.actor_profile_id), - predecessor_submission_id=(UUID(evidence.predecessor_submission_id) - if evidence.predecessor_submission_id is not None else None), - ) - ) - references = task.locked_project_context - locked = await project_contexts.lock_locked_policy_context( - ProjectLockedPolicyContextRequest( - project_id=references.project_id, guide_version=references.guide_version, - source_snapshot_id=references.source_snapshot_id, - source_snapshot_hash=references.source_snapshot_hash, - effective_policy_id=references.effective_policy_id, - effective_policy_hash=references.effective_policy_hash, - pre_submit_policy_id=references.pre_submit_policy_id, - pre_submit_policy_bundle_hash=references.pre_submit_policy_bundle_hash, - ) - ) - except (TaskSubmissionContextUnavailable, ProjectLockedPolicyContextUnavailable) as exc: - raise ArtifactAdmissionRelationshipError("pre_submit_locked_context_changed") from exc - guide_hash = canonical_json_hash({ - "domain": "workstream.locked_task_guide.v1", - "project_id": str(locked.project_id), "guide_id": str(locked.guide_id), - "guide_version": locked.guide_version, - "source_snapshot_id": str(locked.source_snapshot_id), - "source_snapshot_sha256": locked.source_snapshot_hash, - }) - if ( - locked.project_id != UUID(evidence.project_id) - or (task.predecessor.version if task.predecessor else None) - != evidence.predecessor_submission_version - or task.checker_remediation_manifest_id - != evidence.checker_remediation_manifest_id - or task.submitter_contribution_policy_version_id - != locked.activation_receipt.command.contribution_policy_version_id - or locked.guide_id != UUID(evidence.guide_id) - or locked.guide_version != evidence.guide_version - or locked.source_snapshot_id != UUID(evidence.source_snapshot_id) - or locked.source_snapshot_hash != evidence.source_snapshot_sha256 - or guide_hash != evidence.locked_guide_sha256 - or locked.effective_policy_id != UUID(evidence.effective_policy_id) - or locked.effective_policy_hash != evidence.locked_artifact_policy_sha256 - or locked.pre_submit_policy_id != UUID(evidence.pre_submit_policy_id) - or locked.pre_submit_policy_bundle_hash != evidence.locked_checker_policy_sha256 - ): - raise ArtifactAdmissionRelationshipError("submission bundle locked context changed") - operation_identity = canonical_json_hash( - { - "request_type": "submission_bundle", - "pre_submit_evidence_set_id": evidence.id, - } - ) - authority_facts = SubmissionBundleDurableIntentAuthorityFacts( - actor_profile_id=UUID(evidence.actor_profile_id), - identity_link_id=UUID(evidence.identity_link_id), - project_id=UUID(evidence.project_id), - task_id=UUID(evidence.task_id), - assignment_id=UUID(evidence.assignment_id), - predecessor_submission_id=( - UUID(evidence.predecessor_submission_id) - if evidence.predecessor_submission_id is not None - else None - ), - predecessor_submission_version=evidence.predecessor_submission_version, - checker_remediation_manifest_id=evidence.checker_remediation_manifest_id, - pre_submit_evidence_set_id=UUID(evidence.id), - prepared_generation_id=UUID(evidence.prepared_generation_id), - guide_id=UUID(evidence.guide_id), - guide_version=evidence.guide_version, - source_snapshot_id=UUID(evidence.source_snapshot_id), - source_snapshot_sha256=evidence.source_snapshot_sha256, - effective_policy_id=UUID(evidence.effective_policy_id), - effective_policy_sha256=evidence.locked_artifact_policy_sha256, - pre_submit_policy_id=UUID(evidence.pre_submit_policy_id), - pre_submit_policy_sha256=evidence.locked_checker_policy_sha256, - effective_plan_sha256=evidence.effective_plan_sha256, - semantic_manifest_id=UUID(evidence.semantic_manifest_id), - semantic_manifest_sha256=evidence.semantic_manifest_sha256, - semantic_manifest_body=evidence.semantic_manifest_body, - packet_sha256=evidence.packet_sha256, - archive_sha256=evidence.archive_sha256, - archive_byte_count=evidence.archive_byte_count, - media_type=commitment.media_type, - storage_scheme=evidence.storage_scheme, - operation_identity=operation_identity, - replay_durable_intent_id=request.replay_durable_intent_id, - ) - return authority_facts, _AdmissionFacts( - request_type="submission_bundle", - producer_type="actor_profile", - producer_ref=evidence.actor_profile_id, - project_id=evidence.project_id, - guide_id=evidence.guide_id, - task_id=evidence.task_id, - guide_source_item_id=None, - guide_source_snapshot_id=evidence.source_snapshot_id, - checker_run_id=None, - logical_role=None, - submission_id=None, - submission_version=None, - checker_request_digest=None, - checker_request_digest_facts=None, - pre_submit_evidence_set_id=evidence.id, - operation_identity=operation_identity, + return await self._selected_submission_bundle_facts( + request, task_contexts=task_contexts, project_contexts=project_contexts, ) async def _selected_submission_bundle_facts( diff --git a/backend/app/modules/artifacts/submission_admission.py b/backend/app/modules/artifacts/submission_admission.py index 5d3c4ce42..e86fe91af 100644 --- a/backend/app/modules/artifacts/submission_admission.py +++ b/backend/app/modules/artifacts/submission_admission.py @@ -4,7 +4,7 @@ from collections.abc import Callable from contextlib import AbstractAsyncContextManager, AsyncExitStack -from dataclasses import dataclass, replace +from dataclasses import dataclass, field, replace from uuid import UUID from app.core.hashing import canonical_json_hash from app.core.identifiers import new_record_id @@ -29,14 +29,9 @@ ArtifactReplica, ArtifactVerificationJob, ArtifactVerificationReceipt, - PreSubmitEvidenceSet, SubmissionBundleAdmission, SubmissionBundleDurableIntent, ) -from app.modules.artifacts.pre_submit_evidence import ( - PreSubmitEvidenceConflict, - PreSubmitPassCapability, -) from app.modules.artifacts.preparation import ArtifactPreparationService from app.modules.artifacts.schemas import ( ArtifactAdmissionResult, @@ -84,7 +79,7 @@ LockedExternalCheckerPolicies, selected_pre_submit_execution_budget_ms, ) -from app.modules.checkers.api import SubmissionPacketView +from app.modules.checkers.api.pre_submit_material import SubmissionPacketView from app.modules.projects.api import ( ProjectLockedPolicyContextFacts, ProjectLockedPolicyContextPort, @@ -116,12 +111,11 @@ class SubmissionBundleDurablePutRequest: prepared_authorization: object prepared_artifact: PreparedArtifact - pass_capability: PreSubmitPassCapability | None replay_durable_intent_id: UUID | None = None - selected_completion: SelectedPreSubmitCompletion | None = None + selected_completion: SelectedPreSubmitCompletion = field(kw_only=True) def __post_init__(self) -> None: - if (self.pass_capability is None) == (self.selected_completion is None): + if type(self.selected_completion) is not SelectedPreSubmitCompletion: raise ValueError("submission bundle durable PRE custody is invalid") @@ -176,42 +170,24 @@ async def admit_in_transaction( or not transaction.is_active or self._session.in_nested_transaction() or type(prepared) is not PreparedArtifact - or ( - request.pass_capability is not None - and type(request.pass_capability) is not PreSubmitPassCapability - ) - or ( - request.selected_completion is not None - and type(request.selected_completion) is not SelectedPreSubmitCompletion - ) + or type(request.selected_completion) is not SelectedPreSubmitCompletion ): if type(prepared) is PreparedArtifact: await prepared.close() raise RuntimeError("submission bundle durable transaction is unavailable") try: - if request.selected_completion is not None: - custody = SubmissionBundlePreparedCustody._from_selected_pre_submit( - prepared=prepared, - completion=request.selected_completion, - ) - evidence_set_id = None - selected_run_id = custody.selected_reservation.attempt_id - else: - assert request.pass_capability is not None - evidence_set_id = request.pass_capability.evidence_set_id - selected_run_id = None - custody = SubmissionBundlePreparedCustody._from_live_preparation( - prepared=prepared, - capability=request.pass_capability, - ) + custody = SubmissionBundlePreparedCustody._from_selected_pre_submit( + prepared=prepared, completion=request.selected_completion, + ) + selected_run_id = custody.selected_reservation.attempt_id admission = await self._admission.admit( SubmissionBundleArtifactAdmissionRequest( - pre_submit_evidence_set_id=evidence_set_id, + pre_submit_evidence_set_id=None, custody=custody, replay_durable_intent_id=request.replay_durable_intent_id, selected_pre_submit_run_id=selected_run_id, selected_terminal_digest=( - custody.selected_terminal_digest if selected_run_id is not None else None + custody.selected_terminal_digest ), ), submission_prepared_authorization=self._authorization, @@ -220,7 +196,7 @@ async def admit_in_transaction( prepared_authorization=request.prepared_authorization, existing_transaction=True, ) - return prepared, evidence_set_id or selected_run_id, admission + return prepared, selected_run_id, admission except BaseException: await prepared.close() raise @@ -231,13 +207,12 @@ async def publish_after_commit( lineage_id: UUID, admission: ArtifactAdmissionResult, *, - selected_pre_submit_run_id: UUID | None = None, + selected_pre_submit_run_id: UUID, ) -> SubmissionBundleDurablePutResult: """Hand the exact ZIP to storage only after the durable transaction ended.""" - if selected_pre_submit_run_id is not None and selected_pre_submit_run_id != lineage_id: + if selected_pre_submit_run_id != lineage_id: await prepared.close() raise RuntimeError("submission bundle selected lineage changed") - evidence_set_id = None if selected_pre_submit_run_id is not None else lineage_id if self._session.in_transaction(): await prepared.close() raise RuntimeError("submission bundle durable transaction is still active") @@ -252,7 +227,7 @@ async def publish_after_commit( if admission_id is not None: return SubmissionBundleDurablePutResult( put_attempt_id=admission.attempt_id, - pre_submit_evidence_set_id=evidence_set_id, + pre_submit_evidence_set_id=None, operation_identity=admission.operation_identity, status="ready", replayed=True, @@ -262,7 +237,7 @@ async def publish_after_commit( if admission.replayed and admission.status == "object_confirmed": return SubmissionBundleDurablePutResult( put_attempt_id=admission.attempt_id, - pre_submit_evidence_set_id=evidence_set_id, + pre_submit_evidence_set_id=None, operation_identity=admission.operation_identity, status="object_confirmed", replayed=True, @@ -286,7 +261,7 @@ async def publish_after_commit( ) return SubmissionBundleDurablePutResult( put_attempt_id=admission.attempt_id, - pre_submit_evidence_set_id=evidence_set_id, + pre_submit_evidence_set_id=None, operation_identity=admission.operation_identity, status=status, replayed=admission.replayed, @@ -337,6 +312,8 @@ async def publish_verified( ) if intent is None: raise SubmissionBundleAdmissionPublicationError("durable intent is unavailable") + if intent.pre_submit_evidence_set_id is not None or intent.selected_pre_submit_run_id is None: + raise SubmissionBundleAdmissionPublicationError("external PRE durable intent is unavailable") existing = await self._session.scalar( select(SubmissionBundleAdmission) .where(SubmissionBundleAdmission.durable_intent_id == intent.id) @@ -344,40 +321,29 @@ async def publish_verified( ) if existing is not None: return existing - evidence = ( - await self._session.scalar( - select(PreSubmitEvidenceSet) - .where(PreSubmitEvidenceSet.id == intent.pre_submit_evidence_set_id) - .with_for_update(key_share=True) + try: + selected = SelectedPreSubmitReservationFacts.from_canonical_body( + intent.selected_request_json + ) + except (TypeError, ValueError) as exc: + raise SubmissionBundleAdmissionPublicationError( + "selected PRE request snapshot is invalid" + ) from exc + terminal = intent.selected_terminal_json + if ( + selected.admission_lineage is None + or selected.attempt_id != UUID(intent.selected_pre_submit_run_id) + or selected.request_digest != intent.selected_request_digest + or type(terminal) is not dict + or canonical_json_hash(terminal) != intent.selected_terminal_digest + or terminal.get("request_digest") != selected.request_digest + or terminal.get("outcome") != "completed" + or type(terminal.get("execution")) is not dict + or terminal["execution"].get("eligible") is not True + ): + raise SubmissionBundleAdmissionPublicationError( + "selected PRE terminal snapshot is invalid" ) - if intent.pre_submit_evidence_set_id is not None - else None - ) - selected = None - if intent.selected_pre_submit_run_id is not None: - try: - selected = SelectedPreSubmitReservationFacts.from_canonical_body( - intent.selected_request_json - ) - except (TypeError, ValueError) as exc: - raise SubmissionBundleAdmissionPublicationError( - "selected PRE request snapshot is invalid" - ) from exc - terminal = intent.selected_terminal_json - if ( - selected.admission_lineage is None - or selected.attempt_id != UUID(intent.selected_pre_submit_run_id) - or selected.request_digest != intent.selected_request_digest - or type(terminal) is not dict - or canonical_json_hash(terminal) != intent.selected_terminal_digest - or terminal.get("request_digest") != selected.request_digest - or terminal.get("outcome") != "completed" - or type(terminal.get("execution")) is not dict - or terminal["execution"].get("eligible") is not True - ): - raise SubmissionBundleAdmissionPublicationError( - "selected PRE terminal snapshot is invalid" - ) replica = await self._session.scalar( select(ArtifactReplica) .where(ArtifactReplica.id == job.replica_id) @@ -397,175 +363,62 @@ async def publish_verified( if replica is not None else None ) - lineage = selected.admission_lineage if selected is not None else evidence - if ( - lineage is None - or ( - evidence is not None - and (evidence.terminal_status != "passed" or not evidence.eligible) - ) - or not self._matches_verified_bytes( - attempt, - job, - replica, - content, - receipt, - project_id=str( - selected.project_id if selected is not None else evidence.project_id - ), - task_id=str(selected.task_id if selected is not None else evidence.task_id), - actor_profile_id=str( - selected.actor_profile_id if selected is not None else evidence.actor_profile_id - ), - archive_sha256=( - selected.archive_sha256 if selected is not None else evidence.archive_sha256 - ), - archive_byte_count=( - selected.archive_byte_count - if selected is not None - else evidence.archive_byte_count - ), - ) + lineage = selected.admission_lineage + if not self._matches_verified_bytes( + attempt, job, replica, content, receipt, + project_id=str(selected.project_id), task_id=str(selected.task_id), + actor_profile_id=str(selected.actor_profile_id), + archive_sha256=selected.archive_sha256, + archive_byte_count=selected.archive_byte_count, ): raise SubmissionBundleAdmissionPublicationError( "verified submission bundle lineage does not match" ) operation_receipt_id, observation_receipt_id = await self._write_receipt_ids(attempt) - assert replica is not None and content is not None - assert receipt is not None - selected_lineage = selected.admission_lineage if selected is not None else None + assert replica is not None and content is not None and receipt is not None + assert lineage is not None now = await self._session.scalar(select(func.now())) admission = SubmissionBundleAdmission( - id=str(new_record_id()), - durable_intent_id=intent.id, - pre_submit_evidence_set_id=(evidence.id if evidence is not None else None), - selected_pre_submit_run_id=(str(selected.attempt_id) if selected is not None else None), - put_attempt_id=attempt.id, - artifact_content_id=content.id, - verified_replica_id=replica.id, - verification_receipt_id=receipt.id, + id=str(new_record_id()), durable_intent_id=intent.id, + pre_submit_evidence_set_id=None, + selected_pre_submit_run_id=str(selected.attempt_id), + put_attempt_id=attempt.id, artifact_content_id=content.id, + verified_replica_id=replica.id, verification_receipt_id=receipt.id, put_operation_receipt_id=operation_receipt_id, put_observation_receipt_id=observation_receipt_id, - actor_profile_id=str( - selected.actor_profile_id if selected is not None else evidence.actor_profile_id - ), - identity_link_id=str( - selected.identity_link_id if selected is not None else evidence.identity_link_id - ), - project_id=str(selected.project_id if selected is not None else evidence.project_id), - task_id=str(selected.task_id if selected is not None else evidence.task_id), - assignment_id=str( - selected.assignment_id if selected is not None else evidence.assignment_id - ), + actor_profile_id=str(selected.actor_profile_id), + identity_link_id=str(selected.identity_link_id), + project_id=str(selected.project_id), task_id=str(selected.task_id), + assignment_id=str(selected.assignment_id), predecessor_submission_id=( - str(selected_lineage.predecessor_submission_id) - if selected_lineage is not None - and selected_lineage.predecessor_submission_id is not None - else evidence.predecessor_submission_id - if evidence is not None - else None - ), - predecessor_submission_version=( - selected_lineage.predecessor_submission_version - if selected_lineage is not None - else evidence.predecessor_submission_version + str(lineage.predecessor_submission_id) + if lineage.predecessor_submission_id is not None else None ), + predecessor_submission_version=lineage.predecessor_submission_version, checker_remediation_manifest_id=( - str(selected_lineage.checker_remediation_manifest_id) - if selected_lineage is not None - and selected_lineage.checker_remediation_manifest_id is not None - else evidence.checker_remediation_manifest_id - if evidence is not None else None - ), - locked_policy_context_hash=( - selected_lineage.locked_policy_context_hash - if selected_lineage is not None - else evidence.locked_policy_context_hash - ), - guide_id=str( - selected_lineage.guide_id if selected_lineage is not None else evidence.guide_id - ), - guide_version=( - selected_lineage.guide_version - if selected_lineage is not None - else evidence.guide_version - ), - source_snapshot_id=str( - selected_lineage.source_snapshot_id - if selected_lineage is not None - else evidence.source_snapshot_id - ), - source_snapshot_sha256=( - selected_lineage.source_snapshot_sha256 - if selected_lineage is not None - else evidence.source_snapshot_sha256 - ), - effective_policy_id=str( - selected_lineage.effective_policy_id - if selected_lineage is not None - else evidence.effective_policy_id - ), - effective_policy_sha256=( - selected_lineage.effective_policy_sha256 - if selected_lineage is not None - else evidence.locked_artifact_policy_sha256 - ), - pre_submit_policy_id=str( - selected_lineage.pre_submit_policy_id - if selected_lineage is not None - else evidence.pre_submit_policy_id - ), - pre_submit_policy_sha256=( - selected_lineage.pre_submit_policy_sha256 - if selected_lineage is not None - else evidence.locked_checker_policy_sha256 - ), - effective_plan_sha256=( - selected_lineage.effective_plan_sha256 - if selected_lineage is not None - else evidence.effective_plan_sha256 + str(lineage.checker_remediation_manifest_id) + if lineage.checker_remediation_manifest_id is not None else None ), - selected_rules_sha256=( - selected_lineage.rules_sha256 if selected_lineage is not None else None - ), - selected_post_submit_policy_sha256=( - selected_lineage.post_submit_policy_sha256 if selected_lineage is not None else None - ), - selected_post_submit_policy_body=( - selected_lineage.post_submit_policy_body if selected_lineage is not None else None - ), - packet_sha256=( - selected_lineage.packet_sha256 - if selected_lineage is not None - else evidence.packet_sha256 - ), - semantic_manifest_id=str( - selected_lineage.semantic_manifest_id - if selected_lineage is not None - else evidence.semantic_manifest_id - ), - semantic_manifest_sha256=( - selected.semantic_manifest_sha256 - if selected is not None - else evidence.semantic_manifest_sha256 - ), - semantic_manifest_body=( - selected_lineage.semantic_manifest_body - if selected_lineage is not None - else evidence.semantic_manifest_body - ), - archive_sha256=( - selected.archive_sha256 if selected is not None else evidence.archive_sha256 - ), - archive_byte_count=( - selected.archive_byte_count if selected is not None else evidence.archive_byte_count - ), - status="ready", - ready_at=now, - consumed_at=None, - consumed_by_submission_id=None, - stale_at=None, - stale_reason=None, + locked_policy_context_hash=lineage.locked_policy_context_hash, + guide_id=str(lineage.guide_id), guide_version=lineage.guide_version, + source_snapshot_id=str(lineage.source_snapshot_id), + source_snapshot_sha256=lineage.source_snapshot_sha256, + effective_policy_id=str(lineage.effective_policy_id), + effective_policy_sha256=lineage.effective_policy_sha256, + pre_submit_policy_id=str(lineage.pre_submit_policy_id), + pre_submit_policy_sha256=lineage.pre_submit_policy_sha256, + effective_plan_sha256=lineage.effective_plan_sha256, + selected_rules_sha256=lineage.rules_sha256, + selected_post_submit_policy_sha256=lineage.post_submit_policy_sha256, + selected_post_submit_policy_body=lineage.post_submit_policy_body, + packet_sha256=lineage.packet_sha256, + semantic_manifest_id=str(lineage.semantic_manifest_id), + semantic_manifest_sha256=selected.semantic_manifest_sha256, + semantic_manifest_body=lineage.semantic_manifest_body, + archive_sha256=selected.archive_sha256, + archive_byte_count=selected.archive_byte_count, + status="ready", ready_at=now, consumed_at=None, + consumed_by_submission_id=None, stale_at=None, stale_reason=None, ) self._session.add(admission) await self._session.flush() @@ -610,26 +463,6 @@ def _matches_verified_bytes( and attempt.media_type == "application/zip" ) - @staticmethod - def _matches_verified_lineage(evidence, attempt, job, replica, content, receipt) -> bool: - """Retain the historical evidence decoder over the shared byte verifier.""" - return bool( - evidence is not None - and evidence.terminal_status == "passed" - and evidence.eligible - and SubmissionBundleAdmissionPublisher._matches_verified_bytes( - attempt, - job, - replica, - content, - receipt, - project_id=evidence.project_id, - task_id=evidence.task_id, - actor_profile_id=evidence.actor_profile_id, - archive_sha256=evidence.archive_sha256, - archive_byte_count=evidence.archive_byte_count, - ) - ) async def _write_receipt_ids( self, attempt: ArtifactPutAttempt @@ -823,7 +656,6 @@ async def prepare( ), checker_remediation_manifest_id=remediation_manifest_id, prepared_artifact=prepared, - effective_plan=None, inspection=inspection, manifest=manifest, change_gate=selected.change_gate, @@ -884,7 +716,6 @@ async def prepare( SubmissionBundleDurablePutRequest( prepared_authorization=None, prepared_artifact=prepared, - pass_capability=None, selected_completion=completion, ) ) @@ -899,8 +730,6 @@ async def prepare( raise SubmissionBundlePreparationRejected( "submission_bundle_preparation_request_conflict" ) from exc - except PreSubmitEvidenceConflict as exc: - raise self._evidence_failure(exc) from exc except ArtifactAuthorityDeniedError as exc: raise SubmissionBundlePreparationUnavailable( "submission bundle preparation is unavailable" @@ -969,94 +798,7 @@ async def _selected_replay_result( replayed=True, ) - async def _matching_replay_intent(self, evidence_id: UUID) -> UUID | None: - """Find an older exact lineage without trusting client replay selectors.""" - async with self._session.begin(): - current = await self._session.get(PreSubmitEvidenceSet, str(evidence_id)) - if current is None: - raise SubmissionBundlePreparationRejected( - "pre_submission_checked_custody_unavailable" - ) - fields = ( - "actor_profile_id", - "identity_link_id", - "project_id", - "task_id", - "assignment_id", - "predecessor_submission_id", - "predecessor_submission_version", - "checker_remediation_manifest_id", - "archive_sha256", - "archive_byte_count", - "semantic_manifest_sha256", - "guide_id", - "guide_version", - "source_snapshot_id", - "source_snapshot_sha256", - "locked_guide_sha256", - "effective_policy_id", - "locked_artifact_policy_sha256", - "pre_submit_policy_id", - "locked_checker_policy_sha256", - "effective_plan_sha256", - "catalogue_id", - "catalogue_version", - "catalogue_manifest_sha256", - "storage_scheme", - "terminal_status", - "eligible", - "result_count", - "result_manifest_sha256", - ) - statement = ( - select(SubmissionBundleDurableIntent.id) - .join( - PreSubmitEvidenceSet, - PreSubmitEvidenceSet.id - == SubmissionBundleDurableIntent.pre_submit_evidence_set_id, - ) - .join( - ArtifactPutAttempt, - ArtifactPutAttempt.id == SubmissionBundleDurableIntent.put_attempt_id, - ) - .where( - PreSubmitEvidenceSet.id != current.id, - ArtifactPutAttempt.status.in_( - ( - "prepared", - "acknowledgement_unknown", - "absent_replay_required", - "object_confirmed", - ) - ), - *( - getattr(PreSubmitEvidenceSet, field) == getattr(current, field) - for field in fields - ), - ) - .order_by(SubmissionBundleDurableIntent.created_at) - .limit(1) - ) - value = await self._session.scalar(statement) - return UUID(value) if value is not None else None - @staticmethod - def _evidence_failure(exc: PreSubmitEvidenceConflict) -> RuntimeError: - """Separate changed client context from unavailable canonical execution evidence.""" - if str(exc) == "pre_submit_locked_context_changed": - return SubmissionBundlePreparationRejected( - "submission_bundle_preparation_context_changed" - ) - if str(exc) == "pre_submit_attempt_request_conflict": - return SubmissionBundlePreparationRejected( - "submission_bundle_preparation_request_conflict" - ) - code = ( - "pre_submission_attempt_outcome_unresolved" - if str(exc) == "pre_submit_attempt_outcome_unresolved" - else "pre_submission_checked_custody_unavailable" - ) - return SubmissionBundlePreparationInfrastructureUnavailable(code) async def _lock_authorized_context( self, @@ -1104,49 +846,6 @@ async def _lock_context( ) from exc return task_context, project_context - async def _existing_durable_result( - self, evidence_id: UUID - ) -> SubmissionBundlePreparationResult | None: - async with self._session.begin(): - row = ( - await self._session.execute( - select( - SubmissionBundleDurableIntent, - ArtifactPutAttempt, - SubmissionBundleAdmission, - ) - .join( - ArtifactPutAttempt, - ArtifactPutAttempt.id == SubmissionBundleDurableIntent.put_attempt_id, - ) - .outerjoin( - SubmissionBundleAdmission, - SubmissionBundleAdmission.durable_intent_id - == SubmissionBundleDurableIntent.id, - ) - .where( - SubmissionBundleDurableIntent.pre_submit_evidence_set_id == str(evidence_id) - ) - ) - ).one_or_none() - if row is None: - return None - _, attempt, admission = row - status = attempt.status - admission_id = None - if admission is not None: - if admission.status == "ready": - status, admission_id = "ready", UUID(admission.id) - elif admission.status == "stale": - status = "stale" - else: - status = "conflict" - return SubmissionBundlePreparationResult( - put_attempt_id=UUID(attempt.id), - admission_id=admission_id, - submission_bundle_preparation_status=SubmissionBundlePreparationStatus(status), - replayed=True, - ) async def _load_predecessor( self, diff --git a/backend/app/modules/artifacts/submission_bindings.py b/backend/app/modules/artifacts/submission_bindings.py index 30a1bbd37..de9968999 100644 --- a/backend/app/modules/artifacts/submission_bindings.py +++ b/backend/app/modules/artifacts/submission_bindings.py @@ -23,7 +23,6 @@ from app.modules.artifacts.models import ( ArtifactBinding, ArtifactContent, - PreSubmitEvidenceSet, SubmissionBundleAdmission, SubmissionBindingReceipt, ) @@ -124,7 +123,6 @@ async def consume( raise SubmissionAdmissionConsumptionError( "submission_bundle_admission_already_consumed" ) - evidence = await self._legacy_evidence(admission) content = await self._session.scalar( select(ArtifactContent) .where(ArtifactContent.id == admission.artifact_content_id) @@ -134,7 +132,7 @@ async def consume( raise SubmissionAdmissionConsumptionError( "submission_bundle_admission_unavailable" ) - if not self._art_lineage_is_intact(admission, evidence, content): + if not self._art_lineage_is_intact(admission, content): raise SubmissionAdmissionConsumptionError( "submission_bundle_admission_unavailable" ) @@ -255,7 +253,6 @@ async def read_consumed( populate_existing=True) if receipt is None: raise SubmissionAdmissionConsumptionError("submission_bundle_admission_unavailable") - evidence = await self._legacy_evidence(admission) content = await self._session.scalar(select(ArtifactContent).where( ArtifactContent.id == admission.artifact_content_id, ).with_for_update().execution_options(populate_existing=True)) @@ -270,7 +267,7 @@ async def read_consumed( content is None or binding is None or binding.content_id != admission.artifact_content_id or binding.id != receipt.binding_id - or not self._art_lineage_is_intact(admission, evidence, content) + or not self._art_lineage_is_intact(admission, content) or admission.packet_sha256 != request.packet_sha256 ): raise SubmissionAdmissionConsumptionError("submission_bundle_admission_context_changed") @@ -280,66 +277,18 @@ async def read_consumed( return self._result(admission, request, binding=binding, replayed=True, binding_decision_id=UUID(receipt.decision_id)) - async def _legacy_evidence( - self, admission: SubmissionBundleAdmission - ) -> PreSubmitEvidenceSet | None: - """Load retained legacy evidence only for historical lineage validation.""" - if admission.pre_submit_evidence_set_id is None: - return None - return await self._session.scalar( - select(PreSubmitEvidenceSet) - .where(PreSubmitEvidenceSet.id == admission.pre_submit_evidence_set_id) - .with_for_update() - .execution_options(populate_existing=True) - ) - @staticmethod def _art_lineage_is_intact( - admission: SubmissionBundleAdmission, - evidence: PreSubmitEvidenceSet | None, - content: ArtifactContent, + admission: SubmissionBundleAdmission, content: ArtifactContent, ) -> bool: - legacy_intact = evidence is None or bool( - evidence.id == admission.pre_submit_evidence_set_id - and admission.selected_pre_submit_run_id is None - and evidence.actor_profile_id == admission.actor_profile_id - and evidence.identity_link_id == admission.identity_link_id - and evidence.project_id == admission.project_id - and evidence.task_id == admission.task_id - and evidence.assignment_id == admission.assignment_id - and evidence.predecessor_submission_id - == admission.predecessor_submission_id - and evidence.predecessor_submission_version - == admission.predecessor_submission_version - and evidence.checker_remediation_manifest_id - == admission.checker_remediation_manifest_id - and evidence.locked_policy_context_hash - == admission.locked_policy_context_hash - and evidence.semantic_manifest_id == admission.semantic_manifest_id - and evidence.semantic_manifest_sha256 - == admission.semantic_manifest_sha256 - and evidence.archive_sha256 == admission.archive_sha256 - and evidence.archive_byte_count == admission.archive_byte_count - and evidence.terminal_status == "passed" - and evidence.eligible is True - ) - selected_policy_intact = admission.selected_pre_submit_run_id is None - if admission.selected_pre_submit_run_id is not None: - try: - selected_policy = validate_stored_external_post_policy( - admission.selected_post_submit_policy_body - ) - selected_policy_intact = ( - selected_policy.policy_sha256 - == admission.selected_post_submit_policy_sha256 - ) - except (TypeError, ValueError): - selected_policy_intact = False + try: + policy = validate_stored_external_post_policy(admission.selected_post_submit_policy_body) + except (TypeError, ValueError): + return False return bool( - legacy_intact - and selected_policy_intact - and (admission.pre_submit_evidence_set_id is None) - != (admission.selected_pre_submit_run_id is None) + admission.pre_submit_evidence_set_id is None + and admission.selected_pre_submit_run_id is not None + and policy.policy_sha256 == admission.selected_post_submit_policy_sha256 and content.id == admission.artifact_content_id and content.sha256 == admission.archive_sha256 and content.byte_count == admission.archive_byte_count diff --git a/backend/app/modules/artifacts/submission_custody.py b/backend/app/modules/artifacts/submission_custody.py index ba652261a..2efc8f28c 100644 --- a/backend/app/modules/artifacts/submission_custody.py +++ b/backend/app/modules/artifacts/submission_custody.py @@ -5,7 +5,6 @@ from typing import final from uuid import UUID -from app.modules.artifacts.pre_submit_evidence import PreSubmitPassCapability from app.modules.artifacts.sources import CommittedArtifactSource, PreparedArtifact from app.modules.checkers.api.selected_pre_submit import ( SelectedPreSubmitCompletion, @@ -17,32 +16,11 @@ class SubmissionBundlePreparedCustody: """Unforgeable join of live prepared bytes and their fresh pass capability.""" - __slots__ = ("_capability", "_prepared", "_selected") + __slots__ = ("_prepared", "_selected") def __init__(self, *_: object, **__: object) -> None: raise TypeError("submission bundle custody requires live prepared work") - @classmethod - def _from_live_preparation( - cls, - *, - prepared: PreparedArtifact, - capability: PreSubmitPassCapability, - ) -> SubmissionBundlePreparedCustody: - if ( - type(prepared) is not PreparedArtifact - or type(capability) is not PreSubmitPassCapability - ): - raise TypeError("submission bundle custody requires live prepared work") - capability._assert_live_prepared_custody( - prepared_generation_id=prepared.generation_id, - archive_sha256=prepared.commitment.sha256, - ) - custody = object.__new__(cls) - custody._prepared = prepared - custody._capability = capability - custody._selected = None - return custody @classmethod def _from_selected_pre_submit( @@ -82,7 +60,6 @@ def _from_selected_pre_submit( raise TypeError("submission bundle selected custody is unavailable") custody = object.__new__(cls) custody._prepared = prepared - custody._capability = None custody._selected = completion.terminal return custody @@ -90,11 +67,6 @@ def _from_selected_pre_submit( def prepared_generation_id(self) -> UUID: return self._prepared.generation_id - @property - def pass_capability(self) -> PreSubmitPassCapability: - if type(self._capability) is not PreSubmitPassCapability: - raise TypeError("legacy submission pass capability is unavailable") - return self._capability @property def selected_reservation(self) -> SelectedPreSubmitReservationFacts: @@ -120,8 +92,3 @@ def selected_terminal_body(self) -> dict[str, object]: @property def source(self) -> CommittedArtifactSource: return self._prepared.committed_source - - @property - def is_selected(self) -> bool: - """Distinguish new selected custody from the retained legacy decoder.""" - return self._selected is not None diff --git a/backend/app/modules/artifacts/submission_manifest.py b/backend/app/modules/artifacts/submission_manifest.py index 527e38423..2cc31d0a3 100644 --- a/backend/app/modules/artifacts/submission_manifest.py +++ b/backend/app/modules/artifacts/submission_manifest.py @@ -5,7 +5,7 @@ from dataclasses import dataclass from enum import StrEnum from typing import Any -from uuid import UUID +from uuid import NAMESPACE_URL, UUID, uuid5 from app.core.hashing import canonical_json_hash from app.modules.artifacts.api.submission_admission import SubmissionBundleFile @@ -22,6 +22,15 @@ SUBMISSION_MANIFEST_SCHEMA_VERSION = "workstream.submission_bundle_manifest.v1" +def semantic_manifest_identity(semantic_manifest_sha256: str) -> UUID: + """Derive one provider-neutral identity from the canonical manifest digest.""" + ArtifactCommitment.validate_sha256(semantic_manifest_sha256) + return uuid5( + NAMESPACE_URL, + f"workstream:submission-semantic-manifest:v1:{semantic_manifest_sha256}", + ) + + class SubmissionChangeFailureCode(StrEnum): """Stable side-effect-free semantic change-gate failures.""" diff --git a/backend/app/modules/artifacts/submission_materialization.py b/backend/app/modules/artifacts/submission_materialization.py index 1a61d99d2..e4448fb77 100644 --- a/backend/app/modules/artifacts/submission_materialization.py +++ b/backend/app/modules/artifacts/submission_materialization.py @@ -3,19 +3,17 @@ from __future__ import annotations from contextlib import AbstractContextManager, contextmanager -from dataclasses import asdict, dataclass, field, replace +from dataclasses import asdict, dataclass, field from pathlib import Path from typing import Protocol, final from uuid import UUID -from sqlalchemy import text from sqlalchemy.ext.asyncio import AsyncSession from app.core.hashing import canonical_json_hash from app.interfaces.external_checker_execution import ( ExternalCheckerMaterialGrant, ) -from app.modules.artifacts.api import SubmissionBundlePreparationRequest from app.modules.artifacts.schemas import ArtifactAuthorityDeniedError from app.modules.artifacts.preparation import ( ArtifactPreparationService, @@ -23,18 +21,6 @@ ExternalMaterialGrantRequest, ) from app.modules.artifacts.sources import PreparedArtifact -from app.modules.artifacts.pre_submit_evidence import ( - PreSubmitEvidenceInput, - PreSubmitEvidenceContext, - PreSubmitEvidenceConflict, - PreSubmitExecutionCustody, - PreSubmitExecutionResult, - PreSubmitEvidencePersistenceRequest, - PreSubmitEvidencePersistenceResult, - PreSubmitEvidenceService, -) -from app.modules.artifacts.pre_submit_attempts import PreSubmitAttemptClaim, PreSubmitAttemptStore -from app.modules.artifacts.models import PreSubmitExecutionAttempt from app.modules.artifacts.submission_archive import ( SubmissionArchiveInspectionResult, ) @@ -43,14 +29,8 @@ SubmissionManifest, build_submission_manifest, ) -from app.modules.artifacts.submission_authorization import ( - SubmissionBundlePreparationAuthorization, -) -from app.modules.checkers.api import ( +from app.modules.checkers.api.pre_submit_material import ( ALLOWED_PRE_SUBMIT_STORAGE_SCHEMES, - EffectivePreSubmissionExecutionPlan, - PreSubmissionExecutionFacts, - PreSubmissionInfrastructureUnavailableError, SubmissionPacketView, ) from app.modules.checkers.api.default_checker import ( @@ -69,10 +49,10 @@ SelectedPreSubmitExecutionFacts, SelectedPreSubmitLeaseFacts, SelectedPreSubmitReservationFacts, + SelectedPreSubmitInfrastructureUnavailable, ) -from app.modules.projects.api import ProjectLockedPolicyContextPort from app.modules.projects.api import ProjectLockedPolicyContextFacts -from app.modules.tasks.api import TaskSubmissionContextFacts, TaskSubmissionContextPort +from app.modules.tasks.api import TaskSubmissionContextFacts @dataclass(frozen=True, slots=True) @@ -87,21 +67,19 @@ class PreparedBundleMaterializationRequest: predecessor_submission_version: int | None checker_remediation_manifest_id: UUID | None = field(default=None, kw_only=True) prepared_artifact: PreparedArtifact - effective_plan: EffectivePreSubmissionExecutionPlan | None inspection: SubmissionArchiveInspectionResult manifest: SubmissionManifest change_gate: SubmissionChangeGateResult packet: SubmissionPacketView - external_policy: LockedExternalPreSubmitPolicy | None = None - default_checker_input: WorkstreamDefaultCheckerInput | None = None - selected_reservation: SelectedPreSubmitReservationFacts | None = None + external_policy: LockedExternalPreSubmitPolicy + default_checker_input: WorkstreamDefaultCheckerInput + selected_reservation: SelectedPreSubmitReservationFacts @dataclass(frozen=True, slots=True) class PreSubmitCheckerExecutionRequest: """Exact process-local input supplied to the composition CHECKER adapter.""" - plan: EffectivePreSubmissionExecutionPlan | None project_id: UUID task_id: UUID assignment_id: UUID @@ -112,8 +90,8 @@ class PreSubmitCheckerExecutionRequest: packet: SubmissionPacketView prepared_generation_id: UUID storage_scheme: str - external_policy: LockedExternalPreSubmitPolicy | None = None - default_checker_input: WorkstreamDefaultCheckerInput | None = None + external_policy: LockedExternalPreSubmitPolicy + default_checker_input: WorkstreamDefaultCheckerInput attempt_id: UUID | None = None attempt_request_digest: str | None = None external_grants: "PreSubmitExternalGrantPort | None" = None @@ -146,7 +124,7 @@ def __init__( preparation: ArtifactPreparationService, prepared: PreparedArtifact, request: PreparedBundleMaterializationRequest, - claim: PreSubmitAttemptClaim, + claim: _SelectedGrantClaim, ) -> None: self._preparation = preparation self._prepared = prepared @@ -163,13 +141,7 @@ def issue( checked = ExternalCheckerExecutionRequest.model_validate(request) identity = checked.identity source = self._request - project_id = ( - source.selected_reservation.project_id - if source.selected_reservation is not None - else source.effective_plan.lineage.project_id - if source.effective_plan is not None - else None - ) + project_id = source.selected_reservation.project_id if ( not isinstance(identity, PreSubmitExternalCheckerIdentity) or identity.project_id != project_id @@ -181,7 +153,7 @@ def issue( or len(checked.materials) != 1 or not isinstance(checked.materials[0], PreSubmitExternalCheckerMaterial) ): - raise PreSubmitEvidenceConflict("pre_submit_external_request_invalid") + raise SelectedPreSubmitInfrastructureUnavailable("material_unavailable") material = checked.materials[0] commitment = source.prepared_artifact.commitment if ( @@ -193,7 +165,7 @@ def issue( or material.semantic_manifest_sha256 != source.manifest.sha256 or material.media_type != commitment.media_type ): - raise PreSubmitEvidenceConflict("pre_submit_external_material_invalid") + raise SelectedPreSubmitInfrastructureUnavailable("material_unavailable") directories = tuple( item.normalized_path for item in source.manifest.entries @@ -229,32 +201,17 @@ def issue( ) -class PreSubmissionEvaluationPort(Protocol): - """Finish ART's committed selection through the composed checker phase service.""" - - async def evaluate_pre_submission( - self, - request: PreparedBundleMaterializationRequest, - reservation: object, - *, - preparation_request: SubmissionBundlePreparationRequest, - ) -> PreSubmitEvidencePersistenceResult: ... - - class PreSubmitCheckerProcessor(Protocol): """Async processor built by the composition-root CHECKER adapter.""" def abort(self) -> None: ... - async def process(self, reader: object, workspace: object) -> PreSubmissionExecutionFacts: ... + async def process(self, reader: object, workspace: object) -> SelectedPreSubmitExecutionFacts: ... class PreSubmitCheckerExecutionFactory(Protocol): """Build one process-local CHECKER processor without private imports in ART.""" - @property - def catalogue_manifest_sha256(self) -> str: ... - def build(self, request: PreSubmitCheckerExecutionRequest) -> PreSubmitCheckerProcessor: ... @@ -383,80 +340,6 @@ def __init__( raise ValueError("pre-submit materializer storage scheme is invalid") self._storage_scheme = storage_scheme - async def authorize_prepared_bundle( - self, - request: PreparedBundleMaterializationRequest, - *, - claim: PreSubmitAttemptClaim, - ) -> None: - """Consume fixed-service authority and the durable claim in its short root.""" - if type(claim) is not PreSubmitAttemptClaim: - raise PreSubmitEvidenceConflict("pre_submit_attempt_claim_invalid") - facts = self._authority_facts(request) - await self._authorization.consume( - prepared_authorization=request.prepared_authorization, - facts=facts, - ) - await claim.consume(self._session, request) - - async def materialize_prepared_bundle( - self, - request: PreparedBundleMaterializationRequest, - *, - claim: PreSubmitAttemptClaim, - ) -> PreSubmitExecutionResult: - """Execute only after the authority root commits; no external work holds DB locks.""" - if type(claim) is not PreSubmitAttemptClaim: - raise PreSubmitEvidenceConflict("pre_submit_attempt_claim_invalid") - if request.effective_plan is None: - raise PreSubmitEvidenceConflict("pre_submit_effective_plan_invalid") - claim.require_execution(self._session, request) - processor = self._checker_execution.build( - PreSubmitCheckerExecutionRequest( - plan=request.effective_plan, - project_id=request.effective_plan.lineage.project_id, - task_id=request.task_id, - assignment_id=request.assignment_id, - commitment=request.prepared_artifact.commitment, - inspection=request.inspection, - manifest=request.manifest, - change_gate=request.change_gate, - packet=request.packet, - prepared_generation_id=request.prepared_artifact.generation_id, - storage_scheme=self._storage_scheme, - external_policy=request.external_policy, - default_checker_input=request.default_checker_input, - attempt_id=claim.attempt_id, - attempt_request_digest=claim.request_digest, - external_grants=_PreSubmitExternalGrantIssuer( - preparation=self._preparation, - prepared=request.prepared_artifact, - request=request, - claim=claim, - ), - ), - ) - # Intentional friend call: this is the sole authority-gated caller, and - # the preparation byte-access surface must remain private. - checker_facts = await self._preparation._process_prepared_submission( - request.prepared_artifact, - processor, - reserved_bytes=request.manifest.total_expanded_bytes, - # ART's external grant nests the verified tree below one owned mount. - maximum_entries=request.manifest.entry_count + 1, - ) - execution = PreSubmitExecutionResult( - custody=PreSubmitExecutionCustody( - prepared_generation_id=request.prepared_artifact.generation_id, - archive_sha256=request.prepared_artifact.commitment.sha256, - archive_byte_count=request.prepared_artifact.commitment.byte_count, - semantic_manifest_sha256=request.manifest.sha256, - storage_scheme=self._storage_scheme, - ), - checker_facts=checker_facts, - ) - claim.finish(execution) - return execution async def materialize_selected_pre_submit( self, @@ -466,7 +349,7 @@ async def materialize_selected_pre_submit( lease: SelectedPreSubmitLeaseFacts, execution_authority: SelectedPreSubmitExecutionAuthority, ) -> SelectedPreSubmitExecutionFacts: - """Execute the committed selected lease without the legacy invocation store.""" + """Execute the committed external policy lease against genuine prepared bytes.""" if self._session.in_transaction(): raise RuntimeError("selected pre-submit execution requires no transaction") checked = execution_authority.consume(run_id=run_id, lease=lease) @@ -487,10 +370,9 @@ async def materialize_selected_pre_submit( or commitment.byte_count != reservation.archive_byte_count or request.manifest.sha256 != reservation.semantic_manifest_sha256 ): - raise PreSubmitEvidenceConflict("selected_pre_submit_execution_invalid") + raise SelectedPreSubmitInfrastructureUnavailable("material_unavailable") processor = self._checker_execution.build( PreSubmitCheckerExecutionRequest( - plan=request.effective_plan, project_id=reservation.project_id, task_id=request.task_id, assignment_id=request.assignment_id, @@ -523,7 +405,7 @@ async def materialize_selected_pre_submit( maximum_entries=request.manifest.entry_count + 1, ) if type(result) is not SelectedPreSubmitExecutionFacts: - raise PreSubmitEvidenceConflict("selected_pre_submit_execution_invalid") + raise SelectedPreSubmitInfrastructureUnavailable("material_unavailable") return result async def authorize_inspected(self, request: PreparedBundleMaterializationRequest) -> None: @@ -533,46 +415,6 @@ async def authorize_inspected(self, request: PreparedBundleMaterializationReques facts=self._authority_facts(request), ) - async def authorize_original_replay( - self, - request: PreparedBundleMaterializationRequest, - *, - generation_id: UUID, - key: UUID, - ) -> None: - """Check original stored service facts; this grants no retry-byte capability.""" - facts = replace(self._authority_facts(request), prepared_generation_id=generation_id) - handle = await self._authorization.prepare(facts=facts.preparation, idempotency_key=key) - await self._authorization.consume(prepared_authorization=handle, facts=facts) - - async def prepare_authorization( - self, - *, - task_id: UUID, - assignment_id: UUID, - submission_artifact_policy_id: UUID, - checker_policy_id: UUID, - prepared_artifact: PreparedArtifact, - effective_plan: EffectivePreSubmissionExecutionPlan | None, - idempotency_key: UUID, - external_policy: LockedExternalPreSubmitPolicy | None = None, - selected_reservation: SelectedPreSubmitReservationFacts | None = None, - ) -> object: - """Deny unavailable service authority before inspecting the ZIP.""" - facts = self._preparation_facts( - task_id=task_id, - assignment_id=assignment_id, - submission_artifact_policy_id=submission_artifact_policy_id, - checker_policy_id=checker_policy_id, - prepared_artifact=prepared_artifact, - effective_plan=effective_plan, - external_policy=external_policy, - selected_reservation=selected_reservation, - ) - return await self._authorization.prepare( - facts=facts, - idempotency_key=idempotency_key, - ) async def prepare_selected_authorization( self, @@ -604,9 +446,7 @@ async def prepare_selected_authorization( or external_policy.workstream_default.behavior_sha256 != WORKSTREAM_DEFAULT_BEHAVIOR_SHA256 ): - raise PreSubmissionInfrastructureUnavailableError( - "selected_pre_submission_materialization_context_invalid" - ) + raise SelectedPreSubmitInfrastructureUnavailable("material_unavailable") facts = PreSubmitMaterializationPreparationFacts( task_id=task.task_id, assignment_id=task.assignment_id, @@ -636,14 +476,12 @@ def _authority_facts( request: PreparedBundleMaterializationRequest, ) -> PreSubmitMaterializationAuthorityFacts: """Build final authority facts from the canonical inspected manifest.""" - plan = request.effective_plan preparation = self._preparation_facts( task_id=request.task_id, assignment_id=request.assignment_id, submission_artifact_policy_id=request.submission_artifact_policy_id, checker_policy_id=request.checker_policy_id, prepared_artifact=request.prepared_artifact, - effective_plan=plan, external_policy=request.external_policy, selected_reservation=request.selected_reservation, ) @@ -654,9 +492,7 @@ def _authority_facts( or request.prepared_artifact.commitment.byte_count != request.change_gate.archive_byte_count ): - raise PreSubmissionInfrastructureUnavailableError( - "pre_submission_materialization_context_invalid" - ) + raise SelectedPreSubmitInfrastructureUnavailable("material_unavailable") return PreSubmitMaterializationAuthorityFacts( **asdict(preparation), semantic_manifest_sha256=request.manifest.sha256, @@ -670,249 +506,41 @@ def _preparation_facts( submission_artifact_policy_id: UUID, checker_policy_id: UUID, prepared_artifact: PreparedArtifact, - effective_plan: EffectivePreSubmissionExecutionPlan | None, - external_policy: LockedExternalPreSubmitPolicy | None = None, - selected_reservation: SelectedPreSubmitReservationFacts | None = None, + external_policy: LockedExternalPreSubmitPolicy, + selected_reservation: SelectedPreSubmitReservationFacts, ) -> PreSubmitMaterializationPreparationFacts: """Build pre-inspection facts from locked lineage and byte commitment.""" - plan = effective_plan - if selected_reservation is not None: - lineage = selected_reservation.admission_lineage - commitment = prepared_artifact.commitment - if ( - plan is not None - or lineage is None - or external_policy is None - or task_id != selected_reservation.task_id - or assignment_id != selected_reservation.assignment_id - or prepared_artifact.generation_id != selected_reservation.prepared_generation_id - or submission_artifact_policy_id != lineage.effective_policy_id - or checker_policy_id != lineage.pre_submit_policy_id - or external_policy.policy_sha256 != selected_reservation.policy_sha256 - or commitment.sha256 != selected_reservation.archive_sha256 - or commitment.byte_count != selected_reservation.archive_byte_count - ): - raise PreSubmissionInfrastructureUnavailableError( - "selected_pre_submission_materialization_context_invalid" - ) - return PreSubmitMaterializationPreparationFacts( - task_id=task_id, - assignment_id=assignment_id, - project_id=selected_reservation.project_id, - guide_id=lineage.guide_id, - guide_version=lineage.guide_version, - source_snapshot_id=lineage.source_snapshot_id, - source_snapshot_hash=lineage.source_snapshot_sha256, - submission_artifact_policy_id=submission_artifact_policy_id, - submission_artifact_policy_hash=lineage.effective_policy_sha256, - checker_policy_id=checker_policy_id, - checker_policy_hash=lineage.pre_submit_policy_sha256, - prepared_generation_id=prepared_artifact.generation_id, - plan_sha256=selected_reservation.policy_sha256, - catalogue_manifest_sha256=(selected_reservation.default_behavior_sha256), - archive_sha256=commitment.sha256, - archive_byte_count=commitment.byte_count, - storage_scheme=self._storage_scheme, - ) - if plan is None: - raise PreSubmissionInfrastructureUnavailableError( - "pre_submission_materialization_context_invalid" - ) - if plan.plan_sha256 != canonical_json_hash(plan.as_dict()): - raise PreSubmissionInfrastructureUnavailableError( - "pre_submission_plan_identity_invalid" - ) + lineage = selected_reservation.admission_lineage + commitment = prepared_artifact.commitment if ( - submission_artifact_policy_id != plan.lineage.effective_policy_id - or checker_policy_id != plan.lineage.pre_submit_policy_id - or ( - external_policy is None - and plan.catalogue_manifest_sha256 - != self._checker_execution.catalogue_manifest_sha256 - ) - ): - raise PreSubmissionInfrastructureUnavailableError( - "pre_submission_materialization_context_invalid" - ) - if external_policy is not None and ( - external_policy.policy_sha256 - != canonical_json_hash( - external_policy.model_dump(mode="json", exclude={"policy_sha256"}) - ) - or external_policy.workstream_default.behavior_sha256 - != WORKSTREAM_DEFAULT_BEHAVIOR_SHA256 + lineage is None + or external_policy is None + or task_id != selected_reservation.task_id + or assignment_id != selected_reservation.assignment_id + or prepared_artifact.generation_id != selected_reservation.prepared_generation_id + or submission_artifact_policy_id != lineage.effective_policy_id + or checker_policy_id != lineage.pre_submit_policy_id + or external_policy.policy_sha256 != selected_reservation.policy_sha256 + or commitment.sha256 != selected_reservation.archive_sha256 + or commitment.byte_count != selected_reservation.archive_byte_count ): - raise PreSubmissionInfrastructureUnavailableError("external_pre_submit_policy_invalid") - commitment = prepared_artifact.commitment + raise SelectedPreSubmitInfrastructureUnavailable("material_unavailable") return PreSubmitMaterializationPreparationFacts( task_id=task_id, assignment_id=assignment_id, - project_id=plan.lineage.project_id, - guide_id=plan.lineage.guide_id, - guide_version=plan.lineage.guide_version, - source_snapshot_id=plan.lineage.source_snapshot_id, - source_snapshot_hash=plan.lineage.source_snapshot_hash, + project_id=selected_reservation.project_id, + guide_id=lineage.guide_id, + guide_version=lineage.guide_version, + source_snapshot_id=lineage.source_snapshot_id, + source_snapshot_hash=lineage.source_snapshot_sha256, submission_artifact_policy_id=submission_artifact_policy_id, - submission_artifact_policy_hash=plan.lineage.effective_policy_hash, + submission_artifact_policy_hash=lineage.effective_policy_sha256, checker_policy_id=checker_policy_id, - checker_policy_hash=plan.lineage.pre_submit_policy_bundle_hash, + checker_policy_hash=lineage.pre_submit_policy_sha256, prepared_generation_id=prepared_artifact.generation_id, - plan_sha256=plan.plan_sha256, - catalogue_manifest_sha256=plan.catalogue_manifest_sha256, + plan_sha256=selected_reservation.policy_sha256, + catalogue_manifest_sha256=(selected_reservation.default_behavior_sha256), archive_sha256=commitment.sha256, archive_byte_count=commitment.byte_count, storage_scheme=self._storage_scheme, ) - - -class PreparedBundlePreSubmitEvidenceService: - """Execute in scratch, then persist exact evidence in a fresh transaction.""" - - def __init__( - self, - *, - session: AsyncSession, - materialization: PreparedBundleMaterializationService, - preparation_authorization: SubmissionBundlePreparationAuthorization, - task_contexts: TaskSubmissionContextPort, - project_contexts: ProjectLockedPolicyContextPort, - ) -> None: - """Bind execution to the transaction used for durable evidence.""" - self._session = session - self._materialization = materialization - self._preparation_authorization = preparation_authorization - self._task_contexts = task_contexts - self._project_contexts = project_contexts - self._attempts = PreSubmitAttemptStore(session) - - def _evidence_service(self) -> PreSubmitEvidenceService: - """Use the sole evidence owner for both lineage reads and completion.""" - return PreSubmitEvidenceService( - self._session, - task_contexts=self._task_contexts, - project_contexts=self._project_contexts, - ) - - @staticmethod - def _input( - request: PreparedBundleMaterializationRequest, - preparation_request: SubmissionBundlePreparationRequest, - ) -> PreSubmitEvidenceInput: - if ( - request.task_id != preparation_request.task_id - or request.assignment_id != preparation_request.assignment_id - or request.packet.summary != preparation_request.summary - or request.packet.contributor_attestation != preparation_request.contributor_attestation - ): - raise PreSubmitEvidenceConflict("pre_submit_attempt_request_conflict") - commitment = request.prepared_artifact.commitment - return PreSubmitEvidenceInput( - actor_profile_id=preparation_request.actor.actor_profile_id, - identity_link_id=preparation_request.actor.identity_link_id, - task_id=request.task_id, - assignment_id=request.assignment_id, - predecessor_submission_id=preparation_request.predecessor_submission_id, - expected_predecessor_submission_version=request.predecessor_submission_version, - expected_checker_remediation_manifest_id=( - request.checker_remediation_manifest_id - ), - prepared_generation_id=request.prepared_artifact.generation_id, - archive_sha256=commitment.sha256, - archive_byte_count=commitment.byte_count, - semantic_manifest_sha256=request.manifest.sha256, - plan=request.effective_plan, - ) - - async def _lock_authorized_context( - self, - request: PreparedBundleMaterializationRequest, - preparation_request: SubmissionBundlePreparationRequest, - ) -> PreSubmitEvidenceContext: - """Match TASK, AUTH role issuance and revocation without reversing their locks.""" - evidence = self._evidence_service() - values = self._input(request, preparation_request) - task_context = await evidence.lock_task_context(values) - await self._preparation_authorization.lock_actor(request=preparation_request) - context = await evidence.lock_project_context( - values, - task_context=task_context, - storage_scheme=self._materialization._storage_scheme, - ) - await self._preparation_authorization.revalidate(request=preparation_request) - return context - - async def reserve( - self, - request: PreparedBundleMaterializationRequest, - *, - preparation_request: SubmissionBundlePreparationRequest, - ) -> object: - """Consume inspected authority and reserve; the caller must commit before execution.""" - context = await self._lock_authorized_context(request, preparation_request) - await self._materialization.authorize_inspected(request) - selected = await self._attempts.reserve( - context=context, - plan=request.effective_plan, - packet=request.packet, - idempotency_key=preparation_request.idempotency_key, - request=request, - ) - if isinstance(selected, PreSubmitExecutionAttempt): - await self._materialization.authorize_original_replay( - request, - generation_id=UUID(selected.prepared_generation_id), - key=preparation_request.idempotency_key, - ) - return await self._attempts.read_completed( - row=selected, - context=context, - plan=request.effective_plan, - ) - return selected - - async def execute_reserved( - self, - request: PreparedBundleMaterializationRequest, - reservation: object, - *, - preparation_request: SubmissionBundlePreparationRequest, - ) -> PreSubmitEvidencePersistenceResult: - """Run a committed winning claim, then atomically persist its canonical evidence.""" - if self._session.in_transaction(): - raise RuntimeError("pre-submit execution requires a transaction-free session") - claim = await self._attempts.committed_claim(reservation) - authorized_request = None - async with self._session.begin(): - await self._lock_authorized_context(request, preparation_request) - handle = await self._materialization.prepare_authorization( - task_id=request.task_id, - assignment_id=request.assignment_id, - submission_artifact_policy_id=request.submission_artifact_policy_id, - checker_policy_id=request.checker_policy_id, - prepared_artifact=request.prepared_artifact, - effective_plan=request.effective_plan, - idempotency_key=preparation_request.idempotency_key, - external_policy=request.external_policy, - ) - authorized_request = replace(request, prepared_authorization=handle) - await self._materialization.authorize_prepared_bundle( - authorized_request, - claim=claim, - ) - assert authorized_request is not None - execution = await self._materialization.materialize_prepared_bundle( - replace(authorized_request, prepared_authorization=None), - claim=claim, - ) - async with self._session.begin(): - await self._session.execute(text("set transaction isolation level read committed")) - values = self._input(request, preparation_request) - await self._lock_authorized_context(request, preparation_request) - return await self._evidence_service().persist( - PreSubmitEvidencePersistenceRequest( - **{name: getattr(values, name) for name in values.__dataclass_fields__}, - execution=execution, - attempt=claim, - manifest=request.manifest, - ) - ) diff --git a/backend/app/modules/tasks/repository.py b/backend/app/modules/tasks/repository.py index c7e664b14..e64deda54 100644 --- a/backend/app/modules/tasks/repository.py +++ b/backend/app/modules/tasks/repository.py @@ -7,7 +7,6 @@ from app.modules.tasks.api.transition_audit import TaskPolicyLineage from app.modules.checkers.api.external_policy import validate_stored_external_post_policy -from app.modules.checkers.api.historical_post_submit import CompiledPostSubmitPolicy from uuid import UUID from sqlalchemy import Row, Select, and_, or_, select, tuple_ @@ -750,22 +749,12 @@ async def select_submission_context( for value in (getattr(task, key),) })) post_body = task.locked_post_submit_checker_policy_body - if post_body.get("schema_version") == "external_post_submit_policy.v1": - selected_post = validate_stored_external_post_policy(post_body) - if ( - selected_post.policy_sha256 - != locked_policy.locked_post_submit_checker_policy_hash - ): - raise ValueError("task post-submit policy body differs from locked identity") - else: - historical_post = CompiledPostSubmitPolicy.model_validate(post_body) - if ( - historical_post.policy_hash - != locked_policy.locked_post_submit_checker_policy_hash - or historical_post.project_id != UUID(task.project_id) - or historical_post.guide_version != locked_policy.locked_guide_version - ): - raise ValueError("task post-submit policy body differs from locked identity") + selected_post = validate_stored_external_post_policy(post_body) + if ( + selected_post.policy_sha256 + != locked_policy.locked_post_submit_checker_policy_hash + ): + raise ValueError("task post-submit policy body differs from locked identity") locked_project_context = TaskLockedProjectContextReferences( project_id=UUID(task.project_id), locked_contribution_policy_version_id=task.locked_contribution_policy_version_id, diff --git a/backend/app/modules/tasks/service.py b/backend/app/modules/tasks/service.py index 7d9222954..d7b3e1c91 100644 --- a/backend/app/modules/tasks/service.py +++ b/backend/app/modules/tasks/service.py @@ -16,7 +16,6 @@ LockedExternalPostSubmitPolicy, validate_stored_external_post_policy, ) -from app.modules.checkers.api.historical_post_submit import CompiledPostSubmitPolicy from app.modules.projects.api.locked_policy import ( ProjectLockedPolicyContextFacts, ProjectLockedPolicyContextPort, @@ -260,32 +259,22 @@ async def _load_locked_task_context(self, task: WorkstreamTask) -> LockedTaskCon def _parse_post_submit_policy_summary( facts: ProjectLockedPolicyContextFacts, ) -> PostSubmitPolicyBodySummary: - """Decode selected policy bodies while retaining historical read custody.""" + """Decode the closed external POST policy bound to approval custody.""" body = json.loads(facts.compiled_post_submit_policy.value) - if body.get("schema_version") == "external_post_submit_policy.v1": - selected = validate_stored_external_post_policy(body) - policies = LockedExternalCheckerPolicies.model_validate_json( - facts.external_checker_policies.value - ) - if selected != policies.post_submit: - raise ValueError("locked selected POST policy differs from approval") - checkers = tuple(item.registry.capability_id for item in selected.entries) - return PostSubmitPolicyBodySummary( - schema_version=selected.schema_version, - default_checkers=(), - required_checkers=checkers, - warning_checkers=(), - execution_checkers=checkers, - blocking_severities=("critical", "high"), - ) - historical = CompiledPostSubmitPolicy.model_validate(body) + selected = validate_stored_external_post_policy(body) + policies = LockedExternalCheckerPolicies.model_validate_json( + facts.external_checker_policies.value + ) + if selected != policies.post_submit: + raise ValueError("locked selected POST policy differs from approval") + checkers = tuple(item.registry.capability_id for item in selected.entries) return PostSubmitPolicyBodySummary( - schema_version=historical.schema_version, - default_checkers=tuple(historical.default_checkers), - required_checkers=tuple(historical.required_checkers), - warning_checkers=tuple(historical.warning_checkers), - execution_checkers=tuple(historical.execution_checkers), - blocking_severities=tuple(historical.blocking_severities), + schema_version=selected.schema_version, + default_checkers=(), + required_checkers=checkers, + warning_checkers=(), + execution_checkers=checkers, + blocking_severities=("critical", "high"), ) def _missing_locked_context_fields(self, task: WorkstreamTask) -> list[str]: diff --git a/backend/app/modules/tasks/submission_composition.py b/backend/app/modules/tasks/submission_composition.py index 79e78587a..6c9cd30e5 100644 --- a/backend/app/modules/tasks/submission_composition.py +++ b/backend/app/modules/tasks/submission_composition.py @@ -21,7 +21,7 @@ TaskSubmissionContextRequest, TaskSubmissionContextPort, ) -from app.modules.checkers.api import SubmissionPacketView +from app.modules.checkers.api.pre_submit_material import SubmissionPacketView from app.modules.tasks.models import EvidenceItem, Submission from app.modules.tasks.submission_participants import ( SubmissionArtifactAdmissionPort, SubmissionArtifactAdmissionRequest, @@ -34,7 +34,6 @@ from app.modules.tasks.lifecycle import ensure_allowed_transition from app.modules.checkers.api.execution import EvaluationCoordinationPort from app.modules.checkers.api.selected_post_submit import ( - SelectedPostSubmissionEvaluationRequest, make_selected_post_submit_request, ) from app.modules.outbox.api import OutboxAppendPort @@ -305,24 +304,10 @@ async def _replay(self, request, receipt, context) -> SubmissionCreationResult: or evaluation.content_id != consumed.content_id or evaluation.content_sha256 != consumed.archive_sha256 or evaluation.byte_count != consumed.byte_count - or ( - isinstance(evaluation, SelectedPostSubmissionEvaluationRequest) - and ( - consumed.selected_evaluation_content is None - or evaluation.project_id != consumed.selected_evaluation_content.project_id - or evaluation.expected_context - != consumed.selected_evaluation_content.expected_context - or evaluation.policy != consumed.selected_evaluation_content.policy - ) - ) - or ( - not isinstance(evaluation, SelectedPostSubmissionEvaluationRequest) - and ( - evaluation.structural_input.summary != request.summary - or evaluation.structural_input.worker_attestation - != request.contributor_attestation - ) - ) + or consumed.selected_evaluation_content is None + or evaluation.project_id != consumed.selected_evaluation_content.project_id + or evaluation.expected_context != consumed.selected_evaluation_content.expected_context + or evaluation.policy != consumed.selected_evaluation_content.policy ): raise SubmissionCreationUnavailable("submission creation is unavailable") await self._events.require_existing(receipt.evaluation_event_id, evaluation_request_event(receipt)) diff --git a/backend/app/modules/tasks/submission_participants.py b/backend/app/modules/tasks/submission_participants.py index 7d881eb43..9909faab9 100644 --- a/backend/app/modules/tasks/submission_participants.py +++ b/backend/app/modules/tasks/submission_participants.py @@ -1,11 +1,10 @@ """Private TASK composition ports; public TASK facts remain dependency-independent.""" -from dataclasses import dataclass +from dataclasses import dataclass, field as dataclass_field from typing import Protocol from uuid import UUID -from app.modules.checkers.api import SubmissionPacketView -from app.modules.checkers.api.post_submit import PostSubmissionEvaluationContent +from app.modules.checkers.api.pre_submit_material import SubmissionPacketView from app.modules.checkers.api.external_policy import LockedExternalPostSubmitPolicy from app.modules.checkers.api.selected_post_submit import SelectedPostSubmissionContent from app.modules.projects.api import ProjectLockedPolicyContextFacts @@ -29,31 +28,21 @@ class SubmissionArtifactBindingFacts: binding_decision_id: UUID archive_sha256: str byte_count: int - selected_evaluation_content: SelectedPostSubmissionContent | None = None + selected_evaluation_content: SelectedPostSubmissionContent @dataclass(frozen=True, slots=True) class SubmissionArtifactAdmissionResult(SubmissionArtifactBindingFacts): - evaluation_content: PostSubmissionEvaluationContent | None = None - selected_post_submit_policy: LockedExternalPostSubmitPolicy | None = None - selected_evaluation_content: SelectedPostSubmissionContent | None = None + selected_post_submit_policy: LockedExternalPostSubmitPolicy = dataclass_field(kw_only=True) + selected_evaluation_content: SelectedPostSubmissionContent def __post_init__(self) -> None: - """Keep retained legacy and selected content mutually exclusive.""" - if (self.selected_post_submit_policy is None) != ( - self.selected_evaluation_content is None - ): - raise ValueError("selected POST admission content is incomplete") - if (self.evaluation_content is None) == ( - self.selected_evaluation_content is None - ): - raise ValueError("admission must select exactly one POST contract") + """Bind the sole POST contract to the policy admitted by ART.""" if ( - self.selected_evaluation_content is not None - and self.selected_evaluation_content.policy - != self.selected_post_submit_policy + type(self.selected_evaluation_content) is not SelectedPostSubmissionContent + or self.selected_evaluation_content.policy != self.selected_post_submit_policy ): - raise ValueError("selected POST admission policy differs") + raise ValueError("external POST admission policy differs") @dataclass(frozen=True, slots=True) From e818b5014ab42fa34100fccada4c1edf357bdec5 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 13:05:41 +0100 Subject: [PATCH 189/283] [PILOT-04] Document one external checker contract and remove obsolete runtime guidance --- .../pilot04-workstream-default-checker.md | 19 ++++--- docs/architecture_checker_framework.md | 53 +++++++------------ 2 files changed, 28 insertions(+), 44 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 2f72be98c..beedbd939 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -35,7 +35,7 @@ The selected POST processor consumes only actual Submission and ART material through the phase-typed callback grant, runs every locked POST image in order, and returns canonical evidence and observed isolation without any acceptance or routing authority. The existing CHECKERS scheduler now recognizes that -selected envelope alongside retained legacy evidence, derives its lease and +sole external envelope, derives its lease and execution deadlines from the exact locked images, recomputes the ART-owned manifest before execution, and retains the complete selected result for restart/replay. The existing production outbox registry now owns the evaluation @@ -43,11 +43,11 @@ request handler alongside assignment invalidation, leases worker-owned ART material only during execution, and creates the configured Rust adapter only for a selected request. New TASK submission composition now requires selected POST custody and refuses an unresolved legacy admission instead of executing -it; retained legacy envelopes remain read-only decoding inputs. Admission, +it; no old request/result runtime or decoder remains. Admission, routing completion and remediation fixtures now exercise the selected PRE/POST owners. Both obsolete executable catalogues and their isolated callers and -tests have been removed; retained immutable evidence has only its bounded -historical decoder. F-020 recovery now proves that registration alone cannot +tests are removed together with obsolete contracts; stored immutable evidence +remains intact without an old runtime reader. F-020 recovery now proves that registration alone cannot activate the retained warning-bearing generation and that only an exact registered binding in a corrected, linked approval can activate. The combined native journey now exercises real PostgreSQL 16, MinIO, the Rust service and the @@ -272,12 +272,11 @@ acknowledgment guards remain. The old pre/post catalogues are removed in the same final change after every production caller and required proof uses the selected runtime. Retained approvals, locked guides, evidence and completed runs are never -rewritten or deleted. Historical decoders remain narrowly scoped to immutable -old evidence. An unresolved old-catalogue queue item or locked guide fails -closed and requires an authorized recompile/reapproval transition; it is never -silently run through a new image. This retained-data reader is not an executable -compatibility runtime. New selected admission columns are nullable only for -those retained legacy rows; native checks require the complete guide, policy, +rewritten or deleted. No historical catalogue decoder or executable compatibility +path remains. Unsupported queue envelopes and locked policy bodies fail closed; +they cannot select a checker implementation. Existing nullable storage columns +preserve original facts without adding an old writer or reader. Native checks +require the complete guide, policy, packet, manifest and selected-run custody whenever selected lineage is present, so migration does not synthesize or rewrite historical facts. diff --git a/docs/architecture_checker_framework.md b/docs/architecture_checker_framework.md index 54fae520f..dd627d122 100644 --- a/docs/architecture_checker_framework.md +++ b/docs/architecture_checker_framework.md @@ -99,40 +99,25 @@ bindings, registry entries and checker results. Approved policies bind the exact digest, configuration and schema identities; registration alone changes no locked task or approved guide generation. -## Retained post-submit contract - -This section describes immutable pre-cutover policy/result evidence, not new -compilation or execution. New POST requests carry `LockedExternalPostSubmitPolicy` -and `SelectedPostSubmissionEvaluationRequest`; their results retain every -required image and exact observed isolation facts. - -The former CHECKERS implementation owned one immutable initial-v0.1 catalogue, one implementation per -checker ID, and closed evaluation-request/result contracts. PROJECTS used that -same catalogue to compile the retained canonical policy body. Retained-evidence readers validate that body and its exact hash; persisted required, -warning and blocking summaries must agree with it. Unsupported development -bodies reject without translation or an alternate reader. - -The retained structural identities included eight mandatory defaults and -selectable `check_acceptance_criteria_present`; these are not current executors. Criteria presence -does not prove that work satisfies the criteria. Unsupported substantive -automation remains a capability gap; an explicitly approved `human_review` -disposition remains valid without a checker binding. - -The single policy-context check compares actual Task and Submission locks: -guide version, source snapshot, effective artifact policy, pre-submit bundle, -post-submit policy, review policy and revision policy. It has no economic-policy -prerequisite. Compilation and ContributionPolicy task references are not yet -persisted and are not fabricated as checker inputs. Project ownership remains -checked by the owning services. Structural consistency grants no authorization. - -The canonical `policy_hash` binds ordered entries, configuration and exact -catalogue/implementation identities. Domain project policy versions record -changes to project rules; they do not select obsolete software implementations. -These earlier component proofs supplied hidden execution and phase authority; -PILOT-04 separately installs selected production delivery without a public -execution route. -POL-04B connects unified guide setup; POL-05B and POL-06B expose separate -pre-submit and post-submit policy approvals. +## Post-submit contract + +POST requests carry the task's locked `LockedExternalPostSubmitPolicy` and the +exact immutable Submission/ART identity. One request/result contract drives +reservation, execution, completion and recovery. Every approved digest-pinned +image receives verified read-only material; its normalized findings and observed +isolation become immutable evidence for the existing routing owner. + +Policies bind exact registry entries, image digests, configuration and schema +hashes. TASK and ART validate the locked guide, source, policy, assignment, +predecessor and material context before admission or evaluation. Checker results +supply work evidence and do not grant acceptance authority. Passing required +POST checks routes through the existing human-review or shared final-acceptance +branch selected by the locked ReviewPolicy. + +There is no catalogue request/result decoder, generic rule planner, alternate +phase service or old execution path. Removing those implementations does not +rewrite or delete stored records. Unsupported stored envelopes fail closed; +stored historical facts cannot select a checker implementation. ## Durable execution custody From 448433dea7b39c97047b5c1100cc51010c5c21bb Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 13:05:47 +0100 Subject: [PATCH 190/283] Use one external post policy context --- backend/app/adapters/checkers/__init__.py | 7 +++---- .../checkers/api/selected_post_submit.py | 10 ++++------ .../checkers/execution_coordination.py | 6 +++--- .../post_submit_routing/evaluation_guard.py | 10 +++++----- .../external/test_selected_post_submit.py | 20 ++++++++----------- 5 files changed, 23 insertions(+), 30 deletions(-) diff --git a/backend/app/adapters/checkers/__init__.py b/backend/app/adapters/checkers/__init__.py index 4d6cd10d2..fcadc105f 100644 --- a/backend/app/adapters/checkers/__init__.py +++ b/backend/app/adapters/checkers/__init__.py @@ -338,10 +338,9 @@ def selected_submission_evaluation_content( effective_policy_hash=(locked.locked_effective_project_submission_artifact_policy_hash), pre_policy_id=locked.locked_pre_submit_checker_policy_id, pre_policy_hash=locked.locked_pre_submit_checker_bundle_hash, - retained_catalogue_policy_id=(locked.locked_post_submit_checker_policy_id), - retained_catalogue_policy_version=(locked.locked_post_submit_checker_policy_version), - retained_catalogue_policy_hash=(locked.locked_post_submit_checker_policy_hash), - selected_post_policy_hash=policy.policy_sha256, + post_policy_id=(locked.locked_post_submit_checker_policy_id), + post_policy_version=(locked.locked_post_submit_checker_policy_version), + post_policy_hash=(locked.locked_post_submit_checker_policy_hash), review_policy_id=locked.locked_review_policy_id, review_generation=locked.locked_review_policy_generation, review_hash=locked.locked_review_policy_hash, diff --git a/backend/app/modules/checkers/api/selected_post_submit.py b/backend/app/modules/checkers/api/selected_post_submit.py index 997f45b35..d37549983 100644 --- a/backend/app/modules/checkers/api/selected_post_submit.py +++ b/backend/app/modules/checkers/api/selected_post_submit.py @@ -30,10 +30,9 @@ class SelectedPostSubmitLockedContext(CheckerValue): effective_policy_hash: Sha256 pre_policy_id: ResourceId pre_policy_hash: Sha256 - retained_catalogue_policy_id: ResourceId - retained_catalogue_policy_version: str = Field(min_length=1, max_length=50) - retained_catalogue_policy_hash: Sha256 - selected_post_policy_hash: Sha256 + post_policy_id: ResourceId + post_policy_version: str = Field(min_length=1, max_length=50) + post_policy_hash: Sha256 review_policy_id: ResourceId review_generation: VersionNumber review_hash: Sha256 @@ -53,8 +52,7 @@ class SelectedPostSubmissionContent(CheckerValue): def validate_content(self) -> Self: """Require the exact approved policy digest stamped on the Submission.""" if ( - self.expected_context.selected_post_policy_hash - != self.policy.policy_sha256 + self.expected_context.post_policy_hash != self.policy.policy_sha256 ): raise ValueError("selected POST locked policy mismatch") return self diff --git a/backend/app/modules/checkers/execution_coordination.py b/backend/app/modules/checkers/execution_coordination.py index 70c7a76a7..184075688 100644 --- a/backend/app/modules/checkers/execution_coordination.py +++ b/backend/app/modules/checkers/execution_coordination.py @@ -130,11 +130,11 @@ async def _reserve_after_task_lock( worker_lease_generation=0, supersedes_checker_run_id=prior.id if prior else None, locked_guide_version=context.guide_version, - locked_post_submit_checker_policy_id=str(context.retained_catalogue_policy_id), + locked_post_submit_checker_policy_id=str(context.post_policy_id), locked_post_submit_checker_policy_version=( - context.retained_catalogue_policy_version + context.post_policy_version ), - locked_post_submit_checker_policy_hash=context.retained_catalogue_policy_hash, + locked_post_submit_checker_policy_hash=context.post_policy_hash, selected_post_submit_policy_sha256=request.policy.policy_sha256, selected_post_submit_policy_body=request.policy.model_dump(mode="json"), locked_review_policy_id=str(context.review_policy_id), diff --git a/backend/app/modules/tasks/post_submit_routing/evaluation_guard.py b/backend/app/modules/tasks/post_submit_routing/evaluation_guard.py index 20cd7c73c..45665f0a8 100644 --- a/backend/app/modules/tasks/post_submit_routing/evaluation_guard.py +++ b/backend/app/modules/tasks/post_submit_routing/evaluation_guard.py @@ -23,17 +23,17 @@ def _context_matches(request: PostSubmissionExecutionRequest, context: object) - "effective_policy_hash": observed["effective_policy_hash"], "pre_policy_id": observed["pre_policy_id"], "pre_policy_hash": observed["pre_policy_hash"], - "retained_catalogue_policy_id": observed["post_policy_id"], - "retained_catalogue_policy_version": observed["post_policy_version"], - "retained_catalogue_policy_hash": observed["post_policy_hash"], - "selected_post_policy_hash": observed["selected_post_policy_hash"], + "post_policy_id": observed["post_policy_id"], + "post_policy_version": observed["post_policy_version"], + "post_policy_hash": observed["post_policy_hash"], "review_policy_id": observed["review_policy_id"], "review_generation": observed["review_generation"], "review_hash": observed["review_hash"], "revision_policy_id": observed["revision_policy_id"], "revision_generation": observed["revision_generation"], "revision_hash": observed["revision_hash"], - } and observed["selected_post_policy_body"] == request.policy.model_dump(mode="json") + } and observed["selected_post_policy_hash"] == request.expected_context.post_policy_hash \ + and observed["selected_post_policy_body"] == request.policy.model_dump(mode="json") class TaskEvaluationGuard: diff --git a/backend/tests/checkers/external/test_selected_post_submit.py b/backend/tests/checkers/external/test_selected_post_submit.py index 7a6cfb56a..c88a04396 100644 --- a/backend/tests/checkers/external/test_selected_post_submit.py +++ b/backend/tests/checkers/external/test_selected_post_submit.py @@ -110,10 +110,9 @@ def _request(identity, policy): effective_policy_hash=SHA, pre_policy_id=new_record_id(), pre_policy_hash=SHA, - retained_catalogue_policy_id=new_record_id(), - retained_catalogue_policy_version="guide-v1", - retained_catalogue_policy_hash=SHA, - selected_post_policy_hash=policy.policy_sha256, + post_policy_id=new_record_id(), + post_policy_version="guide-v1", + post_policy_hash=policy.policy_sha256, review_policy_id=new_record_id(), review_generation=1, review_hash=SHA, @@ -312,7 +311,7 @@ async def test_selected_post_request_and_result_bind_exact_locked_policy() -> No policy=empty_policy, expected_context=request.expected_context.model_copy( update={ - "selected_post_policy_hash": empty_policy.policy_sha256 + "post_policy_hash": empty_policy.policy_sha256 } ), ) @@ -366,7 +365,7 @@ def test_execution_boundary_rejects_removed_catalogue_request_schema() -> None: validate_stored_execution_request(json.dumps(removed)) -def test_selected_post_content_uses_selected_digest_not_catalogue_hash() -> None: +def test_selected_post_content_uses_exact_locked_external_policy() -> None: policy = _policy() locked = SimpleNamespace( locked_guide_version="guide-v1", @@ -376,7 +375,7 @@ def test_selected_post_content_uses_selected_digest_not_catalogue_hash() -> None locked_effective_project_submission_artifact_policy_hash=SHA, locked_pre_submit_checker_policy_id=new_record_id(), locked_pre_submit_checker_bundle_hash=SHA, - locked_post_submit_checker_policy_hash="sha256:" + "1" * 64, + locked_post_submit_checker_policy_hash=policy.policy_sha256, locked_post_submit_checker_policy_id=new_record_id(), locked_post_submit_checker_policy_version="guide-v1", locked_review_policy_id=new_record_id(), @@ -393,8 +392,5 @@ def test_selected_post_content_uses_selected_digest_not_catalogue_hash() -> None content = selected_submission_evaluation_content(task, policy) - assert content.expected_context.selected_post_policy_hash == policy.policy_sha256 - assert ( - content.expected_context.selected_post_policy_hash - != locked.locked_post_submit_checker_policy_hash - ) + assert content.expected_context.post_policy_hash == policy.policy_sha256 + assert content.expected_context.post_policy_hash == locked.locked_post_submit_checker_policy_hash From 461ad80131962d7cbc1edb00974e37d3ae0fe4bd Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 13:13:22 +0100 Subject: [PATCH 191/283] Use canonical PRE packet in default checker API --- backend/app/modules/checkers/api/default_checker.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/app/modules/checkers/api/default_checker.py b/backend/app/modules/checkers/api/default_checker.py index 1256d97a4..e869e6f71 100644 --- a/backend/app/modules/checkers/api/default_checker.py +++ b/backend/app/modules/checkers/api/default_checker.py @@ -10,7 +10,7 @@ from app.core.hashing import canonical_json_hash from app.modules.checkers.api.material import SubmissionMaterialEntry -from app.modules.checkers.api.pre_submit import SubmissionPacketView +from app.modules.checkers.api.pre_submit_material import SubmissionPacketView WORKSTREAM_DEFAULT_CHECKER_ID = "workstream.default" From 5526676eb8f18229167bf947d457aedce00c78fb Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 13:15:43 +0100 Subject: [PATCH 192/283] Align current ART custody and selected PRE proof --- .../pilot04-workstream-default-checker.md | 24 ++ .../artifacts/post_submit_selection.py | 8 +- .../modules/artifacts/submission_admission.py | 18 +- .../modules/artifacts/submission_bindings.py | 16 +- .../artifacts/submission_materialization.py | 6 +- .../external/test_selected_pre_submit.py | 211 +++++++++--------- .../run_selected_end_to_end_probe.py | 32 +-- 7 files changed, 167 insertions(+), 148 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index beedbd939..6426fdd72 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -663,3 +663,27 @@ Validation at this source checkpoint: TASK/ART Ruff and Python compilation pass; current owner/DTO imports pass. Native and broader current-flow checks remain required after the CHECKERS composition and selected fixture repairs are combined. This checkpoint does not claim hosted suite readiness. + + +### Current ART projection and runtime proof reconciliation + +ART input selection now uses the single POST context identity and requires its +hash to equal the retained submitted external policy digest. Binding authority +projects the sole selected PRE run and a constant null historical evidence key, +matching the unchanged authorization protocol. The private durable put result and +publish call expose one selected run only. PRE execution input requires the lease +attempt, request digest and genuine ART grant port, with no optional old plan. + +The selected PRE unit arrangement now uses canonical reservation and committed +lease facts instead of the retired plan/invocation claim. It retains real scratch +inspection and the callback grant and proves that substituting the default packet +fails before byte access or external invocation. The actual Rust end-to-end probe +constructs its registry specs from the pure external contract helper; it no longer +imports the obsolete PRE arrangement merely for a spec. The open PRE schema, +digest pinning and resource limits remain the same. + +Focused selected PRE processor, current ART factory/admission publication and +short-root execution service checks pass (11 cases). Ruff and diff whitespace +checks pass. This is author verification; independent review and the final clean +combined PostgreSQL/MinIO/real-image journey remain required, as does full hosted +CI. No migration or provider proof is claimed by this checkpoint. diff --git a/backend/app/modules/artifacts/post_submit_selection.py b/backend/app/modules/artifacts/post_submit_selection.py index bc3d24ab4..c98092db5 100644 --- a/backend/app/modules/artifacts/post_submit_selection.py +++ b/backend/app/modules/artifacts/post_submit_selection.py @@ -68,13 +68,13 @@ async def select_post_submission_material( and context.pre_policy_id == request.expected_context.pre_policy_id and context.pre_policy_hash == request.expected_context.pre_policy_hash and context.post_policy_id - == request.expected_context.retained_catalogue_policy_id + == request.expected_context.post_policy_id and context.post_policy_version - == request.expected_context.retained_catalogue_policy_version + == request.expected_context.post_policy_version and context.post_policy_hash - == request.expected_context.retained_catalogue_policy_hash + == request.expected_context.post_policy_hash and context.selected_post_policy_hash - == request.expected_context.selected_post_policy_hash + == request.expected_context.post_policy_hash and context.selected_post_policy_body == request.policy.model_dump(mode="json") and context.review_policy_id == request.expected_context.review_policy_id and context.review_generation == request.expected_context.review_generation diff --git a/backend/app/modules/artifacts/submission_admission.py b/backend/app/modules/artifacts/submission_admission.py index e86fe91af..6763f25d1 100644 --- a/backend/app/modules/artifacts/submission_admission.py +++ b/backend/app/modules/artifacts/submission_admission.py @@ -124,12 +124,11 @@ class SubmissionBundleDurablePutResult: """Bounded durable operation result without provider coordinates.""" put_attempt_id: UUID - pre_submit_evidence_set_id: UUID | None operation_identity: str status: str replayed: bool admission_id: UUID | None - selected_pre_submit_run_id: UUID | None = None + selected_pre_submit_run_id: UUID class SubmissionBundleDurablePutService: @@ -206,13 +205,8 @@ async def publish_after_commit( prepared: PreparedArtifact, lineage_id: UUID, admission: ArtifactAdmissionResult, - *, - selected_pre_submit_run_id: UUID, ) -> SubmissionBundleDurablePutResult: """Hand the exact ZIP to storage only after the durable transaction ended.""" - if selected_pre_submit_run_id != lineage_id: - await prepared.close() - raise RuntimeError("submission bundle selected lineage changed") if self._session.in_transaction(): await prepared.close() raise RuntimeError("submission bundle durable transaction is still active") @@ -227,22 +221,20 @@ async def publish_after_commit( if admission_id is not None: return SubmissionBundleDurablePutResult( put_attempt_id=admission.attempt_id, - pre_submit_evidence_set_id=None, operation_identity=admission.operation_identity, status="ready", replayed=True, admission_id=admission_id, - selected_pre_submit_run_id=selected_pre_submit_run_id, + selected_pre_submit_run_id=lineage_id, ) if admission.replayed and admission.status == "object_confirmed": return SubmissionBundleDurablePutResult( put_attempt_id=admission.attempt_id, - pre_submit_evidence_set_id=None, operation_identity=admission.operation_identity, status="object_confirmed", replayed=True, admission_id=None, - selected_pre_submit_run_id=selected_pre_submit_run_id, + selected_pre_submit_run_id=lineage_id, ) if admission.replayed: status = await self._storage.resume_committed_put( @@ -261,12 +253,11 @@ async def publish_after_commit( ) return SubmissionBundleDurablePutResult( put_attempt_id=admission.attempt_id, - pre_submit_evidence_set_id=None, operation_identity=admission.operation_identity, status=status, replayed=admission.replayed, admission_id=admission_id, - selected_pre_submit_run_id=selected_pre_submit_run_id, + selected_pre_submit_run_id=lineage_id, ) finally: await prepared.close() @@ -723,7 +714,6 @@ async def prepare( retained, reservation.attempt_id, durable, - selected_pre_submit_run_id=reservation.attempt_id, ) return self._result(result) except SelectedPreSubmitRequestConflict as exc: diff --git a/backend/app/modules/artifacts/submission_bindings.py b/backend/app/modules/artifacts/submission_bindings.py index de9968999..233ca0257 100644 --- a/backend/app/modules/artifacts/submission_bindings.py +++ b/backend/app/modules/artifacts/submission_bindings.py @@ -330,16 +330,8 @@ def _authority_facts( ) -> SubmissionBindingAuthorityFacts: return SubmissionBindingAuthorityFacts( admission_id=request.admission_id, - evidence_set_id=( - UUID(admission.pre_submit_evidence_set_id) - if admission.pre_submit_evidence_set_id is not None - else None - ), - selected_pre_submit_run_id=( - UUID(admission.selected_pre_submit_run_id) - if admission.selected_pre_submit_run_id is not None - else None - ), + evidence_set_id=None, + selected_pre_submit_run_id=UUID(admission.selected_pre_submit_run_id), actor_profile_id=UUID(admission.actor_profile_id), identity_link_id=UUID(admission.identity_link_id), project_id=UUID(admission.project_id), @@ -403,9 +395,9 @@ def _result( material=material, binding_decision_id=binding_decision_id, selected_post_submit_policy_sha256=( - getattr(admission, "selected_post_submit_policy_sha256", None) + admission.selected_post_submit_policy_sha256 ), selected_post_submit_policy_body=( - getattr(admission, "selected_post_submit_policy_body", None) + admission.selected_post_submit_policy_body ), ) diff --git a/backend/app/modules/artifacts/submission_materialization.py b/backend/app/modules/artifacts/submission_materialization.py index e4448fb77..3e27546a6 100644 --- a/backend/app/modules/artifacts/submission_materialization.py +++ b/backend/app/modules/artifacts/submission_materialization.py @@ -92,9 +92,9 @@ class PreSubmitCheckerExecutionRequest: storage_scheme: str external_policy: LockedExternalPreSubmitPolicy default_checker_input: WorkstreamDefaultCheckerInput - attempt_id: UUID | None = None - attempt_request_digest: str | None = None - external_grants: "PreSubmitExternalGrantPort | None" = None + attempt_id: UUID + attempt_request_digest: str + external_grants: "PreSubmitExternalGrantPort" class PreSubmitExternalGrantPort(Protocol): diff --git a/backend/tests/checkers/external/test_selected_pre_submit.py b/backend/tests/checkers/external/test_selected_pre_submit.py index db1afba90..b1848b7fd 100644 --- a/backend/tests/checkers/external/test_selected_pre_submit.py +++ b/backend/tests/checkers/external/test_selected_pre_submit.py @@ -10,7 +10,7 @@ from pathlib import Path from types import SimpleNamespace from typing import cast -from unittest.mock import AsyncMock, Mock +from unittest.mock import AsyncMock, Mock, patch import zipfile import pytest @@ -54,7 +54,6 @@ ) from app.modules.checkers.selected_pre_submit_execution import SelectedPreSubmitProcessor from app.adapters.checkers import SelectedPreSubmitCheckerExecutionAdapter -from app.modules.artifacts.pre_submit_attempts import PreSubmitAttemptClaim from app.modules.artifacts.preparation import ( HARD_MAXIMUM_ARTIFACT_BYTES, ArtifactPreparationLimits, @@ -73,6 +72,7 @@ from app.modules.artifacts.submission_manifest import ( SubmissionCanonicalPredecessor, build_submission_manifest, + semantic_manifest_identity, evaluate_submission_change, ) from app.modules.artifacts.submission_materialization import ( @@ -80,11 +80,7 @@ PreparedBundleMaterializationService, ) from app.modules.authorization.prepared import PreparedAuthorizationHandle -from app.modules.checkers.api.pre_submit import ( - EffectivePreSubmissionExecutionPlan, - EffectivePreSubmissionPlanLineage, - SubmissionPacketView, -) +from app.modules.checkers.api.pre_submit_material import SubmissionPacketView from tests.checkers.external.support import SHA, registry_entry @@ -256,27 +252,6 @@ async def _request( *, primary_bytes: bytes = b"[task]\nname='proof'\n", ): - lineage = EffectivePreSubmissionPlanLineage( - project_id=new_record_id(), - guide_id=new_record_id(), - guide_version="v1", - source_snapshot_id=new_record_id(), - source_snapshot_hash=SHA, - effective_policy_id=new_record_id(), - effective_policy_hash=SHA, - pre_submit_policy_id=new_record_id(), - pre_submit_policy_bundle_hash=SHA, - ) - plan = EffectivePreSubmissionExecutionPlan( - lineage=lineage, - catalogue_id="retired.test.fixture", - catalogue_version="v1", - catalogue_schema_version="retired", - catalogue_manifest_sha256=SHA, - entries=(), - plan_sha256=SHA, - ) - plan = replace(plan, plan_sha256=canonical_json_hash(plan.as_dict())) inspector = SubmissionArchiveInspector(SubmissionArchiveLimits()) manager = ArtifactScratchManager(root=tmp_path / "scratch", limits=_limits()) preparation = ArtifactPreparationService(manager) @@ -285,30 +260,54 @@ async def _request( ) inspection = await prepared.inspect(inspector) manifest = build_submission_manifest(inspection) + policy = _policy() + packet = SubmissionPacketView( + summary="Completed exact project work.", contributor_attestation="rights_confirmed", + ) + _, _, seed = _selected_admission_reservation() + default_input = WorkstreamDefaultCheckerInput( + archive_sha256=prepared.commitment.sha256, + archive_byte_count=prepared.commitment.byte_count, + archive_media_type="application/zip", + semantic_manifest_sha256=manifest.sha256, + entries=tuple(SubmissionMaterialEntry( + item.normalized_path, item.entry_type.value, item.byte_count, + item.sha256, item.executable, + ) for item in manifest.entries), + predecessor=None, predecessor_exists=False, current_predecessor=None, + current_rules_sha256=seed.admission_lineage.rules_sha256, + predecessor_rules_sha256=None, packet=packet, + ) + reservation = replace( + seed, + prepared_generation_id=prepared.generation_id, + policy_sha256=policy.policy_sha256, + default_input_sha256=workstream_default_input_sha256(default_input), + archive_sha256=prepared.commitment.sha256, + archive_byte_count=prepared.commitment.byte_count, + semantic_manifest_sha256=manifest.sha256, + admission_lineage=replace( + seed.admission_lineage, + effective_plan_sha256=policy.policy_sha256, + semantic_manifest_id=semantic_manifest_identity(manifest.sha256), + semantic_manifest_body=manifest.as_dict(), packet_sha256=packet.sha256, + ), + ) request = PreparedBundleMaterializationRequest( prepared_authorization=cast(PreparedAuthorizationHandle, _PreparedHandle()), - task_id=new_record_id(), - assignment_id=new_record_id(), - submission_artifact_policy_id=lineage.effective_policy_id, - checker_policy_id=lineage.pre_submit_policy_id, - predecessor_submission_version=None, - checker_remediation_manifest_id=None, - prepared_artifact=prepared, - effective_plan=plan, - inspection=inspection, - manifest=manifest, + task_id=reservation.task_id, assignment_id=reservation.assignment_id, + submission_artifact_policy_id=reservation.admission_lineage.effective_policy_id, + checker_policy_id=reservation.admission_lineage.pre_submit_policy_id, + predecessor_submission_version=None, checker_remediation_manifest_id=None, + prepared_artifact=prepared, inspection=inspection, manifest=manifest, change_gate=evaluate_submission_change( - commitment=prepared.commitment, - manifest=manifest, - predecessor=None, - predecessor_exists=False, - ), - packet=SubmissionPacketView( - summary="Completed exact project work.", - contributor_attestation="rights_confirmed", + commitment=prepared.commitment, manifest=manifest, + predecessor=None, predecessor_exists=False, ), + packet=packet, external_policy=policy, default_checker_input=default_input, + selected_reservation=reservation, ) - return request, inspector, manager, preparation, None + return request, inspector, manager, preparation def _open_input_schema() -> ExternalCheckerSchema: @@ -458,7 +457,7 @@ async def execute(self, request, _grant): def _execution_context(request, policy): identity = PreSubmitExternalCheckerIdentity( - project_id=request.effective_plan.lineage.project_id, + project_id=request.selected_reservation.project_id, task_id=request.task_id, assignment_id=request.assignment_id, prepared_generation_id=request.prepared_artifact.generation_id, @@ -495,7 +494,7 @@ def _execution_context(request, policy): predecessor=None, predecessor_exists=False, current_predecessor=None, - current_rules_sha256=request.effective_plan.lineage.pre_submit_policy_bundle_hash, + current_rules_sha256=request.selected_reservation.admission_lineage.rules_sha256, predecessor_rules_sha256=None, packet=SubmissionPacketView(summary="", contributor_attestation=""), ) @@ -552,7 +551,7 @@ def _assert_terminal_round_trip(identity, policy, default_input, material, resul async def test_selected_pre_runs_default_then_locked_external_image( tmp_path, verdict: str, eligible: bool ) -> None: - request, inspector, manager, preparation, _catalogue = await _request(tmp_path) + request, inspector, manager, preparation = await _request(tmp_path) policy = _policy() identity, material, default_input = _execution_context(request, policy) grants, execution = _GrantIssuer(), _Execution(verdict) @@ -595,7 +594,7 @@ async def test_selected_pre_runs_default_then_locked_external_image( async def test_selected_pre_only_requires_runtime_for_locked_external_images( tmp_path, external: bool ) -> None: - request, inspector, manager, preparation, _catalogue = await _request(tmp_path) + request, inspector, manager, preparation = await _request(tmp_path) policy = _policy() if external else _empty_policy() identity, material, default_input = _execution_context(request, policy) grants = _GrantIssuer() @@ -681,13 +680,13 @@ async def test_selected_pre_terminal_publishes_self_contained_ready_admission( async def test_selected_pre_default_secret_blocker_precedes_external_image( tmp_path, ) -> None: - request, inspector, manager, preparation, _catalogue = await _request( + request, inspector, manager, preparation = await _request( tmp_path, primary_bytes=b"-----BEGIN OPENSSH PRIVATE KEY-----\nencoded", ) policy = _policy() identity = PreSubmitExternalCheckerIdentity( - project_id=request.effective_plan.lineage.project_id, + project_id=request.selected_reservation.project_id, task_id=request.task_id, assignment_id=request.assignment_id, prepared_generation_id=request.prepared_artifact.generation_id, @@ -730,7 +729,7 @@ async def test_selected_pre_default_secret_blocker_precedes_external_image( predecessor=None, predecessor_exists=False, current_predecessor=None, - current_rules_sha256=request.effective_plan.lineage.pre_submit_policy_bundle_hash, + current_rules_sha256=request.selected_reservation.admission_lineage.rules_sha256, predecessor_rules_sha256=None, packet=request.packet, ), @@ -762,9 +761,9 @@ async def test_selected_pre_default_secret_blocker_precedes_external_image( async def test_selected_admission_binds_unchanged_work_to_current_task_rules( tmp_path, ) -> None: - request, _inspector, manager, _preparation, _catalogue = await _request(tmp_path) + request, _inspector, manager, _preparation = await _request(tmp_path) policies = _policies() - project_id = request.effective_plan.lineage.project_id + project_id = request.selected_reservation.project_id actor_profile_id = new_record_id() identity_link_id = new_record_id() assignment_id = new_record_id() @@ -861,8 +860,8 @@ async def test_selected_admission_binds_unchanged_work_to_current_task_rules( @pytest.mark.asyncio async def test_selected_factory_uses_request_bound_art_grant(tmp_path) -> None: - request, inspector, manager, preparation, _catalogue = await _request(tmp_path) - policy = _policy() + request, inspector, manager, preparation = await _request(tmp_path) + policy = request.external_policy entries = tuple( SubmissionMaterialEntry( item.normalized_path, @@ -874,41 +873,40 @@ async def test_selected_factory_uses_request_bound_art_grant(tmp_path) -> None: for item in request.manifest.entries ) request = replace( - request, - external_policy=policy, + request, external_policy=policy, default_checker_input=WorkstreamDefaultCheckerInput( archive_sha256=request.prepared_artifact.commitment.sha256, archive_byte_count=request.prepared_artifact.commitment.byte_count, archive_media_type="application/zip", semantic_manifest_sha256=request.manifest.sha256, - entries=entries, - predecessor=None, - predecessor_exists=False, + entries=entries, predecessor=None, predecessor_exists=False, current_predecessor=None, - current_rules_sha256=request.effective_plan.lineage.pre_submit_policy_bundle_hash, - predecessor_rules_sha256=None, - packet=request.packet, + current_rules_sha256=request.selected_reservation.admission_lineage.rules_sha256, + predecessor_rules_sha256=None, packet=request.packet, ), ) - transaction = True - claim = object.__new__(PreSubmitAttemptClaim) - claim.attempt_id, claim._nonce = new_record_id(), new_record_id() - claim.request_digest = SHA - claim._request = replace(request, prepared_authorization=None) - claim._started, claim._execution = False, None - row = SimpleNamespace( - status="reserved", - evidence_set_id=None, - claim_nonce=str(claim._nonce), - request_digest=claim.request_digest, - prepared_generation_id=str(request.prepared_artifact.generation_id), - ) - session = SimpleNamespace( - in_transaction=lambda: transaction, - in_nested_transaction=lambda: False, - scalar=AsyncMock(return_value=row), + reservation = request.selected_reservation + lease = SelectedPreSubmitLeaseFacts( + reservation=reservation, lease_id=new_record_id(), lease_generation=1, + lease_expires_at=datetime.now(UTC) + timedelta(minutes=2), ) - claim._session = session + transaction = True + session = SimpleNamespace(in_transaction=lambda: transaction) + + class CommittedAuthority: + def __init__(self): + self.calls = 0 + + def consume(self, *, run_id, lease): + assert not transaction + assert run_id == reservation.attempt_id + assert lease == expected_lease + assert self.calls == 0 + self.calls += 1 + return lease + + expected_lease = lease + committed = CommittedAuthority() execution = _Execution("passed") authority = SimpleNamespace( prepare=AsyncMock(return_value=object()), @@ -925,25 +923,38 @@ async def test_selected_factory_uses_request_bound_art_grant(tmp_path) -> None: storage_scheme="s3", ) try: - await service.prepare_authorization( - task_id=request.task_id, - assignment_id=request.assignment_id, - submission_artifact_policy_id=request.submission_artifact_policy_id, - checker_policy_id=request.checker_policy_id, - prepared_artifact=request.prepared_artifact, - effective_plan=request.effective_plan, - idempotency_key=new_record_id(), - external_policy=policy, - ) - assert authority.prepare.await_count == 1 - await service.authorize_prepared_bundle(request, claim=claim) + await service.authorize_inspected(request) + assert authority.consume.await_count == 1 + assert execution.requests == [] transaction = False - result = await service.materialize_prepared_bundle( - replace(request, prepared_authorization=None), claim=claim + # A substituted default packet must fail before byte access or grants, + # even when the committed lease is otherwise exact. + process = AsyncMock() + with patch.object(preparation, "_process_prepared_submission", process): + with pytest.raises(SelectedPreSubmitInfrastructureUnavailable) as refusal: + await service.materialize_selected_pre_submit( + replace( + request, + prepared_authorization=None, + default_checker_input=replace( + request.default_checker_input, + packet=SubmissionPacketView("Changed packet", "rights_confirmed"), + ), + ), + run_id=reservation.attempt_id, lease=lease, + execution_authority=CommittedAuthority(), + ) + assert refusal.value.code == "material_unavailable" + process.assert_not_awaited() + assert execution.requests == [] + result = await service.materialize_selected_pre_submit( + replace(request, prepared_authorization=None), + run_id=reservation.attempt_id, lease=lease, execution_authority=committed, ) - assert result.checker_facts.eligible is True + assert result.eligible is True + assert committed.calls == 1 assert len(execution.requests) == 1 - assert execution.requests[0].identity.attempt_id == claim.attempt_id + assert execution.requests[0].identity.attempt_id == reservation.attempt_id assert execution.requests[0].materials[0].archive_sha256 == ( request.prepared_artifact.commitment.sha256 ) diff --git a/experiments/pilot04_external_checker_runtime/run_selected_end_to_end_probe.py b/experiments/pilot04_external_checker_runtime/run_selected_end_to_end_probe.py index 34a4582af..3a772c03a 100644 --- a/experiments/pilot04_external_checker_runtime/run_selected_end_to_end_probe.py +++ b/experiments/pilot04_external_checker_runtime/run_selected_end_to_end_probe.py @@ -47,7 +47,12 @@ PreparedSubmissionBundlePreparationAuthorization, ) from app.modules.authorization.api import ActorIdentityFacts, ActorKind -from app.modules.checkers.api.external import ExternalCheckerRegistrySpec +from app.modules.checkers.api.external import ( + PRE_SUBMIT_INPUT_SCHEMA_ID, + ExternalCheckerRegistrySpec, + ExternalCheckerSchema, + external_checker_json_hash, +) from app.modules.checkers.models import CheckerRun, SelectedPreSubmitRun from app.modules.tasks.api import SubmissionCreationRequest from app.modules.tasks.models import Submission, SubmissionDispatch, WorkstreamTask @@ -57,8 +62,7 @@ from tests.authorization.post_submit_routing.support import provision_router from tests.tasks.evaluation_delivery.support import delivery_fixture, outcome from tests.tasks.post_submit_routing.outcome_support import outcome_snapshot -from tests.checkers.external.test_selected_post_submit import _post_spec -from tests.checkers.external.test_selected_pre_submit import _policy +from tests.checkers.external.support import post_registry_spec, registry_spec from tests.archive_fixtures import byte_source from tests.post_submit_materialization_helpers import material_fixture from tests.tasks.lineage_fixtures import seed_started_task_for_artifact_test @@ -72,18 +76,16 @@ def _locked_spec(phase: str, image: dict[str, str]) -> ExternalCheckerRegistrySpec: - source = _policy().entries[0].registry if phase == "pre_submit" else _post_spec() - values = source.model_dump( - mode="json", - exclude={ - "registry_entry_id", - "entry_digest", - "registration_operation_id", - "registered_by_actor_profile_id", - "authorization_decision_event_id", - "created_at", - }, - ) + source = registry_spec("pre_submit") if phase == "pre_submit" else post_registry_spec() + values = source.model_dump(mode="json") + if phase == "pre_submit": + document = {"type": "object"} + values["input_schema"] = ExternalCheckerSchema( + schema_id=PRE_SUBMIT_INPUT_SCHEMA_ID, + schema_version="v1", + document=document, + schema_sha256=external_checker_json_hash(document), + ).model_dump(mode="json") values["image_digest"] = image["platform_manifest_digest"] values["resources"] |= {"deadline_ms": 30_000, "maximum_output_bytes": 8_192} return ExternalCheckerRegistrySpec.model_validate(values) From bf85c7991309fdf21ecb1b666dba86a591181ed6 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 13:18:10 +0100 Subject: [PATCH 193/283] Require selected checker custody at the database boundary --- .../versions/0036_selected_checker_flow.py | 106 +++++++++--------- backend/tests/conftest.py | 2 +- backend/tests/test_alembic.py | 54 +++++++++ 3 files changed, 107 insertions(+), 55 deletions(-) diff --git a/backend/alembic/versions/0036_selected_checker_flow.py b/backend/alembic/versions/0036_selected_checker_flow.py index cf8251808..5deb678d2 100644 --- a/backend/alembic/versions/0036_selected_checker_flow.py +++ b/backend/alembic/versions/0036_selected_checker_flow.py @@ -828,29 +828,26 @@ def _replace_checker_run_custody() -> None: raise RuntimeError("checker run custody declaration shape changed") definition = definition.replace( declaration, - " DECLARE body jsonb; source submissions; mutable text[]; selected boolean;", + " DECLARE body jsonb; source submissions; mutable text[];", ) body_anchor = " body := NEW.request_json::jsonb;" if definition.count(body_anchor) != 1: raise RuntimeError("checker run request body shape changed") definition = definition.replace( body_anchor, - body_anchor + "\n selected := body->>'schema_version'=" - "'workstream.selected_post_submit_request.v1';", + body_anchor + "\n IF body->>'schema_version' IS DISTINCT FROM " + "'workstream.selected_post_submit_request.v1' THEN\n" + " RAISE EXCEPTION 'checker request schema unavailable' " + "USING ERRCODE='23514';\n END IF;", ) old_policy = """ OR source.locked_post_submit_checker_policy_body::jsonb IS DISTINCT FROM body->'policy' OR body->>'project_id' IS DISTINCT FROM NEW.project_id::text""" - new_policy = """ OR (NOT selected AND ( - source.locked_post_submit_checker_policy_body::jsonb IS DISTINCT FROM body->'policy' - OR NEW.selected_post_submit_policy_sha256 IS NOT NULL - OR NEW.selected_post_submit_policy_body IS NOT NULL)) - OR (selected AND ( - source.selected_post_submit_policy_body::jsonb IS DISTINCT FROM body->'policy' + new_policy = """ OR source.selected_post_submit_policy_body::jsonb IS DISTINCT FROM body->'policy' OR source.selected_post_submit_policy_sha256 IS DISTINCT FROM - body#>>'{expected_context,selected_post_policy_hash}' + body#>>'{expected_context,post_policy_hash}' OR NEW.selected_post_submit_policy_body::jsonb IS DISTINCT FROM body->'policy' OR NEW.selected_post_submit_policy_sha256 IS DISTINCT FROM - body#>>'{expected_context,selected_post_policy_hash}')) + body#>>'{expected_context,post_policy_hash}' OR body->>'project_id' IS DISTINCT FROM NEW.project_id::text""" if definition.count(old_policy) != 1: raise RuntimeError("checker run policy body shape changed") @@ -858,20 +855,12 @@ def _replace_checker_run_custody() -> None: old_context = """ OR body#>>'{expected_context,post_policy_id}' IS DISTINCT FROM NEW.locked_post_submit_checker_policy_id::text OR body#>>'{expected_context,post_policy_version}' IS DISTINCT FROM NEW.locked_post_submit_checker_policy_version OR body#>>'{expected_context,post_policy_hash}' IS DISTINCT FROM NEW.locked_post_submit_checker_policy_hash""" - new_context = """ OR (NOT selected AND ( - body#>>'{expected_context,post_policy_id}' IS DISTINCT FROM + new_context = """ OR body#>>'{expected_context,post_policy_id}' IS DISTINCT FROM NEW.locked_post_submit_checker_policy_id::text OR body#>>'{expected_context,post_policy_version}' IS DISTINCT FROM NEW.locked_post_submit_checker_policy_version OR body#>>'{expected_context,post_policy_hash}' IS DISTINCT FROM - NEW.locked_post_submit_checker_policy_hash)) - OR (selected AND ( - body#>>'{expected_context,retained_catalogue_policy_id}' IS DISTINCT FROM - NEW.locked_post_submit_checker_policy_id::text - OR body#>>'{expected_context,retained_catalogue_policy_version}' IS DISTINCT FROM - NEW.locked_post_submit_checker_policy_version - OR body#>>'{expected_context,retained_catalogue_policy_hash}' IS DISTINCT FROM - NEW.locked_post_submit_checker_policy_hash))""" + NEW.locked_post_submit_checker_policy_hash""" if definition.count(old_context) != 1: raise RuntimeError("checker run locked context shape changed") op.execute(definition.replace(old_context, new_context)) @@ -883,15 +872,11 @@ def _replace_submission_dispatch_custody() -> None: )).scalar_one() old_packet = """ AND (r.request_json::jsonb->'structural_input'->>'summary')=s.summary AND (r.request_json::jsonb->'structural_input'->>'worker_attestation')=s.worker_attestation""" - new_packet = """ AND ((r.request_json::jsonb->>'schema_version'= + new_packet = """ AND r.request_json::jsonb->>'schema_version' IS NOT DISTINCT FROM 'workstream.selected_post_submit_request.v1' AND r.selected_post_submit_policy_sha256=s.selected_post_submit_policy_sha256 AND r.selected_post_submit_policy_body::jsonb=s.selected_post_submit_policy_body::jsonb - AND r.request_json::jsonb->'policy'=s.selected_post_submit_policy_body::jsonb) - OR (r.request_json::jsonb->>'schema_version'<> - 'workstream.selected_post_submit_request.v1' - AND (r.request_json::jsonb->'structural_input'->>'summary')=s.summary - AND (r.request_json::jsonb->'structural_input'->>'worker_attestation')=s.worker_attestation))""" + AND r.request_json::jsonb->'policy'=s.selected_post_submit_policy_body::jsonb""" if definition.count(old_packet) != 1: raise RuntimeError("submission dispatch packet custody shape changed") definition = definition.replace(old_packet, new_packet) @@ -913,13 +898,9 @@ def _replace_submission_dispatch_custody() -> None: ) if definition.count(old_evidence_cause) != 1: raise RuntimeError("submission dispatch evidence cause shape changed") - new_evidence_cause = """((a.selected_pre_submit_run_id IS NULL - AND evidence.id IS NOT NULL - AND evidence.checker_remediation_manifest_id IS NOT DISTINCT FROM - a.checker_remediation_manifest_id) - OR (a.selected_pre_submit_run_id IS NOT NULL + new_evidence_cause = """(a.selected_pre_submit_run_id IS NOT NULL AND a.pre_submit_evidence_set_id IS NULL - AND evidence.id IS NULL))""" + AND evidence.id IS NULL)""" op.execute(definition.replace(old_evidence_cause, new_evidence_cause)) @@ -974,17 +955,33 @@ def _replace_checker_input_authority_digest() -> None: def _replace_checker_result_custody() -> None: - definition = op.get_bind().execute(sa.text( - "select pg_get_functiondef('public.protect_checker_result_custody()'::regprocedure)" - )).scalar_one() - anchor = ( - " entry := parent.request_json::jsonb #> " - "ARRAY['policy','entries',NEW.member_order::text];" - ) - selected = r""" - IF parent.request_json::jsonb->>'schema_version'= + op.execute(r""" +CREATE OR REPLACE FUNCTION public.protect_checker_result_custody() RETURNS trigger +LANGUAGE plpgsql SET search_path = pg_catalog, public, pg_temp AS $$ + DECLARE parent public.checker_runs; entry jsonb; + BEGIN + IF TG_OP <> 'INSERT' THEN + RAISE EXCEPTION 'checker result custody is immutable' USING ERRCODE='23514'; + END IF; + SELECT * INTO parent FROM public.checker_runs + WHERE id=NEW.checker_run_id AND task_id=NEW.task_id + AND submission_id=NEW.submission_id FOR UPDATE; + IF NOT FOUND THEN + RAISE EXCEPTION 'checker result violates fk_checker_results_run_ownership' + USING ERRCODE='23503', CONSTRAINT='fk_checker_results_run_ownership', + TABLE='checker_results'; + END IF; + IF parent.status IS DISTINCT FROM 'running' OR parent.completed_at IS NOT NULL THEN + RAISE EXCEPTION 'finished or unclaimed checker run cannot receive results' + USING ERRCODE='23514'; + END IF; + entry := parent.request_json::jsonb #> + ARRAY['policy','entries',NEW.member_order::text]; + IF parent.request_json::jsonb->>'schema_version' IS DISTINCT FROM 'workstream.selected_post_submit_request.v1' THEN - IF entry->>'requirement_id' IS DISTINCT FROM NEW.checker_name + RAISE EXCEPTION 'checker request schema unavailable' USING ERRCODE='23514'; + END IF; + IF entry->>'requirement_id' IS DISTINCT FROM NEW.checker_name OR entry#>>'{registry,entry_digest}' IS DISTINCT FROM NEW.implementation_version OR NEW.definition_version IS DISTINCT FROM 'external_checker_result.v1' OR NEW.status NOT IN ('passed','failed') @@ -998,11 +995,10 @@ def _replace_checker_result_custody() -> None: RAISE EXCEPTION 'checker member differs from selected definition' USING ERRCODE='23514'; END IF; - RETURN NEW; - END IF;""" - if definition.count(anchor) != 1: - raise RuntimeError("checker result selected definition anchor changed") - op.execute(definition.replace(anchor, anchor + selected)) + RETURN NEW; + END +$$; +""") def _replace_checker_terminal_custody() -> None: @@ -1030,7 +1026,8 @@ def _replace_checker_terminal_custody() -> None: if mismatch not in definition: mismatch = mismatch.replace(" IF", " IF").replace(" OR", " OR") selected_check = r""" - IF result->>'schema_version'='workstream.selected_post_submit_result.v1' + IF result->>'schema_version' IS NOT DISTINCT FROM + 'workstream.selected_post_submit_result.v1' AND result->>'outcome'='completed' THEN SELECT coalesce(jsonb_agg(jsonb_build_object( 'schema_version','post_submit_structural_result', @@ -1059,11 +1056,12 @@ def _replace_checker_terminal_custody() -> None: END IF; END IF; """ - replacement = selected_check + mismatch.replace( - "IF result->'member_results'", - "IF result->>'schema_version'<>'workstream.selected_post_submit_result.v1'\n" - " AND result->'member_results'", - ) + replacement = selected_check + """ + IF result->>'schema_version' IS DISTINCT FROM + 'workstream.selected_post_submit_result.v1' THEN + RAISE EXCEPTION 'checker result schema unavailable' USING ERRCODE='23514'; + END IF; +""" if definition.count(mismatch) != 1: raise RuntimeError("checker terminal member comparison shape changed") op.execute(definition.replace(mismatch, replacement)) diff --git a/backend/tests/conftest.py b/backend/tests/conftest.py index c034cff55..b7e1638a7 100644 --- a/backend/tests/conftest.py +++ b/backend/tests/conftest.py @@ -23,7 +23,7 @@ DDL_LOCK_DIRECTORY = Path("/tmp") # Match the PostgreSQL 16 engine used by Backend CI. Catalog identity rendering # differs across major versions; regenerate only after comparing actual objects. -EXPECTED_PUBLIC_SCHEMA_SHA256 = "8d9ba7f3f7b7701775b23257a4eb0ceb898fa6cf6bf615dd6f694da8b7ffb1b8" +EXPECTED_PUBLIC_SCHEMA_SHA256 = "d7e18ed618affa6c6dfaa0ad725ec63c87cb34241455626859bb5f1bc597d7ef" PROTECTED_TEST_TABLES = ( "actor_profile_migration_state", "alembic_version", diff --git a/backend/tests/test_alembic.py b/backend/tests/test_alembic.py index 628e319fc..cd90cc02f 100644 --- a/backend/tests/test_alembic.py +++ b/backend/tests/test_alembic.py @@ -204,6 +204,60 @@ def test_repeated_upgrade_head_preserves_current_database( assert after == before +def test_current_head_installs_selected_only_checker_custody( + isolated_database_env: str, migration_lock +) -> None: + """Current writers reject missing schemas and contain no executable catalogue tail.""" + config = _alembic_config() + with migration_lock(): + asyncio.run( + _execute(isolated_database_env, "drop schema public cascade; create schema public") + ) + command.upgrade(config, HEAD_REVISION) + + async def installed_functions() -> dict[str, str]: + connection = await asyncpg.connect(isolated_database_env.replace("+asyncpg", "")) + try: + rows = await connection.fetch( + "select p.proname,pg_get_functiondef(p.oid) as definition " + "from pg_proc p join pg_namespace n on n.oid=p.pronamespace " + "where n.nspname='public' and p.proname=any($1::text[])", + [ + "protect_checker_run_custody", + "protect_checker_result_custody", + "validate_checker_terminal_custody", + "submission_dispatch_valid", + ], + ) + return {row["proname"]: row["definition"] for row in rows} + finally: + await connection.close() + + definitions = asyncio.run(installed_functions()) + assert set(definitions) == { + "protect_checker_run_custody", + "protect_checker_result_custody", + "validate_checker_terminal_custody", + "submission_dispatch_valid", + } + for name in ( + "protect_checker_run_custody", + "protect_checker_result_custody", + "validate_checker_terminal_custody", + ): + assert "schema_version' IS DISTINCT FROM" in definitions[name] + assert "check_submission_packet" not in definitions["protect_checker_result_custody"] + assert "member_results' IS DISTINCT FROM members" not in definitions[ + "validate_checker_terminal_custody" + ] + assert "workstream.selected_post_submit_request.v1" in definitions[ + "submission_dispatch_valid" + ] + assert "selected_pre_submit_run_id IS NOT NULL" in definitions[ + "submission_dispatch_valid" + ] + + def test_current_head_installs_submission_lineage_contract( isolated_database_env: str, migration_lock ) -> None: From deca5835b37533bfaee08f7228b8324afab1cbc2 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 13:21:04 +0100 Subject: [PATCH 194/283] [PILOT-04] Delete obsolete checker catalogue contracts and planner exports --- .../pilot04-workstream-default-checker.md | 12 + backend/app/modules/checkers/api/__init__.py | 24 -- .../checkers/api/historical_post_submit.py | 316 --------------- .../checkers/api/policy_compilation.py | 27 -- .../app/modules/checkers/api/post_submit.py | 376 ------------------ .../app/modules/checkers/api/pre_submit.py | 351 ---------------- .../modules/checkers/post_submit_contracts.py | 32 -- 7 files changed, 12 insertions(+), 1126 deletions(-) delete mode 100644 backend/app/modules/checkers/api/historical_post_submit.py delete mode 100644 backend/app/modules/checkers/api/policy_compilation.py delete mode 100644 backend/app/modules/checkers/api/post_submit.py delete mode 100644 backend/app/modules/checkers/api/pre_submit.py delete mode 100644 backend/app/modules/checkers/post_submit_contracts.py diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 6426fdd72..3a60543e8 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -59,6 +59,18 @@ cleanup. ### Allowed +- Final dead-contract removal permits the obsolete CHECKERS modules + `api/pre_submit.py`, `api/post_submit.py`, `api/historical_post_submit.py`, + `api/policy_compilation.py` and `post_submit_contracts.py`, their unused exports + in `api/__init__.py`, and this record. Production consumers now use the sole + external contracts and canonical packet/value primitives. Remove these + unreferenced catalogue/planner/DTO implementations rather than aliases or + replacement decoders. Preserve current public ports, schema identifiers, + stored records, migrations, AUTH and immutable evidence. Acceptance is no + production reference to the removed modules, current app/contract imports, + Ruff, full collection, focused current-owner controls and the final native + journey. Architecture reviewers inspect the combined removal; risk is L1. + - Project POST-policy custody accepts only the locked external-image policy. This repair permits `backend/app/modules/projects/post_policy/custody.py` and this record: remove the obsolete catalogue union, read fallback and diff --git a/backend/app/modules/checkers/api/__init__.py b/backend/app/modules/checkers/api/__init__.py index f2f695c19..1e2fcea36 100644 --- a/backend/app/modules/checkers/api/__init__.py +++ b/backend/app/modules/checkers/api/__init__.py @@ -28,19 +28,6 @@ make_external_checker_execution_result, make_external_checker_registration_request, ) -from app.modules.checkers.api.pre_submit import ( - EffectivePreSubmissionExecutionPlan, - EffectivePreSubmissionPlanEntry, - EffectivePreSubmissionPlanError, - EffectivePreSubmissionPlanLineage, - EffectivePreSubmissionPlanningPort, - FrozenJsonObject, - PreSubmissionExecutionEntryFacts, - PreSubmissionExecutionFacts, - PreSubmissionInfrastructureUnavailableError, - PRE_SUBMISSION_RESULT_METADATA_KEYS, - validate_pre_submission_execution_facts, -) from app.modules.checkers.api.pre_submit_material import ( ALLOWED_PRE_SUBMIT_STORAGE_SCHEMES, SubmissionPacketView, @@ -54,18 +41,7 @@ __all__ = ( "ALLOWED_PRE_SUBMIT_STORAGE_SCHEMES", - "EffectivePreSubmissionExecutionPlan", - "EffectivePreSubmissionPlanEntry", - "EffectivePreSubmissionPlanError", - "EffectivePreSubmissionPlanLineage", - "EffectivePreSubmissionPlanningPort", - "FrozenJsonObject", - "PreSubmissionExecutionEntryFacts", - "PreSubmissionExecutionFacts", - "PreSubmissionInfrastructureUnavailableError", - "PRE_SUBMISSION_RESULT_METADATA_KEYS", "SubmissionPacketView", - "validate_pre_submission_execution_facts", "ExternalPreSubmitIsolationFacts", "ExternalPreSubmitMemberFacts", "SelectedPreSubmitExecutionFacts", diff --git a/backend/app/modules/checkers/api/historical_post_submit.py b/backend/app/modules/checkers/api/historical_post_submit.py deleted file mode 100644 index 05909f83d..000000000 --- a/backend/app/modules/checkers/api/historical_post_submit.py +++ /dev/null @@ -1,316 +0,0 @@ -"""Decode immutable stored pre-cutover policy facts; no catalogue construction.""" - -from __future__ import annotations - -import json -from collections.abc import Mapping -from typing import Annotated, Literal, Self -from uuid import UUID - -from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictInt, StrictStr, model_validator - -from app.core.hashing import canonical_json_hash - -Sha256 = Annotated[StrictStr, Field(pattern=r"^sha256:[0-9a-f]{64}$")] -Identifier = Annotated[ - StrictStr, Field(min_length=1, max_length=100, pattern=r"^[a-z][a-z0-9_.-]*$") -] -VersionNumber = Annotated[StrictInt, Field(ge=1, le=2_147_483_647)] -GuideVersion = Annotated[StrictStr, Field(min_length=1, max_length=50, pattern=r"\S")] -ResourceId = Annotated[UUID, Field(strict=True)] -ByteCount = Annotated[StrictInt, Field(ge=0, le=9_223_372_036_854_775_807)] -Severity = Literal["info", "low", "medium", "high", "critical"] -POST_SUBMIT_IMPLEMENTATION_ID = "workstream-structural" -POST_SUBMIT_COMPILER_ID = "workstream-post-submit-compiler" -POST_SUBMIT_CATALOGUE_ID = "workstream.post_submission_checkers" -POST_SUBMIT_CATALOGUE_SCHEMA = "post_submission_checker_capability_projection" -POST_SUBMIT_POLICY_SCHEMA = "post_submit_checker_policy" - - -class PostSubmitValue(BaseModel): - """Reject unknown fields and revalidate even previously constructed instances.""" - - model_config = ConfigDict(extra="forbid", frozen=True, revalidate_instances="always") - - -class EmptyPostSubmitConfiguration(PostSubmitValue): - """The stored pre-cutover structural configuration had no parameters.""" - - -class PostSubmitResourceLimits(PostSubmitValue): - """Code-owned input ceilings; deadline enforcement belongs to the executor.""" - - maximum_input_bytes: Literal[1_048_576] = 1_048_576 - maximum_result_bytes: Literal[4096] = 4096 - maximum_results: Literal[1] = 1 - maximum_generated_output_bytes: Literal[0] = 0 - deadline_ms: Literal[5000] = 5000 - phase_deadline_ms: Literal[45000] = 45000 - maximum_manifest_items: Literal[1024] = 1024 - maximum_evidence_items: Literal[1024] = 1024 - maximum_policy_items: Literal[256] = 256 - maximum_text_characters: Literal[65536] = 65536 - - @model_validator(mode="before") - @classmethod - def reject_noninteger_limits(cls, value: object) -> object: - """Exact integer literals must reject boolean, float and string coercion.""" - if isinstance(value, Mapping) and any(type(item) is not int for item in value.values()): - raise ValueError("post-submit limits require integers") - return value - - -class PostSubmitDefinition(PostSubmitValue): - """Registered implementation metadata, never a callable or authority grant.""" - - capability_id: Identifier - capability_version: Literal["v0.1"] = "v0.1" - implementation_version: Identifier - stage: Literal["post_submit"] = "post_submit" - platform_default: StrictBool - selectable: StrictBool - state: Literal["enabled", "disabled"] = "enabled" - disabled_behavior: Literal["unavailable"] = "unavailable" - execution_method: Literal["deterministic"] = "deterministic" - configuration_schema: Literal["post_submit_empty_configuration"] = ( - "post_submit_empty_configuration" - ) - input_schema: Literal["post_submit_structural_input"] = "post_submit_structural_input" - result_schema: Literal["post_submit_structural_result"] = "post_submit_structural_result" - order: Annotated[StrictInt, Field(ge=1, le=9)] - dependencies: tuple[Identifier, ...] = Field(default=(), max_length=8) - supported_claim: Literal[ - "packet_presence", - "policy_context_consistency", - "evidence_presence", - "evidence_structure", - "required_path_presence", - "forbidden_path_detection", - "attestation_presence", - "placeholder_signal_detection", - "criteria_presence", - ] - failure_code: Literal[ - "packet_fields_missing", - "policy_context_invalid", - "evidence_missing", - "evidence_structure_invalid", - "required_files_missing", - "forbidden_path_present", - "attestation_missing", - "placeholder_signal", - "acceptance_criteria_missing", - ] - failure_category: Literal["submission_structure", "task_configuration"] - failure_status: Literal["warning", "failed"] = "failed" - failure_severity: Literal["medium", "high"] = "high" - resources: PostSubmitResourceLimits = PostSubmitResourceLimits() - provider_recovery: Literal["none"] = "none" - required_output_roles: tuple[Identifier, ...] = Field(default=(), max_length=0) - - @model_validator(mode="after") - def validate_classification(self) -> Self: - """Require exactly one policy classification and consistent warning severity.""" - if len(self.dependencies) != len(set(self.dependencies)): - raise ValueError("post-submit definition has duplicate dependencies") - if self.platform_default == self.selectable: - raise ValueError("post-submit definition classification is invalid") - if (self.failure_status == "warning") != (self.failure_severity == "medium"): - raise ValueError("post-submit failure severity is invalid") - return self - - def validate_configuration(self, configuration: object) -> EmptyPostSubmitConfiguration: - """Use the exact registered closed schema, including for empty parameters.""" - self = PostSubmitDefinition.model_validate(self) - if self.state != "enabled": - raise ValueError("post-submit definition is unavailable") - return EmptyPostSubmitConfiguration.model_validate(configuration) - - -class PostSubmitCatalogue(PostSubmitValue): - """A canonical frozen snapshot; its hash proves identity, not installation.""" - - catalogue_id: Literal["workstream.post_submission_checkers"] = POST_SUBMIT_CATALOGUE_ID - source_version: Literal["v0.1"] = "v0.1" - schema_version: Literal["post_submission_checker_capability_projection"] = ( - POST_SUBMIT_CATALOGUE_SCHEMA - ) - definitions: tuple[PostSubmitDefinition, ...] = Field(min_length=1, max_length=9) - manifest_sha256: Sha256 - - @model_validator(mode="after") - def validate_snapshot(self) -> Self: - """Validate order/dependencies and all hash-bound definition semantics.""" - seen: set[str] = set() - orders: set[int] = set() - previous = 0 - for definition in self.definitions: - if definition.capability_id in seen or definition.order in orders: - raise ValueError("post-submit catalogue has duplicate definitions") - if definition.order <= previous or not set(definition.dependencies).issubset(seen): - raise ValueError("post-submit catalogue order or dependency is invalid") - seen.add(definition.capability_id) - orders.add(definition.order) - previous = definition.order - if self.manifest_sha256 != canonical_json_hash( - self.model_dump(mode="json", exclude={"manifest_sha256"}) - ): - raise ValueError("post-submit catalogue hash mismatch") - return self - - def definition(self, capability_id: str, version: str) -> PostSubmitDefinition: - """Select exactly the pinned definition, with no latest-version substitution.""" - self = PostSubmitCatalogue.model_validate(self) - for definition in self.definitions: - if (definition.capability_id, definition.capability_version) == ( - capability_id, - version, - ): - return definition - raise ValueError("post-submit capability or version is unavailable") - - -class PostSubmitPolicyEntry(PostSubmitValue): - """One ordered compiled entry pinned to an exact registered implementation.""" - - checker_id: Identifier - definition_version: Literal["v0.1"] - implementation_version: Identifier - classification: Literal["platform_default", "project_required", "project_warning"] - configuration: EmptyPostSubmitConfiguration - - -class CompiledPostSubmitPolicy(PostSubmitValue): - """Canonical policy body; its existing policy_hash remains the only plan hash.""" - - schema_version: Literal["post_submit_checker_policy"] = POST_SUBMIT_POLICY_SCHEMA - compiler_version: Literal["workstream-post-submit-compiler"] = POST_SUBMIT_COMPILER_ID - project_id: ResourceId - guide_version: GuideVersion - catalogue_id: Literal["workstream.post_submission_checkers"] = POST_SUBMIT_CATALOGUE_ID - catalogue_source_version: Literal["v0.1"] = "v0.1" - catalogue_schema_version: Literal["post_submission_checker_capability_projection"] = ( - POST_SUBMIT_CATALOGUE_SCHEMA - ) - catalogue_manifest_sha256: Sha256 - entries: tuple[PostSubmitPolicyEntry, ...] = Field(min_length=1, max_length=9) - blocking_severities: tuple[Severity, ...] = Field(min_length=2, max_length=5) - - @model_validator(mode="after") - def validate_unique_entries(self) -> Self: - """Never repeat a member or weaken the mandatory blocking floor.""" - if len({entry.checker_id for entry in self.entries}) != len(self.entries): - raise ValueError("post-submit policy has duplicate entries") - order = ("critical", "high", "medium", "low", "info") - expected = tuple(item for item in order if item in self.blocking_severities) - if expected != self.blocking_severities or not {"critical", "high"}.issubset(expected): - raise ValueError("post-submit policy blocking severities are invalid") - return self - - @property - def policy_hash(self) -> str: - """Hash the canonical body without adding a second persisted hash field.""" - return canonical_json_hash(self.model_dump(mode="json")) - - @property - def policy_body(self) -> dict: - """Return the one serialized policy representation.""" - return self.model_dump(mode="json") - - @property - def default_checkers(self) -> list[str]: - """Derive mandatory entries from the canonical policy.""" - return [ - entry.checker_id for entry in self.entries if entry.classification == "platform_default" - ] - - @property - def required_checkers(self) -> list[str]: - """Derive project-required entries from the canonical policy.""" - return [ - entry.checker_id for entry in self.entries if entry.classification == "project_required" - ] - - @property - def warning_checkers(self) -> list[str]: - """Derive advisory project entries from the canonical policy.""" - return [ - entry.checker_id for entry in self.entries if entry.classification == "project_warning" - ] - - @property - def execution_checkers(self) -> list[str]: - """Derive execution order without another stored plan.""" - return [entry.checker_id for entry in self.entries] - - def validate_sidecars( - self, - *, - required_checkers: list[str], - warning_checkers: list[str], - blocking_severities: list[str], - ) -> None: - """Reject persisted policy summaries that disagree with the canonical body.""" - if ( - required_checkers != self.required_checkers - or warning_checkers != self.warning_checkers - or blocking_severities != list(self.blocking_severities) - ): - raise ValueError("post-submit policy summaries disagree with canonical body") - - def validate_catalogue(self, catalogue: PostSubmitCatalogue) -> None: - """Validate exact pinned members, defaults, configuration and ordering.""" - self = CompiledPostSubmitPolicy.model_validate(self) - catalogue = PostSubmitCatalogue.model_validate(catalogue) - if self.catalogue_manifest_sha256 != catalogue.manifest_sha256: - raise ValueError("post-submit policy catalogue hash mismatch") - defaults = {item.capability_id for item in catalogue.definitions if item.platform_default} - actual_defaults: set[str] = set() - previous = 0 - seen: set[str] = set() - for entry in self.entries: - definition = catalogue.definition(entry.checker_id, entry.definition_version) - if entry.implementation_version != definition.implementation_version: - raise ValueError("post-submit implementation version mismatch") - if (entry.classification == "platform_default") != definition.platform_default: - raise ValueError("post-submit policy default classification mismatch") - definition.validate_configuration(entry.configuration) - if definition.order <= previous or not set(definition.dependencies).issubset(seen): - raise ValueError("post-submit policy order or dependency mismatch") - if definition.platform_default: - actual_defaults.add(entry.checker_id) - previous = definition.order - seen.add(entry.checker_id) - if defaults != actual_defaults: - raise ValueError("post-submit policy omits mandatory defaults") - - -def canonical_post_submit_bytes( - value: PostSubmitValue, *, exclude: set[str] | None = None, include: set[str] | None = None -) -> bytes: - """Use the canonical hash encoding for finite serialized-size checks.""" - return json.dumps( - value.model_dump(mode="json", exclude=exclude, include=include), - sort_keys=True, - separators=(",", ":"), - ensure_ascii=False, - allow_nan=False, - ).encode("utf-8") - - -def parse_locked_post_submit_policy( - body: object, - *, - project_id: str, - guide_version: str, - policy_hash: str, -) -> CompiledPostSubmitPolicy: - """Decode immutable pre-cutover policy evidence without restoring eligibility.""" - if not isinstance(body, dict): - raise ValueError("locked post-submit checker policy body is missing") - policy = CompiledPostSubmitPolicy.model_validate_json(json.dumps(body)) - if str(policy.project_id) != project_id or policy.guide_version != guide_version: - raise ValueError("locked post-submit checker policy guide context mismatch") - if policy.policy_hash != policy_hash: - raise ValueError("locked post-submit checker policy hash is invalid") - return policy diff --git a/backend/app/modules/checkers/api/policy_compilation.py b/backend/app/modules/checkers/api/policy_compilation.py deleted file mode 100644 index 269d2d99f..000000000 --- a/backend/app/modules/checkers/api/policy_compilation.py +++ /dev/null @@ -1,27 +0,0 @@ -"""Typed bundle-and-plan compilation; private implementation stays in CHECKERS.""" - -from dataclasses import dataclass -from typing import Any, Mapping, Protocol - -from app.modules.checkers.api.pre_submit import EffectivePreSubmissionPlanningPort - - -@dataclass(frozen=True) -class CompiledPreSubmitCheckerPolicy: - """Compiled bundle plus index projections persisted on policy rows.""" - - compiler_version: str - compiled_bundle: dict[str, Any] - compiled_bundle_hash: str - checker_names: list[str] - checker_configs: dict[str, Any] - - - -class PreSubmissionPolicyCompilationPort(EffectivePreSubmissionPlanningPort, Protocol): - """The CHECKERS owner supplies the exact default and external policy compilation.""" - - def compile_policy_bundle( - self, *, effective_policy: Mapping[str, object], effective_policy_hash: str, - ) -> CompiledPreSubmitCheckerPolicy: - """Compile the exact policy, raising ValueError for an unsupported contract.""" diff --git a/backend/app/modules/checkers/api/post_submit.py b/backend/app/modules/checkers/api/post_submit.py deleted file mode 100644 index e352909b6..000000000 --- a/backend/app/modules/checkers/api/post_submit.py +++ /dev/null @@ -1,376 +0,0 @@ -"""Detached, bounded post-submit phase facts; no persistence or authorization.""" - -from __future__ import annotations - -from typing import Annotated, Literal, Protocol, Self - -from pydantic import TypeAdapter, Field, StrictInt, StrictStr, model_validator - -from app.core.hashing import canonical_json_hash -from app.modules.checkers.api.historical_post_submit import ( - ByteCount, - CompiledPostSubmitPolicy, - GuideVersion, - Identifier, - PostSubmitCatalogue, - PostSubmitValue, - ResourceId, - Severity, - Sha256, - VersionNumber, - canonical_post_submit_bytes, -) - -Text = Annotated[StrictStr, Field(max_length=65_536)] -PathText = Annotated[StrictStr, Field(max_length=1000)] -KeyText = Annotated[StrictStr, Field(max_length=200)] -HashText = Annotated[StrictStr, Field(max_length=128)] -CounterValue = Annotated[StrictInt, Field(ge=0, le=1024)] - - -class PostSubmitManifestEntry(PostSubmitValue): - """Untrusted structural text remains representable so checkers can reject it.""" - - artifact: PathText - hash: HashText - notes: Annotated[StrictStr, Field(max_length=4096)] | None = None - size_bytes: ByteCount | None = None - - -class PostSubmitEvidenceEntry(PostSubmitValue): - """A finite evidence projection without arbitrary metadata or lazy relations.""" - - label: KeyText - uri: PathText | None = None - hash: HashText | None = None - type: KeyText - key: KeyText | None = None - policy_key: KeyText | None = None - evidence_key: KeyText | None = None - required_evidence_key: KeyText | None = None - - -class PostSubmitPolicyInputs(PostSubmitValue): - """Detached effective-policy values; the later owning resolver verifies derivation.""" - - required_evidence_keys: tuple[PathText, ...] = Field(default=(), max_length=256) - required_artifact_paths: tuple[PathText, ...] = Field(default=(), max_length=256) - forbidden_artifact_patterns: tuple[PathText, ...] = Field(default=(), max_length=256) - required_attestation_terms: tuple[PathText, ...] = Field(default=(), max_length=256) - - -class ObservedPostSubmitContext(PostSubmitValue): - """Nullable observed source fields permit precise missing-context outcomes.""" - - guide_version: GuideVersion | None = None - source_id: ResourceId | None = None - source_hash: Sha256 | None = None - effective_policy_id: ResourceId | None = None - effective_policy_hash: Sha256 | None = None - pre_policy_id: ResourceId | None = None - pre_policy_hash: Sha256 | None = None - post_policy_id: ResourceId | None = None - post_policy_version: GuideVersion | None = None - post_policy_hash: Sha256 | None = None - review_policy_id: ResourceId | None = None - review_generation: VersionNumber | None = None - review_hash: Sha256 | None = None - revision_policy_id: ResourceId | None = None - revision_generation: VersionNumber | None = None - revision_hash: Sha256 | None = None - - -class ExpectedPostSubmitContext(ObservedPostSubmitContext): - """Complete currently persisted task lineage expected on a submission.""" - - guide_version: GuideVersion - source_id: ResourceId - source_hash: Sha256 - effective_policy_id: ResourceId - effective_policy_hash: Sha256 - pre_policy_id: ResourceId - pre_policy_hash: Sha256 - post_policy_id: ResourceId - post_policy_version: GuideVersion - post_policy_hash: Sha256 - review_policy_id: ResourceId - review_generation: VersionNumber - review_hash: Sha256 - revision_policy_id: ResourceId - revision_generation: VersionNumber - revision_hash: Sha256 - - @model_validator(mode="after") - def validate_versions(self) -> Self: - """Preserve the existing post-policy/guide string-version relationship.""" - if self.post_policy_version != self.guide_version: - raise ValueError("post-submit guide and policy versions differ") - return self - - -class PostSubmissionStructuralInput(PostSubmitValue): - """Immutable detached structural facts retained in pre-cutover request records.""" - - schema_version: Literal["post_submit_structural_input"] = "post_submit_structural_input" - summary: Text - worker_attestation: Text - package_hash: HashText - criteria: Text - manifest: tuple[PostSubmitManifestEntry, ...] = Field(max_length=1024) - evidence: tuple[PostSubmitEvidenceEntry, ...] = Field(max_length=1024) - policy_inputs: PostSubmitPolicyInputs - observed_context: ObservedPostSubmitContext - - -# Keep the locked catalogue's 1 MiB request ceiling; reserve its finite envelope. -POST_SUBMIT_CONTENT_BYTE_LIMIT = 1_048_576 - 1024 - - -class PostSubmissionEvaluationContent(PostSubmitValue): - """Exact bounded content shared by admission and later identified execution.""" - - project_id: ResourceId - expected_context: ExpectedPostSubmitContext - catalogue: PostSubmitCatalogue - policy: CompiledPostSubmitPolicy - structural_input: PostSubmissionStructuralInput - - @model_validator(mode="after") - def validate_content(self) -> Self: - """Reject impossible content before any record identities are allocated.""" - if len(canonical_post_submit_bytes( - self, include=set(PostSubmissionEvaluationContent.model_fields), - )) > POST_SUBMIT_CONTENT_BYTE_LIMIT: - raise ValueError("post-submit content capacity exceeded") - if self.project_id != self.policy.project_id: - raise ValueError("post-submit request project mismatch") - if self.policy.guide_version != self.expected_context.guide_version: - raise ValueError("post-submit request guide version mismatch") - if self.policy.policy_hash != self.expected_context.post_policy_hash: - raise ValueError("post-submit request policy hash mismatch") - self.policy.validate_catalogue(self.catalogue) - return self - - -class PostSubmissionEvaluationRequest(PostSubmissionEvaluationContent): - """Hash-bound value consistency, never stored ownership or execution authority.""" - - schema_version: Literal["post_submit_evaluation_request"] = ( - "post_submit_evaluation_request" - ) - evaluation_request_id: ResourceId - evaluation_generation: VersionNumber - task_id: ResourceId - assignment_id: ResourceId - submission_id: ResourceId - submission_version: VersionNumber - content_id: ResourceId - binding_id: ResourceId - content_sha256: Sha256 - byte_count: ByteCount - request_sha256: Sha256 - - @model_validator(mode="after") - def validate_request(self) -> Self: - """Retain the full envelope ceiling and exact request digest.""" - if len(canonical_post_submit_bytes(self)) > 1_048_576: - raise ValueError("post-submit request capacity exceeded") - expected = canonical_json_hash(self.model_dump(mode="json", exclude={"request_sha256"})) - if self.request_sha256 != expected: - raise ValueError("post-submit request digest mismatch") - return self - - -class PostSubmitCounter(PostSubmitValue): - """Closed counters cannot carry arbitrary checker messages or references.""" - - key: Literal["artifact_count", "missing_count", "invalid_count", "matched_count"] - value: CounterValue - - -class PostSubmitMemberResult(PostSubmitValue): - """One sanitized structural outcome, validated against its pinned definition.""" - - schema_version: Literal["post_submit_structural_result"] = "post_submit_structural_result" - checker_id: Identifier - definition_version: Literal["v0.1"] = "v0.1" - implementation_version: Identifier - status: Literal["passed", "warning", "failed"] - code: Literal[ - "passed", - "packet_fields_missing", - "policy_context_invalid", - "evidence_missing", - "evidence_structure_invalid", - "required_files_missing", - "forbidden_path_present", - "attestation_missing", - "placeholder_signal", - "acceptance_criteria_missing", - ] - failure_category: Literal["none", "submission_structure", "task_configuration"] - severity: Severity - counters: tuple[PostSubmitCounter, ...] = Field(default=(), max_length=4) - - @model_validator(mode="after") - def validate_shape(self) -> Self: - """Check closed passing/failing combinations and finite counters.""" - passed_fields = ( - self.code == "passed", - self.failure_category == "none", - self.severity == "info", - ) - if self.status == "passed" and not all(passed_fields): - raise ValueError("post-submit passing result shape is invalid") - if self.status != "passed" and any(passed_fields): - raise ValueError("post-submit nonpassing result shape is invalid") - if len({item.key for item in self.counters}) != len(self.counters): - raise ValueError("post-submit result counters repeat") - return self - - def validate_catalogue(self, catalogue: PostSubmitCatalogue) -> None: - """Require exactly the registered implementation's claim-specific outcome.""" - self = PostSubmitMemberResult.model_validate(self) - definition = catalogue.definition(self.checker_id, self.definition_version) - if self.implementation_version != definition.implementation_version: - raise ValueError("post-submit result implementation mismatch") - if self.status != "passed" and ( - self.code, - self.failure_category, - self.status, - self.severity, - ) != ( - definition.failure_code, - definition.failure_category, - definition.failure_status, - definition.failure_severity, - ): - raise ValueError("post-submit result does not match registered claim") - - -class PostSubmissionEvaluationResult(PostSubmitValue): - """A typed phase result is not evidence that a durable result is current.""" - - schema_version: Literal["post_submit_evaluation_result"] = "post_submit_evaluation_result" - request_id: ResourceId - request_digest: Sha256 - attempt_id: ResourceId - evaluation_generation: VersionNumber - result_id: ResourceId - result_digest: Sha256 - outcome: Literal["completed", "infrastructure_failed"] - member_results: tuple[PostSubmitMemberResult, ...] = Field(max_length=9) - infrastructure_failure_code: ( - Literal[ - "capacity_exceeded", - "deadline_exceeded", - "material_unavailable", - "implementation_unavailable", - "invalid_output", - ] - | None - ) = None - - @model_validator(mode="after") - def validate_result(self) -> Self: - """Separate infrastructure failure and recompute exact result identity.""" - if self.outcome == "completed": - if not self.member_results or self.infrastructure_failure_code is not None: - raise ValueError("post-submit completed result shape is invalid") - elif self.member_results or self.infrastructure_failure_code is None: - raise ValueError("post-submit infrastructure result shape is invalid") - if self.result_digest != canonical_json_hash( - self.model_dump(mode="json", exclude={"result_digest"}) - ): - raise ValueError("post-submit result digest mismatch") - return self - - def validate_request(self, request: PostSubmissionEvaluationRequest) -> None: - """Bind the complete member list to the exact request without claiming custody.""" - self = PostSubmissionEvaluationResult.model_validate(self) - request = PostSubmissionEvaluationRequest.model_validate(request) - if (self.request_id, self.request_digest, self.evaluation_generation) != ( - request.evaluation_request_id, - request.request_sha256, - request.evaluation_generation, - ): - raise ValueError("post-submit result request mismatch") - if self.outcome == "completed": - expected = tuple( - (entry.checker_id, entry.definition_version, entry.implementation_version) - for entry in request.policy.entries - ) - actual = tuple( - (item.checker_id, item.definition_version, item.implementation_version) - for item in self.member_results - ) - if actual != expected: - raise ValueError("post-submit result members mismatch") - for member in self.member_results: - member.validate_catalogue(request.catalogue) - - -class PostSubmitCurrentResultReference(PostSubmitValue): - """A later owner-issued reference, with no self-authorizing is_current flag.""" - - schema_version: Literal["post_submit_current_result_reference"] = ( - "post_submit_current_result_reference" - ) - request_id: ResourceId - request_digest: Sha256 - attempt_id: ResourceId - evaluation_generation: VersionNumber - result_id: ResourceId - result_digest: Sha256 - - def validate_result(self, result: object) -> None: - """Match exact completed result identity; the repository must prove currentness.""" - self = PostSubmitCurrentResultReference.model_validate(self) - from app.modules.checkers.api.evaluation_contract import ( - validate_execution_result, - ) - - result = validate_execution_result(result) - names = ( - "request_id", - "request_digest", - "attempt_id", - "evaluation_generation", - "result_id", - "result_digest", - ) - if result.outcome != "completed" or any( - getattr(self, key) != getattr(result, key) for key in names - ): - raise ValueError("post-submit current reference result mismatch") - - -class PostSubmissionExecutionPort(Protocol): - """One complete locked phase command, never caller-selected individual checks.""" - - async def evaluate_post_submission( - self, request: PostSubmissionEvaluationRequest - ) -> PostSubmissionEvaluationResult: - """Evaluate one request after later owner resolution and authority checks.""" - ... - - -_REQUEST_FIELDS = { - name: TypeAdapter(field.rebuild_annotation()) - for name, field in PostSubmissionEvaluationRequest.model_fields.items() -} - -def make_post_submit_request(**fields: object) -> PostSubmissionEvaluationRequest: - """Compute identity and then validate every field; this grants no authority.""" - if "request_sha256" in fields: - raise ValueError("request identity is derived, not caller selected") - fields = { - name: _REQUEST_FIELDS[name].validate_python(value) if name in _REQUEST_FIELDS else value - for name, value in fields.items() - } - candidate = PostSubmissionEvaluationRequest.model_construct( - **fields, request_sha256="sha256:" + "0" * 64 - ) - body = candidate.model_dump(mode="json", exclude={"request_sha256"}) - fields["request_sha256"] = canonical_json_hash(body) - return PostSubmissionEvaluationRequest.model_validate(fields) diff --git a/backend/app/modules/checkers/api/pre_submit.py b/backend/app/modules/checkers/api/pre_submit.py deleted file mode 100644 index 07a9aa39a..000000000 --- a/backend/app/modules/checkers/api/pre_submit.py +++ /dev/null @@ -1,351 +0,0 @@ -"""Dependency-safe CHECKER contracts for pre-submission planning and results.""" - -from __future__ import annotations - -from dataclasses import dataclass -from typing import Any, Mapping, Protocol -from uuid import UUID - - -EFFECTIVE_PRE_SUBMISSION_PLAN_SCHEMA_VERSION = "effective_pre_submission_plan.v1" -EFFECTIVE_PRE_SUBMISSION_PLAN_HASH_DOMAIN = "workstream.effective_pre_submission_plan.v1" -ALLOWED_PRE_SUBMIT_STORAGE_SCHEMES = frozenset({"local", "s3"}) -_RESULT_MESSAGE_CODES = frozenset( - { - "advisory_disabled", - "attestation_missing", - "dependency_not_run", - "file_size_limit_exceeded", - "forbidden_artifact_present", - "package_size_limit_exceeded", - "archive_entry_limit_exceeded", - "archive_size_limit_exceeded", - "packaging_requirement_failed", - "passed", - "policy_attestation_missing", - "quality_signal_warning", - "required_evidence_missing", - "required_file_missing", - "sensitive_path_forbidden", - "storage_scheme_not_allowed", - "submission_packet_invalid", - } -) -PRE_SUBMISSION_RESULT_METADATA_KEYS = frozenset( - {"entry_count", "finding_count", "matched_category_count"} -) -_EXECUTION_STATUSES = frozenset( - {"passed", "warning", "advisory_disabled", "dependency_not_run", "failed"} -) - - -class EffectivePreSubmissionPlanError(ValueError): - """Reject a stale, ambiguous, or unavailable effective plan.""" - - -class PreSubmissionInfrastructureUnavailableError(EffectivePreSubmissionPlanError): - """Fail preparation closed when mandatory deployment capability is disabled.""" - - -@dataclass(frozen=True, slots=True) -class EffectivePreSubmissionPlanLineage: - """Exact server-locked lineage used to compile one checker plan.""" - - project_id: UUID - guide_id: UUID - guide_version: str - source_snapshot_id: UUID - source_snapshot_hash: str - effective_policy_id: UUID - effective_policy_hash: str - pre_submit_policy_id: UUID - pre_submit_policy_bundle_hash: str - - def __post_init__(self) -> None: - if any( - type(value) is not UUID - for value in ( - self.project_id, - self.guide_id, - self.source_snapshot_id, - self.effective_policy_id, - self.pre_submit_policy_id, - ) - ): - raise EffectivePreSubmissionPlanError("effective plan lineage id is invalid") - if type(self.guide_version) is not str or not 1 <= len(self.guide_version) <= 50: - raise EffectivePreSubmissionPlanError("effective plan guide version is invalid") - for value in ( - self.source_snapshot_hash, - self.effective_policy_hash, - self.pre_submit_policy_bundle_hash, - ): - _validate_sha256(value) - - def as_dict(self) -> dict[str, Any]: - return { - "project_id": str(self.project_id), - "guide_id": str(self.guide_id), - "guide_version": self.guide_version, - "source_snapshot_id": str(self.source_snapshot_id), - "source_snapshot_hash": self.source_snapshot_hash, - "effective_policy_id": str(self.effective_policy_id), - "effective_policy_hash": self.effective_policy_hash, - "pre_submit_policy_id": str(self.pre_submit_policy_id), - "pre_submit_policy_bundle_hash": self.pre_submit_policy_bundle_hash, - } - - -@dataclass(frozen=True, slots=True) -class FrozenJsonObject: - """Hashable deeply immutable projection of one canonical JSON object.""" - - items: tuple[tuple[str, Any], ...] - - def as_dict(self) -> dict[str, Any]: - return {key: thaw_json(value) for key, value in self.items} - - -@dataclass(frozen=True, slots=True) -class EffectivePreSubmissionPlanEntry: - """One ordered checker definition or locked-policy rule instance.""" - - definition_id: str - definition_version: str - public_name: str - phase: str - order: int - dependencies: tuple[str, ...] - classification: str - checker_definition_state: str - disabled_behavior: str - dispatch_kind: str - dispatch_capability: str - typed_inputs: tuple[str, ...] - result_schema: str - failure_code: str - resource_budget: tuple[tuple[str, int], ...] - policy_trace_source: str - rule_instance_id: str | None - configuration: FrozenJsonObject - configuration_sha256: str - - def as_dict(self) -> dict[str, Any]: - return { - "definition_id": self.definition_id, - "definition_version": self.definition_version, - "public_name": self.public_name, - "phase": self.phase, - "order": self.order, - "dependencies": list(self.dependencies), - "classification": self.classification, - "checker_definition_state": self.checker_definition_state, - "disabled_behavior": self.disabled_behavior, - "dispatch_kind": self.dispatch_kind, - "dispatch_capability": self.dispatch_capability, - "typed_inputs": list(self.typed_inputs), - "result_schema": self.result_schema, - "failure_code": self.failure_code, - "resource_budget": dict(self.resource_budget), - "policy_trace_source": self.policy_trace_source, - "rule_instance_id": self.rule_instance_id, - "configuration": self.configuration.as_dict(), - "configuration_sha256": self.configuration_sha256, - } - - -@dataclass(frozen=True, slots=True) -class EffectivePreSubmissionExecutionPlan: - """Canonical side-effect-free plan returned by the CHECKER capability.""" - - lineage: EffectivePreSubmissionPlanLineage - catalogue_id: str - catalogue_version: str - catalogue_schema_version: str - catalogue_manifest_sha256: str - entries: tuple[EffectivePreSubmissionPlanEntry, ...] - plan_sha256: str - - def as_dict(self) -> dict[str, Any]: - return effective_plan_body( - self.lineage, - self.catalogue_id, - self.catalogue_version, - self.catalogue_schema_version, - self.catalogue_manifest_sha256, - self.entries, - ) - - -class EffectivePreSubmissionPlanningPort(Protocol): - """CHECKER-owned deterministic planning capability.""" - - def compile_effective_plan( - self, - *, - lineage: EffectivePreSubmissionPlanLineage, - effective_policy: Mapping[str, object], - compiled_bundle: Mapping[str, object], - ) -> EffectivePreSubmissionExecutionPlan: - """Compile one plan from exact immutable locked-policy facts.""" - - -@dataclass(frozen=True, slots=True) -class SubmissionPacketView: - """Bounded contributor-authored text accompanying server-owned ZIP facts.""" - - summary: str - contributor_attestation: str - - def __post_init__(self) -> None: - for value in (self.summary, self.contributor_attestation): - if type(value) is not str or len(value.encode("utf-8")) > 64 * 1024: - raise ValueError("submission packet text is invalid") - - @property - def sha256(self) -> str: - """Commit to the same exact text at preparation and Submission creation.""" - from app.core.hashing import canonical_json_hash - - return canonical_json_hash({ - "summary": self.summary, - "contributor_attestation": self.contributor_attestation, - }) - - -@dataclass(frozen=True, slots=True) -class PreSubmissionExecutionEntryFacts: - """One bounded checker outcome without ART custody or persistence facts.""" - - dispatch_authority: str - definition_id: str - definition_version: str - public_name: str - policy_source: str - effective_plan_sha256: str - rule_instance_id: str | None - locked_policy_sha256: str - phase: str - order: int - classification: str - severity: str - checker_execution_status: str - failure_code: str | None - message_code: str - metadata: tuple[tuple[str, int], ...] - - -@dataclass(frozen=True, slots=True) -class PreSubmissionExecutionFacts: - """Bounded immutable CHECKER result safe for cross-module use.""" - - plan_sha256: str - eligible: bool - entries: tuple[PreSubmissionExecutionEntryFacts, ...] - - -def validate_pre_submission_execution_facts( - plan: EffectivePreSubmissionExecutionPlan, - execution: PreSubmissionExecutionFacts, -) -> None: - """Validate one bounded CHECKER result against its exact immutable plan.""" - if ( - type(execution.eligible) is not bool - or execution.plan_sha256 != plan.plan_sha256 - or len(execution.entries) != len(plan.entries) - ): - raise PreSubmissionInfrastructureUnavailableError( - "pre_submission_result_context_invalid" - ) - disqualified = False - for plan_entry, result in zip(plan.entries, execution.entries, strict=True): - expected_severity = ( - "warning" if plan_entry.classification == "advisory" else "blocking" - ) - status = result.checker_execution_status - if ( - result.dispatch_authority != "workstream.pre_submission_checker_catalogue" - or result.definition_id != plan_entry.definition_id - or result.definition_version != plan_entry.definition_version - or result.public_name != plan_entry.public_name - or result.policy_source != plan_entry.policy_trace_source - or result.effective_plan_sha256 != plan.plan_sha256 - or result.rule_instance_id != plan_entry.rule_instance_id - or result.locked_policy_sha256 != plan.lineage.effective_policy_hash - or result.phase != plan_entry.phase - or result.order != plan_entry.order - or result.classification != plan_entry.classification - or result.severity != expected_severity - or status not in _EXECUTION_STATUSES - or result.message_code not in _RESULT_MESSAGE_CODES - or result.failure_code - != (plan_entry.failure_code if status == "failed" else None) - or len(result.metadata) != len({key for key, _ in result.metadata}) - or any( - key not in PRE_SUBMISSION_RESULT_METADATA_KEYS - or type(value) is not int - or value < 0 - for key, value in result.metadata - ) - ): - raise PreSubmissionInfrastructureUnavailableError( - "pre_submission_result_context_invalid" - ) - disqualified = disqualified or status in {"failed", "dependency_not_run"} - if execution.eligible == disqualified: - raise PreSubmissionInfrastructureUnavailableError( - "pre_submission_result_context_invalid" - ) - - -def effective_plan_body( - lineage: EffectivePreSubmissionPlanLineage, - catalogue_id: str, - catalogue_version: str, - catalogue_schema_version: str, - catalogue_manifest_sha256: str, - entries: tuple[EffectivePreSubmissionPlanEntry, ...], -) -> dict[str, Any]: - """Return the canonical hash body for one public plan.""" - return { - "domain": EFFECTIVE_PRE_SUBMISSION_PLAN_HASH_DOMAIN, - "schema_version": EFFECTIVE_PRE_SUBMISSION_PLAN_SCHEMA_VERSION, - "lineage": lineage.as_dict(), - "catalogue": { - "id": catalogue_id, - "version": catalogue_version, - "schema_version": catalogue_schema_version, - "manifest_sha256": catalogue_manifest_sha256, - }, - "entries": [entry.as_dict() for entry in entries], - } - - -def freeze_json(value: Any) -> Any: - """Convert canonical JSON containers into immutable public values.""" - if isinstance(value, dict): - return FrozenJsonObject( - tuple((key, freeze_json(item)) for key, item in sorted(value.items())) - ) - if isinstance(value, list): - return tuple(freeze_json(item) for item in value) - return value - - -def thaw_json(value: Any) -> Any: - """Return a detached JSON-compatible projection.""" - if isinstance(value, FrozenJsonObject): - return value.as_dict() - if isinstance(value, tuple): - return [thaw_json(item) for item in value] - return value - - -def _validate_sha256(value: str) -> None: - if ( - type(value) is not str - or len(value) != 71 - or not value.startswith("sha256:") - or any(character not in "0123456789abcdef" for character in value[7:]) - ): - raise EffectivePreSubmissionPlanError("effective plan lineage hash is invalid") diff --git a/backend/app/modules/checkers/post_submit_contracts.py b/backend/app/modules/checkers/post_submit_contracts.py deleted file mode 100644 index c30fb18c4..000000000 --- a/backend/app/modules/checkers/post_submit_contracts.py +++ /dev/null @@ -1,32 +0,0 @@ -"""Owner-local construction helpers for hash-bound post-submit facts.""" - -from __future__ import annotations - -from pydantic import TypeAdapter - -from app.core.hashing import canonical_json_hash -from app.modules.checkers.api.post_submit import ( - PostSubmissionEvaluationResult, -) - - -_RESULT_FIELDS = { - name: TypeAdapter(field.rebuild_annotation()) - for name, field in PostSubmissionEvaluationResult.model_fields.items() -} - - -def make_post_submit_result(**fields: object) -> PostSubmissionEvaluationResult: - """Derive a result identity before validating its closed outcome shape.""" - if "result_digest" in fields: - raise ValueError("result identity is derived, not caller selected") - fields = { - name: _RESULT_FIELDS[name].validate_python(value) if name in _RESULT_FIELDS else value - for name, value in fields.items() - } - candidate = PostSubmissionEvaluationResult.model_construct( - **fields, result_digest="sha256:" + "0" * 64 - ) - body = candidate.model_dump(mode="json", exclude={"result_digest"}) - fields["result_digest"] = canonical_json_hash(body) - return PostSubmissionEvaluationResult.model_validate(fields) From 2f77226be355ba7d01d4ca63168f664dd78db66b Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 13:28:34 +0100 Subject: [PATCH 195/283] Bind selected POST results to every locked image --- .../checkers/api/selected_post_submit.py | 28 +++++- .../external/test_selected_post_submit.py | 97 +++++++++++++++++++ 2 files changed, 124 insertions(+), 1 deletion(-) diff --git a/backend/app/modules/checkers/api/selected_post_submit.py b/backend/app/modules/checkers/api/selected_post_submit.py index d37549983..46bcf9702 100644 --- a/backend/app/modules/checkers/api/selected_post_submit.py +++ b/backend/app/modules/checkers/api/selected_post_submit.py @@ -239,6 +239,28 @@ def validate_request( """Bind result identity and selected policy without claiming currentness.""" result = SelectedPostSubmissionEvaluationResult.model_validate(self) request = SelectedPostSubmissionEvaluationRequest.model_validate(request) + expected_members = tuple( + ( + order, + entry.requirement_id, + entry.registry.registry_entry_id, + entry.registry.entry_digest, + ) + for order, entry in enumerate(request.policy.entries) + ) + actual_members = ( + tuple( + ( + member.order, + member.requirement_id, + member.registry_entry_id, + member.registry_entry_digest, + ) + for member in result.execution.external_members + ) + if result.execution is not None + else () + ) if ( result.request_id, result.request_digest, @@ -249,7 +271,11 @@ def validate_request( request.evaluation_generation, ) or ( result.execution is not None - and result.execution.policy_sha256 != request.policy.policy_sha256 + and ( + result.execution.policy_sha256 != request.policy.policy_sha256 + or result.execution.required_external_count != len(expected_members) + or actual_members != expected_members + ) ): raise ValueError("selected POST result request mismatch") diff --git a/backend/tests/checkers/external/test_selected_post_submit.py b/backend/tests/checkers/external/test_selected_post_submit.py index c88a04396..ca0341ec2 100644 --- a/backend/tests/checkers/external/test_selected_post_submit.py +++ b/backend/tests/checkers/external/test_selected_post_submit.py @@ -3,6 +3,7 @@ from __future__ import annotations from contextlib import contextmanager +from dataclasses import replace import json from types import SimpleNamespace @@ -39,6 +40,7 @@ SelectedPostSubmitProcessor, ) from app.modules.checkers.api.selected_post_submit import ( + SelectedPostSubmitExecutionFacts, SelectedPostSubmitLockedContext, make_selected_post_submit_request, make_selected_post_submit_result, @@ -317,6 +319,101 @@ async def test_selected_post_request_and_result_bind_exact_locked_policy() -> No ) ) + missing = SelectedPostSubmitExecutionFacts( + policy_sha256=policy.policy_sha256, + required_external_count=0, + external_members=(), + ) + with pytest.raises(ValueError, match="request mismatch"): + make_selected_post_submit_result( + **result.model_dump(exclude={"result_digest", "execution"}), + execution=missing, + ).validate_request(request) + + member = execution.external_members[0] + extra = SelectedPostSubmitExecutionFacts( + policy_sha256=policy.policy_sha256, + required_external_count=2, + external_members=( + member, + replace(member, order=1, requirement_id="project.unrequested"), + ), + ) + with pytest.raises(ValueError, match="request mismatch"): + make_selected_post_submit_result( + **result.model_dump(exclude={"result_digest", "execution"}), + execution=extra, + ).validate_request(request) + + second = policy.entries[0].model_copy( + update={"requirement_id": "project.post_evidence.secondary"} + ) + two_policy_body = { + "schema_version": "external_post_submit_policy.v1", + "entries": [item.model_dump(mode="json") for item in (*policy.entries, second)], + } + two_policy = LockedExternalPostSubmitPolicy( + entries=(*policy.entries, second), + policy_sha256=canonical_json_hash(two_policy_body), + ) + two_request = _request(identity, two_policy) + two_execution = await SelectedPostSubmitProcessor( + policy=two_policy, + identity=identity, + execution=_Execution(), + ).evaluate(two_request, _MaterialView(execution_material(identity))) + reordered = SelectedPostSubmitExecutionFacts( + policy_sha256=two_policy.policy_sha256, + required_external_count=2, + external_members=( + replace(two_execution.external_members[1], order=0), + replace(two_execution.external_members[0], order=1), + ), + ) + with pytest.raises(ValueError, match="request mismatch"): + make_selected_post_submit_result( + request_id=two_request.evaluation_request_id, + request_digest=two_request.request_sha256, + attempt_id=identity.attempt_id, + evaluation_generation=two_request.evaluation_generation, + result_id=identity.result_id, + outcome="completed", + execution=reordered, + infrastructure_failure_code=None, + ).validate_request(two_request) + + foreign_registry = two_policy.entries[0].registry.model_copy( + update={"registry_entry_id": new_record_id()} + ) + foreign_entry = two_policy.entries[0].model_copy(update={"registry": foreign_registry}) + foreign_policy_body = { + "schema_version": "external_post_submit_policy.v1", + "entries": [ + item.model_dump(mode="json") for item in (foreign_entry, two_policy.entries[1]) + ], + } + foreign_policy = LockedExternalPostSubmitPolicy( + entries=(foreign_entry, two_policy.entries[1]), + policy_sha256=canonical_json_hash(foreign_policy_body), + ) + foreign_request = _request(identity, foreign_policy) + wrong_registry_execution = SelectedPostSubmitExecutionFacts( + policy_sha256=foreign_policy.policy_sha256, + required_external_count=2, + external_members=two_execution.external_members, + ) + with pytest.raises(ValueError, match="request mismatch"): + make_selected_post_submit_result( + request_id=foreign_request.evaluation_request_id, + request_digest=foreign_request.request_sha256, + attempt_id=identity.attempt_id, + evaluation_generation=foreign_request.evaluation_generation, + result_id=identity.result_id, + outcome="completed", + execution=wrong_registry_execution, + infrastructure_failure_code=None, + ).validate_request(foreign_request) + @pytest.mark.asyncio @pytest.mark.parametrize( From d08301617a0b21ce07e836004f875fc47f900221 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 13:29:49 +0100 Subject: [PATCH 196/283] Bind selected POST results to the pinned image digest --- .../checkers/api/selected_post_submit.py | 2 ++ .../external/test_selected_post_submit.py | 26 +++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/backend/app/modules/checkers/api/selected_post_submit.py b/backend/app/modules/checkers/api/selected_post_submit.py index 46bcf9702..2f8880613 100644 --- a/backend/app/modules/checkers/api/selected_post_submit.py +++ b/backend/app/modules/checkers/api/selected_post_submit.py @@ -245,6 +245,7 @@ def validate_request( entry.requirement_id, entry.registry.registry_entry_id, entry.registry.entry_digest, + entry.registry.image_digest, ) for order, entry in enumerate(request.policy.entries) ) @@ -255,6 +256,7 @@ def validate_request( member.requirement_id, member.registry_entry_id, member.registry_entry_digest, + member.isolation.platform_manifest_digest, ) for member in result.execution.external_members ) diff --git a/backend/tests/checkers/external/test_selected_post_submit.py b/backend/tests/checkers/external/test_selected_post_submit.py index ca0341ec2..5206b68ca 100644 --- a/backend/tests/checkers/external/test_selected_post_submit.py +++ b/backend/tests/checkers/external/test_selected_post_submit.py @@ -414,6 +414,32 @@ async def test_selected_post_request_and_result_bind_exact_locked_policy() -> No infrastructure_failure_code=None, ).validate_request(foreign_request) + wrong_image_execution = SelectedPostSubmitExecutionFacts( + policy_sha256=two_policy.policy_sha256, + required_external_count=2, + external_members=( + replace( + two_execution.external_members[0], + isolation=replace( + two_execution.external_members[0].isolation, + platform_manifest_digest="sha256:" + "b" * 64, + ), + ), + two_execution.external_members[1], + ), + ) + with pytest.raises(ValueError, match="request mismatch"): + make_selected_post_submit_result( + request_id=two_request.evaluation_request_id, + request_digest=two_request.request_sha256, + attempt_id=identity.attempt_id, + evaluation_generation=two_request.evaluation_generation, + result_id=identity.result_id, + outcome="completed", + execution=wrong_image_execution, + infrastructure_failure_code=None, + ).validate_request(two_request) + @pytest.mark.asyncio @pytest.mark.parametrize( From 75a02296d1fd7a77658933f347d1879ebd2f21a5 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 13:32:44 +0100 Subject: [PATCH 197/283] Require external policies at current database writers --- .../versions/0036_selected_checker_flow.py | 136 +++++++----------- backend/tests/conftest.py | 2 +- backend/tests/test_alembic.py | 15 ++ 3 files changed, 71 insertions(+), 82 deletions(-) diff --git a/backend/alembic/versions/0036_selected_checker_flow.py b/backend/alembic/versions/0036_selected_checker_flow.py index 5deb678d2..c84d23303 100644 --- a/backend/alembic/versions/0036_selected_checker_flow.py +++ b/backend/alembic/versions/0036_selected_checker_flow.py @@ -563,22 +563,24 @@ def _replace_guide_approval_custody() -> None: registry_row public.external_checker_registry_entries%rowtype; prior_requirement text; prior_capability text; prior_version text; begin - if jsonb_typeof(value)<>'object' or (select count(*) from jsonb_object_keys(value))<>4 - or value->>'schema_version'<>'external_checker_policies.v1' - or value->>'policies_sha256'<>expected_hash - or public.guide_proposal_hash(value-'policies_sha256')<>expected_hash then + if jsonb_typeof(value) is distinct from 'object' + or (select count(*) from jsonb_object_keys(value))<>4 + or value->>'schema_version' is distinct from 'external_checker_policies.v1' + or value->>'policies_sha256' is distinct from expected_hash + or public.guide_proposal_hash(value-'policies_sha256') is distinct from expected_hash then raise exception 'external checker policy envelope mismatch' using errcode='23514'; end if; - if jsonb_typeof(value->'pre_submit')<>'object' - or jsonb_typeof(value->'post_submit')<>'object' then + if jsonb_typeof(value->'pre_submit') is distinct from 'object' + or jsonb_typeof(value->'post_submit') is distinct from 'object' then raise exception 'external checker phase policy is missing' using errcode='23514'; end if; foreach phase_name in array array['pre_submit','post_submit'] loop policy:=value->phase_name; if (select count(*) from jsonb_object_keys(policy))<>(case when phase_name='pre_submit' then 4 else 3 end) - or policy->>'schema_version'<>'external_'||phase_name||'_policy.v1' - or public.guide_proposal_hash(policy-'policy_sha256')<>policy->>'policy_sha256' - or jsonb_typeof(policy->'entries')<>'array' then + or policy->>'schema_version' is distinct from 'external_'||phase_name||'_policy.v1' + or public.guide_proposal_hash(policy-'policy_sha256') is distinct from + policy->>'policy_sha256' + or jsonb_typeof(policy->'entries') is distinct from 'array' then raise exception 'external checker phase policy mismatch' using errcode='23514'; end if; if phase_name='pre_submit' and policy->'workstream_default' is distinct from @@ -588,30 +590,36 @@ def _replace_guide_approval_custody() -> None: end if; prior_requirement:=null; prior_capability:=null; prior_version:=null; for binding in select item from jsonb_array_elements(policy->'entries') item loop - if jsonb_typeof(binding)<>'object' or (select count(*) from jsonb_object_keys(binding))<>5 - or binding->>'stage'<>phase_name - or jsonb_typeof(binding->'configuration')<>'object' + if jsonb_typeof(binding) is distinct from 'object' + or (select count(*) from jsonb_object_keys(binding))<>5 + or binding->>'requirement_id' is null + or binding->>'stage' is distinct from phase_name + or jsonb_typeof(binding->'configuration') is distinct from 'object' or public.external_checker_registry_digest(binding->'configuration') - <>binding->>'configuration_sha256' then + is distinct from binding->>'configuration_sha256' then raise exception 'external checker policy binding mismatch' using errcode='23514'; end if; registry:=binding->'registry'; - if jsonb_typeof(registry)<>'object' or (select count(*) from jsonb_object_keys(registry))<>14 then + if jsonb_typeof(registry) is distinct from 'object' + or (select count(*) from jsonb_object_keys(registry))<>14 then raise exception 'external checker registry value mismatch' using errcode='23514'; end if; select * into registry_row from public.external_checker_registry_entries where id=(registry->>'registry_entry_id')::uuid and entry_digest=registry->>'entry_digest'; if not found - or registry_row.capability_id<>registry->>'capability_id' - or registry_row.capability_version<>registry->>'capability_version' - or registry_row.phase<>registry->>'phase' - or registry_row.phase<>phase_name - or registry_row.image_digest<>registry->>'image_digest' - or registry_row.registration_operation_id<>(registry->>'registration_operation_id')::uuid - or registry_row.registered_by_actor_profile_id<>(registry->>'registered_by_actor_profile_id')::uuid - or registry_row.authorization_decision_event_id<>(registry->>'authorization_decision_event_id')::uuid - or registry_row.created_at<>(registry->>'created_at')::timestamptz + or registry_row.capability_id is distinct from registry->>'capability_id' + or registry_row.capability_version is distinct from registry->>'capability_version' + or registry_row.phase is distinct from registry->>'phase' + or registry_row.phase is distinct from phase_name + or registry_row.image_digest is distinct from registry->>'image_digest' + or registry_row.registration_operation_id is distinct from + (registry->>'registration_operation_id')::uuid + or registry_row.registered_by_actor_profile_id is distinct from + (registry->>'registered_by_actor_profile_id')::uuid + or registry_row.authorization_decision_event_id is distinct from + (registry->>'authorization_decision_event_id')::uuid + or registry_row.created_at is distinct from (registry->>'created_at')::timestamptz or registry->'configuration_schema' is distinct from jsonb_build_object( 'schema_id',registry_row.configuration_schema_id, 'schema_version',registry_row.configuration_schema_version, @@ -657,9 +665,6 @@ def _replace_guide_approval_custody() -> None: declaration = " prior project_guide_proposal_approvals%rowtype;" if definition.count(declaration) != 1: raise RuntimeError("guide approval declaration shape changed") - definition = definition.replace( - declaration, declaration + "\n external_plan boolean;" - ) anchor = """ IF a.operation_id IS NULL THEN RAISE EXCEPTION 'immutable proposal approval operation missing' USING ERRCODE='23514'; END IF;""" @@ -668,8 +673,10 @@ def _replace_guide_approval_custody() -> None: definition = definition.replace( anchor, anchor + """ - external_plan:=a.effective_pre_submit_plan::jsonb->>'schema_version' - ='external_checker_policies.v1';""", + IF a.effective_pre_submit_plan::jsonb->>'schema_version' IS DISTINCT FROM + 'external_checker_policies.v1' THEN + RAISE EXCEPTION 'external proposal policy schema unavailable' USING ERRCODE='23514'; + END IF;""", ) selected_pre = """ SELECT * INTO pre FROM pre_submit_checker_policies WHERE id=a.pre_submit_policy_id;""" if definition.count(selected_pre) != 1: @@ -677,24 +684,21 @@ def _replace_guide_approval_custody() -> None: definition = definition.replace( selected_pre, selected_pre + """ - IF external_plan AND pre.compiled_bundle::jsonb IS DISTINCT FROM + IF pre.compiled_bundle::jsonb IS DISTINCT FROM a.effective_pre_submit_plan::jsonb->'pre_submit' THEN RAISE EXCEPTION 'external proposal PRE policy custody mismatch' USING ERRCODE='23514'; END IF; - IF external_plan AND NOT public.external_checker_locked_policies_valid( + IF NOT public.external_checker_locked_policies_valid( a.effective_pre_submit_plan::jsonb,a.effective_pre_submit_plan_hash) THEN RAISE EXCEPTION 'external proposal policy custody mismatch' USING ERRCODE='23514'; END IF;""", ) old_hashes = """ OR guide_proposal_hash(pre.compiled_bundle::jsonb) IS DISTINCT FROM pre.compiled_bundle_hash OR guide_proposal_hash(a.effective_pre_submit_plan::jsonb) IS DISTINCT FROM a.effective_pre_submit_plan_hash""" - new_hashes = """ OR (NOT external_plan AND ( - guide_proposal_hash(pre.compiled_bundle::jsonb) IS DISTINCT FROM pre.compiled_bundle_hash - OR guide_proposal_hash(a.effective_pre_submit_plan::jsonb) IS DISTINCT FROM a.effective_pre_submit_plan_hash)) - OR (external_plan AND ( - pre.compiled_bundle::jsonb IS DISTINCT FROM a.effective_pre_submit_plan::jsonb->'pre_submit' - OR NOT public.external_checker_locked_policies_valid( - a.effective_pre_submit_plan::jsonb,a.effective_pre_submit_plan_hash)))""" + new_hashes = """ OR pre.compiled_bundle::jsonb IS DISTINCT FROM + a.effective_pre_submit_plan::jsonb->'pre_submit' + OR NOT public.external_checker_locked_policies_valid( + a.effective_pre_submit_plan::jsonb,a.effective_pre_submit_plan_hash)""" if definition.count(old_hashes) != 1: raise RuntimeError("guide approval plan digest shape changed") definition = definition.replace(old_hashes, new_hashes) @@ -709,18 +713,7 @@ def _replace_guide_approval_custody() -> None: 'id',a.target_json->>'pre_catalogue_id','version',a.target_json->>'pre_catalogue_version', 'schema_version',a.target_json->>'pre_catalogue_schema_version', 'manifest_sha256',a.target_json->>'pre_catalogue_manifest_hash')""" - new_plan = """ OR (NOT external_plan AND ( - a.effective_pre_submit_plan::jsonb->'lineage' IS DISTINCT FROM jsonb_build_object( - 'project_id',a.project_id,'guide_id',a.guide_id, - 'guide_version',a.target_json->>'guide_version', - 'source_snapshot_id',a.target_json->>'source_snapshot_id', - 'source_snapshot_hash',a.target_json->>'source_snapshot_hash', - 'effective_policy_id',e.id,'effective_policy_hash',e.effective_policy_hash, - 'pre_submit_policy_id',pre.id,'pre_submit_policy_bundle_hash',pre.compiled_bundle_hash) - OR a.effective_pre_submit_plan::jsonb->'catalogue' IS DISTINCT FROM jsonb_build_object( - 'id',a.target_json->>'pre_catalogue_id','version',a.target_json->>'pre_catalogue_version', - 'schema_version',a.target_json->>'pre_catalogue_schema_version', - 'manifest_sha256',a.target_json->>'pre_catalogue_manifest_hash')))""" + new_plan = """""" if definition.count(old_plan) != 1: raise RuntimeError("guide approval legacy plan binding shape changed") op.execute(definition.replace(old_plan, new_plan)) @@ -732,16 +725,13 @@ def _replace_post_policy_custody() -> None: )).scalar_one() old_policy = """ OR p.policy_hash IS DISTINCT FROM guide_proposal_hash(p.policy_body::jsonb) OR p.policy_body->>'catalogue_manifest_sha256' IS DISTINCT FROM t->'proposal'->>'post_catalogue_manifest_hash'""" - new_policy = """ OR (p.policy_body->>'schema_version'='external_post_submit_policy.v1' AND ( - p.policy_hash IS DISTINCT FROM p.policy_body->>'policy_sha256' - OR p.policy_hash IS DISTINCT FROM guide_proposal_hash( - p.policy_body::jsonb-'policy_sha256') - OR p.policy_body::jsonb IS DISTINCT FROM - a.effective_pre_submit_plan::jsonb->'post_submit')) - OR (p.policy_body->>'schema_version'<>'external_post_submit_policy.v1' AND ( - p.policy_hash IS DISTINCT FROM guide_proposal_hash(p.policy_body::jsonb) - OR p.policy_body->>'catalogue_manifest_sha256' IS DISTINCT FROM - t->'proposal'->>'post_catalogue_manifest_hash'))""" + new_policy = """ OR p.policy_body->>'schema_version' IS DISTINCT FROM + 'external_post_submit_policy.v1' + OR p.policy_hash IS DISTINCT FROM p.policy_body->>'policy_sha256' + OR p.policy_hash IS DISTINCT FROM guide_proposal_hash( + p.policy_body::jsonb-'policy_sha256') + OR p.policy_body::jsonb IS DISTINCT FROM + a.effective_pre_submit_plan::jsonb->'post_submit'""" if definition.count(old_policy) != 1: raise RuntimeError("post policy custody shape changed") definition = definition.replace(old_policy, new_policy) @@ -762,19 +752,12 @@ def _replace_post_policy_custody() -> None: jsonb_array_elements(c.canonical_result::jsonb->'post_submit_bindings') binding WHERE c.id=NEW.compilation_id AND NOT EXISTS( SELECT 1 FROM jsonb_array_elements(p.policy_body::jsonb->'entries') entry - WHERE CASE WHEN p.policy_body->>'schema_version'='external_post_submit_policy.v1' - THEN entry->>'requirement_id'=binding->>'requirement_id' + WHERE entry->>'requirement_id'=binding->>'requirement_id' AND entry->>'stage'='post_submit' AND entry->'registry'->>'capability_id'=binding->>'capability_id' AND entry->'registry'->>'capability_version'=binding->>'capability_version' AND entry->'configuration'=COALESCE((SELECT jsonb_object_agg(parameter->>'name',parameter->'value') - FROM jsonb_array_elements(binding->'parameters') parameter),'{}'::jsonb) - ELSE entry->>'checker_id'=binding->>'capability_id' - AND entry->>'definition_version'=binding->>'capability_version' - AND entry->>'classification'='project_required' - AND entry->'configuration'=COALESCE((SELECT jsonb_object_agg(parameter->>'name',parameter->'value') - FROM jsonb_array_elements(binding->'parameters') parameter),'{}'::jsonb) - END)) THEN + FROM jsonb_array_elements(binding->'parameters') parameter),'{}'::jsonb))) THEN RAISE EXCEPTION 'post-policy compiled required binding missing' USING ERRCODE='23514'; END IF;""" old_extra = """ IF EXISTS( @@ -793,25 +776,16 @@ def _replace_post_policy_custody() -> None: END IF;""" new_extra = """ IF EXISTS( SELECT 1 FROM jsonb_array_elements(p.policy_body::jsonb->'entries') entry - WHERE (p.policy_body->>'schema_version'='external_post_submit_policy.v1' - OR entry->>'classification' IS DISTINCT FROM 'platform_default') - AND NOT EXISTS( + WHERE NOT EXISTS( SELECT 1 FROM project_guide_compilations c, jsonb_array_elements(c.canonical_result::jsonb->'post_submit_bindings') binding - WHERE c.id=NEW.compilation_id AND CASE - WHEN p.policy_body->>'schema_version'='external_post_submit_policy.v1' - THEN entry->>'requirement_id'=binding->>'requirement_id' + WHERE c.id=NEW.compilation_id + AND entry->>'requirement_id'=binding->>'requirement_id' AND entry->>'stage'='post_submit' AND entry->'registry'->>'capability_id'=binding->>'capability_id' AND entry->'registry'->>'capability_version'=binding->>'capability_version' AND entry->'configuration'=COALESCE((SELECT jsonb_object_agg(parameter->>'name',parameter->'value') - FROM jsonb_array_elements(binding->'parameters') parameter),'{}'::jsonb) - ELSE entry->>'checker_id'=binding->>'capability_id' - AND entry->>'definition_version'=binding->>'capability_version' - AND entry->>'classification'='project_required' - AND entry->'configuration'=COALESCE((SELECT jsonb_object_agg(parameter->>'name',parameter->'value') - FROM jsonb_array_elements(binding->'parameters') parameter),'{}'::jsonb) - END)) THEN + FROM jsonb_array_elements(binding->'parameters') parameter),'{}'::jsonb)) THEN RAISE EXCEPTION 'post-policy compiled selection not requested' USING ERRCODE='23514'; END IF;""" if definition.count(old_required) != 1 or definition.count(old_extra) != 1: diff --git a/backend/tests/conftest.py b/backend/tests/conftest.py index b7e1638a7..52e222404 100644 --- a/backend/tests/conftest.py +++ b/backend/tests/conftest.py @@ -23,7 +23,7 @@ DDL_LOCK_DIRECTORY = Path("/tmp") # Match the PostgreSQL 16 engine used by Backend CI. Catalog identity rendering # differs across major versions; regenerate only after comparing actual objects. -EXPECTED_PUBLIC_SCHEMA_SHA256 = "d7e18ed618affa6c6dfaa0ad725ec63c87cb34241455626859bb5f1bc597d7ef" +EXPECTED_PUBLIC_SCHEMA_SHA256 = "7e60f0c99a9968edf0e64781d7c9a8c8495fab3cfd3200a4d01fc09bdd6fa4e9" PROTECTED_TEST_TABLES = ( "actor_profile_migration_state", "alembic_version", diff --git a/backend/tests/test_alembic.py b/backend/tests/test_alembic.py index cd90cc02f..0397929b2 100644 --- a/backend/tests/test_alembic.py +++ b/backend/tests/test_alembic.py @@ -227,6 +227,9 @@ async def installed_functions() -> dict[str, str]: "protect_checker_result_custody", "validate_checker_terminal_custody", "submission_dispatch_valid", + "external_checker_locked_policies_valid", + "require_guide_proposal_approval", + "require_post_policy_operation", ], ) return {row["proname"]: row["definition"] for row in rows} @@ -239,6 +242,9 @@ async def installed_functions() -> dict[str, str]: "protect_checker_result_custody", "validate_checker_terminal_custody", "submission_dispatch_valid", + "external_checker_locked_policies_valid", + "require_guide_proposal_approval", + "require_post_policy_operation", } for name in ( "protect_checker_run_custody", @@ -256,6 +262,15 @@ async def installed_functions() -> dict[str, str]: assert "selected_pre_submit_run_id IS NOT NULL" in definitions[ "submission_dispatch_valid" ] + assert "external_plan" not in definitions["require_guide_proposal_approval"] + assert "->'catalogue'" not in definitions["require_guide_proposal_approval"] + assert "catalogue_manifest_sha256" not in definitions["require_post_policy_operation"] + assert "external_post_submit_policy.v1" in definitions[ + "require_post_policy_operation" + ] + assert "is distinct from 'external_checker_policies.v1'" in definitions[ + "external_checker_locked_policies_valid" + ].lower() def test_current_head_installs_submission_lineage_contract( From 614549df45600ae51b5cf5871cb5e0a0f24e5a02 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 12:48:37 +0100 Subject: [PATCH 198/283] test(pilot04): reconcile selected execution proof and remove obsolete catalogue contracts --- .../pilot04-workstream-default-checker.md | 66 +++++ .../post_submit/test_live_authority.py | 7 +- .../post_submit/test_receipt_custody.py | 16 +- .../authorization/post_submit/test_timeout.py | 6 +- .../task_locked_context/test_visibility.py | 18 +- .../execution/material_storage_helpers.py | 17 +- .../checkers/execution/storage_fixture.py | 40 +-- backend/tests/checkers/execution/support.py | 24 ++ .../checkers/execution/test_concurrency.py | 26 +- .../checkers/execution/test_coordination.py | 4 +- .../checkers/execution/test_execution.py | 59 ++--- .../execution/test_material_lineage.py | 6 +- .../tests/checkers/execution/test_storage.py | 78 +++--- backend/tests/checkers/post_submit/support.py | 132 +--------- .../post_submit/test_configuration.py | 25 -- .../checkers/post_submit/test_input_bounds.py | 197 --------------- .../post_submit/test_public_boundary.py | 8 +- .../checkers/post_submit/test_request.py | 87 ------- .../test_requirement_dispositions.py | 69 +----- .../post_submit/test_result_contract.py | 227 ------------------ backend/tests/reviews/decision/support.py | 11 +- .../tasks/post_submit_routing/support.py | 6 +- .../test_evaluation_currentness.py | 4 +- .../test_evaluation_guard.py | 5 +- backend/tests/test_agent_runtime.py | 4 +- .../tests/test_post_submit_materialization.py | 10 +- backend/tests/test_post_submit_selection.py | 10 +- 27 files changed, 246 insertions(+), 916 deletions(-) delete mode 100644 backend/tests/checkers/post_submit/test_configuration.py delete mode 100644 backend/tests/checkers/post_submit/test_input_bounds.py delete mode 100644 backend/tests/checkers/post_submit/test_request.py delete mode 100644 backend/tests/checkers/post_submit/test_result_contract.py diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 3a60543e8..47d269e84 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -699,3 +699,69 @@ short-root execution service checks pass (11 cases). Ruff and diff whitespace checks pass. This is author verification; independent review and the final clean combined PostgreSQL/MinIO/real-image journey remain required, as does full hosted CI. No migration or provider proof is claimed by this checkpoint. + +### Hosted selected-test reconciliation + +The hosted cutover artifacts expose obsolete catalogue test callers alongside +real owner defects. This test-only repair replaces live fixture references to +removed structural request/consumer/result contracts with selected external +contracts and deletes cases whose sole purpose is built-in catalogue execution. +Immutable retained data remains; no historical runtime/DTO path is restored. Authority, full lineage, lease/lock, cleanup, rollback, exact replay and +review-source proof must remain. No aliases, fallback providers, skips, selector, +timeout, migration or production edits are allowed. + +Allowed files: this record; backend/tests/checkers/execution/{support.py, +test_concurrency.py,test_coordination.py,test_execution.py}; +backend/tests/checkers/post_submit/{test_requirement_dispositions.py, +test_public_boundary.py}; backend/tests/authorization/post_submit/{test_live_authority.py, +test_timeout.py}; backend/tests/test_post_submit_materialization.py; +backend/tests/test_post_submit_selection.py; backend/tests/test_agent_runtime.py; +backend/tests/tasks/post_submit_routing/{support.py,test_evaluation_guard.py, +test_evaluation_currentness.py}; backend/tests/reviews/decision/support.py. +Parent/peer owns admin permission counts, TASK port fixture wiring, current +owner corrections, compilation coordinator awaits and migration baselines. + +Acceptance: updated live tests target the sole selected execution contract; +retained required checks keep their discriminating negatives; deleted obsolete +semantics have an explicit retained-proof mapping. Focused pure/current-contract +checks and native authority/material/locking cases are required, followed by the +lead's complete canonical suite. Risk is test-integrity: independent test-delta +review checks each deletion and preserves authority/evidence behavior. + +Additional causal test scope (peer confirmed disjoint): +backend/tests/checkers/execution/{test_material_lineage.py,test_storage.py, +material_storage_helpers.py,storage_fixture.py}; +backend/tests/authorization/post_submit/test_receipt_custody.py; +backend/tests/authorization/task_locked_context/test_visibility.py. These repair +selected result/member SQL fixture shapes and retain current closed-policy +visibility, immutable lineage and action receipt controls. The unsupported raw +envelope guard is retained at the current owner entry. Retained raw row migration +custody remains peer-owned proof. + +Explicit user cleanup supersedes prior retained-runtime/decoder test preservation. +Allowed additional files: backend/tests/checkers/post_submit/support.py and +removal of test_configuration.py, test_input_bounds.py, test_request.py and +test_result_contract.py in that directory. These obsolete tests enforce removed +historical catalogue/rule request contracts, not current selected execution. +Current selected PRE/POST/default tests retain exact closed input/result bounds, +phase/id/digest/stage binding, infrastructure/work separation and no acceptance. +Stored immutable data remains; no active historical DTO/factory/terminal executor +path is recreated. The unsupported raw envelope negative retains the no alternate +execution boundary. Exact module inventory deletion is coordinated with the lead +for the final canonical exhaustive suite; no test selection/cap is weakened. + +Deleted semantic families: built-in catalogue configuration/selection, old +structural request DTO field/aggregate bounds, nine-member generic result shapes, +and disabled mandatory catalogue readiness. Required current proof remains in +checkers/external/{test_contracts.py,test_policy.py,test_selected_pre_submit.py, +test_selected_post_submit.py}, test_workstream_default_checker.py and unified +project guide compilation contract tests (unknown/stale/stage/typed config). +Authority, callback lifetime, post-I/O revocation, cleanup failure, crossed native +lineage/receipts, exact replay, complete selected member closure and review-source +mutation tests are updated rather than removed. + +First focused pure scope passed 5 tests in 21.53s before the backend selected-only +API checkpoint; raw /tmp/pilot04-selected-test-pure-current.log. The wider caller +collection failure from module-level old output fixture imports is retained at +/tmp/pilot04-selected-test-pure-first.log. Full composed collection/native proof +remains required after peer source/shared fixture cleanup; this is not green CI. diff --git a/backend/tests/authorization/post_submit/test_live_authority.py b/backend/tests/authorization/post_submit/test_live_authority.py index 6f2cfd207..3bc4e1448 100644 --- a/backend/tests/authorization/post_submit/test_live_authority.py +++ b/backend/tests/authorization/post_submit/test_live_authority.py @@ -103,7 +103,7 @@ async def test_revoked_after_consumer_cannot_publish(tmp_path, isolated_database async with material_fixture(tmp_path, isolated_database_env) as h: reserved = await reserve(h) entered, release = asyncio.Event(), asyncio.Event() - original = execution._StructuralConsumer.evaluate + original = execution._SelectedExternalConsumer.evaluate calls = [] async def paused(consumer, request, material): @@ -113,7 +113,7 @@ async def paused(consumer, request, material): await release.wait() return value - monkeypatch.setattr(execution._StructuralConsumer, "evaluate", paused) + monkeypatch.setattr(execution._SelectedExternalConsumer, "evaluate", paused) operation = asyncio.create_task(live_executor(h).evaluate_post_submission(h.request)) try: await asyncio.wait_for(entered.wait(), 15) @@ -146,8 +146,7 @@ async def test_execution_identity_substitution_denies_before_material_access(tmp reservation = reservation.model_copy(update={field: getattr(foreign.lease.reservation, field)}) elif field == "project_id": request = change_request(request, project_id=other.request.project_id, - policy=other.request.policy, expected_context=other.request.expected_context, - structural_input=other.request.structural_input) + policy=other.request.policy, expected_context=other.request.expected_context) elif field == "evaluation_request_id": request = change_request(request, evaluation_request_id=other.request.evaluation_request_id) else: diff --git a/backend/tests/authorization/post_submit/test_receipt_custody.py b/backend/tests/authorization/post_submit/test_receipt_custody.py index 4fc4d7dcd..ceb30b649 100644 --- a/backend/tests/authorization/post_submit/test_receipt_custody.py +++ b/backend/tests/authorization/post_submit/test_receipt_custody.py @@ -15,7 +15,7 @@ ) from app.modules.checkers.execution_repository import ExecutionRepository, reservation from app.modules.checkers.models import CheckerRun, CheckerResult -from app.modules.checkers.post_submit_contracts import make_post_submit_result +from app.modules.checkers.api.selected_post_submit import make_selected_post_submit_result from app.modules.outbox.models import OutboxEvent from app.modules.tasks.models import AuditEvent from tests.checkers.execution.support import live_executor, reserve @@ -122,16 +122,16 @@ async def test_final_receipt_commits_only_exact_outcome( await wait_for_expiry(h, lease) lease = await next_lease(h) source = await final_facts(h, lease) - result = make_post_submit_result( + result = make_selected_post_submit_result( request_id=h.request.evaluation_request_id, request_digest=h.request.request_sha256, attempt_id=lease.reservation.attempt_id, result_id=lease.reservation.result_id, evaluation_generation=h.request.evaluation_generation, outcome="infrastructure_failed", - member_results=(), infrastructure_failure_code="deadline_exceeded", + execution=None, infrastructure_failure_code="deadline_exceeded", ) facts = source.model_copy(update={"result": result}) stored = facts if substitution == "result": - changed = make_post_submit_result(**(result.model_dump(exclude={"result_digest"}) | { + changed = make_selected_post_submit_result(**(result.model_dump(exclude={"result_digest"}) | { "infrastructure_failure_code": "invalid_output", })) stored = facts.model_copy(update={"result": changed}) @@ -181,14 +181,14 @@ async def test_terminal_receipt_digest_matches_database(tmp_path, isolated_datab update={ "material": None, "input_materialization_evidence_id": None, - "result": make_post_submit_result( + "result": make_selected_post_submit_result( request_id=h.request.evaluation_request_id, request_digest=h.request.request_sha256, attempt_id=lease.reservation.attempt_id, result_id=lease.reservation.result_id, evaluation_generation=h.request.evaluation_generation, outcome=outcome, - member_results=(), + execution=None, infrastructure_failure_code="material_unavailable", ), } @@ -218,14 +218,14 @@ async def test_final_receipt_independently_requires_execute_receipt( update={ "material": None, "input_materialization_evidence_id": None, - "result": make_post_submit_result( + "result": make_selected_post_submit_result( request_id=h.request.evaluation_request_id, request_digest=h.request.request_sha256, attempt_id=lease.reservation.attempt_id, result_id=lease.reservation.result_id, evaluation_generation=h.request.evaluation_generation, outcome="infrastructure_failed", - member_results=(), + execution=None, infrastructure_failure_code="material_unavailable", ), } diff --git a/backend/tests/authorization/post_submit/test_timeout.py b/backend/tests/authorization/post_submit/test_timeout.py index 61954f3fd..f8d74fdd4 100644 --- a/backend/tests/authorization/post_submit/test_timeout.py +++ b/backend/tests/authorization/post_submit/test_timeout.py @@ -29,7 +29,7 @@ async def paused(consumer, request, material): error = RuntimeError if consumer_failure == "runtime_error" else TimeoutError raise error("consumer failed after abort") from None raise - monkeypatch.setattr(execution._StructuralConsumer, "evaluate", paused) + monkeypatch.setattr(execution._SelectedExternalConsumer, "evaluate", paused) # Arm the actual asyncio deadline after the consumer enters, avoiding a # machine-speed race between setup queries and the short test deadline. deadlines = controlled_deadline(monkeypatch, execution) @@ -74,7 +74,7 @@ def timeout(seconds): if seconds == 12345: deadlines.append(timer) return timer - monkeypatch.setattr(execution, "EXECUTION_TIMEOUT_SECONDS", 12345) + monkeypatch.setattr(execution.PostSubmissionExecutor, "_execution_budget_seconds", staticmethod(lambda request: 12345)) monkeypatch.setattr(asyncio, "timeout", timeout) return deadlines @@ -110,7 +110,7 @@ def failed_workspace(name): if failure == "release": monkeypatch.setattr(h.manager, "release", failed_release) else: - monkeypatch.setattr(execution._StructuralConsumer, "evaluate", paused_consumer) + monkeypatch.setattr(execution._SelectedExternalConsumer, "evaluate", paused_consumer) if failure == "workspace": monkeypatch.setattr(h.manager, "_cleanup_workspace_sync", failed_workspace) else: diff --git a/backend/tests/authorization/task_locked_context/test_visibility.py b/backend/tests/authorization/task_locked_context/test_visibility.py index 9c5be7f8d..68565b642 100644 --- a/backend/tests/authorization/task_locked_context/test_visibility.py +++ b/backend/tests/authorization/task_locked_context/test_visibility.py @@ -1,17 +1,15 @@ """Historical locked facts remain readable in every stored lifecycle state.""" -import json - import pytest from sqlalchemy import select from app.db import session as db_session from app.modules.authorization.models import AdminRoleGrant -from app.modules.checkers.api.historical_post_submit import CompiledPostSubmitPolicy +from app.modules.checkers.api.external_policy import validate_stored_external_post_policy from app.modules.tasks.lifecycle import ALLOWED_TASK_TRANSITIONS from app.modules.tasks.models import WorkstreamTask from tests.authorization.task_locked_context.support import KINDS, grant_for, path from tests.authorization.task_reads.support import task_case -from tests.tasks.test_locked_context import REFERENCE_FIELDS, SUMMARY, SUMMARY_FIELDS +from tests.tasks.test_locked_context import REFERENCE_FIELDS, SUMMARY @pytest.mark.parametrize("kind", KINDS) @@ -23,9 +21,11 @@ async def test_locked_context_exact_fields_all_states_and_corrupt_custody(admin_ stored = await session.get(WorkstreamTask, str(task)) expected = {field: str(getattr(stored, "id" if field == "task_id" else field)) if field.endswith("_id") else getattr(stored, field) for field in REFERENCE_FIELDS} - compiled = CompiledPostSubmitPolicy.model_validate_json(json.dumps(stored.locked_post_submit_checker_policy_body)) - summary = {field: getattr(compiled, field) for field in SUMMARY_FIELDS} - summary["blocking_severities"] = list(compiled.blocking_severities) + compiled = validate_stored_external_post_policy(stored.locked_post_submit_checker_policy_body) + required = [item.registry.capability_id for item in compiled.entries] + summary = dict(schema_version=compiled.schema_version, default_checkers=[], + required_checkers=required, warning_checkers=[], + execution_checkers=required, blocking_severities=["critical", "high"]) expected |= {SUMMARY: summary} if kind == "management" else {} states = {state for transition in ALLOWED_TASK_TRANSITIONS for state in transition} assert len(states) == 9 @@ -40,9 +40,9 @@ async def test_locked_context_exact_fields_all_states_and_corrupt_custody(admin_ assert response.json() == expected async with factory() as session, session.begin(): stored = await session.get(WorkstreamTask, str(task)) - stored.locked_post_submit_checker_policy_body = {**stored.locked_post_submit_checker_policy_body, "blocking_severities": []} + stored.locked_post_submit_checker_policy_body = {**stored.locked_post_submit_checker_policy_body, "policy_sha256": "sha256:" + "0" * 64} async with factory() as independent: - assert (await independent.get(WorkstreamTask, str(task))).locked_post_submit_checker_policy_body["blocking_severities"] == [] + assert (await independent.get(WorkstreamTask, str(task))).locked_post_submit_checker_policy_body["policy_sha256"] == "sha256:" + "0" * 64 response = await admin_access.signed.client.get(path(kind, project, task), headers=admin_access.target.headers) assert response.status_code == 422, response.text assert response.json()["error"]["code"] == "task_locked_context_invalid" diff --git a/backend/tests/checkers/execution/material_storage_helpers.py b/backend/tests/checkers/execution/material_storage_helpers.py index 84f82e4e6..da2037989 100644 --- a/backend/tests/checkers/execution/material_storage_helpers.py +++ b/backend/tests/checkers/execution/material_storage_helpers.py @@ -40,14 +40,19 @@ async def stage_terminal(session, facts, material, evidence_id): request, result = facts.request, facts.result run = await session.get(CheckerRun, str(result.attempt_id)) classification = classify_result(request, result) - for order, member in enumerate(result.member_results): + for member in result.execution.external_members if result.execution else (): await session.execute(insert(CheckerResult).values( id=str(new_record_id()), checker_run_id=run.id, task_id=run.task_id, - submission_id=run.submission_id, member_order=order, checker_name=member.checker_id, - definition_version=member.definition_version, implementation_version=member.implementation_version, - status=member.status, severity=member.severity, code=member.code, - failure_category=member.failure_category, - counters=[item.model_dump(mode="json") for item in member.counters], + submission_id=run.submission_id, member_order=member.order, + checker_name=member.requirement_id, + definition_version=member.result.schema_version, + implementation_version=member.registry_entry_digest, + status=member.result.verdict, + severity="info" if member.result.verdict == "passed" else "error", + code=("passed" if member.result.verdict == "passed" else + member.result.findings[0].code if member.result.findings else "invalid_output"), + failure_category="none" if member.result.verdict == "passed" else "submission_structure", + counters=[], )) event_id = None if result.outcome == "completed": diff --git a/backend/tests/checkers/execution/storage_fixture.py b/backend/tests/checkers/execution/storage_fixture.py index efd6a3f0f..85a618fdc 100644 --- a/backend/tests/checkers/execution/storage_fixture.py +++ b/backend/tests/checkers/execution/storage_fixture.py @@ -1,18 +1,14 @@ """Closed history with canonical stored ART lineage and real fixed-service phase authority.""" -from app.modules.checkers.api.post_submit import make_post_submit_request +from app.modules.checkers.api.selected_post_submit import make_selected_post_submit_request from uuid import UUID from app.modules.actors.api import ServiceIdentity from app.modules.artifacts.models import SubmissionBundleAdmission from app.modules.checkers.api.execution import ExecuteFacts, FinalizeFacts, VerifiedMaterialFacts -from app.modules.checkers.api.post_submit import PostSubmitMemberResult from app.adapters.checkers import evaluation_coordinator -from app.modules.checkers.post_submit_contracts import ( - make_post_submit_result, -) from app.modules.tasks.models import Submission -from tests.checkers.post_submit.test_result_contract import result as value_result +from tests.checkers.execution.support import selected_result from tests.checkers.execution.support import live_executor, provision_post_submit_service from types import SimpleNamespace @@ -30,7 +26,7 @@ async def storage_request(session, submission_id, *, generation=1): return stored.request body = stored.request.model_dump(exclude={"request_sha256"}) body.update(evaluation_generation=generation, evaluation_request_id=new_record_id()) - return make_post_submit_request(**body) + return make_selected_post_submit_request(**body) async def seed_storage_run(factory, submission_id, *, failures=(), state="completed", generation=1): @@ -46,30 +42,12 @@ async def seed_storage_run(factory, submission_id, *, failures=(), state="comple if state == "running": return str(receipt.attempt_id) assert state in {"completed", "infrastructure_failed"} - members = [] - for member in value_result(request).member_results: - if member.checker_id in failures: - definition = request.catalogue.definition(member.checker_id, member.definition_version) - member = PostSubmitMemberResult( - checker_id=member.checker_id, - definition_version=member.definition_version, - implementation_version=member.implementation_version, - status=definition.failure_status, - severity=definition.failure_severity, - code=definition.failure_code, - failure_category=definition.failure_category, - ) - members.append(member) - assert set(failures).issubset({member.checker_id for member in members}) - result = make_post_submit_result( - request_id=request.evaluation_request_id, - request_digest=request.request_sha256, - attempt_id=receipt.attempt_id, - result_id=receipt.result_id, - evaluation_generation=generation, + assert not failures, "removed built-in checker failures are not selected image evidence" + result = selected_result( + request, attempt_id=receipt.attempt_id, result_id=receipt.result_id, outcome=state, - member_results=tuple(members) if state == "completed" else (), - infrastructure_failure_code=None if state == "completed" else "deadline_exceeded", + **({"execution": None, "infrastructure_failure_code": "deadline_exceeded"} + if state == "infrastructure_failed" else {}), ) async with factory() as session: submission = await session.get(Submission, str(submission_id)) @@ -149,7 +127,7 @@ async def authorize_stored_material(factory, execution, material): MaterializationFacts( execution=execution, material=material, - evidence_id=UUID(a.pre_submit_evidence_set_id), + evidence_id=UUID(a.selected_pre_submit_run_id), verification_receipt_id=UUID(v.id), verification_job_id=UUID(v.verification_job_id), verification_generation=v.execution_generation, diff --git a/backend/tests/checkers/execution/support.py b/backend/tests/checkers/execution/support.py index 6d485926a..45302b299 100644 --- a/backend/tests/checkers/execution/support.py +++ b/backend/tests/checkers/execution/support.py @@ -63,6 +63,30 @@ async def execute(self, request, grant): ) +def selected_result(source, **changes): + """Supply closed empty-policy evidence for owner and material boundary tests.""" + from app.modules.checkers.api.selected_post_submit import ( + SelectedPostSubmissionEvaluationRequest, + SelectedPostSubmitExecutionFacts, + make_selected_post_submit_result, + ) + + source = SelectedPostSubmissionEvaluationRequest.model_validate(source) + assert source.policy.entries == (), "external members require actual image execution" + fields = dict( + request_id=source.evaluation_request_id, + request_digest=source.request_sha256, + attempt_id=new_record_id(), + evaluation_generation=source.evaluation_generation, + result_id=new_record_id(), + outcome="completed", + execution=SelectedPostSubmitExecutionFacts(source.policy.policy_sha256, 0, ()), + infrastructure_failure_code=None, + ) + fields.update(changes) + return make_selected_post_submit_result(**fields) + + class ForbiddenPostSubmission: async def evaluate_post_submission(self, request): pytest.fail("pre-submit-only test entered post-submit execution") diff --git a/backend/tests/checkers/execution/test_concurrency.py b/backend/tests/checkers/execution/test_concurrency.py index 49af8bf6e..79965db5b 100644 --- a/backend/tests/checkers/execution/test_concurrency.py +++ b/backend/tests/checkers/execution/test_concurrency.py @@ -15,16 +15,34 @@ from app.adapters.checkers import evaluation_coordinator from app.modules.checkers.models import CheckerRun from tests.checkers.post_submit.support import change_request -from tests.checkers.post_submit.test_result_contract import result +from tests.checkers.execution.support import selected_result as result from tests.post_submit_materialization_helpers import material_fixture from .support import reserve, live_executor -async def final_facts(h, lease): +async def final_facts(h, lease, *, verdict="passed"): """A controlled closed result for lease races, not a byte-evaluation assertion.""" from tests.checkers.execution.storage_fixture import authorize_stored_material from app.modules.checkers.api.execution import ExecuteFacts + if h.request.policy.entries: + from dataclasses import asdict + from .support import ControlledSelectedExecution + + consumer = live_executor( + h, selected_execution=ControlledSelectedExecution(verdict=verdict), + )._consumer(h.request, lease) + materialized = await h.service.materialize(ExecuteFacts(request=h.request, lease=lease), consumer) + material = VerifiedMaterialFacts(**{ + key: value for key, value in asdict(materialized).items() + if key not in {"evaluation", "input_materialization_evidence_id"} + }) + return FinalizeFacts( + request=h.request, lease=lease, result=materialized.evaluation, + material=material, + input_materialization_evidence_id=materialized.input_materialization_evidence_id, + output_binding_ids=(), + ) material = VerifiedMaterialFacts( submission_id=h.request.submission_id, submission_version=h.request.submission_version, @@ -232,14 +250,14 @@ async def materialize(self, request, consumer): await probe("before_bytes") return await h.service.materialize(request, consumer) - original = execution._StructuralConsumer.evaluate + original = execution._SelectedExternalConsumer.evaluate async def evaluate(consumer, request, material): assert material.entries await probe("inside_consumer") return await original(consumer, request, material) - monkeypatch.setattr(execution._StructuralConsumer, "evaluate", evaluate) + monkeypatch.setattr(execution._SelectedExternalConsumer, "evaluate", evaluate) executor = live_executor(h) executor._execute_authority = TrackingAuthority executor._materialization = MaterializationProbe() diff --git a/backend/tests/checkers/execution/test_coordination.py b/backend/tests/checkers/execution/test_coordination.py index a06835fd6..bec05fcf2 100644 --- a/backend/tests/checkers/execution/test_coordination.py +++ b/backend/tests/checkers/execution/test_coordination.py @@ -16,9 +16,7 @@ async def test_reservation_replay_rejects_changed_envelope(tmp_path, isolated_da async with material_fixture(tmp_path, isolated_database_env) as h: first = await reserve(h) assert await reserve(h) == first - changed = change_request(h.request, structural_input=h.request.structural_input.model_copy( - update={"summary": "Changed request with the same exact owner lineage."} - )) + changed = change_request(h.request, byte_count=h.request.byte_count + 1) with pytest.raises(CheckerRequestConflict, match="checker_request_conflict"): await reserve(h, changed) async with h.factory() as session: diff --git a/backend/tests/checkers/execution/test_execution.py b/backend/tests/checkers/execution/test_execution.py index 2c5145a57..37a1e146e 100644 --- a/backend/tests/checkers/execution/test_execution.py +++ b/backend/tests/checkers/execution/test_execution.py @@ -5,7 +5,6 @@ from app.modules.checkers.api.execution import CheckerExecutionUnavailable, COMPLETION_EVENT from app.adapters.checkers import evaluation_coordinator -from app.core.identifiers import new_record_id from app.modules.checkers.models import CheckerRun, CheckerResult from app.modules.outbox.models import OutboxEvent from tests.post_submit_materialization_helpers import material_fixture @@ -105,9 +104,9 @@ async def observe_receipt(*args, **kwargs): ) ) assert tuple(row.checker_name for row in rows) == tuple( - m.checker_id for m in result.member_results + m.registry_entry_id for m in result.execution.external_members ) - assert len(rows) == len(h.request.policy.entries) + assert len(rows) == len(h.request.policy.entries) == 0 event = await session.scalar( select(OutboxEvent).where(OutboxEvent.event_type == COMPLETION_EVENT) ) @@ -118,28 +117,21 @@ async def observe_receipt(*args, **kwargs): assert list((h.scratch / "workspaces").iterdir()) == [] -async def test_unresolved_legacy_request_is_refused_without_leasing_or_materialization( - tmp_path, isolated_database_env, autoflush_clock -): - async with material_fixture(tmp_path, isolated_database_env) as h: - await reserve(h) - executor = live_executor(h) - with pytest.raises(CheckerExecutionUnavailable, match="checker_legacy_execution_retired"): - await executor.evaluate_post_submission(h.request) - assert h.store.opens == [] - async with h.factory() as session, session.begin(): - run = await session.scalar(select(CheckerRun)) - assert run.status == "queued" - assert run.worker_lease_id is None - assert run.execute_evidence_id is None - assert ( - await session.scalar( - select(func.count()) - .select_from(OutboxEvent) - .where(OutboxEvent.event_type == COMPLETION_EVENT) - ) - == 0 - ) +async def test_unsupported_request_envelope_never_reaches_execution(monkeypatch): + """Raw obsolete or arbitrary envelopes cannot claim, materialize or publish.""" + import app.modules.checkers.execution as owner + + async def forbidden_claim(request): + pytest.fail("unsupported request reached execution lease or authority") + + executor = owner.PostSubmissionExecutor( + sessions=None, execute_authority=None, finalize_authority=None, + materialization=None, outbox=None, + ) + monkeypatch.setattr(executor, "_claim", forbidden_claim) + for schema in ("workstream.post_submit_request.v1", "arbitrary_request.v1"): + with pytest.raises(ValueError): + await executor.evaluate_post_submission({"schema_version": schema}) @pytest.mark.parametrize("substitution", ["prepared", "receipt"]) @@ -380,7 +372,7 @@ async def retain_finalization(facts): result = await finalize(pending[0]) assert result.outcome == "infrastructure_failed" assert result.infrastructure_failure_code == "material_unavailable" - assert result.member_results == () + assert result.execution is None assert not h.preparation._active assert list((h.scratch / "workspaces").iterdir()) == [] opened = len(h.store.opens) @@ -415,17 +407,6 @@ async def test_nonrecordable_material_failure_leaves_attempt_recoverable( ) async with material_fixture(tmp_path, isolated_database_env) as h: - if failure == "cleanup": - from tests.checkers.post_submit.support import change_request - - h.request = change_request( - h.request, - evaluation_request_id=new_record_id(), - evaluation_generation=2, - structural_input=h.request.structural_input.model_copy( - update={"manifest": ()}, - ), - ) reservation = await reserve(h) executor = live_executor(h) if failure == "authority": @@ -447,6 +428,10 @@ async def fail_close(prepared): await original_close(prepared) raise ArtifactScratchIntegrityError("controlled close failure") + async def fail_inspect(prepared, inspector): + raise PostSubmissionMaterializationFailure("post_submit_material_manifest_mismatch") + + monkeypatch.setattr(PreparedArtifact, "inspect", fail_inspect) monkeypatch.setattr(PreparedArtifact, "close", fail_close) else: expected = { diff --git a/backend/tests/checkers/execution/test_material_lineage.py b/backend/tests/checkers/execution/test_material_lineage.py index 6167f3837..a07a24e43 100644 --- a/backend/tests/checkers/execution/test_material_lineage.py +++ b/backend/tests/checkers/execution/test_material_lineage.py @@ -5,7 +5,7 @@ from sqlalchemy.exc import IntegrityError from app.modules.checkers.models import CheckerRun, CheckerResult -from app.modules.checkers.post_submit_contracts import make_post_submit_result +from app.modules.checkers.api.selected_post_submit import make_selected_post_submit_result from app.modules.outbox.models import OutboxEvent from tests.post_submit_materialization_helpers import material_fixture from .support import live_executor, reserve @@ -17,8 +17,8 @@ async def terminal_facts(h, lease, outcome): facts = await final_facts(h, lease) if outcome == "infrastructure_failed": body = facts.result.model_dump(exclude={"result_digest"}) - body.update(outcome=outcome, member_results=(), infrastructure_failure_code="implementation_unavailable") - facts = facts.model_copy(update={"result": make_post_submit_result(**body)}) + body.update(outcome=outcome, execution=None, infrastructure_failure_code="implementation_unavailable") + facts = facts.model_copy(update={"result": make_selected_post_submit_result(**body)}) return facts diff --git a/backend/tests/checkers/execution/test_storage.py b/backend/tests/checkers/execution/test_storage.py index 733962d1f..82860e816 100644 --- a/backend/tests/checkers/execution/test_storage.py +++ b/backend/tests/checkers/execution/test_storage.py @@ -13,6 +13,7 @@ from tests.post_submit_materialization_helpers import material_fixture from .support import reserve, live_executor from .test_concurrency import final_facts +from tests.checkers.external.support import post_registry_spec @pytest.mark.parametrize("duplicate", ["request", "generation"]) @@ -55,31 +56,15 @@ async def test_duplicate_request_and_generation_rejected( async def test_terminal_member_and_routing_custody(tmp_path, isolated_database_env, monkeypatch): - from app.modules.checkers.api.post_submit import PostSubmitMemberResult - from app.modules.checkers.post_submit_contracts import make_post_submit_result import app.modules.checkers.execution as execution - async with material_fixture(tmp_path, isolated_database_env) as h: + async with material_fixture(tmp_path, isolated_database_env, + post_submit_registry_spec=post_registry_spec()) as h: await reserve(h) executor = live_executor(h) lease, _ = await executor._claim(h.request) - facts = await final_facts(h, lease) - members = list(facts.result.member_results) - definition = h.request.catalogue.definition( - members[0].checker_id, members[0].definition_version - ) - members[0] = PostSubmitMemberResult( - checker_id=definition.capability_id, - implementation_version=definition.implementation_version, - status=definition.failure_status, - severity=definition.failure_severity, - code=definition.failure_code, - failure_category=definition.failure_category, - ) - body = facts.result.model_dump(exclude={"result_digest"}) - body["member_results"] = tuple(members) - blocked = make_post_submit_result(**body) - facts = facts.model_copy(update={"result": blocked}) + facts = await final_facts(h, lease, verdict="failed") + blocked = facts.result canonical = execution.classify_result assert canonical(h.request, blocked).routing == "needs_revision" monkeypatch.setattr( @@ -122,7 +107,8 @@ async def test_execution_custody_rejects_mutation(tmp_path, isolated_database_en async def test_unfinished_members_cannot_commit(tmp_path, isolated_database_env): - async with material_fixture(tmp_path, isolated_database_env) as h: + async with material_fixture(tmp_path, isolated_database_env, + post_submit_registry_spec=post_registry_spec()) as h: await reserve(h) lease, _ = await live_executor(h)._claim(h.request) async with h.factory() as session: @@ -143,36 +129,37 @@ async def test_member_shape_and_complete_set_enforced_in_database( from sqlalchemy import insert from app.modules.checkers.execution_repository import ExecutionRepository - async with material_fixture(tmp_path, isolated_database_env) as h: + async with material_fixture(tmp_path, isolated_database_env, + post_submit_registry_spec=post_registry_spec()) as h: await reserve(h) executor = live_executor(h) lease, _ = await executor._claim(h.request) facts = await final_facts(h, lease) - first = facts.result.member_results[0] + first = facts.result.execution.external_members[0] values = dict( id=str(new_record_id()), checker_run_id=str(lease.reservation.attempt_id), task_id=str(h.request.task_id), submission_id=str(h.request.submission_id), member_order=0, - checker_name=first.checker_id, - definition_version=first.definition_version, - implementation_version=first.implementation_version, - status=first.status, - code=first.code, - failure_category=first.failure_category, - severity=first.severity, + checker_name=first.requirement_id, + definition_version=first.result.schema_version, + implementation_version=first.registry_entry_digest, + status=first.result.verdict, + code="passed", + failure_category="none", + severity="info", counters=[], ) invalid = [ ({"checker_name": "unselected_checker"}, "differs from selected definition"), ( - {"member_order": len(facts.result.member_results)}, + {"member_order": len(facts.result.execution.external_members)}, "differs from selected definition", ), - ({"status": "passed", "code": "packet_fields_missing"}, "passing member shape invalid"), - ({"counters": [{"key": "invalid_count", "value": 1025}]}, "counters invalid"), - ({"counters": [{"key": "invalid_count"}]}, "counters invalid"), + ({"status": "passed", "code": "packet_fields_missing"}, "differs from selected definition"), + ({"counters": [{"key": "invalid_count", "value": 1025}]}, "differs from selected definition"), + ({"counters": [{"key": "invalid_count"}]}, "differs from selected definition"), ({"task_id": str(new_record_id())}, "fk_checker_results_run_ownership"), ] async with h.factory() as session: @@ -188,7 +175,7 @@ async def test_member_shape_and_complete_set_enforced_in_database( async def omit_last(repo, run, result): await original( - repo, run, result.model_copy(update={"member_results": result.member_results[:-1]}) + repo, run, result.model_copy(update={"execution": replace(result.execution, required_external_count=0, external_members=())}) ) monkeypatch.setattr(ExecutionRepository, "write_members", omit_last) @@ -207,23 +194,24 @@ async def test_consistently_short_result_cannot_omit_selected_policy_member( tmp_path, isolated_database_env, monkeypatch ): from app.modules.checkers.execution_results import ResultClassification - from app.modules.checkers.post_submit_contracts import make_post_submit_result + from app.modules.checkers.api.selected_post_submit import make_selected_post_submit_result from app.modules.outbox.models import OutboxEvent from app.modules.checkers.api.execution import COMPLETION_EVENT from sqlalchemy import func from sqlalchemy import text from . import material_storage_helpers - async with material_fixture(tmp_path, isolated_database_env) as h: + async with material_fixture(tmp_path, isolated_database_env, + post_submit_registry_spec=post_registry_spec()) as h: await reserve(h) executor = live_executor(h) lease, _ = await executor._claim(h.request) valid = await final_facts(h, lease) - assert len(valid.result.member_results) > 1 - assert all(member.status == "passed" for member in valid.result.member_results) + assert len(valid.result.execution.external_members) == 1 + assert all(member.result.verdict == "passed" for member in valid.result.execution.external_members) body = valid.result.model_dump(exclude={"result_digest"}) - body["member_results"] = valid.result.member_results[:-1] - short = make_post_submit_result(**body) + body["execution"] = replace(valid.result.execution, required_external_count=0, external_members=()) + short = make_selected_post_submit_result(**body) facts = valid.model_copy(update={"result": short}) # Simulate a faulty validator/compiler accepting a self-consistent short # result. Persisted members, counts, result digest and event all agree; @@ -232,7 +220,7 @@ async def test_consistently_short_result_cannot_omit_selected_policy_member( def faulty_classifier(request, result): assert request == h.request and result == short - return ResultClassification("allow_review", len(short.member_results), 0, 0, 0) + return ResultClassification("allow_review", len(short.execution.external_members), 0, 0, 0) monkeypatch.setattr(material_storage_helpers, "classify_result", faulty_classifier) async with h.factory() as session: @@ -263,16 +251,16 @@ async def test_infrastructure_failure_code_is_closed_in_database(tmp_path, isola import json from sqlalchemy import update, func, text from app.core.hashing import canonical_json_hash - from app.modules.checkers.post_submit_contracts import make_post_submit_result + from app.modules.checkers.api.selected_post_submit import make_selected_post_submit_result async with material_fixture(tmp_path, isolated_database_env) as h: await reserve(h) lease, _ = await live_executor(h)._claim(h.request) - result = make_post_submit_result( + result = make_selected_post_submit_result( request_id=h.request.evaluation_request_id, request_digest=h.request.request_sha256, attempt_id=lease.reservation.attempt_id, result_id=lease.reservation.result_id, evaluation_generation=h.request.evaluation_generation, outcome="infrastructure_failed", - member_results=(), infrastructure_failure_code="material_unavailable", + execution=None, infrastructure_failure_code="material_unavailable", ) body = result.model_dump(mode="json", exclude={"result_digest"}) async with h.factory() as session: diff --git a/backend/tests/checkers/post_submit/support.py b/backend/tests/checkers/post_submit/support.py index 1ac4b387e..8e5beea63 100644 --- a/backend/tests/checkers/post_submit/support.py +++ b/backend/tests/checkers/post_submit/support.py @@ -1,135 +1,9 @@ -"""Controlled owner facts; no future database rows, authorization, or worker fixtures.""" +"""Current selected request identity mutations for authority and lineage controls.""" -from uuid import UUID -from app.core.identifiers import new_record_id - -from app.core.hashing import canonical_json_hash -from app.modules.checkers.api import ( - ExpectedPostSubmitContext, - ObservedPostSubmitContext, - PostSubmissionStructuralInput, - PostSubmitEvidenceEntry, - PostSubmitManifestEntry, - PostSubmitPolicyInputs, -) -from app.modules.checkers.api.historical_post_submit import ( - CompiledPostSubmitPolicy, - EmptyPostSubmitConfiguration, - PostSubmitCatalogue, - PostSubmitDefinition, - PostSubmitPolicyEntry, -) -from app.modules.checkers.api.post_submit import make_post_submit_request -from app.modules.checkers.api.selected_post_submit import ( - SelectedPostSubmissionEvaluationRequest, - make_selected_post_submit_request, -) -from tests.historical_checker_metadata import historical_post_submit_catalogue - -HASH = "sha256:" + "a" * 64 -OTHER_HASH = "sha256:" + "b" * 64 -PROJECT = UUID("11111111-1111-4111-8111-111111111111") - - -def catalogue(): - """Return the frozen retained-history decoder, never an executable registry.""" - return historical_post_submit_catalogue() - - -def _policy(*, project_id: UUID, snapshot: PostSubmitCatalogue) -> CompiledPostSubmitPolicy: - """Build a retained historical value without restoring its removed compiler.""" - selected = { - "check_acceptance_criteria_present": "project_required", - } - entries = tuple( - PostSubmitPolicyEntry( - checker_id=item.capability_id, - definition_version=item.capability_version, - implementation_version=item.implementation_version, - classification=( - "platform_default" - if item.platform_default - else selected[item.capability_id] - ), - configuration=EmptyPostSubmitConfiguration(), - ) - for item in snapshot.definitions - if item.platform_default or item.capability_id in selected - ) - return CompiledPostSubmitPolicy( - project_id=project_id, - guide_version="v1", - catalogue_manifest_sha256=snapshot.manifest_sha256, - entries=entries, - blocking_severities=("critical", "high"), - ) - - -def altered_catalogue(original=None, *, index=8, **changes): - source = original or catalogue() - body = source.model_dump(mode="json", exclude={"manifest_sha256"}) - body["definitions"][index].update(changes) - body["definitions"][index] = PostSubmitDefinition.model_validate( - body["definitions"][index] - ).model_dump(mode="json") - return PostSubmitCatalogue(**body, manifest_sha256=canonical_json_hash(body)) - - -def request(*, snapshot=None, project_id=PROJECT): - snapshot = snapshot or catalogue() - policy = _policy(project_id=project_id, snapshot=snapshot) - policy.validate_catalogue(snapshot) - fields = {} - for name in ExpectedPostSubmitContext.model_fields: - if name.endswith("_id"): - fields[name] = new_record_id() - elif "version" in name: - fields[name] = "v1" - elif name.endswith("generation"): - fields[name] = 1 - else: - fields[name] = HASH - fields.update(post_policy_hash=policy.policy_hash) - expected = ExpectedPostSubmitContext(**fields) - data = PostSubmissionStructuralInput( - summary="Delivered the documented result with supporting evidence.", - worker_attestation="I confirm this submission contains no confidential data, credentials, secrets, or copied source or platform artifacts. Rights confirmed.", - package_hash=HASH, - criteria="Provide an accurate analysis with supporting evidence.", - manifest=(PostSubmitManifestEntry(artifact="report.txt", hash=HASH, size_bytes=10),), - evidence=( - PostSubmitEvidenceEntry(label="proof", type="file", uri="report.txt", hash=HASH), - ), - policy_inputs=PostSubmitPolicyInputs( - required_evidence_keys=("proof",), - required_artifact_paths=("report.txt",), - forbidden_artifact_patterns=("forbidden/**",), - required_attestation_terms=("rights confirmed",), - ), - observed_context=ObservedPostSubmitContext(**expected.model_dump()), - ) - return make_post_submit_request( - evaluation_request_id=new_record_id(), - evaluation_generation=1, - project_id=project_id, - task_id=new_record_id(), - assignment_id=new_record_id(), - submission_id=new_record_id(), - submission_version=1, - content_id=new_record_id(), - binding_id=new_record_id(), - content_sha256=HASH, - byte_count=10, - expected_context=expected, - catalogue=snapshot, - policy=policy, - structural_input=data, - ) +from app.modules.checkers.api.selected_post_submit import make_selected_post_submit_request def change_request(source, **changes): fields = source.model_dump(exclude={"request_sha256"}) fields.update(changes) - if type(source) is SelectedPostSubmissionEvaluationRequest: - return make_selected_post_submit_request(**fields) - return make_post_submit_request(**fields) + return make_selected_post_submit_request(**fields) diff --git a/backend/tests/checkers/post_submit/test_configuration.py b/backend/tests/checkers/post_submit/test_configuration.py deleted file mode 100644 index b71f22514..000000000 --- a/backend/tests/checkers/post_submit/test_configuration.py +++ /dev/null @@ -1,25 +0,0 @@ -"""No arbitrary post-submit configuration or implicit version selection.""" - -import pytest -from pydantic import ValidationError - -from tests.checkers.post_submit.support import altered_catalogue, catalogue - - -def test_binding_uses_registered_configuration(): - definition = catalogue().definition("check_acceptance_criteria_present", "v0.1") - assert definition.validate_configuration({}).model_dump() == {} - with pytest.raises(ValidationError, match="Extra inputs"): - definition.validate_configuration({"script": "arbitrary"}) - with pytest.raises(ValueError, match="unavailable"): - altered_catalogue(state="disabled").definition( - "check_acceptance_criteria_present", "v0.1" - ).validate_configuration({}) - - -@pytest.mark.parametrize( - "name,version", [("unknown", "v0.1"), ("check_acceptance_criteria_present", "unsupported")] -) -def test_missing_exact_definition_does_not_select_latest(name, version): - with pytest.raises(ValueError, match="capability or version is unavailable"): - catalogue().definition(name, version) diff --git a/backend/tests/checkers/post_submit/test_input_bounds.py b/backend/tests/checkers/post_submit/test_input_bounds.py deleted file mode 100644 index aaeaf2691..000000000 --- a/backend/tests/checkers/post_submit/test_input_bounds.py +++ /dev/null @@ -1,197 +0,0 @@ -"""Finite detached values, strict numbers and a reachable aggregate byte boundary.""" - -from collections import UserDict -from types import MappingProxyType - -import pytest -from pydantic import ValidationError - -from app.modules.checkers.api import ExpectedPostSubmitContext, PostSubmissionStructuralInput -from app.modules.checkers.api.post_submit import ( - POST_SUBMIT_CONTENT_BYTE_LIMIT, - PostSubmissionEvaluationContent, - PostSubmitEvidenceEntry, - PostSubmitManifestEntry, - PostSubmitPolicyInputs, -) -from app.modules.checkers.api.historical_post_submit import ( - PostSubmitResourceLimits, - canonical_post_submit_bytes, -) -from tests.checkers.post_submit.support import HASH, change_request, request - - -@pytest.mark.parametrize("field", ("summary", "worker_attestation", "criteria")) -def test_structural_text_exact_limit_and_limit_plus_one(field): - fields = request().structural_input.model_dump() - fields[field] = "x" * 65536 - assert len(getattr(PostSubmissionStructuralInput(**fields), field)) == 65536 - fields[field] += "x" - with pytest.raises(ValidationError, match="65536"): - PostSubmissionStructuralInput(**fields) - - -@pytest.mark.parametrize( - "kind,field,limit", - [ - ("manifest", "artifact", 1000), - ("manifest", "hash", 128), - ("manifest", "notes", 4096), - ("evidence", "label", 200), - ("evidence", "uri", 1000), - ("evidence", "hash", 128), - ("evidence", "type", 200), - ("evidence", "key", 200), - ("evidence", "policy_key", 200), - ("evidence", "evidence_key", 200), - ("evidence", "required_evidence_key", 200), - ], -) -def test_entry_text_bounds(kind, field, limit): - cls = PostSubmitManifestEntry if kind == "manifest" else PostSubmitEvidenceEntry - values = ( - dict(artifact="file", hash=HASH) if kind == "manifest" else dict(label="label", type="file") - ) - values[field] = "x" * limit - assert len(getattr(cls(**values), field)) == limit - values[field] += "x" - with pytest.raises(ValidationError): - cls(**values) - - -@pytest.mark.parametrize("field", ("manifest", "evidence")) -def test_collection_limits_are_independent_of_request_aggregate(field): - data = request().structural_input.model_dump() - element = data[field][0] - data[field] = (element,) * 1024 - assert len(getattr(PostSubmissionStructuralInput(**data), field)) == 1024 - data[field] += (element,) - with pytest.raises(ValidationError, match="1024"): - PostSubmissionStructuralInput(**data) - - -@pytest.mark.parametrize("field", tuple(PostSubmitPolicyInputs.model_fields)) -def test_policy_input_count_and_token_limit(field): - assert len(getattr(PostSubmitPolicyInputs(**{field: ("x",) * 256}), field)) == 256 - assert getattr(PostSubmitPolicyInputs(**{field: ("x" * 1000,)}), field)[0] == "x" * 1000 - for value in (("x",) * 257, ("x" * 1001,)): - with pytest.raises(ValidationError): - PostSubmitPolicyInputs(**{field: value}) - - -@pytest.mark.parametrize("invalid", (True, -1, 9_223_372_036_854_775_808, "1")) -def test_strict_size_boundaries(invalid): - for valid in (0, 9_223_372_036_854_775_807): - assert ( - PostSubmitManifestEntry(artifact="x", hash=HASH, size_bytes=valid).size_bytes == valid - ) - assert change_request(request(), byte_count=valid).byte_count == valid - with pytest.raises(ValidationError): - PostSubmitManifestEntry(artifact="x", hash=HASH, size_bytes=invalid) - with pytest.raises(ValidationError): - change_request(request(), byte_count=invalid) - - -def test_version_types_and_numeric_generations_match_existing_owners(): - base = request().expected_context.model_dump() - expected = ExpectedPostSubmitContext( - **{**base, "guide_version": "x" * 50, "post_policy_version": "x" * 50} - ) - assert len(expected.guide_version) == 50 - for value in ("x" * 51, " ", 1): - with pytest.raises(ValidationError): - ExpectedPostSubmitContext( - **{**base, "guide_version": value, "post_policy_version": value} - ) - for field in ("review_generation", "revision_generation"): - assert ( - getattr(ExpectedPostSubmitContext(**{**base, field: 2_147_483_647}), field) - == 2_147_483_647 - ) - for value in (True, 0, 2_147_483_648, "1"): - with pytest.raises(ValidationError): - ExpectedPostSubmitContext(**{**base, field: value}) - for field in ("submission_version", "evaluation_generation"): - assert getattr(change_request(request(), **{field: 2_147_483_647}), field) == 2_147_483_647 - with pytest.raises(ValidationError): - change_request(request(), **{field: 2_147_483_648}) - - -def test_nested_extra_fields_and_strict_resource_ids_deny(): - base = request() - for owner in ( - base.structural_input, - base.structural_input.policy_inputs, - base.expected_context, - ): - with pytest.raises(ValidationError, match="Extra inputs"): - type(owner)(**owner.model_dump(), unexpected={"private": "data"}) - with pytest.raises(ValidationError, match="UUID"): - change_request(base, task_id=str(base.task_id)) - with pytest.raises(ValidationError): - change_request(base, content_sha256="sha256:invalid") - - -@pytest.mark.parametrize( - "field,maximum", - [ - ("maximum_input_bytes", 1_048_576), - ("maximum_result_bytes", 4096), - ("deadline_ms", 5000), - ("phase_deadline_ms", 45000), - ("maximum_manifest_items", 1024), - ("maximum_evidence_items", 1024), - ("maximum_policy_items", 256), - ("maximum_text_characters", 65536), - ], -) -def test_catalogue_resource_limits_match_exact_enforced_contract(field, maximum): - assert getattr(PostSubmitResourceLimits(**{field: maximum}), field) == maximum - for value in (True, 0, maximum - 1, maximum + 1, float(maximum), str(maximum)): - with pytest.raises(ValidationError): - PostSubmitResourceLimits(**{field: value}) - - -@pytest.mark.parametrize("prefix", ("", "é\n\"")) -def test_request_aggregate_exact_limit_and_one_byte_over(prefix): - source = request() - data = source.structural_input.model_dump() - data["summary"] = prefix - # Each item remains within its own limit; only the aggregate boundary varies. - data["manifest"] = tuple( - {"artifact": f"entry{i}", "hash": HASH, "notes": "x" * 3800, "size_bytes": 0} - for i in range(260) - ) - small = change_request(source, structural_input=data) - fields = set(PostSubmissionEvaluationContent.model_fields) - delta = POST_SUBMIT_CONTENT_BYTE_LIMIT - len(canonical_post_submit_bytes(small, include=fields)) - assert 0 < delta < 65536 - data["summary"] = prefix + "x" * delta - exact = change_request(source, structural_input=data) - content = PostSubmissionEvaluationContent(**exact.model_dump(include=fields)) - assert len(canonical_post_submit_bytes(content)) == POST_SUBMIT_CONTENT_BYTE_LIMIT - maximum = change_request(exact, evaluation_generation=2_147_483_647, - submission_version=2_147_483_647, byte_count=9_223_372_036_854_775_807) - # All remaining fields are fixed-width UUID/hash/schema values. - assert len(canonical_post_submit_bytes(maximum)) - len(canonical_post_submit_bytes(content)) <= 1024 - assert len(canonical_post_submit_bytes(maximum)) <= 1_048_576 - data["summary"] += "x" - with pytest.raises(ValidationError, match="content capacity exceeded"): - change_request(source, structural_input=data) - with pytest.raises(ValidationError, match="content capacity exceeded"): - PostSubmissionEvaluationContent(**{**content.model_dump(), "structural_input": data}) - - -@pytest.mark.parametrize("mapping", (dict, UserDict, MappingProxyType)) -@pytest.mark.parametrize("invalid", (True, 1.0, "1")) -def test_resource_literal_strictness_does_not_depend_on_mapping_type(mapping, invalid): - assert PostSubmitResourceLimits.model_validate(mapping({"maximum_results": 1})).maximum_results == 1 - with pytest.raises(ValidationError, match="limits require integers"): - PostSubmitResourceLimits.model_validate(mapping({"maximum_results": invalid})) - - -@pytest.mark.parametrize("invalid", (True, 1.0, "1")) -def test_resource_literals_revalidate_unchecked_copies(invalid): - unchecked = PostSubmitResourceLimits().model_copy(update={"maximum_results": invalid}) - with pytest.raises(ValidationError, match="limits require integers"): - PostSubmitResourceLimits.model_validate(unchecked) diff --git a/backend/tests/checkers/post_submit/test_public_boundary.py b/backend/tests/checkers/post_submit/test_public_boundary.py index 54f2119bd..857a4fa70 100644 --- a/backend/tests/checkers/post_submit/test_public_boundary.py +++ b/backend/tests/checkers/post_submit/test_public_boundary.py @@ -5,12 +5,12 @@ from pathlib import Path from app.modules.checkers.api import PostSubmissionExecutionPort -from app.modules.checkers.api.post_submit import PostSubmissionEvaluationRequest +from app.modules.checkers.api.selected_post_submit import SelectedPostSubmissionEvaluationRequest def test_public_api_has_no_private_owner_types(): directory = Path(__file__).resolve().parents[3] / "app" / "modules" / "checkers" / "api" - for name in ("post_submit.py", "post_submit_catalogue.py"): + for name in ("selected_post_submit.py", "external.py"): tree = ast.parse((directory / name).read_text()) imports = [node.module or "" for node in ast.walk(tree) if isinstance(node, ast.ImportFrom)] assert not any( @@ -26,5 +26,5 @@ def test_public_api_has_no_private_owner_types(): if not name.startswith("_") ] assert methods == ["evaluate_post_submission"] - assert "checker_names" not in PostSubmissionEvaluationRequest.model_fields - assert "prepared" not in PostSubmissionEvaluationRequest.model_fields + assert "checker_names" not in SelectedPostSubmissionEvaluationRequest.model_fields + assert "prepared" not in SelectedPostSubmissionEvaluationRequest.model_fields diff --git a/backend/tests/checkers/post_submit/test_request.py b/backend/tests/checkers/post_submit/test_request.py deleted file mode 100644 index bede51a79..000000000 --- a/backend/tests/checkers/post_submit/test_request.py +++ /dev/null @@ -1,87 +0,0 @@ -"""Identity consistency, complete valid denial control, and absence of owner authority.""" - -from app.adapters.checkers import post_submission_executor -from sqlalchemy.ext.asyncio import async_sessionmaker - -from app.core.identifiers import new_record_id - -import pytest -from pydantic import ValidationError - -from app.modules.checkers.api import ( - PostSubmissionEvaluationRequest, - PostSubmissionEvaluationContent, -) -from app.modules.checkers.api.post_submit import make_post_submit_request -from tests.checkers.post_submit.support import OTHER_HASH, change_request, request - - -@pytest.mark.parametrize( - "change,message", - [ - ("project", "project mismatch"), - ("guide", "guide version mismatch"), - ("policy_hash", "policy hash mismatch"), - ("version", "guide and policy versions differ"), - ("digest", "request digest mismatch"), - ], -) -def test_request_digest_and_lineage(change, message): - source = request() - assert PostSubmissionEvaluationRequest.model_validate_json(source.model_dump_json()) == source - fields = source.model_dump(exclude={"request_sha256"}) - if change == "project": - fields["project_id"] = new_record_id() - elif change == "guide": - fields["expected_context"].update(guide_version="other", post_policy_version="other") - elif change == "policy_hash": - fields["expected_context"]["post_policy_hash"] = OTHER_HASH - elif change == "version": - fields["expected_context"]["post_policy_version"] = "other" - with pytest.raises(ValueError, match=message): - if change == "digest": - PostSubmissionEvaluationRequest(**fields, request_sha256=OTHER_HASH) - else: - make_post_submit_request(**fields) - if change != "digest": - with pytest.raises(ValueError, match=message): - PostSubmissionEvaluationContent(**{ - key: fields[key] for key in PostSubmissionEvaluationContent.model_fields - }) - - -def test_coherent_foreign_facts_are_not_an_authorization_proof(): - first = request() - other = request(project_id=new_record_id()) - assert first.project_id != other.project_id - assert PostSubmissionEvaluationRequest.model_validate(other) == other - assert first.request_sha256 != other.request_sha256 - assert not hasattr(other, "authorized") - assert not hasattr(other, "is_current") - - -def test_fact_hashes_are_derived_and_nested_values_are_immutable(): - source = request() - with pytest.raises(ValueError, match="derived"): - make_post_submit_request(**source.model_dump()) - with pytest.raises(ValidationError, match="frozen"): - source.structural_input.manifest[0].artifact = "changed" - dumped = source.model_dump() - dumped["structural_input"]["manifest"][0]["artifact"] = "changed" - assert source.structural_input.manifest[0].artifact == "report.txt" - with pytest.raises(ValidationError, match="digest mismatch"): - PostSubmissionEvaluationRequest.model_validate(dumped) - - -@pytest.mark.parametrize("field", ("submission_version", "evaluation_generation", "byte_count")) -@pytest.mark.parametrize("invalid", (True, -1, "1")) -def test_strict_request_numbers(field, invalid): - with pytest.raises(ValidationError): - change_request(request(), **{field: invalid}) - - -async def test_executor_revalidates_unsafe_constructed_instances(): - source = request() - forged = source.model_copy(update={"project_id": new_record_id()}) - with pytest.raises(ValidationError, match="project mismatch"): - await post_submission_executor(sessions=async_sessionmaker(), materialization=None).evaluate_post_submission(forged) diff --git a/backend/tests/checkers/post_submit/test_requirement_dispositions.py b/backend/tests/checkers/post_submit/test_requirement_dispositions.py index 243277946..54cde4e8a 100644 --- a/backend/tests/checkers/post_submit/test_requirement_dispositions.py +++ b/backend/tests/checkers/post_submit/test_requirement_dispositions.py @@ -6,25 +6,10 @@ AtomicGuideRequirement, CapabilitySuggestion, PostSubmissionBindingProposal, - CapabilityParameter, - ProjectGuideCompilationContext, ProjectGuideCompilationResult, validate_project_guide_compilation_result, ) -from app.modules.checkers.api.historical_post_submit import ( - PostSubmitCatalogue, -) from tests.test_project_guide_compilation_contracts import _artifact_policy, _context, _evidence -from tests.checkers.post_submit.support import altered_catalogue, catalogue - - -def context(snapshot=None): - base = _context() - fields = base.model_dump() - fields["post_submission_capabilities"] = PostSubmitCatalogue.model_validate( - (snapshot or catalogue()).model_dump() - ) - return ProjectGuideCompilationContext.model_validate(fields) def proposal(disposition, *, binding=False): @@ -55,8 +40,8 @@ def proposal(disposition, *, binding=False): post_submit_bindings=( PostSubmissionBindingProposal( requirement_id="quality", - capability_id="check_acceptance_criteria_present", - capability_version="v0.1", + capability_id="acme.post", + capability_version="v1.2.3", stage="post_submit", ), ) @@ -66,7 +51,7 @@ def proposal(disposition, *, binding=False): def test_requirement_disposition_is_preserved(): - source = context() + source = _context() human = proposal("human_review") validate_project_guide_compilation_result(source, human) assert human.requirements[0].disposition.value == "human_review" @@ -84,53 +69,7 @@ def test_requirement_disposition_is_preserved(): @pytest.mark.parametrize("disposition", ("human_review", "post_submit_capability_gap")) def test_unbound_dispositions_cannot_acquire_a_binding(disposition): - source = context() + source = _context() validate_project_guide_compilation_result(source, proposal(disposition)) with pytest.raises(ValueError, match="compilation capability binding is invalid"): validate_project_guide_compilation_result(source, proposal(disposition, binding=True)) - - -def test_supported_binding_is_valid_and_roundtrips(): - source = context() - valid = proposal("supported_post_submit", binding=True) - validate_project_guide_compilation_result(source, valid) - assert ProjectGuideCompilationContext.model_validate_json(source.model_dump_json()) == source - - -@pytest.mark.parametrize( - "change,message", - [ - ({"capability_version": "wrong"}, "version is stale"), - ({"capability_id": "unknown"}, "binding is invalid"), - ({"capability_id": "check_submission_packet"}, "binding is invalid"), - ({"stage": "pre_submit"}, "binding is invalid"), - ({"parameters": (CapabilityParameter(name="arbitrary", value="data"),)}, "Extra inputs"), - ({"parameters": (CapabilityParameter(name="supported_claim", value="criteria_presence"),)}, "Extra inputs"), - ], -) -def test_binding_rejects_exact_invalid_property(change, message): - valid = proposal("supported_post_submit", binding=True) - binding = valid.post_submit_bindings[0] - invalid = PostSubmissionBindingProposal(**{**binding.model_dump(), **change}) - with pytest.raises(ValueError, match=message): - validate_project_guide_compilation_result( - context(), valid.model_copy(update={"post_submit_bindings": (invalid,)}) - ) - - -def test_disabled_selection_stays_a_gap_and_cannot_bind(): - source = context(altered_catalogue(state="disabled")) - gap = proposal("post_submit_capability_gap") - validate_project_guide_compilation_result(source, gap) - assert gap.requirements[0].disposition.value == "post_submit_capability_gap" - with pytest.raises(ValueError, match="definition is unavailable"): - validate_project_guide_compilation_result( - source, proposal("supported_post_submit", binding=True) - ) - - -def test_disabled_mandatory_catalogue_cannot_produce_a_ready_guide(): - with pytest.raises(ValueError, match="post-submit capability projection is unavailable"): - validate_project_guide_compilation_result( - context(altered_catalogue(index=0, state="disabled")), proposal("human_review") - ) diff --git a/backend/tests/checkers/post_submit/test_result_contract.py b/backend/tests/checkers/post_submit/test_result_contract.py deleted file mode 100644 index 8ec701398..000000000 --- a/backend/tests/checkers/post_submit/test_result_contract.py +++ /dev/null @@ -1,227 +0,0 @@ -"""Phase/result reference identity and closed failure semantics without persistence.""" - -from app.core.identifiers import new_record_id - -import pytest -from pydantic import ValidationError - -from app.modules.checkers.api import ( - PostSubmissionEvaluationResult, - PostSubmitCurrentResultReference, - PostSubmitMemberResult, -) -from app.modules.checkers.api.post_submit import PostSubmitCounter -from app.modules.checkers.post_submit_contracts import make_post_submit_result -from tests.checkers.post_submit.support import OTHER_HASH, request - - -def result(source, **changes): - fields = dict( - request_id=source.evaluation_request_id, - request_digest=source.request_sha256, - attempt_id=new_record_id(), - evaluation_generation=source.evaluation_generation, - result_id=new_record_id(), - outcome="completed", - member_results=tuple( - PostSubmitMemberResult( - checker_id=item.checker_id, - definition_version=item.definition_version, - implementation_version=item.implementation_version, - status="passed", - code="passed", - failure_category="none", - severity="info", - ) - for item in source.policy.entries - ), - ) - fields.update(changes) - return make_post_submit_result(**fields) - - -def test_result_is_not_currentness_or_acceptance(): - source = request() - completed = result(source) - completed.validate_request(source) - fields = { - name: getattr(completed, name) - for name in PostSubmitCurrentResultReference.model_fields - if name != "schema_version" - } - reference = PostSubmitCurrentResultReference(**fields) - reference.validate_result(completed) - assert not hasattr(reference, "is_current") - assert not hasattr(completed, "accept") - assert ( - PostSubmissionEvaluationResult.model_validate_json(completed.model_dump_json()) == completed - ) - - -@pytest.mark.parametrize("field", ("request_id", "request_digest", "evaluation_generation")) -def test_result_rejects_crossed_request(field): - source = request() - value = ( - OTHER_HASH if field.endswith("digest") else 2 if field.endswith("generation") else new_record_id() - ) - with pytest.raises(ValueError, match="request mismatch"): - result(source, **{field: value}).validate_request(source) - - -@pytest.mark.parametrize("damage", ("omit", "reorder", "version", "claim")) -def test_completed_member_list_matches_plan_exactly(damage): - source = request() - members = list(result(source).member_results) - if damage == "omit": - members.pop() - elif damage == "reorder": - members.reverse() - elif damage == "version": - members[0] = members[0].model_copy(update={"implementation_version": "other"}) - else: - members[0] = PostSubmitMemberResult( - **{ - **members[0].model_dump(), - "status": "failed", - "code": "evidence_missing", - "failure_category": "submission_structure", - "severity": "high", - } - ) - with pytest.raises(ValueError, match="members mismatch|registered claim"): - result(source, member_results=tuple(members)).validate_request(source) - - -@pytest.mark.parametrize( - "code", - ("capacity_exceeded", "deadline_exceeded", "material_unavailable", "implementation_unavailable", "invalid_output"), -) -def test_infrastructure_failure_never_carries_work_failure(code): - source = request() - failed = result( - source, outcome="infrastructure_failed", member_results=(), infrastructure_failure_code=code - ) - failed.validate_request(source) - assert failed.member_results == () - fields = { - key: getattr(failed, key) - for key in PostSubmitCurrentResultReference.model_fields - if key != "schema_version" - } - with pytest.raises(ValueError, match="current reference result mismatch"): - PostSubmitCurrentResultReference(**fields).validate_result(failed) - - -@pytest.mark.parametrize( - "changes", - [ - {"member_results": ()}, - {"infrastructure_failure_code": "deadline_exceeded"}, - {"outcome": "infrastructure_failed"}, - {"outcome": "accept"}, - {"outcome": "infrastructure_failed", "member_results": ()}, - ], -) -def test_phase_shapes_reject_conflicting_or_empty_outcomes(changes): - with pytest.raises(ValueError): - result(request(), **changes) - - -def test_result_digest_and_reference_require_exact_identity(): - source = request() - complete = result(source) - body = complete.model_dump() - body["result_digest"] = OTHER_HASH - with pytest.raises(ValueError, match="result digest mismatch"): - PostSubmissionEvaluationResult.model_validate(body) - with pytest.raises(ValueError, match="derived"): - make_post_submit_result(**complete.model_dump()) - fields = { - key: getattr(complete, key) - for key in PostSubmitCurrentResultReference.model_fields - if key != "schema_version" - } - fields["attempt_id"] = new_record_id() - with pytest.raises(ValueError, match="current reference result mismatch"): - PostSubmitCurrentResultReference(**fields).validate_result(complete) - - -@pytest.mark.parametrize( - "changes", - [ - {"severity": "high"}, - {"code": "packet_fields_missing"}, - {"failure_category": "task_configuration"}, - {"status": "failed"}, - {"message": "private/path"}, - {"counters": ({"key": "artifact_count", "value": True},)}, - {"counters": ({"key": "raw_path", "value": 1},)}, - {"counters": ({"key": "artifact_count", "value": 1},) * 2}, - ], -) -def test_member_result_shape_is_closed(changes): - passing = result(request()).member_results[0] - with pytest.raises(ValidationError): - PostSubmitMemberResult(**{**passing.model_dump(), **changes}) - - -def test_registered_failure_and_result_counter_boundaries(): - source = request() - definition = source.catalogue.definitions[0] - member = PostSubmitMemberResult( - checker_id=definition.capability_id, - implementation_version=definition.implementation_version, - status="failed", - code="packet_fields_missing", - failure_category="submission_structure", - severity="high", - counters=(PostSubmitCounter(key="missing_count", value=1024),), - ) - member.validate_catalogue(source.catalogue) - assert PostSubmitCounter(key="missing_count", value=0).value == 0 - with pytest.raises(ValidationError): - PostSubmitCounter(key="missing_count", value=1025) - with pytest.raises(ValueError, match="implementation mismatch"): - member.model_copy(update={"implementation_version": "other"}).validate_catalogue( - source.catalogue - ) - - -def test_consumers_revalidate_unchecked_copies(): - source = request() - complete = result(source) - forged = complete.model_copy(update={"result_digest": OTHER_HASH}) - with pytest.raises(ValidationError, match="result digest mismatch"): - forged.validate_request(source) - forged_member = complete.member_results[0].model_copy(update={"severity": "high"}) - with pytest.raises(ValidationError, match="passing result shape"): - forged_member.validate_catalogue(source.catalogue) - - -def test_closed_result_shape_stays_below_declared_byte_ceilings(): - from app.modules.checkers.api.historical_post_submit import ( - PostSubmitResourceLimits, canonical_post_submit_bytes, - ) - - # Longest allowed ASCII identities, closed tokens, all four counters at their - # maximum, and nine members bound the complete JSON shape without free text. - member = PostSubmitMemberResult( - checker_id="x" * 100, - implementation_version="x" * 100, - status="warning", - code="acceptance_criteria_missing", - failure_category="submission_structure", - severity="critical", - counters=tuple(PostSubmitCounter(key=key, value=1024) for key in ( - "artifact_count", "missing_count", "invalid_count", "matched_count", - )), - ) - phase = result(request(), member_results=(member,) * 9, evaluation_generation=2_147_483_647) - assert len(canonical_post_submit_bytes(member)) == 604 - assert len(canonical_post_submit_bytes(phase)) == 5942 - assert len(canonical_post_submit_bytes(member)) < PostSubmitResourceLimits().maximum_result_bytes - assert len(canonical_post_submit_bytes(phase)) < 65536 - with pytest.raises(ValidationError, match="100"): - PostSubmitMemberResult(**{**member.model_dump(), "checker_id": "x" * 101}) - with pytest.raises(ValidationError, match="at most 9"): - result(request(), member_results=(member,) * 10) diff --git a/backend/tests/reviews/decision/support.py b/backend/tests/reviews/decision/support.py index b48243c98..173d3e335 100644 --- a/backend/tests/reviews/decision/support.py +++ b/backend/tests/reviews/decision/support.py @@ -37,6 +37,9 @@ @asynccontextmanager async def review_source(tmp_path, database_url, **options): + from tests.checkers.external.support import post_registry_spec + + options.setdefault("post_submit_registry_spec", post_registry_spec()) async with packet_source(tmp_path, database_url, **options) as h: await attach_review_source(h) yield h @@ -180,7 +183,7 @@ async def _route_replacement_cause(h): from app.adapters.tasks import evaluation_completion_handler from app.modules.outbox.api import HandlerOutcome from tests.authorization.post_submit_routing.support import provision_router - from tests.checkers.execution.completion_fixture import controlled_registry + from tests.checkers.execution.support import ControlledSelectedExecution from tests.tasks.post_submit_routing.outcome_support import invoked_completion async with h.factory() as session: @@ -200,7 +203,7 @@ async def _route_replacement_cause(h): await next_request(failure) await reserve(failure) failure.result = await live_executor( - failure, registry=controlled_registry("needs_revision") + failure, selected_execution=ControlledSelectedExecution(verdict="failed") ).evaluate_post_submission(failure.request) async with h.factory() as session: run = await session.get(CheckerRun, str(failure.result.attempt_id)) @@ -277,8 +280,8 @@ async def _admit_successor(h): assignment_id=h.request.assignment_id, predecessor_submission_id=h.request.submission_id, idempotency_key=new_record_id(), - summary=h.request.structural_input.summary, - contributor_attestation=h.request.structural_input.worker_attestation, + summary=h.creation_request.summary, + contributor_attestation=h.creation_request.contributor_attestation, media_type="application/zip", byte_source=_bytes(revised_data), ) diff --git a/backend/tests/tasks/post_submit_routing/support.py b/backend/tests/tasks/post_submit_routing/support.py index e534f1387..95e8d8c83 100644 --- a/backend/tests/tasks/post_submit_routing/support.py +++ b/backend/tests/tasks/post_submit_routing/support.py @@ -215,6 +215,7 @@ async def completed_source( storage_settings=None, contribution_awards=(), human_review_required=True, + post_submit_registry_spec=None, ): """Yield one real authorized allow-review run and its valid source scalars.""" async with material_fixture( @@ -224,6 +225,7 @@ async def completed_source( storage_settings=storage_settings, contribution_awards=contribution_awards, human_review_required=human_review_required, + post_submit_registry_spec=post_submit_registry_spec, ) as h: await reserve(h) result = await live_executor(h).evaluate_post_submission(h.request) @@ -252,8 +254,8 @@ async def _create_submission(h, context, task_id, assignment_id, predecessor_id= assignment_id=assignment_id, predecessor_submission_id=predecessor_id, idempotency_key=new_record_id(), - summary=h.request.structural_input.summary, - contributor_attestation=h.request.structural_input.worker_attestation, + summary=h.creation_request.summary, + contributor_attestation=h.creation_request.contributor_attestation, media_type="application/zip", byte_source=_bytes(h.data), ) diff --git a/backend/tests/tasks/post_submit_routing/test_evaluation_currentness.py b/backend/tests/tasks/post_submit_routing/test_evaluation_currentness.py index 6e412f7e7..03ea290ff 100644 --- a/backend/tests/tasks/post_submit_routing/test_evaluation_currentness.py +++ b/backend/tests/tasks/post_submit_routing/test_evaluation_currentness.py @@ -91,9 +91,7 @@ async def compete(): {"id": original.attempt_id}) await session.execute(text("SET LOCAL lock_timeout='250ms'")) assert await evaluation_coordinator(session).reserve_current_evaluation(h.request) == original - changed = change_request(h.request, structural_input=h.request.structural_input.model_copy( - update={"summary": "Changed envelope, unchanged immutable TASK lineage."}, - )) + changed = change_request(h.request, byte_count=h.request.byte_count + 1) with pytest.raises(CheckerRequestConflict, match="checker_request_conflict"): await evaluation_coordinator(session).reserve_current_evaluation(changed) fence = await session.get(CheckerSubmissionFence, str(h.request.submission_id)) diff --git a/backend/tests/tasks/post_submit_routing/test_evaluation_guard.py b/backend/tests/tasks/post_submit_routing/test_evaluation_guard.py index 4f7501e2b..00faaa39a 100644 --- a/backend/tests/tasks/post_submit_routing/test_evaluation_guard.py +++ b/backend/tests/tasks/post_submit_routing/test_evaluation_guard.py @@ -113,10 +113,7 @@ async def test_changed_locked_context_cannot_advance_generation(tmp_path, isolat for field in ("source_id", "effective_policy_id", "pre_policy_id", "review_policy_id", "revision_policy_id"): context = h.request.expected_context.model_copy(update={field: new_record_id()}) changed = change_request(h.request, expected_context=context, - structural_input=h.request.structural_input.model_copy(update={ - "observed_context": h.request.structural_input.observed_context.model_copy( - update={field: getattr(context, field)}), - }), evaluation_request_id=new_record_id(), evaluation_generation=2) + evaluation_request_id=new_record_id(), evaluation_generation=2) async with h.factory() as session, session.begin(): with pytest.raises(CheckerExecutionUnavailable, match="checker_reservation_scope_unavailable"): await evaluation_coordinator(session).reserve_current_evaluation(changed) diff --git a/backend/tests/test_agent_runtime.py b/backend/tests/test_agent_runtime.py index 579c0bba7..36686c485 100644 --- a/backend/tests/test_agent_runtime.py +++ b/backend/tests/test_agent_runtime.py @@ -475,7 +475,9 @@ def test_sdk_output_schema_has_one_intake_configuration_and_separate_post_parame pre = schema["$defs"]["PreSubmissionBindingProposal"] post = schema["$defs"]["PostSubmissionBindingProposal"] assert pre["additionalProperties"] is False - assert "parameters" not in pre["properties"] + assert "parameters" in pre["properties"] + assert pre["properties"]["parameters"]["maxItems"] == 50 + assert post["properties"]["parameters"]["maxItems"] == 50 assert "parameters" in post["properties"] parameter_values = schema["$defs"]["CapabilityParameter"]["properties"]["value"]["anyOf"] array = next(item for item in parameter_values if item.get("type") == "array") diff --git a/backend/tests/test_post_submit_materialization.py b/backend/tests/test_post_submit_materialization.py index 8d988f5ff..b1ea62ec8 100644 --- a/backend/tests/test_post_submit_materialization.py +++ b/backend/tests/test_post_submit_materialization.py @@ -13,7 +13,7 @@ PostSubmissionMaterializationUnavailable, PostSubmissionMaterializationFailure, ) from tests.checkers.post_submit.support import change_request -from tests.checkers.post_submit.test_result_contract import result +from tests.checkers.execution.support import selected_result as result from tests.post_submit_materialization_helpers import material_fixture from tests.checkers.execution.support import material_execution, service_link_state from app.modules.actors.api import ServiceIdentity @@ -228,7 +228,7 @@ async def test_async_exit_and_concurrent_drift_never_return_stale_material(tmp_p assert_closed(h, consumer) -async def test_wrong_provider_bytes_or_manifest_never_reach_consumer(tmp_path, isolated_database_env): +async def test_wrong_provider_bytes_never_reach_consumer(tmp_path, isolated_database_env): from tests.archive_fixtures import byte_source as _bytes async with material_fixture(tmp_path, isolated_database_env) as h: execution = await material_execution(h) @@ -238,12 +238,6 @@ async def test_wrong_provider_bytes_or_manifest_never_reach_consumer(tmp_path, i with pytest.raises(PostSubmissionMaterializationFailure, match="material_unavailable"): await h.service.materialize(execution, consumer) h.store.open = original - packet = h.request.structural_input.model_copy(update={"manifest": ()}) - h.request = change_request(h.request, structural_input=packet, - evaluation_request_id=new_record_id(), evaluation_generation=2) - execution = await material_execution(h) - with pytest.raises(PostSubmissionMaterializationFailure, match="manifest_mismatch"): - await h.service.materialize(execution, consumer) assert consumer.calls == 0 and not h.preparation._active diff --git a/backend/tests/test_post_submit_selection.py b/backend/tests/test_post_submit_selection.py index b4352eb8a..02cdc39ef 100644 --- a/backend/tests/test_post_submit_selection.py +++ b/backend/tests/test_post_submit_selection.py @@ -66,14 +66,11 @@ def observe(connection, cursor, statement, parameters, context, executemany): async def test_frozen_context_substitution_rejected_by_art_selection(tmp_path, isolated_database_env): async with material_fixture(tmp_path, isolated_database_env) as h: - for name in ("source_id", "effective_policy_id", "pre_policy_id", "post_policy_id", "review_policy_id", "revision_policy_id", "review_generation", "revision_hash"): + for name in ("source_id", "effective_policy_id", "pre_policy_id", "retained_catalogue_policy_id", "review_policy_id", "revision_policy_id", "review_generation", "revision_hash"): value = (2 if name == "review_generation" else "sha256:" + "0" * 64 if name == "revision_hash" else new_record_id()) expected = h.request.expected_context.model_copy(update={name: value}) - packet = h.request.structural_input.model_copy(update={ - "observed_context": h.request.structural_input.observed_context.model_copy(update={name: value}), - }) with pytest.raises(PostSubmissionMaterializationUnavailable, match="identity_mismatch"): - await select_material(h, change_request(h.request, expected_context=expected, structural_input=packet)) + await select_material(h, change_request(h.request, expected_context=expected)) assert not h.store.opens and not h.preparation._active selected = await select_material(h, h.request) assert selected.submission.admission_id == h.created.admission_id @@ -111,8 +108,7 @@ def forbidden(*args, **kwargs): # Keep duplicated project/policy facts schema-valid so # rejection must come from persisted owner selection. mix.update(policy=foreign.request.policy, - expected_context=foreign.request.expected_context, - structural_input=foreign.request.structural_input) + expected_context=foreign.request.expected_context) mixed = change_request(own.request, **mix) with pytest.raises((PostSubmissionMaterializationUnavailable, SubmittedBundleUnavailable)): await select_material(own, mixed) From b1fe30e1fe2243fcb2cf6c3e868b63d6d54ec86e Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 12:50:51 +0100 Subject: [PATCH 199/283] test(pilot04): use current member closure negatives and exact retired envelope --- backend/tests/checkers/execution/test_execution.py | 2 +- backend/tests/checkers/execution/test_storage.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/backend/tests/checkers/execution/test_execution.py b/backend/tests/checkers/execution/test_execution.py index 37a1e146e..5804aeff0 100644 --- a/backend/tests/checkers/execution/test_execution.py +++ b/backend/tests/checkers/execution/test_execution.py @@ -129,7 +129,7 @@ async def forbidden_claim(request): materialization=None, outbox=None, ) monkeypatch.setattr(executor, "_claim", forbidden_claim) - for schema in ("workstream.post_submit_request.v1", "arbitrary_request.v1"): + for schema in ("post_submit_evaluation_request", "arbitrary_request.v1"): with pytest.raises(ValueError): await executor.evaluate_post_submission({"schema_version": schema}) diff --git a/backend/tests/checkers/execution/test_storage.py b/backend/tests/checkers/execution/test_storage.py index 82860e816..0e6744603 100644 --- a/backend/tests/checkers/execution/test_storage.py +++ b/backend/tests/checkers/execution/test_storage.py @@ -157,9 +157,9 @@ async def test_member_shape_and_complete_set_enforced_in_database( {"member_order": len(facts.result.execution.external_members)}, "differs from selected definition", ), - ({"status": "passed", "code": "packet_fields_missing"}, "differs from selected definition"), - ({"counters": [{"key": "invalid_count", "value": 1025}]}, "differs from selected definition"), - ({"counters": [{"key": "invalid_count"}]}, "differs from selected definition"), + ({"status": "passed", "code": "unexpected_pass_code"}, "differs from selected definition"), + ({"counters": [{"metric": 1}]}, "differs from selected definition"), + ({"counters": {"metric": 1}}, "differs from selected definition"), ({"task_id": str(new_record_id())}, "fk_checker_results_run_ownership"), ] async with h.factory() as session: From 6be5dff6972b53c399feac80823b316b321e279a Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 12:52:57 +0100 Subject: [PATCH 200/283] test(pilot04): bind selected member race and current canonical envelopes --- .../execution/material_storage_helpers.py | 10 ++++---- .../checkers/execution/test_concurrency.py | 23 +++++++++++-------- .../tasks/post_submit_routing/support.py | 9 ++++---- 3 files changed, 22 insertions(+), 20 deletions(-) diff --git a/backend/tests/checkers/execution/material_storage_helpers.py b/backend/tests/checkers/execution/material_storage_helpers.py index da2037989..f82e4156c 100644 --- a/backend/tests/checkers/execution/material_storage_helpers.py +++ b/backend/tests/checkers/execution/material_storage_helpers.py @@ -10,8 +10,8 @@ from app.adapters.outbox import outbox_append from app.core.identifiers import new_record_id from app.modules.checkers.api.execution import COMPLETION_EVENT, EvaluationCompletion -from app.modules.checkers.api.post_submit import PostSubmitCurrentResultReference -from app.modules.checkers.api.historical_post_submit import canonical_post_submit_bytes +from app.modules.checkers.api.selected_post_submit import SelectedPostSubmitCurrentResultReference +from app.modules.checkers.api.canonical_values import canonical_checker_bytes from app.modules.checkers.execution_results import classify_result from app.modules.checkers.models import CheckerResult, CheckerRun from app.modules.outbox.api import OutboxAppendInput @@ -56,8 +56,8 @@ async def stage_terminal(session, facts, material, evidence_id): )) event_id = None if result.outcome == "completed": - reference = PostSubmitCurrentResultReference(**result.model_dump( - include=set(PostSubmitCurrentResultReference.model_fields) - {"schema_version"}, + reference = SelectedPostSubmitCurrentResultReference(**result.model_dump( + include=set(SelectedPostSubmitCurrentResultReference.model_fields) - {"schema_version"}, )) event = EvaluationCompletion( project_id=request.project_id, task_id=request.task_id, submission_id=request.submission_id, @@ -77,7 +77,7 @@ async def stage_terminal(session, facts, material, evidence_id): .where(CheckerRun.id == run.id) .values( status=result.outcome, - result_json=canonical_post_submit_bytes(result, exclude={"result_digest"}).decode(), + result_json=canonical_checker_bytes(result, exclude={"result_digest"}).decode(), result_digest=result.result_digest, material_custody=material, finalize_evidence_id=str(evidence_id), diff --git a/backend/tests/checkers/execution/test_concurrency.py b/backend/tests/checkers/execution/test_concurrency.py index 79965db5b..e77bba29e 100644 --- a/backend/tests/checkers/execution/test_concurrency.py +++ b/backend/tests/checkers/execution/test_concurrency.py @@ -274,7 +274,10 @@ async def test_member_insertion_waits_for_terminal_parent( from app.modules.checkers.execution_repository import ExecutionRepository from tests.auth_concurrency_support import wait_for_named_database_lock - async with material_fixture(tmp_path, isolated_database_env) as h: + from tests.checkers.external.support import post_registry_spec + + async with material_fixture(tmp_path, isolated_database_env, + post_submit_registry_spec=post_registry_spec()) as h: await reserve(h) executor = live_executor(h) lease, _ = await executor._claim(h.request) @@ -290,7 +293,7 @@ async def paused(repo, run, result): return await original(repo, run, result) monkeypatch.setattr(ExecutionRepository, "write_members", paused) - first = facts.result.member_results[0] + first = facts.result.execution.external_members[0] waiter = "checker-member-race-" + new_record_id().hex async def insert_member(): @@ -305,13 +308,13 @@ async def insert_member(): task_id=str(h.request.task_id), submission_id=str(h.request.submission_id), member_order=0, - checker_name=first.checker_id, - definition_version=first.definition_version, - implementation_version=first.implementation_version, - status=first.status, - code=first.code, - failure_category=first.failure_category, - severity=first.severity, + checker_name=first.requirement_id, + definition_version=first.result.schema_version, + implementation_version=first.registry_entry_digest, + status=first.result.verdict, + code="passed", + failure_category="none", + severity="info", counters=[], ) ) @@ -345,7 +348,7 @@ async def insert_member(): await asyncio.gather(*pending, return_exceptions=True) async with h.factory() as session: assert await session.scalar(select(func.count()).select_from(CheckerResult)) == len( - facts.result.member_results + facts.result.execution.external_members ) assert ( await session.get(CheckerRun, str(facts.result.attempt_id)) diff --git a/backend/tests/tasks/post_submit_routing/support.py b/backend/tests/tasks/post_submit_routing/support.py index 95e8d8c83..2dcc83ab4 100644 --- a/backend/tests/tasks/post_submit_routing/support.py +++ b/backend/tests/tasks/post_submit_routing/support.py @@ -78,13 +78,12 @@ async def source_rows(session) -> list[dict]: ) -async def next_request(h, *, structural_input=None): +async def next_request(h): """Build a genuine later generation for the same immutable Submission.""" request = change_request( h.request, evaluation_request_id=new_record_id(), evaluation_generation=h.request.evaluation_generation + 1, - **({"structural_input": structural_input} if structural_input is not None else {}), ) h.request = request return request @@ -438,13 +437,13 @@ async def activate_successor_guide(h): def completion_for(h): """Build the actual completed publication from retained fixture facts.""" from app.modules.checkers.api.execution import EvaluationCompletion - from app.modules.checkers.api.post_submit import PostSubmitCurrentResultReference + from app.modules.checkers.api.selected_post_submit import SelectedPostSubmitCurrentResultReference return EvaluationCompletion( project_id=h.request.project_id, task_id=h.request.task_id, submission_id=h.request.submission_id, - reference=PostSubmitCurrentResultReference( - **h.result.model_dump(include=set(PostSubmitCurrentResultReference.model_fields) - {"schema_version"}) + reference=SelectedPostSubmitCurrentResultReference( + **h.result.model_dump(include=set(SelectedPostSubmitCurrentResultReference.model_fields) - {"schema_version"}) ), routing_recommendation="allow_review", output_binding_ids=(), execute_evidence_id=h.source["execute_evidence_id"], From a46c80062970cdabe4f2c9037ca9898d30cb9800 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 12:55:25 +0100 Subject: [PATCH 201/283] test(pilot04): distinguish required selected policy from private packet projection --- .commitrail/changes/pilot04-workstream-default-checker.md | 7 +++++++ backend/tests/test_post_submit_selection.py | 7 ++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 47d269e84..4ed2537c3 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -765,3 +765,10 @@ API checkpoint; raw /tmp/pilot04-selected-test-pure-current.log. The wider calle collection failure from module-level old output fixture imports is retained at /tmp/pilot04-selected-test-pure-first.log. Full composed collection/native proof remains required after peer source/shared fixture cleanup; this is not green CI. + +The TASK-to-ART selected-source query now requires the exact immutable +selected_post_submit_policy_body. Its privacy test asserts that field is present, +while exact raw guide/review/revision policy bodies, package URI, summary and +attestation remain absent. The previous blanket policy_body substring assertion +rejected the required selected policy projection; exact project selectors and +no FOR UPDATE read contract remain unchanged. diff --git a/backend/tests/test_post_submit_selection.py b/backend/tests/test_post_submit_selection.py index 02cdc39ef..51bb74400 100644 --- a/backend/tests/test_post_submit_selection.py +++ b/backend/tests/test_post_submit_selection.py @@ -33,7 +33,12 @@ def observe(connection, cursor, statement, parameters, context, executemany): assert "workstream_tasks.project_id =" in statement assert "submissions.task_id =" in statement and "submissions.id =" in statement assert "FOR UPDATE" not in statement - assert "package_uri" not in statement and "policy_body" not in statement + assert "package_uri" not in statement + assert "selected_post_submit_policy_body" in statement + assert not any(field in statement for field in ( + "locked_post_submit_checker_policy_body", "locked_review_policy_body", + "locked_revision_policy_body", + )) assert "worker_attestation" not in statement and "summary" not in statement finally: event.remove(h.engine.sync_engine, "before_cursor_execute", observe) From 6c2090dc922d5cbeee08f0720efc15287e3f249f Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 13:05:25 +0100 Subject: [PATCH 202/283] test(pilot04): remove obsolete phase fixtures and bind current public feedback --- .../pilot04-workstream-default-checker.md | 10 + .../tests/checker_output_admission_helpers.py | 20 +- backend/tests/checkers/execution/support.py | 32 +++ .../execution/test_completion_contract.py | 17 +- .../checkers/execution/test_execution.py | 2 +- .../post_submit/test_public_boundary.py | 9 - backend/tests/checkers/test_phase_service.py | 126 --------- backend/tests/test_checker_output_custody.py | 4 +- ..._submission_bundle_preparation_recovery.py | 266 +++--------------- backend/tests/test_tasks.py | 6 +- 10 files changed, 104 insertions(+), 388 deletions(-) delete mode 100644 backend/tests/checkers/test_phase_service.py diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 4ed2537c3..ba412e928 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -772,3 +772,13 @@ while exact raw guide/review/revision policy bodies, package URI, summary and attestation remain absent. The previous blanket policy_body substring assertion rejected the required selected policy projection; exact project selectors and no FOR UPDATE read contract remain unchanged. + +Further current test-consumer scope, explicitly handed off by the peer: backend/ +tests/checker_output_admission_helpers.py, tests/test_tasks.py, +tests/test_checker_output_custody.py, tests/test_submission_bundle_preparation_recovery.py, +tests/checkers/execution/test_completion_contract.py, removal of +tests/checkers/test_phase_service.py. The obsolete phase adapter is removed; +selected PRE ownership and selected POST consumer/current completion tests retain +phase isolation, canonical result binding and no unchecked callback shortcut. +Output reservation fixtures derive exact stored current request facts, not a +constructed unrelated catalogue request. Unsupported output access remains denied. diff --git a/backend/tests/checker_output_admission_helpers.py b/backend/tests/checker_output_admission_helpers.py index a8843f535..2a1ce4c24 100644 --- a/backend/tests/checker_output_admission_helpers.py +++ b/backend/tests/checker_output_admission_helpers.py @@ -27,9 +27,8 @@ CheckerOutputSlot, ) from app.modules.checkers.models import CheckerRun -from app.modules.checkers.api.post_submit import make_post_submit_request +from app.modules.checkers.api.evaluation_contract import validate_execution_request from app.modules.tasks.models import Submission, WorkstreamTask -from tests.checkers.post_submit.support import request as checker_evaluation_request async def make_checker_output_reservation( @@ -54,15 +53,14 @@ async def make_checker_output_reservation( ) task = await session.get(WorkstreamTask, checker_run.task_id) assert submission is not None and task is not None - seed = checker_evaluation_request(project_id=UUID(task.project_id)) - fields = seed.model_dump(exclude={"request_sha256"}) - fields.update( - task_id=UUID(task.id), - assignment_id=UUID(submission.task_assignment_id), - submission_id=UUID(submission.id), - submission_version=submission.version, - ) - evaluation = make_post_submit_request(**fields) + import json + + evaluation = validate_execution_request(json.loads(checker_run.request_json)) + assert (evaluation.project_id, evaluation.task_id, evaluation.submission_id, + evaluation.submission_version, evaluation.assignment_id) == ( + UUID(task.project_id), UUID(task.id), UUID(submission.id), + submission.version, UUID(submission.task_assignment_id), + ) return CheckerOutputReservation( evaluation=evaluation, checker_run_id=UUID(checker_run.id), diff --git a/backend/tests/checkers/execution/support.py b/backend/tests/checkers/execution/support.py index 45302b299..bc6727fbb 100644 --- a/backend/tests/checkers/execution/support.py +++ b/backend/tests/checkers/execution/support.py @@ -63,6 +63,38 @@ async def execute(self, request, grant): ) +def selected_request(*, project_id=None): + """Supply a closed empty selected policy for pure contract boundary tests.""" + from app.core.hashing import canonical_json_hash + from app.modules.checkers.api.external_policy import LockedExternalPostSubmitPolicy + from app.modules.checkers.api.selected_post_submit import ( + SelectedPostSubmitLockedContext, make_selected_post_submit_request, + ) + + sha = "sha256:" + "a" * 64 + policy = LockedExternalPostSubmitPolicy( + entries=(), policy_sha256=canonical_json_hash({ + "schema_version": "external_post_submit_policy.v1", "entries": [], + }), + ) + context = { + name: (new_record_id() if name.endswith("_id") else + 1 if name.endswith("generation") else + "v1" if "version" in name else sha) + for name in SelectedPostSubmitLockedContext.model_fields + } + context["selected_post_policy_hash"] = policy.policy_sha256 + return make_selected_post_submit_request( + project_id=project_id or new_record_id(), + expected_context=SelectedPostSubmitLockedContext(**context), policy=policy, + evaluation_request_id=new_record_id(), evaluation_generation=1, + task_id=new_record_id(), assignment_id=new_record_id(), + submission_id=new_record_id(), submission_version=1, + content_id=new_record_id(), binding_id=new_record_id(), + content_sha256=sha, byte_count=42, + ) + + def selected_result(source, **changes): """Supply closed empty-policy evidence for owner and material boundary tests.""" from app.modules.checkers.api.selected_post_submit import ( diff --git a/backend/tests/checkers/execution/test_completion_contract.py b/backend/tests/checkers/execution/test_completion_contract.py index df26bc4d9..0f3ad86b9 100644 --- a/backend/tests/checkers/execution/test_completion_contract.py +++ b/backend/tests/checkers/execution/test_completion_contract.py @@ -5,16 +5,15 @@ from app.core.identifiers import new_record_id from app.modules.checkers.api.execution import EvaluationCompletion, VerifiedEvaluationCompletion, VerifiedMaterialFacts -from app.modules.checkers.api.post_submit import PostSubmitCurrentResultReference -from tests.checkers.post_submit.support import request -from tests.checkers.post_submit.test_result_contract import result +from app.modules.checkers.api.selected_post_submit import SelectedPostSubmitCurrentResultReference +from tests.checkers.execution.support import selected_request, selected_result def test_verified_completion_rejects_mismatched_result(): - source = request() - completed = result(source) - reference = PostSubmitCurrentResultReference(**completed.model_dump( - include=set(PostSubmitCurrentResultReference.model_fields) - {"schema_version"}, + source = selected_request() + completed = selected_result(source) + reference = SelectedPostSubmitCurrentResultReference(**completed.model_dump( + include=set(SelectedPostSubmitCurrentResultReference.model_fields) - {"schema_version"}, )) fields = dict( completion=EvaluationCompletion( @@ -33,9 +32,9 @@ def test_verified_completion_rejects_mismatched_result(): ) value = VerifiedEvaluationCompletion(**fields) assert VerifiedEvaluationCompletion.model_validate_json(value.model_dump_json()) == value - other = result(source) + other = selected_result(source) assert other.result_digest != completed.result_digest - infrastructure = result(source, outcome="infrastructure_failed", member_results=(), + infrastructure = selected_result(source, outcome="infrastructure_failed", execution=None, infrastructure_failure_code="material_unavailable") for invalid in (other, infrastructure): with pytest.raises(ValidationError, match="current reference result mismatch"): diff --git a/backend/tests/checkers/execution/test_execution.py b/backend/tests/checkers/execution/test_execution.py index 5804aeff0..5081d924d 100644 --- a/backend/tests/checkers/execution/test_execution.py +++ b/backend/tests/checkers/execution/test_execution.py @@ -104,7 +104,7 @@ async def observe_receipt(*args, **kwargs): ) ) assert tuple(row.checker_name for row in rows) == tuple( - m.registry_entry_id for m in result.execution.external_members + m.requirement_id for m in result.execution.external_members ) assert len(rows) == len(h.request.policy.entries) == 0 event = await session.scalar( diff --git a/backend/tests/checkers/post_submit/test_public_boundary.py b/backend/tests/checkers/post_submit/test_public_boundary.py index 857a4fa70..20d140b0c 100644 --- a/backend/tests/checkers/post_submit/test_public_boundary.py +++ b/backend/tests/checkers/post_submit/test_public_boundary.py @@ -1,10 +1,8 @@ """New contracts cannot expose persistence, individual dispatch or live execution.""" import ast -import inspect from pathlib import Path -from app.modules.checkers.api import PostSubmissionExecutionPort from app.modules.checkers.api.selected_post_submit import SelectedPostSubmissionEvaluationRequest @@ -19,12 +17,5 @@ def test_public_api_has_no_private_owner_types(): assert not any( item.startswith(("sqlalchemy", "app.interfaces.project_agents")) for item in imports ) - for cls in (PostSubmissionExecutionPort,): - methods = [ - name - for name, method in inspect.getmembers(cls, inspect.isfunction) - if not name.startswith("_") - ] - assert methods == ["evaluate_post_submission"] assert "checker_names" not in SelectedPostSubmissionEvaluationRequest.model_fields assert "prepared" not in SelectedPostSubmissionEvaluationRequest.model_fields diff --git a/backend/tests/checkers/test_phase_service.py b/backend/tests/checkers/test_phase_service.py deleted file mode 100644 index fe3dfdf19..000000000 --- a/backend/tests/checkers/test_phase_service.py +++ /dev/null @@ -1,126 +0,0 @@ -"""Phase delegation and removed JSON precheck; no fake post execution custody.""" - -from app.modules.checkers.api.execution import CheckerExecutionUnavailable - -from tests.checkers.execution.support import forbidden_post_submission - -import inspect -from types import SimpleNamespace -from unittest.mock import AsyncMock -from app.core.identifiers import new_record_id - -import pytest -from pydantic import ValidationError - -from app.adapters.artifacts import CheckerPhaseService -from app.modules.artifacts.pre_submit_evidence import PreSubmitEvidencePersistenceResult -from tests.checkers.post_submit.support import OTHER_HASH, request -from tests.checkers.post_submit.test_result_contract import result - - -def phases(pre=None, post=None): - return CheckerPhaseService( - pre_submission=pre if pre is not None else SimpleNamespace(execute_reserved=AsyncMock()), - post_submission=post if post is not None else forbidden_post_submission(), - ) - - -@pytest.mark.asyncio -@pytest.mark.parametrize("replay", (False, True)) -async def test_pre_phase_preserves_owner_result_and_pass_capability(replay): - capability = None if replay else object() - canonical = PreSubmitEvidencePersistenceResult( - evidence=object(), execution=object(), pass_capability=capability, failure_audit=None, - ) - owner = SimpleNamespace(execute_reserved=AsyncMock(return_value=canonical)) - material = SimpleNamespace(prepared_authorization=None) - preparation = object() - selection = canonical if replay else object() - actual = await phases(pre=owner).evaluate_pre_submission( - material, selection, preparation_request=preparation, - ) - assert actual is canonical - assert actual.pass_capability is capability - if replay: - owner.execute_reserved.assert_not_awaited() - else: - owner.execute_reserved.assert_awaited_once_with( - material, selection, preparation_request=preparation, - ) - - -@pytest.mark.asyncio -async def test_pre_phase_rejects_authorization_handle_and_propagates_owner_failure(): - owner = SimpleNamespace(execute_reserved=AsyncMock(side_effect=RuntimeError("unresolved"))) - service = phases(pre=owner) - with pytest.raises(ValueError, match="requires_consumed_authorization"): - await service.evaluate_pre_submission( - SimpleNamespace(prepared_authorization=object()), object(), preparation_request=object(), - ) - owner.execute_reserved.assert_not_awaited() - with pytest.raises(RuntimeError, match="^unresolved$"): - await service.evaluate_pre_submission( - SimpleNamespace(prepared_authorization=None), object(), preparation_request=object(), - ) - owner.execute_reserved.assert_awaited_once() - - -@pytest.mark.asyncio -async def test_post_phase_propagates_owner_denial_without_invoking_pre_owner(): - owner = SimpleNamespace(execute_reserved=AsyncMock()) - executor = SimpleNamespace(evaluate_post_submission=AsyncMock( - side_effect=CheckerExecutionUnavailable("post_submit_execution_unavailable"), - )) - source = request() - with pytest.raises(CheckerExecutionUnavailable, match="^post_submit_execution_unavailable$"): - await phases(pre=owner, post=executor).evaluate_post_submission(source) - executor.evaluate_post_submission.assert_awaited_once_with(source) - owner.execute_reserved.assert_not_awaited() - - -@pytest.mark.asyncio -@pytest.mark.parametrize("damage", (None, "request", "digest", "generation", "members")) -async def test_post_phase_validates_exact_delegated_result(damage): - source = request() - changes = {} - if damage == "request": - changes["request_id"] = new_record_id() - elif damage == "digest": - changes["request_digest"] = OTHER_HASH - elif damage == "generation": - changes["evaluation_generation"] = 2 - elif damage == "members": - changes["member_results"] = result(source).member_results[:-1] - completed = result(source, **changes) - executor = SimpleNamespace(evaluate_post_submission=AsyncMock(return_value=completed)) - service = phases(post=executor) - if damage is None: - assert await service.evaluate_post_submission(source) == completed - else: - with pytest.raises(ValueError, match="post-submit result .* mismatch"): - await service.evaluate_post_submission(source) - executor.evaluate_post_submission.assert_awaited_once_with(source) - - -@pytest.mark.asyncio -async def test_invalid_post_request_never_reaches_executor(): - executor = SimpleNamespace(evaluate_post_submission=AsyncMock()) - source = request().model_copy(update={"project_id": new_record_id()}) - with pytest.raises(ValidationError, match="project mismatch"): - await phases(post=executor).evaluate_post_submission(source) - executor.evaluate_post_submission.assert_not_awaited() - - -def test_two_phase_commands_and_no_draft_packet_precheck_route(): - from app.main import create_app - from app.modules.checkers import runner - - assert [name for name, method in inspect.getmembers(CheckerPhaseService, inspect.isfunction) - if not name.startswith("_")] == ["evaluate_post_submission", "evaluate_pre_submission"] - app = create_app() - assert all("submission-precheck" not in getattr(route, "path", "") for route in app.routes) - schema = app.openapi() - assert all("submission-precheck" not in path for path in schema["paths"]) - for name in ("PreSubmitCheckRequest", "PreSubmitCheckResponse", "CheckerFeedbackItem"): - assert name not in schema["components"]["schemas"] - assert not hasattr(runner, "pre_submit_static_feedback") diff --git a/backend/tests/test_checker_output_custody.py b/backend/tests/test_checker_output_custody.py index b039ca851..d42754f1f 100644 --- a/backend/tests/test_checker_output_custody.py +++ b/backend/tests/test_checker_output_custody.py @@ -35,7 +35,7 @@ output_custody_harness, selector_for, ) -from tests.checkers.post_submit.support import request as post_submit_request +from tests.checkers.execution.support import selected_request async def test_default_composition_denies_before_owner_source_or_storage() -> None: @@ -57,7 +57,7 @@ async def source(): yield b"must-not-be-read" selector = CheckerOutputSelector( - evaluation=post_submit_request(), + evaluation=selected_request(), checker_run_id=new_record_id(), worker_lease_id=new_record_id(), worker_lease_generation=1, diff --git a/backend/tests/test_submission_bundle_preparation_recovery.py b/backend/tests/test_submission_bundle_preparation_recovery.py index 42557b176..768978d53 100644 --- a/backend/tests/test_submission_bundle_preparation_recovery.py +++ b/backend/tests/test_submission_bundle_preparation_recovery.py @@ -1,21 +1,15 @@ """Command recovery distinguishes checked failure, unavailable custody and authority.""" -from contextlib import asynccontextmanager -from dataclasses import asdict, replace -import json from types import SimpleNamespace -from unittest.mock import AsyncMock, Mock, call +from unittest.mock import AsyncMock from app.core.identifiers import new_record_id import pytest from httpx import ASGITransport, AsyncClient -from app.adapters.artifacts import CheckerPhaseService -from tests.checkers.execution.support import forbidden_post_submission from fastapi import HTTPException from starlette.requests import Request -import app.modules.artifacts.submission_admission as submission_admission_module from app.api.routes.artifact_submissions import prepare_submission_bundle from app.adapters.artifacts import ( get_submission_bundle_preparation_actor, @@ -24,57 +18,37 @@ from app.main import create_app from app.modules.artifacts.api import ( SubmissionBundlePreparationCheckFailed, - SubmissionBundlePreparationRequest, SubmissionBundlePreparationRejected, SubmissionBundlePreparationUnavailable, SubmissionBundlePreparationInfrastructureUnavailable, SubmissionBundlePreparationResult, SubmissionBundlePreparationStatus, ) -from app.modules.checkers.api import ( - PreSubmissionExecutionEntryFacts, - PreSubmissionExecutionFacts, +from app.modules.checkers.api.default_checker import ( + WORKSTREAM_DEFAULT_BEHAVIOR_SHA256, WORKSTREAM_DEFAULT_CHECK_IDS, + WorkstreamDefaultCheckerResult, ) +from app.modules.checkers.api.selected_pre_submit import SelectedPreSubmitExecutionFacts from app.modules.authorization.api import ActorIdentityFacts, ActorKind -from app.modules.artifacts.pre_submit_evidence import ( - PreSubmitEvidenceConflict, PreSubmitEvidencePersistenceResult, -) -from app.modules.artifacts.submission_admission import ( - PreparedSubmissionBundlePreparationCommand, SubmissionBundlePreparationRuntime, -) -from tests.artifact_store_helpers import artifact_byte_stream -from tests.test_submission_bundle_admission import _actor, _transaction +def _actor(): + return ActorIdentityFacts(new_record_id(), new_record_id(), ActorKind.HUMAN) + -def _feedback_facts(*, eligible: bool = False) -> PreSubmissionExecutionFacts: - """Build exact canonical facts without defining another feedback contract.""" - statuses = (("passed", None, "passed"),) if eligible else ( - ("warning", None, "quality_signal_warning"), - ("failed", "pre_submission_required_file_missing", "required_file_missing"), - ("dependency_not_run", None, "dependency_not_run"), +def _feedback_facts(*, eligible: bool = False) -> SelectedPreSubmitExecutionFacts: + """Use the sole selected default result shape for sanitized HTTP feedback.""" + checks = tuple({ + "check_id": check_id, + "status": ("passed" if eligible or index < 2 else "failed" if index == 2 else "not_run"), + "failure_code": "high_confidence_secret_detected" if not eligible and index == 2 else None, + "finding_count": 1 if not eligible and index == 2 else 0, + } for index, check_id in enumerate(WORKSTREAM_DEFAULT_CHECK_IDS)) + default = WorkstreamDefaultCheckerResult( + behavior_sha256=WORKSTREAM_DEFAULT_BEHAVIOR_SHA256, + eligible=eligible, checks=checks, + warnings=({"code": "submission_summary_missing"}, {"code": "submission_attestation_missing"}), ) - return PreSubmissionExecutionFacts( - plan_sha256="sha256:" + "1" * 64, - eligible=eligible, - entries=tuple( - PreSubmissionExecutionEntryFacts( - dispatch_authority="workstream.pre_submission_checker_catalogue", - definition_id=f"workstream.test.{index}", - definition_version="1.0.0", - public_name=f"Test check {index}", - policy_source="workstream_default", - effective_plan_sha256="sha256:" + "1" * 64, - rule_instance_id=None, - locked_policy_sha256="sha256:" + "2" * 64, - phase="default_policy", - order=index, - classification="advisory" if status == "warning" else "blocking", - severity="warning" if status == "warning" else "blocking", - checker_execution_status=status, - failure_code=failure_code, - message_code=message_code, - metadata=(("finding_count", index + 1),) if not eligible else (), - ) - for index, (status, failure_code, message_code) in enumerate(statuses) - ), + return SelectedPreSubmitExecutionFacts( + policy_sha256="sha256:" + "1" * 64, workstream_default=default, + required_external_count=0, external_members=(), eligible=eligible, ) @@ -118,7 +92,13 @@ async def test_mounted_preparation_returns_exact_ordered_bounded_feedback() -> N assert payload["error"]["details"] == { "status": "failed", "eligible_to_submit": False, - "results": json.loads(json.dumps([asdict(entry) for entry in facts.entries])), + "results": [ + {"source": "workstream_default", **check.model_dump(mode="json")} + for check in facts.workstream_default.checks + ] + [ + {"source": "workstream_default", "status": "warning", "warning_code": warning.code} + for warning in facts.workstream_default.warnings + ], } rendered = response.text assert all(value not in rendered for value in ("/tmp/", "s3://", "task.toml")) @@ -168,21 +148,22 @@ async def test_mounted_preparation_preserves_non_feedback_error_boundaries( def test_blocked_feedback_rejects_noncanonical_or_non_false_facts(eligible) -> None: with pytest.raises(TypeError, match="feedback facts are invalid"): SubmissionBundlePreparationCheckFailed(object()) # type: ignore[arg-type] + from dataclasses import fields + + original = _feedback_facts() + forged = object.__new__(SelectedPreSubmitExecutionFacts) + for field in fields(original): + object.__setattr__(forged, field.name, getattr(original, field.name)) + object.__setattr__(forged, "eligible", eligible) with pytest.raises(ValueError, match="require eligible false"): - SubmissionBundlePreparationCheckFailed( - replace(_feedback_facts(), eligible=eligible) # type: ignore[arg-type] - ) + SubmissionBundlePreparationCheckFailed(forged) @pytest.mark.asyncio @pytest.mark.parametrize("error,status_code,detail", ( (SubmissionBundlePreparationRejected("submission_bundle_preparation_context_changed"), 409,"submission_bundle_preparation_context_changed"), - (PreparedSubmissionBundlePreparationCommand._evidence_failure( - PreSubmitEvidenceConflict("pre_submit_attempt_result_unavailable")), - 503,"pre_submission_checked_custody_unavailable"), - (PreparedSubmissionBundlePreparationCommand._evidence_failure( - PreSubmitEvidenceConflict("pre_submit_attempt_member_invalid")), + (SubmissionBundlePreparationInfrastructureUnavailable("pre_submission_checked_custody_unavailable"), 503,"pre_submission_checked_custody_unavailable"), (SubmissionBundlePreparationInfrastructureUnavailable("pre_submission_attempt_outcome_unresolved"), 503,"pre_submission_attempt_outcome_unresolved"), @@ -244,172 +225,3 @@ async def test_hidden_preparation_treats_missing_optional_packet_text_as_warning prepared = command.prepare.await_args.args[0] assert prepared.summary == "" assert prepared.contributor_attestation == "" - - - -def _preparation_replay_runtime(prepare_bytes, evidence_id, *, eligible): - """Supply bounded ART outcome doubles for command routing proof.""" - evidence = SimpleNamespace( - reserve=AsyncMock(return_value=object()), - execute_reserved=AsyncMock(return_value=PreSubmitEvidencePersistenceResult( - evidence=SimpleNamespace(evidence_set_id=evidence_id), - pass_capability=None, failure_audit=None, - execution=SimpleNamespace( - eligible=eligible, - checker_facts=_feedback_facts(eligible=eligible), - ), - )), - ) - checker_service = CheckerPhaseService( - pre_submission=evidence, post_submission=forbidden_post_submission(), - ) - checker_service.evaluate_pre_submission = AsyncMock(wraps=checker_service.evaluate_pre_submission) - from app.modules.checkers.api import PostSubmissionEvaluationContent - from tests.checkers.post_submit.support import request as evaluation_request - content = evaluation_request().model_dump(include=set(PostSubmissionEvaluationContent.model_fields)) - return SubmissionBundlePreparationRuntime( - evaluation_content=Mock(return_value=PostSubmissionEvaluationContent(**content)), - checker_service=checker_service, - preparation=SimpleNamespace(prepare=AsyncMock(side_effect=prepare_bytes)), - inspector=object(), - catalogue=object(), - materialization=SimpleNamespace(prepare_authorization=AsyncMock(return_value=object())), - evidence=evidence, - durable_put=object(), - ) - - -async def _assert_blocked_feedback(command, request, runtime) -> None: - with pytest.raises( - SubmissionBundlePreparationCheckFailed, - match="pre_submission_checker_failed", - ) as failure: - await command.prepare(request) - assert ( - failure.value.facts - == runtime.evidence.execute_reserved.return_value.execution.checker_facts - ) - - -@pytest.mark.asyncio -@pytest.mark.parametrize("outcome", ("completed", "blocked", "unresolved", "no_continuation", "corrupt_evidence")) -async def test_hidden_preparation_replays_persisted_checked_custody(monkeypatch, outcome) -> None: - actor_id, task_id, assignment_id = new_record_id(), new_record_id(), new_record_id() - evidence_id = new_record_id() - expected = SubmissionBundlePreparationResult( - put_attempt_id=new_record_id(), - admission_id=new_record_id(), - submission_bundle_preparation_status="ready", - replayed=True, - ) - locked = SimpleNamespace(effective_policy_id=new_record_id(), pre_submit_policy_id=new_record_id()) - prepared = SimpleNamespace( - commitment=SimpleNamespace(sha256="sha256:" + "a" * 64), - inspect=AsyncMock(return_value=object()), - close=AsyncMock(), - ) - events: list[str] = [] - - async def prepare_bytes(*_args, **_kwargs): - events.append("prepare_bytes") - return prepared - - async def revalidate(**_kwargs): - events.append("revalidate") - - runtime = _preparation_replay_runtime(prepare_bytes, evidence_id, eligible=outcome != "blocked") - - @asynccontextmanager - async def runtime_factory(): - yield runtime - - monkeypatch.setattr( - submission_admission_module, - "build_submission_manifest", - Mock(return_value=SimpleNamespace(file_facts=Mock(return_value=()))), - ) - monkeypatch.setattr( - submission_admission_module, - "evaluate_submission_change", - Mock(return_value=object()), - ) - project_id = new_record_id() - authority = SimpleNamespace( - preflight=AsyncMock(), revalidate=AsyncMock(side_effect=revalidate), close=Mock() - ) - command = PreparedSubmissionBundlePreparationCommand( - session=SimpleNamespace(begin=_transaction), - authority=authority, - task_contexts=SimpleNamespace(), - project_contexts=SimpleNamespace(), - runtime_factory=runtime_factory, - ) - command._lock_context = AsyncMock( - return_value=( - SimpleNamespace( - predecessor=None, - checker_remediation_manifest_id=None, - locked_project_context=SimpleNamespace(project_id=project_id), - ), - locked, - ) - ) - command._compile_plan = Mock(return_value=object()) - command._load_predecessor = AsyncMock(return_value=None) - command._existing_durable_result = AsyncMock(return_value=expected) - - request = SubmissionBundlePreparationRequest( - actor=ActorIdentityFacts( - actor_profile_id=actor_id, - identity_link_id=new_record_id(), - actor_kind=ActorKind.HUMAN, - ), - request_id=new_record_id(), - correlation_id=new_record_id(), - task_id=task_id, - assignment_id=assignment_id, - predecessor_submission_id=None, - idempotency_key=new_record_id(), - summary="summary", - contributor_attestation="attestation", - media_type="application/zip", - byte_source=artifact_byte_stream(b"PK\x03\x04replay"), - ) - if outcome in {"unresolved", "corrupt_evidence"}: - runtime.evidence.reserve.side_effect = PreSubmitEvidenceConflict( - "pre_submit_attempt_outcome_unresolved" if outcome == "unresolved" - else "pre_submit_attempt_result_digest_invalid" - ) - if outcome == "no_continuation": - command._existing_durable_result.return_value = None - if outcome == "completed": - runtime.evidence.reserve.return_value = runtime.evidence.execute_reserved.return_value - assert await command.prepare(request) == expected - elif outcome == "blocked": - await _assert_blocked_feedback(command, request, runtime) - command._existing_durable_result.assert_not_awaited() - else: - code = ("pre_submission_attempt_outcome_unresolved" if outcome == "unresolved" - else "pre_submission_checked_custody_unavailable") - with pytest.raises(SubmissionBundlePreparationInfrastructureUnavailable, match=code): - await command.prepare(request) - runtime.preparation.prepare.assert_awaited_once() - assert authority.revalidate.await_args_list == [ - call(request=request, project_id=project_id), - call(request=request, project_id=project_id), - ] - assert events[:2] == ["revalidate", "prepare_bytes"] - runtime.evidence.reserve.assert_awaited_once() - if outcome in {"unresolved", "corrupt_evidence"}: - runtime.checker_service.evaluate_pre_submission.assert_not_awaited() - else: - runtime.checker_service.evaluate_pre_submission.assert_awaited_once() - phase_request, selection = runtime.checker_service.evaluate_pre_submission.await_args.args - assert phase_request.prepared_authorization is None - assert selection is runtime.evidence.reserve.return_value - if outcome in {"completed", "unresolved", "corrupt_evidence"}: - runtime.evidence.execute_reserved.assert_not_awaited() - else: - runtime.evidence.execute_reserved.assert_awaited_once() - prepared.close.assert_awaited_once() - authority.close.assert_called_once_with() diff --git a/backend/tests/test_tasks.py b/backend/tests/test_tasks.py index 1b524b305..81076d016 100644 --- a/backend/tests/test_tasks.py +++ b/backend/tests/test_tasks.py @@ -173,7 +173,7 @@ async def test_task_repository_locks_initial_and_revision_submission_context() - locked_pre_submit_checker_policy_id=str(references.pre_submit_policy_id), locked_pre_submit_checker_bundle_hash=references.pre_submit_policy_bundle_hash, ) - from tests.checkers.post_submit.support import request as evaluation_request + from tests.checkers.execution.support import selected_request from app.modules.tasks.api.transition_audit import TaskPolicyLineage base_context = submission_context_facts( @@ -182,10 +182,10 @@ async def test_task_repository_locks_initial_and_revision_submission_context() - submitter_contribution_policy_version_id=references.locked_contribution_policy_version_id, locked_project_context=references, ) - post_policy = evaluation_request(project_id=references.project_id).policy + post_policy = selected_request(project_id=references.project_id).policy lineage = TaskPolicyLineage(**{ **base_context.locked_policy.model_dump(), - "locked_post_submit_checker_policy_hash": post_policy.policy_hash, + "locked_post_submit_checker_policy_hash": post_policy.policy_sha256, }) for field, value in lineage.model_dump().items(): setattr(task, field, str(value) if field.endswith("_id") and field != "locked_contribution_policy_version_id" else value) From cd93a96dd27e20475276583aa5afbf4021952d75 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 13:07:04 +0100 Subject: [PATCH 203/283] test(pilot04): bind fixtures to sole selected post policy context --- backend/tests/checkers/execution/support.py | 2 +- backend/tests/test_post_submit_selection.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/tests/checkers/execution/support.py b/backend/tests/checkers/execution/support.py index bc6727fbb..ea5b7b445 100644 --- a/backend/tests/checkers/execution/support.py +++ b/backend/tests/checkers/execution/support.py @@ -83,7 +83,7 @@ def selected_request(*, project_id=None): "v1" if "version" in name else sha) for name in SelectedPostSubmitLockedContext.model_fields } - context["selected_post_policy_hash"] = policy.policy_sha256 + context["post_policy_hash"] = policy.policy_sha256 return make_selected_post_submit_request( project_id=project_id or new_record_id(), expected_context=SelectedPostSubmitLockedContext(**context), policy=policy, diff --git a/backend/tests/test_post_submit_selection.py b/backend/tests/test_post_submit_selection.py index 51bb74400..a117ef0dd 100644 --- a/backend/tests/test_post_submit_selection.py +++ b/backend/tests/test_post_submit_selection.py @@ -71,7 +71,7 @@ def observe(connection, cursor, statement, parameters, context, executemany): async def test_frozen_context_substitution_rejected_by_art_selection(tmp_path, isolated_database_env): async with material_fixture(tmp_path, isolated_database_env) as h: - for name in ("source_id", "effective_policy_id", "pre_policy_id", "retained_catalogue_policy_id", "review_policy_id", "revision_policy_id", "review_generation", "revision_hash"): + for name in ("source_id", "effective_policy_id", "pre_policy_id", "post_policy_id", "review_policy_id", "revision_policy_id", "review_generation", "revision_hash"): value = (2 if name == "review_generation" else "sha256:" + "0" * 64 if name == "revision_hash" else new_record_id()) expected = h.request.expected_context.model_copy(update={name: value}) with pytest.raises(PostSubmissionMaterializationUnavailable, match="identity_mismatch"): From 1d447799fecb019800a4c76d7b3d8ea57f81121a Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 13:18:29 +0100 Subject: [PATCH 204/283] test(pilot04): retain current admission guards without obsolete evidence writers --- .../pilot04-workstream-default-checker.md | 13 + .../test_selected_preparation_command.py | 5 +- .../tests/test_pre_submit_evidence_relock.py | 121 ++-- .../tests/test_submission_bundle_admission.py | 671 +----------------- 4 files changed, 95 insertions(+), 715 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index ba412e928..6febad358 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -782,3 +782,16 @@ selected PRE ownership and selected POST consumer/current completion tests retai phase isolation, canonical result binding and no unchecked callback shortcut. Output reservation fixtures derive exact stored current request facts, not a constructed unrelated catalogue request. Unsupported output access remains denied. + +Further explicit lead scope: backend/tests/test_pre_submit_evidence_relock.py and +backend/tests/test_submission_bundle_admission.py; peer handoff also permits +backend/tests/checkers/external/test_selected_preparation_command.py. Remove only +old evidence writer/pass-capability publication phases. Retain current adapter, +preflight-denial-before-bytes, TASK/actor/PROJECT/grant order, root-only authority, +header/media, status projection and cleanup controls. Post-byte drift moves to +the actual selected preparation command and proves no coordinator execution or +durable intent on failed relock. Exact selected admission capability single-use, +construction/substitution and locked lineage remain in +test_selected_pre_submit_coordination.py; selected command/service and actual +root Rust/MinIO failure/replay evidence cover no admission on work/infrastructure +failure. No old writer or live historical factory is reconstructed. diff --git a/backend/tests/checkers/external/test_selected_preparation_command.py b/backend/tests/checkers/external/test_selected_preparation_command.py index 4b4a24a7e..c3855a457 100644 --- a/backend/tests/checkers/external/test_selected_preparation_command.py +++ b/backend/tests/checkers/external/test_selected_preparation_command.py @@ -81,7 +81,6 @@ def _runtime_case(prepared, attempt_id): publish_after_commit=AsyncMock( return_value=SubmissionBundleDurablePutResult( put_attempt_id=new_record_id(), - pre_submit_evidence_set_id=None, operation_identity="sha256:" + "2" * 64, status="prepared", replayed=False, @@ -132,7 +131,7 @@ async def runtime_factory(): external_checker_policies=SimpleNamespace(value="{}"), ) command._lock_authorized_context = AsyncMock( - return_value=(SimpleNamespace(predecessor=None), project) + return_value=(SimpleNamespace(predecessor=None, checker_remediation_manifest_id=None), project) ) command._load_predecessor = AsyncMock(return_value=None) command._load_predecessor_rules = AsyncMock(return_value=None) @@ -184,11 +183,9 @@ async def test_hidden_preparation_uses_selected_pre_before_durable_admission( case.coordinator.reserve.assert_awaited_once_with(case.reservation) case.selected_execution.execute.assert_awaited_once() admitted = case.durable.admit_in_transaction.await_args.args[0] - assert admitted.pass_capability is None assert admitted.selected_completion is case.completion case.durable.publish_after_commit.assert_awaited_once_with( prepared, attempt_id, case.durable.admit_in_transaction.return_value[2], - selected_pre_submit_run_id=attempt_id, ) diff --git a/backend/tests/test_pre_submit_evidence_relock.py b/backend/tests/test_pre_submit_evidence_relock.py index 7ba53ee84..6dc630659 100644 --- a/backend/tests/test_pre_submit_evidence_relock.py +++ b/backend/tests/test_pre_submit_evidence_relock.py @@ -1,73 +1,76 @@ -"""Focused proof for post-byte pre-submit evidence relocking.""" +"""Post-byte TASK drift refuses selected execution and durable admission.""" +from contextlib import asynccontextmanager from types import SimpleNamespace -from unittest.mock import AsyncMock +from unittest.mock import AsyncMock, Mock import pytest -from app.modules.artifacts import pre_submit_evidence -from app.modules.artifacts.pre_submit_evidence import ( - PreSubmitEvidenceConflict, - PreSubmitEvidenceService, +from app.core.identifiers import new_record_id +from app.modules.artifacts.api import ( + SubmissionBundlePreparationRejected, SubmissionBundlePreparationRequest, ) +from app.modules.artifacts.submission_admission import PreparedSubmissionBundlePreparationCommand +from app.modules.authorization.api import ActorIdentityFacts, ActorKind from app.modules.tasks.api import TaskSubmissionContextUnavailable -from tests.test_submission_manifest import _archive, _manifest @pytest.mark.asyncio -async def test_stale_task_relock_denies_before_evidence_or_pass_capability( - monkeypatch: pytest.MonkeyPatch, -) -> None: - """A post-byte TASK drift cannot persist evidence or mint continuation.""" - transaction = SimpleNamespace(is_active=True) - session = SimpleNamespace( - sync_session=SimpleNamespace(get_transaction=lambda: transaction), - in_nested_transaction=lambda: False, +async def test_stale_task_relock_denies_before_selected_execution_or_admission(): + actor = ActorIdentityFacts(new_record_id(), new_record_id(), ActorKind.HUMAN) + references = SimpleNamespace( + project_id=new_record_id(), guide_version="v1", + source_snapshot_id=new_record_id(), source_snapshot_hash="sha256:" + "1" * 64, + effective_policy_id=new_record_id(), effective_policy_hash="sha256:" + "2" * 64, + pre_submit_policy_id=new_record_id(), pre_submit_policy_bundle_hash="sha256:" + "3" * 64, ) - task_contexts = SimpleNamespace( - lock_submission_context=AsyncMock( - side_effect=TaskSubmissionContextUnavailable( - "task_submission_context_invalid" - ) - ) - ) - project_contexts = SimpleNamespace(lock_locked_policy_context=AsyncMock()) - service = PreSubmitEvidenceService( - session, # type: ignore[arg-type] - task_contexts=task_contexts, - project_contexts=project_contexts, - ) - service._repository.persist = AsyncMock() # type: ignore[method-assign] - monkeypatch.setattr(pre_submit_evidence, "_validate_execution", lambda *_: None) - manifest = _manifest(_archive([("answer.txt", b"verified")])) - custody = SimpleNamespace( - storage_scheme="s3", - prepared_generation_id="generation", - archive_sha256="archive", - archive_byte_count=1, - semantic_manifest_sha256=manifest.sha256, - ) - request = SimpleNamespace( - manifest=manifest, - plan=object(), - execution=SimpleNamespace(custody=custody), - prepared_generation_id="generation", - archive_sha256="archive", - archive_byte_count=1, - semantic_manifest_sha256=manifest.sha256, - task_id="task", - assignment_id="assignment", - actor_profile_id="actor", - predecessor_submission_id=None, + task = SimpleNamespace(locked_project_context=references, predecessor=None, + checker_remediation_manifest_id=None) + tasks = SimpleNamespace(lock_submission_context=AsyncMock(side_effect=[ + task, TaskSubmissionContextUnavailable("task_submission_context_invalid"), + ])) + projects = SimpleNamespace(lock_locked_policy_context=AsyncMock(return_value=object())) + authority = SimpleNamespace(preflight=AsyncMock(), lock_actor=AsyncMock(), + revalidate=AsyncMock(), close=Mock()) + prepared = SimpleNamespace(close=AsyncMock()) + coordinator = SimpleNamespace(read_current=AsyncMock(), reserve=AsyncMock()) + executor = SimpleNamespace(execute=AsyncMock()) + durable = SimpleNamespace(admit_in_transaction=AsyncMock(), publish_after_commit=AsyncMock()) + runtime = SimpleNamespace( + selected_coordinator=coordinator, selected_execution=executor, storage_scheme="s3", + preparation=SimpleNamespace(prepare=AsyncMock(return_value=prepared)), durable_put=durable, ) - with pytest.raises( - PreSubmitEvidenceConflict, - match="pre_submit_locked_context_changed", - ): - await service.persist(request) # type: ignore[arg-type] + @asynccontextmanager + async def root(): + yield - task_contexts.lock_submission_context.assert_awaited_once() - project_contexts.lock_locked_policy_context.assert_not_awaited() - service._repository.persist.assert_not_awaited() # type: ignore[union-attr] - assert service._live_pass_bindings == set() + @asynccontextmanager + async def runtime_factory(): + yield runtime + + command = PreparedSubmissionBundlePreparationCommand( + session=SimpleNamespace(begin=root), authority=authority, + task_contexts=tasks, project_contexts=projects, runtime_factory=runtime_factory, + ) + request = SubmissionBundlePreparationRequest( + actor=actor, request_id=new_record_id(), correlation_id=new_record_id(), + task_id=new_record_id(), assignment_id=new_record_id(), predecessor_submission_id=None, + idempotency_key=new_record_id(), summary="", contributor_attestation="", + media_type="application/zip", byte_source=object(), + ) + with pytest.raises(SubmissionBundlePreparationRejected, + match="^submission_bundle_preparation_context_changed$"): + await command.prepare(request) + assert tasks.lock_submission_context.await_count == 2 + runtime.preparation.prepare.assert_awaited_once_with(request.byte_source, media_type="application/zip") + projects.lock_locked_policy_context.assert_awaited_once() + authority.lock_actor.assert_awaited_once() + authority.revalidate.assert_awaited_once() + coordinator.read_current.assert_not_awaited() + coordinator.reserve.assert_not_awaited() + executor.execute.assert_not_awaited() + durable.admit_in_transaction.assert_not_awaited() + durable.publish_after_commit.assert_not_awaited() + prepared.close.assert_awaited_once() + authority.close.assert_called_once_with() diff --git a/backend/tests/test_submission_bundle_admission.py b/backend/tests/test_submission_bundle_admission.py index 94c01bf54..bb5b33ad8 100644 --- a/backend/tests/test_submission_bundle_admission.py +++ b/backend/tests/test_submission_bundle_admission.py @@ -2,9 +2,7 @@ from __future__ import annotations -import asyncio from contextlib import asynccontextmanager -from datetime import UTC, datetime from types import SimpleNamespace from unittest.mock import AsyncMock, Mock from app.core.identifiers import new_record_id @@ -14,22 +12,14 @@ import app.adapters.artifacts as artifact_adapters from app.core.config import Settings -from app.modules.artifacts.pre_submit_evidence import ( - PreSubmitEvidenceConflict, - PreSubmitEvidenceService, - PreSubmitPassCapability, -) from app.modules.artifacts.api import ( SubmissionBundlePreparationRejected, SubmissionBundlePreparationRequest, SubmissionBundlePreparationResult, SubmissionBundlePreparationUnavailable, ) -from app.modules.artifacts.preparation import ArtifactPreparationService, ArtifactScratchManager from app.modules.artifacts.schemas import ( - ArtifactAdmissionResult, ArtifactAuthorityDeniedError, - SubmissionBundleArtifactAdmissionRequest, ) from app.interfaces.artifacts import ( ArtifactConfigurationError, @@ -40,25 +30,14 @@ DenySubmissionBundlePreparationAuthorization, ) from app.modules.artifacts.submission_admission import ( - SubmissionBundleDurablePutRequest, SubmissionBundleDurablePutResult, - SubmissionBundleDurablePutService, -) -from app.modules.artifacts.submission_materialization import ( - PreparedBundlePreSubmitEvidenceService, ) -from app.modules.artifacts.submission_admission import ( - SubmissionBundleAdmissionPublicationError, - SubmissionBundleAdmissionPublisher, -) -from app.modules.artifacts.service import ArtifactAdmissionService -from app.modules.artifacts.submission_custody import SubmissionBundlePreparedCustody from app.modules.artifacts.submission_admission import ( PreparedSubmissionBundlePreparationCommand, ) from app.modules.authorization.api import ActorIdentityFacts, ActorKind from app.modules.authorization.prepared import PreparedAuthorizationHandle -from tests.artifact_store_helpers import artifact_byte_stream, artifact_preparation_limits +from tests.artifact_store_helpers import artifact_byte_stream from tests.artifact_store_helpers import artifact_admission_limit_settings from app.main import create_app from app.api.routes.artifact_submissions import router as submission_router @@ -240,7 +219,6 @@ def test_artifact_adapter_composes_submission_command_from_owner_ports( request.scope["app"] = SimpleNamespace( state=SimpleNamespace( settings=Settings(), - pre_submission_checker_catalogue=object(), ) ) session = object() @@ -301,18 +279,6 @@ async def _transaction(): yield -async def _prepared(tmp_path): - manager = ArtifactScratchManager( - root=tmp_path / "scratch", - limits=artifact_preparation_limits(), - ) - prepared = await ArtifactPreparationService(manager).prepare( - artifact_byte_stream(b"PK\x03\x04checked submission"), - media_type="application/zip", - ) - return manager, prepared - - @pytest.mark.asyncio async def test_hidden_preparation_denies_before_reading_uploaded_bytes() -> None: reads = 0 @@ -386,33 +352,29 @@ async def invoke(*_args, **_kwargs): lock_actor=AsyncMock(side_effect=phase("actor")), revalidate=AsyncMock(side_effect=phase("grant")), ) - materialization = SimpleNamespace( - _storage_scheme="s3", - authorize_inspected=AsyncMock(), - ) - workflow = PreparedBundlePreSubmitEvidenceService( - session=SimpleNamespace(), - materialization=materialization, - preparation_authorization=authority, - task_contexts=SimpleNamespace(), - project_contexts=SimpleNamespace(), - ) - evidence = SimpleNamespace( - lock_task_context=AsyncMock(side_effect=phase("task")), - lock_project_context=AsyncMock(side_effect=phase("project")), + references = SimpleNamespace( + project_id=new_record_id(), guide_version="v1", + source_snapshot_id=new_record_id(), source_snapshot_hash=_sha("1"), + effective_policy_id=new_record_id(), effective_policy_hash=_sha("2"), + pre_submit_policy_id=new_record_id(), pre_submit_policy_bundle_hash=_sha("3"), + ) + task = SimpleNamespace(locked_project_context=references) + async def lock_task(*args): + events.append("task") + return task + project_contexts = SimpleNamespace(lock_locked_policy_context=AsyncMock(side_effect=phase("project"))) + command = PreparedSubmissionBundlePreparationCommand( + session=SimpleNamespace(), authority=authority, + task_contexts=SimpleNamespace(lock_submission_context=AsyncMock(side_effect=lock_task)), + project_contexts=project_contexts, runtime_factory=Mock(), ) - workflow._evidence_service = lambda: evidence - workflow._input = Mock(return_value=object()) - workflow._attempts.reserve = AsyncMock() - with pytest.raises(ArtifactAuthorityDeniedError) as caught: - await workflow.reserve(object(), preparation_request=object()) + await command._lock_authorized_context(_preparation_request(byte_source=object())) assert caught.value is denial assert events == ( ["task", "actor"] if denied_phase == "actor" else ["task", "actor", "project", "grant"] ) - materialization.authorize_inspected.assert_not_awaited() - workflow._attempts.reserve.assert_not_awaited() + command._runtime_factory.assert_not_called() @pytest.mark.asyncio @@ -479,7 +441,7 @@ def test_durable_put_result_projects_every_closed_preparation_status( ) -> None: durable = SubmissionBundleDurablePutResult( put_attempt_id=new_record_id(), - pre_submit_evidence_set_id=new_record_id(), + selected_pre_submit_run_id=new_record_id(), operation_identity=_sha("9"), admission_id=None, status=durable_status, @@ -495,601 +457,6 @@ def test_durable_put_result_projects_every_closed_preparation_status( ) -def test_post_byte_locked_context_conflict_maps_to_public_race_code() -> None: - conflict = PreSubmitEvidenceConflict("pre_submit_locked_context_changed") - failure = PreparedSubmissionBundlePreparationCommand._evidence_failure(conflict) - assert isinstance(failure, SubmissionBundlePreparationRejected) - assert str(failure) == "submission_bundle_preparation_context_changed" - - -def _capability(prepared, evidence_set_id): - service = PreSubmitEvidenceService( - SimpleNamespace(), - task_contexts=SimpleNamespace(), - project_contexts=SimpleNamespace(), - ) - return service._mint_pass_capability( - evidence_set_id=evidence_set_id, - prepared_generation_id=prepared.generation_id, - predecessor_submission_id=None, - checker_remediation_manifest_id=None, - effective_plan_sha256=_sha("7"), - archive_sha256=prepared.commitment.sha256, - semantic_manifest_sha256=_sha("2"), - storage_scheme="s3", - ) - - -@pytest.mark.asyncio -@pytest.mark.parametrize("observed_confirmation", [False, True]) -async def test_verified_submission_lineage_publishes_one_ready_admission( - observed_confirmation: bool, -) -> None: - attempt_id = str(new_record_id()) - replica_id = str(new_record_id()) - content_id = str(new_record_id()) - job_id = str(new_record_id()) - receipt_id = str(new_record_id()) - evidence_id = str(new_record_id()) - digest = _sha("1") - evidence = SimpleNamespace( - id=evidence_id, - terminal_status="passed", - eligible=True, - archive_sha256=digest, - archive_byte_count=25, - actor_profile_id=str(new_record_id()), - identity_link_id=str(new_record_id()), - project_id=str(new_record_id()), - task_id=str(new_record_id()), - assignment_id=str(new_record_id()), - predecessor_submission_id=None, - predecessor_submission_version=None, - checker_remediation_manifest_id=None, - semantic_manifest_id=str(new_record_id()), - semantic_manifest_sha256=_sha("2"), - guide_id=str(new_record_id()), - guide_version="1", - source_snapshot_id=str(new_record_id()), - source_snapshot_sha256=_sha("3"), - locked_guide_sha256=_sha("4"), - effective_policy_id=str(new_record_id()), - locked_artifact_policy_sha256=_sha("5"), - pre_submit_policy_id=str(new_record_id()), - locked_checker_policy_sha256=_sha("6"), - effective_plan_sha256=_sha("7"), - locked_policy_context_hash=_sha("8"), - packet_sha256=_sha("9"), - semantic_manifest_body={"schema_version": "submission_manifest.v1", "entries": []}, - ) - attempt = SimpleNamespace( - id=attempt_id, - producer_request_type="submission_bundle", - producer_ref=evidence.actor_profile_id, - project_id=evidence.project_id, - task_id=evidence.task_id, - sha256=digest, - byte_count=25, - media_type="application/zip", - replica_id=replica_id, - receipt_id=None if observed_confirmation else str(new_record_id()), - ) - job = SimpleNamespace( - id=job_id, - originating_put_attempt_id=attempt_id, - replica_id=replica_id, - execution_generation=2, - ) - intent = SimpleNamespace( - id=str(new_record_id()), - pre_submit_evidence_set_id=evidence_id, - selected_pre_submit_run_id=None, - ) - replica = SimpleNamespace( - id=replica_id, - content_id=content_id, - verification_state="verified", - availability_state="available", - integrity_state="valid", - ) - content = SimpleNamespace(id=content_id, sha256=digest, byte_count=25) - verification = SimpleNamespace( - id=receipt_id, - verification_job_id=job_id, - execution_generation=2, - outcome="verified", - observed_sha256=digest, - observed_byte_count=25, - ) - put_receipt = SimpleNamespace( - id=str(new_record_id()) if observed_confirmation else attempt.receipt_id - ) - now = datetime.now(UTC) - session = SimpleNamespace( - scalar=AsyncMock( - side_effect=[ - job, - attempt, - intent, - None, - evidence, - replica, - verification, - content, - put_receipt, - now, - ] - ), - add=Mock(), - flush=AsyncMock(), - ) - - admission = await SubmissionBundleAdmissionPublisher(session).publish_verified( - verification_job_id=job_id, - verification_receipt_id=receipt_id, - ) - - assert admission is not None - assert admission.status == "ready" - assert admission.pre_submit_evidence_set_id == evidence_id - assert admission.artifact_content_id == content_id - assert admission.put_operation_receipt_id == ( - None if observed_confirmation else attempt.receipt_id - ) - assert admission.put_observation_receipt_id == ( - put_receipt.id if observed_confirmation else None - ) - session.add.assert_called_once_with(admission) - - -@pytest.mark.asyncio -async def test_observed_confirmed_write_receipt_is_supported() -> None: - attempt = SimpleNamespace( - id=str(new_record_id()), - receipt_id=None, - sha256=_sha("1"), - byte_count=25, - ) - observation = SimpleNamespace(id=str(new_record_id())) - session = SimpleNamespace(scalar=AsyncMock(return_value=observation)) - - operation_id, observation_id = await SubmissionBundleAdmissionPublisher( - session - )._write_receipt_ids(attempt) - - assert operation_id is None - assert observation_id == observation.id - - -@pytest.mark.asyncio -async def test_retained_guide_verification_cannot_publish_submission_admission() -> None: - job = SimpleNamespace(id=str(new_record_id()), originating_put_attempt_id=str(new_record_id())) - attempt = SimpleNamespace(id=job.originating_put_attempt_id, producer_request_type="guide") - session = SimpleNamespace( - scalar=AsyncMock(side_effect=[job, attempt]), - add=Mock(), - ) - - result = await SubmissionBundleAdmissionPublisher(session).publish_verified( - verification_job_id=job.id, - verification_receipt_id=str(new_record_id()), - ) - - assert result is None - session.add.assert_not_called() - - -@pytest.mark.asyncio -async def test_unverified_or_mismatched_lineage_is_not_publishable() -> None: - digest = _sha("1") - evidence = SimpleNamespace( - id=str(new_record_id()), - terminal_status="failed", - eligible=False, - archive_sha256=digest, - archive_byte_count=25, - actor_profile_id=str(new_record_id()), - project_id=str(new_record_id()), - task_id=str(new_record_id()), - ) - attempt = SimpleNamespace( - id=str(new_record_id()), - sha256=digest, - byte_count=25, - producer_ref=evidence.actor_profile_id, - project_id=evidence.project_id, - task_id=evidence.task_id, - media_type="application/zip", - replica_id=str(new_record_id()), - ) - job = SimpleNamespace( - id=str(new_record_id()), - originating_put_attempt_id=attempt.id, - replica_id=attempt.replica_id, - execution_generation=1, - ) - replica = SimpleNamespace( - id=attempt.replica_id, - content_id=str(new_record_id()), - verification_state="verified", - availability_state="available", - integrity_state="valid", - ) - content = SimpleNamespace(id=replica.content_id, sha256=digest, byte_count=25) - receipt = SimpleNamespace( - verification_job_id=job.id, - execution_generation=1, - outcome="integrity_mismatch", - observed_sha256=digest, - observed_byte_count=25, - ) - - assert not SubmissionBundleAdmissionPublisher._matches_verified_lineage( - evidence, attempt, job, replica, content, receipt - ) - intent = SimpleNamespace( - id=str(new_record_id()), - pre_submit_evidence_set_id=evidence.id, - selected_pre_submit_run_id=None, - ) - session = SimpleNamespace( - scalar=AsyncMock( - side_effect=[job, attempt, intent, None, evidence, replica, receipt, content] - ), - add=Mock(), - flush=AsyncMock(), - ) - attempt.producer_request_type = "submission_bundle" - with pytest.raises( - SubmissionBundleAdmissionPublicationError, - match="verified submission bundle lineage does not match", - ): - await SubmissionBundleAdmissionPublisher(session).publish_verified( - verification_job_id=job.id, - verification_receipt_id=str(new_record_id()), - ) - session.add.assert_not_called() - session.flush.assert_not_awaited() - - -@pytest.mark.asyncio -async def test_durable_put_admits_in_transaction_then_publishes(tmp_path) -> None: - manager, prepared = await _prepared(tmp_path) - evidence_set_id = new_record_id() - state = {"transaction": True} - transaction = SimpleNamespace(is_active=True) - session = SimpleNamespace( - sync_session=SimpleNamespace(get_transaction=lambda: transaction), - in_nested_transaction=lambda: False, - in_transaction=lambda: state["transaction"], - scalar=AsyncMock(return_value=None), - begin=_transaction, - ) - admission_result = ArtifactAdmissionResult( - attempt_id=new_record_id(), - status="prepared", - operation_identity=_sha("3"), - request_digest=_sha("4"), - charge_ids=(new_record_id(),), - replayed=False, - ) - - async def admit(request, **values): - assert state["transaction"] is True - assert type(request) is SubmissionBundleArtifactAdmissionRequest - assert request.pre_submit_evidence_set_id == evidence_set_id - assert request.custody.prepared_generation_id == prepared.generation_id - assert type(request.custody.pass_capability) is PreSubmitPassCapability - assert values["existing_transaction"] is True - assert values["prepared_authorization"] is None - assert values["submission_prepared_authorization"] is service._authorization - return admission_result - - admission = SimpleNamespace(admit=admit) - storage = SimpleNamespace( - execute_committed_put=AsyncMock(return_value="object_confirmed"), - resume_committed_put=AsyncMock(), - ) - service = SubmissionBundleDurablePutService( - task_contexts=object(), - project_contexts=object(), - session=session, - admission=admission, - storage=storage, - authorization=object(), - ) - try: - retained, selected_evidence_id, durable = await service.admit_in_transaction( - SubmissionBundleDurablePutRequest( - prepared_authorization=None, - prepared_artifact=prepared, - pass_capability=_capability(prepared, evidence_set_id), - ) - ) - storage.execute_committed_put.assert_not_awaited() - state["transaction"] = False - result = await service.publish_after_commit( - retained, - selected_evidence_id, - durable, - ) - assert result.pre_submit_evidence_set_id == evidence_set_id - assert result.status == "object_confirmed" - storage.execute_committed_put.assert_awaited_once() - storage.resume_committed_put.assert_not_awaited() - with pytest.raises(RuntimeError, match="prepared artifact is closed"): - _ = prepared.generation_id - finally: - await prepared.close() - manager.close() - - -def test_pass_capability_rejects_direct_construction() -> None: - with pytest.raises(TypeError, match="can only be created by pre-submit evidence"): - PreSubmitPassCapability( - evidence_set_id=new_record_id(), - prepared_generation_id=new_record_id(), - predecessor_submission_id=None, - checker_remediation_manifest_id=None, - effective_plan_sha256=_sha("7"), - archive_sha256=_sha("1"), - semantic_manifest_sha256=_sha("2"), - storage_scheme="s3", - ) - - -def test_pass_capability_rejects_unregistered_service_owner() -> None: - with pytest.raises(TypeError, match="can only be created by pre-submit evidence"): - PreSubmitPassCapability._from_evidence_service( - owner=object.__new__(PreSubmitEvidenceService), - binding=object(), - evidence_set_id=new_record_id(), - prepared_generation_id=new_record_id(), - predecessor_submission_id=None, - checker_remediation_manifest_id=None, - effective_plan_sha256=_sha("7"), - archive_sha256=_sha("1"), - semantic_manifest_sha256=_sha("2"), - storage_scheme="s3", - ) - - -def test_submission_custody_rejects_direct_construction() -> None: - with pytest.raises(TypeError, match="requires live prepared work"): - SubmissionBundlePreparedCustody() - - -def test_submission_request_rejects_evidence_without_live_custody() -> None: - request = SubmissionBundleArtifactAdmissionRequest( - pre_submit_evidence_set_id=new_record_id(), - custody=object(), - replay_durable_intent_id=None, - ) - with pytest.raises(TypeError, match="prepared custody is unavailable"): - _ = request.source - - -def test_replay_lineage_includes_policy_catalogue_and_manifest_identity() -> None: - values = { - "actor_profile_id": str(new_record_id()), - "identity_link_id": str(new_record_id()), - "project_id": str(new_record_id()), - "task_id": str(new_record_id()), - "assignment_id": str(new_record_id()), - "predecessor_submission_id": None, - "predecessor_submission_version": None, - "checker_remediation_manifest_id": None, - "archive_sha256": _sha("1"), - "archive_byte_count": 10, - "semantic_manifest_id": str(new_record_id()), - "semantic_manifest_sha256": _sha("2"), - "guide_id": str(new_record_id()), - "guide_version": "1", - "source_snapshot_id": str(new_record_id()), - "source_snapshot_sha256": _sha("3"), - "locked_guide_sha256": _sha("4"), - "effective_policy_id": str(new_record_id()), - "locked_artifact_policy_sha256": _sha("5"), - "pre_submit_policy_id": str(new_record_id()), - "locked_checker_policy_sha256": _sha("6"), - "effective_plan_sha256": _sha("7"), - "catalogue_id": "workstream.default", - "catalogue_version": "1", - "catalogue_manifest_sha256": _sha("8"), - "storage_scheme": "s3", - "terminal_status": "passed", - "eligible": True, - "result_count": 2, - "result_manifest_sha256": _sha("9"), - } - original = SimpleNamespace(**values) - for field, changed in { - "semantic_manifest_id": str(new_record_id()), - "locked_guide_sha256": _sha("a"), - "effective_policy_id": str(new_record_id()), - "pre_submit_policy_id": str(new_record_id()), - "catalogue_id": "other.catalogue", - "catalogue_version": "2", - "catalogue_manifest_sha256": _sha("b"), - }.items(): - drifted = SimpleNamespace(**{**values, field: changed}) - assert ArtifactAdmissionService._submission_replay_lineage( - original - ) != ArtifactAdmissionService._submission_replay_lineage(drifted) - - -@pytest.mark.asyncio -async def test_concurrent_pass_capability_consumption_has_one_winner(tmp_path) -> None: - manager, prepared = await _prepared(tmp_path) - capability = _capability(prepared, new_record_id()) - - def consume() -> bool: - try: - capability.consume( - prepared_generation_id=prepared.generation_id, - predecessor_submission_id=None, - checker_remediation_manifest_id=None, - effective_plan_sha256=capability.effective_plan_sha256, - archive_sha256=prepared.commitment.sha256, - semantic_manifest_sha256=capability.semantic_manifest_sha256, - storage_scheme=capability.storage_scheme, - ) - except PreSubmitEvidenceConflict: - return False - return True - - try: - outcomes = await asyncio.gather( - asyncio.to_thread(consume), - asyncio.to_thread(consume), - ) - assert sorted(outcomes) == [False, True] - finally: - await prepared.close() - manager.close() - - -@pytest.mark.asyncio -async def test_fresh_checked_custody_resumes_existing_committed_intent(tmp_path) -> None: - manager, prepared = await _prepared(tmp_path) - evidence_set_id = new_record_id() - replay_intent_id = new_record_id() - state = {"transaction": True} - admission_result = ArtifactAdmissionResult( - attempt_id=new_record_id(), - status="absent_replay_required", - operation_identity=_sha("3"), - request_digest=_sha("4"), - charge_ids=(new_record_id(),), - replayed=True, - ) - - async def admit(request, **values): - assert request.replay_durable_intent_id == replay_intent_id - return admission_result - - storage = SimpleNamespace( - execute_committed_put=AsyncMock(), - resume_committed_put=AsyncMock(return_value="object_confirmed"), - ) - service = SubmissionBundleDurablePutService( - task_contexts=object(), - project_contexts=object(), - session=SimpleNamespace( - sync_session=SimpleNamespace(get_transaction=lambda: SimpleNamespace(is_active=True)), - in_nested_transaction=lambda: False, - in_transaction=lambda: state["transaction"], - scalar=AsyncMock(return_value=None), - begin=_transaction, - ), - admission=SimpleNamespace(admit=admit), - storage=storage, - authorization=object(), - ) - try: - retained, selected_evidence_id, durable = await service.admit_in_transaction( - SubmissionBundleDurablePutRequest( - prepared_authorization=object.__new__(PreparedAuthorizationHandle), - prepared_artifact=prepared, - pass_capability=_capability(prepared, evidence_set_id), - replay_durable_intent_id=replay_intent_id, - ) - ) - state["transaction"] = False - result = await service.publish_after_commit( - retained, - selected_evidence_id, - durable, - ) - assert result.replayed is True - storage.resume_committed_put.assert_awaited_once() - storage.execute_committed_put.assert_not_awaited() - finally: - await prepared.close() - manager.close() - - -@pytest.mark.asyncio -async def test_object_confirmed_replay_does_not_reclaim_provider_work(tmp_path) -> None: - manager, prepared = await _prepared(tmp_path) - storage = SimpleNamespace( - execute_committed_put=AsyncMock(), - resume_committed_put=AsyncMock(), - ) - service = SubmissionBundleDurablePutService( - task_contexts=object(), - project_contexts=object(), - session=SimpleNamespace( - in_transaction=lambda: False, - scalar=AsyncMock(return_value=None), - begin=_transaction, - ), - admission=SimpleNamespace(), - storage=storage, - authorization=object(), - ) - try: - result = await service.publish_after_commit( - prepared, - new_record_id(), - ArtifactAdmissionResult( - attempt_id=new_record_id(), - status="object_confirmed", - operation_identity=_sha("3"), - request_digest=_sha("4"), - charge_ids=(new_record_id(),), - replayed=True, - ), - ) - assert result.status == "object_confirmed" - storage.execute_committed_put.assert_not_awaited() - storage.resume_committed_put.assert_not_awaited() - finally: - await prepared.close() - manager.close() - - -@pytest.mark.asyncio -async def test_durable_put_rejects_capability_replay_before_admission(tmp_path) -> None: - manager, prepared = await _prepared(tmp_path) - capability = _capability(prepared, new_record_id()) - capability.consume( - prepared_generation_id=prepared.generation_id, - predecessor_submission_id=None, - checker_remediation_manifest_id=None, - effective_plan_sha256=capability.effective_plan_sha256, - archive_sha256=prepared.commitment.sha256, - semantic_manifest_sha256=capability.semantic_manifest_sha256, - storage_scheme=capability.storage_scheme, - ) - admission = SimpleNamespace(admit=AsyncMock()) - service = SubmissionBundleDurablePutService( - task_contexts=object(), - project_contexts=object(), - session=SimpleNamespace( - sync_session=SimpleNamespace(get_transaction=lambda: SimpleNamespace(is_active=True)), - in_nested_transaction=lambda: False, - in_transaction=lambda: True, - ), - admission=admission, - storage=SimpleNamespace(), - authorization=object(), - ) - try: - with pytest.raises(PreSubmitEvidenceConflict): - await service.admit_in_transaction( - SubmissionBundleDurablePutRequest( - prepared_authorization=object.__new__(PreparedAuthorizationHandle), - prepared_artifact=prepared, - pass_capability=capability, - ) - ) - admission.admit.assert_not_awaited() - finally: - await prepared.close() - manager.close() - - @pytest.mark.asyncio async def test_deny_submission_authority_fails_closed() -> None: with pytest.raises(ArtifactAuthorityDeniedError): From 68a66f172e741767f141fbe8c48ed4f5705fcd65 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 13:27:07 +0100 Subject: [PATCH 205/283] test(pilot04): isolate locked policy closure from counterfeit receipt mismatch --- .../changes/pilot04-workstream-default-checker.md | 7 +++++++ backend/tests/checkers/execution/test_storage.py | 14 +++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 6febad358..582d04d43 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -795,3 +795,10 @@ construction/substitution and locked lineage remain in test_selected_pre_submit_coordination.py; selected command/service and actual root Rust/MinIO failure/replay evidence cover no admission on work/infrastructure failure. No old writer or live historical factory is reconstructed. + +The zero-member/locked-one-image direct SQL negative now binds fresh final AUTH +to the same counterfeit facts and bypasses request validation only for that +exact counterfeit, simulating a faulty application. This prevents a mismatched +valid AUTH digest from masking the locked-policy completeness guard. The normal +request validator remains active for every other result; the final positive +control uses the original complete result. No product checks are weakened. diff --git a/backend/tests/checkers/execution/test_storage.py b/backend/tests/checkers/execution/test_storage.py index 0e6744603..c45b53e29 100644 --- a/backend/tests/checkers/execution/test_storage.py +++ b/backend/tests/checkers/execution/test_storage.py @@ -223,9 +223,21 @@ def faulty_classifier(request, result): return ResultClassification("allow_review", len(short.execution.external_members), 0, 0, 0) monkeypatch.setattr(material_storage_helpers, "classify_result", faulty_classifier) + # This SQL-owner control deliberately simulates an application accepting + # only this counterfeit, while its AUTH digest binds the same counterfeit + # facts. A mismatched valid AUTH receipt must not mask policy-set custody. + from app.modules.checkers.api.selected_post_submit import SelectedPostSubmissionEvaluationResult + validate_request = SelectedPostSubmissionEvaluationResult.validate_request + + def faulty_request_validator(result, request): + if result == short and request == h.request: + return None + return validate_request(result, request) + + monkeypatch.setattr(SelectedPostSubmissionEvaluationResult, "validate_request", faulty_request_validator) async with h.factory() as session: await material_storage_helpers.write_terminal( - session, facts, facts.material.model_dump(mode="json"), authorized_facts=valid, + session, facts, facts.material.model_dump(mode="json"), ) with pytest.raises(IntegrityError, match="checker completed custody or routing invalid"): await session.execute(text("SET CONSTRAINTS public.checker_terminal_custody IMMEDIATE")) From dae26bb9c8a8daa0c3d38a5b2500ec893d1cd68c Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 13:42:01 +0100 Subject: [PATCH 206/283] test(pilot04): project replay status through current selected owner --- backend/tests/test_submission_bundle_admission.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/backend/tests/test_submission_bundle_admission.py b/backend/tests/test_submission_bundle_admission.py index bb5b33ad8..f80f971ef 100644 --- a/backend/tests/test_submission_bundle_admission.py +++ b/backend/tests/test_submission_bundle_admission.py @@ -386,7 +386,7 @@ async def lock_task(*args): ("consumed", "conflict"), ), ) -async def test_existing_durable_preparation_projects_current_admission_state( +async def test_selected_replay_projects_current_admission_state( admission_status, expected_status, ) -> None: @@ -408,7 +408,10 @@ async def test_existing_durable_preparation_projects_current_admission_state( runtime_factory=Mock(), ) - result = await command._existing_durable_result(new_record_id()) + result = await command._selected_replay_result(SimpleNamespace( + run_id=new_record_id(), status="completed", + terminal=SimpleNamespace(outcome="completed", execution=SimpleNamespace(eligible=True)), + )) assert result == SubmissionBundlePreparationResult( put_attempt_id=attempt_id, From 79397fb0be6c672d1e8dfb612a8935fa20cb061f Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 13:54:11 +0100 Subject: [PATCH 207/283] [PILOT-04] Validate selected checker database guards --- .../versions/0036_selected_checker_flow.py | 6 +++-- backend/tests/conftest.py | 2 +- backend/tests/test_alembic.py | 23 +++++++++++++++++++ 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/backend/alembic/versions/0036_selected_checker_flow.py b/backend/alembic/versions/0036_selected_checker_flow.py index c84d23303..2366f15a7 100644 --- a/backend/alembic/versions/0036_selected_checker_flow.py +++ b/backend/alembic/versions/0036_selected_checker_flow.py @@ -785,7 +785,7 @@ def _replace_post_policy_custody() -> None: AND entry->'registry'->>'capability_id'=binding->>'capability_id' AND entry->'registry'->>'capability_version'=binding->>'capability_version' AND entry->'configuration'=COALESCE((SELECT jsonb_object_agg(parameter->>'name',parameter->'value') - FROM jsonb_array_elements(binding->'parameters') parameter),'{}'::jsonb)) THEN + FROM jsonb_array_elements(binding->'parameters') parameter),'{}'::jsonb))) THEN RAISE EXCEPTION 'post-policy compiled selection not requested' USING ERRCODE='23514'; END IF;""" if definition.count(old_required) != 1 or definition.count(old_extra) != 1: @@ -996,7 +996,9 @@ def _replace_checker_terminal_custody() -> None: ) mismatch = """ IF result->'member_results' IS DISTINCT FROM members OR current_run.passed_count IS DISTINCT FROM passed OR current_run.warning_count IS DISTINCT FROM warning OR current_run.failed_count IS DISTINCT FROM failed - OR current_run.blocking_count IS DISTINCT FROM blocking THEN""" + OR current_run.blocking_count IS DISTINCT FROM blocking THEN + RAISE EXCEPTION 'checker terminal members differ' USING ERRCODE='23514'; + END IF;""" if mismatch not in definition: mismatch = mismatch.replace(" IF", " IF").replace(" OR", " OR") selected_check = r""" diff --git a/backend/tests/conftest.py b/backend/tests/conftest.py index 52e222404..3c241717b 100644 --- a/backend/tests/conftest.py +++ b/backend/tests/conftest.py @@ -23,7 +23,7 @@ DDL_LOCK_DIRECTORY = Path("/tmp") # Match the PostgreSQL 16 engine used by Backend CI. Catalog identity rendering # differs across major versions; regenerate only after comparing actual objects. -EXPECTED_PUBLIC_SCHEMA_SHA256 = "7e60f0c99a9968edf0e64781d7c9a8c8495fab3cfd3200a4d01fc09bdd6fa4e9" +EXPECTED_PUBLIC_SCHEMA_SHA256 = "a8511b13c4657acec11a612b1ab572703dbc0a1a728d2eedbf0221f769d78a99" PROTECTED_TEST_TABLES = ( "actor_profile_migration_state", "alembic_version", diff --git a/backend/tests/test_alembic.py b/backend/tests/test_alembic.py index 0397929b2..7518951e5 100644 --- a/backend/tests/test_alembic.py +++ b/backend/tests/test_alembic.py @@ -216,8 +216,29 @@ def test_current_head_installs_selected_only_checker_custody( command.upgrade(config, HEAD_REVISION) async def installed_functions() -> dict[str, str]: + from tests.conftest import _assert_canonical_test_schema + connection = await asyncpg.connect(isolated_database_env.replace("+asyncpg", "")) + transaction = connection.transaction() + await transaction.start() try: + await connection.execute("set local check_function_bodies = true") + installed = await connection.fetch( + "select p.oid,p.oid::regprocedure::text as identity " + "from pg_proc p join pg_namespace n on n.oid=p.pronamespace " + "join pg_language l on l.oid=p.prolang " + "where n.nspname='public' and l.lanname='plpgsql' order by p.oid" + ) + assert installed + for row in installed: + try: + await connection.fetchval( + "select pg_catalog.plpgsql_validator($1::oid)", row["oid"] + ) + except asyncpg.PostgresError as error: + raise AssertionError( + f"installed function does not compile: {row['identity']}" + ) from error rows = await connection.fetch( "select p.proname,pg_get_functiondef(p.oid) as definition " "from pg_proc p join pg_namespace n on n.oid=p.pronamespace " @@ -232,8 +253,10 @@ async def installed_functions() -> dict[str, str]: "require_post_policy_operation", ], ) + await _assert_canonical_test_schema(connection) return {row["proname"]: row["definition"] for row in rows} finally: + await transaction.rollback() await connection.close() definitions = asyncio.run(installed_functions()) From faf6bbda0155f0550c3ac8a415f9bcd6189291f8 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 13:55:11 +0100 Subject: [PATCH 208/283] [PILOT-04] Seed checker migration history as raw facts --- .../execution/historical_execution.py | 169 ++++++---- .../tests/historical_submission_fixtures.py | 298 ++++++++++++------ 2 files changed, 303 insertions(+), 164 deletions(-) diff --git a/backend/tests/checkers/execution/historical_execution.py b/backend/tests/checkers/execution/historical_execution.py index 6728ebe39..726873618 100644 --- a/backend/tests/checkers/execution/historical_execution.py +++ b/backend/tests/checkers/execution/historical_execution.py @@ -4,43 +4,41 @@ fabricated: that evidence did not exist in these schema revisions. """ +import json from contextlib import asynccontextmanager from datetime import timedelta from uuid import UUID -from pydantic import BaseModel from sqlalchemy import insert, text from app.adapters.outbox import outbox_append +from app.core.hashing import canonical_json_hash from app.core.identifiers import new_record_id from app.modules.checkers.api.execution import ( EvaluationReservation, ExecutionLease, - EvaluationCompletion, VerifiedMaterialFacts, COMPLETION_EVENT, ) -from app.modules.checkers.api.post_submit import ( - PostSubmissionEvaluationRequest, - PostSubmissionEvaluationResult, - PostSubmitCurrentResultReference, -) -from app.modules.checkers.api.historical_post_submit import canonical_post_submit_bytes -from app.modules.checkers.execution_repository import request_text -from app.modules.checkers.execution_results import classify_result from app.modules.checkers.models import CheckerRun, CheckerResult -from app.modules.checkers.post_submit_contracts import make_post_submit_result from app.modules.outbox.api import OutboxAppendInput from app.modules.tasks.models import AuditEvent -from tests.checkers.post_submit.test_result_contract import result as value_result -from tests.historical_submission_fixtures import historical_material_fixture +from tests.historical_submission_fixtures import ( + HistoricalRawValue, + _raw, + historical_material_fixture, +) -class HistoricalTerminalFacts(BaseModel): - request: PostSubmissionEvaluationRequest - lease: ExecutionLease - result: PostSubmissionEvaluationResult - material: VerifiedMaterialFacts | None +def _canonical_text(value: HistoricalRawValue, *, exclude=frozenset()) -> str: + """Encode an archived predecessor object without invoking a product decoder.""" + return json.dumps( + value.model_dump(exclude=exclude), + sort_keys=True, + separators=(",", ":"), + ensure_ascii=False, + allow_nan=False, + ) async def historical_revision(session): @@ -75,7 +73,7 @@ async def historical_reserve(h): evaluation_request_id=str(r.evaluation_request_id), phase="post_submission", evaluation_generation=r.evaluation_generation, - request_json=request_text(r), + request_json=_canonical_text(r, exclude={"request_sha256"}), request_digest=r.request_sha256, result_id=str(result_id), trigger_source="coordinated_evaluation", @@ -207,25 +205,45 @@ async def historical_lease(h): def historical_terminal_facts(h, lease, outcome="completed"): - result = value_result( - h.request, attempt_id=lease.reservation.attempt_id, result_id=lease.reservation.result_id - ) - if outcome == "infrastructure_failed": - result = make_post_submit_result( - **( - result.model_dump(exclude={"result_digest"}) - | { - "outcome": outcome, - "member_results": (), - "infrastructure_failure_code": "implementation_unavailable", - } - ) + """Build literal result rows from the archived request facts.""" + members = tuple( + _raw( + { + "schema_version": "post_submit_structural_result", + "checker_id": entry.checker_id, + "definition_version": entry.definition_version, + "implementation_version": entry.implementation_version, + "status": "passed", + "code": "passed", + "failure_category": "none", + "severity": "info", + "counters": [], + } ) - return HistoricalTerminalFacts( - request=h.request, - lease=lease, - result=result, - material=VerifiedMaterialFacts( + for entry in h.request.policy.entries + ) + body = { + "schema_version": "post_submit_evaluation_result", + "request_id": h.request.evaluation_request_id, + "request_digest": h.request.request_sha256, + "attempt_id": lease.reservation.attempt_id, + "evaluation_generation": h.request.evaluation_generation, + "result_id": lease.reservation.result_id, + "outcome": outcome, + "member_results": members if outcome == "completed" else (), + "infrastructure_failure_code": ( + None if outcome == "completed" else "implementation_unavailable" + ), + } + body["result_digest"] = canonical_json_hash( + _raw(body).model_dump() + ) + return _raw( + { + "request": h.request, + "lease": lease, + "result": _raw(body), + "material": VerifiedMaterialFacts( submission_id=h.request.submission_id, submission_version=h.request.submission_version, admission_id=h.created.admission_id, @@ -235,7 +253,8 @@ def historical_terminal_facts(h, lease, outcome="completed"): content_sha256=h.request.content_sha256, byte_count=h.request.byte_count, semantic_manifest_sha256=h.manifest.sha256, - ), + ), + } ) @@ -247,7 +266,28 @@ async def historical_write_terminal(session, facts, material): text("SELECT execute_evidence_id FROM public.checker_runs WHERE id=:id"), {"id": run_id} ) final_id = new_record_id() - classification = classify_result(request, result) + members = result.member_results + passed = sum(item.status == "passed" for item in members) + warning = sum(item.status == "warning" for item in members) + failed = sum(item.status == "failed" for item in members) + blocking_severities = set(request.policy.blocking_severities) + blocking = sum( + item.status != "passed" and item.severity in blocking_severities + for item in members + ) + setup = any( + item.status != "passed" and item.failure_category == "task_configuration" + for item in members + ) + routing = ( + "not_evaluated" + if result.outcome != "completed" + else "task_setup_blocked" + if setup + else "needs_revision" + if blocking + else "allow_review" + ) for order, member in enumerate(result.member_results): await session.execute( insert(CheckerResult.__table__).values( @@ -263,26 +303,30 @@ async def historical_write_terminal(session, facts, material): severity=member.severity, code=member.code, failure_category=member.failure_category, - counters=[v.model_dump(mode="json") for v in member.counters], + counters=[value.model_dump() for value in member.counters], ) ) event_id = None if result.outcome == "completed": - reference = PostSubmitCurrentResultReference( - **result.model_dump( - include=set(PostSubmitCurrentResultReference.model_fields) - {"schema_version"} - ) - ) - event = EvaluationCompletion( - project_id=request.project_id, - task_id=request.task_id, - submission_id=request.submission_id, - reference=reference, - routing_recommendation=classification.routing, - output_binding_ids=(), - execute_evidence_id=UUID(str(execute_id)), - finalize_evidence_id=final_id, - ) + reference = { + "schema_version": "post_submit_current_result_reference", + "request_id": str(result.request_id), + "request_digest": result.request_digest, + "attempt_id": str(result.attempt_id), + "evaluation_generation": result.evaluation_generation, + "result_id": str(result.result_id), + "result_digest": result.result_digest, + } + event = { + "project_id": str(request.project_id), + "task_id": str(request.task_id), + "submission_id": str(request.submission_id), + "reference": reference, + "routing_recommendation": routing, + "output_binding_ids": [], + "execute_evidence_id": str(execute_id), + "finalize_evidence_id": str(final_id), + } appended = await outbox_append(session).append( OutboxAppendInput( event_type=COMPLETION_EVENT, @@ -292,11 +336,10 @@ async def historical_write_terminal(session, facts, material): project_id=request.project_id, correlation_id=str(request.evaluation_request_id), idempotency_key="checker-completed:" + str(run_id), - payload=event.model_dump(mode="json"), + payload=event, ) ) event_id = appended.event_id - import json await session.execute( text("""UPDATE public.checker_runs SET status=:status, @@ -307,16 +350,16 @@ async def historical_write_terminal(session, facts, material): dict( id=run_id, status=result.outcome, - body=canonical_post_submit_bytes(result, exclude={"result_digest"}).decode(), + body=_canonical_text(result, exclude={"result_digest"}), digest=result.result_digest, material=json.dumps(material) if material is not None else None, final=final_id, - routing=classification.routing, + routing=routing, failure=result.infrastructure_failure_code, - passed=classification.passed, - warning=classification.warning, - failed=classification.failed, - blocking=classification.blocking, + passed=passed, + warning=warning, + failed=failed, + blocking=blocking, event=event_id, ), ) diff --git a/backend/tests/historical_submission_fixtures.py b/backend/tests/historical_submission_fixtures.py index 026a914e1..265f3ed3a 100644 --- a/backend/tests/historical_submission_fixtures.py +++ b/backend/tests/historical_submission_fixtures.py @@ -5,35 +5,123 @@ receipts. Preparation and verification still use real ART owners and ZIP bytes. """ +import json from contextlib import AsyncExitStack, asynccontextmanager +from copy import deepcopy from types import SimpleNamespace from uuid import UUID from sqlalchemy import select, func from app.core.identifiers import new_record_id +from app.core.hashing import canonical_json_hash +from app.modules.artifacts.api import SubmissionBundleFile from app.modules.artifacts.models import ArtifactBinding, SubmissionBundleAdmission -from app.modules.checkers.api.post_submit import make_post_submit_request +from app.modules.checkers.api.artifact_paths import required_evidence_path +from app.modules.projects.api import ProjectLockedPolicyContextFacts from app.modules.tasks.api import TaskSubmissionContextRequest +from app.modules.tasks.api import TaskSubmissionContextFacts from app.modules.tasks.models import Submission from app.modules.tasks.repository import TaskRepository from app.modules.tasks.submission_composition import build_submission -from tests.post_submit_materialization_helpers import _material_fixture, _archive_facts from tests.migration_fixtures import current_art_attempt_seed_schema +from tests.post_submit_materialization_helpers import _archive_facts, _material_fixture -import json -from app.modules.artifacts.api import SubmissionBundleFile -from app.modules.projects.api import ProjectLockedPolicyContextFacts -from app.modules.tasks.api import TaskSubmissionContextFacts -from app.modules.checkers.api import SubmissionPacketView -from app.modules.checkers.api.artifact_paths import required_evidence_path -from app.modules.checkers.api.historical_post_submit import CompiledPostSubmitPolicy -from app.modules.checkers.api.post_submit import ( - ExpectedPostSubmitContext, ObservedPostSubmitContext, PostSubmissionEvaluationContent, - PostSubmissionStructuralInput, PostSubmitEvidenceEntry, PostSubmitManifestEntry, PostSubmitPolicyInputs, +class HistoricalRawValue(SimpleNamespace): + """Attribute access over literal predecessor JSON, never a product contract.""" + + def model_dump(self, *, exclude=frozenset(), **_options): + def dump(value): + if isinstance(value, HistoricalRawValue): + return {key: dump(item) for key, item in vars(value).items()} + if isinstance(value, tuple): + return [dump(item) for item in value] + if isinstance(value, UUID): + return str(value) + return deepcopy(value) + + return { + key: dump(value) + for key, value in vars(self).items() + if key not in exclude + } + + def model_copy(self, *, update): + values = vars(self) | update + return HistoricalRawValue(**values) + + +def _raw(value): + if isinstance(value, dict): + return HistoricalRawValue(**{key: _raw(item) for key, item in value.items()}) + if isinstance(value, list): + return tuple(_raw(item) for item in value) + return value + + +_HISTORICAL_DEFINITIONS = ( + ("check_submission_packet", "packet_presence", "packet_fields_missing", "submission_structure", "failed", "high", True), + ("check_policy_context_present", "policy_context_consistency", "policy_context_invalid", "task_configuration", "failed", "high", True), + ("check_evidence_present", "evidence_presence", "evidence_missing", "submission_structure", "failed", "high", True), + ("check_evidence_integrity", "evidence_structure", "evidence_structure_invalid", "submission_structure", "failed", "high", True), + ("check_required_files", "required_path_presence", "required_files_missing", "submission_structure", "failed", "high", True), + ("check_forbidden_files", "forbidden_path_detection", "forbidden_path_present", "submission_structure", "failed", "high", True), + ("check_confidentiality_attestation", "attestation_presence", "attestation_missing", "submission_structure", "failed", "high", True), + ("check_low_quality_generated_artifacts", "placeholder_signal_detection", "placeholder_signal", "submission_structure", "warning", "medium", True), + ("check_acceptance_criteria_present", "criteria_presence", "acceptance_criteria_missing", "task_configuration", "failed", "high", False), ) -from tests.historical_checker_metadata import historical_post_submit_catalogue + + +def _historical_catalogue() -> dict[str, object]: + resources = { + "deadline_ms": 5000, + "maximum_evidence_items": 1024, + "maximum_generated_output_bytes": 0, + "maximum_input_bytes": 1_048_576, + "maximum_manifest_items": 1024, + "maximum_policy_items": 256, + "maximum_result_bytes": 4096, + "maximum_results": 1, + "maximum_text_characters": 65_536, + "phase_deadline_ms": 45_000, + } + definitions = [] + for order, values in enumerate(_HISTORICAL_DEFINITIONS, 1): + capability, claim, code, category, status, severity, platform_default = values + definitions.append( + { + "capability_id": capability, + "capability_version": "v0.1", + "configuration_schema": "post_submit_empty_configuration", + "dependencies": [], + "disabled_behavior": "unavailable", + "execution_method": "deterministic", + "failure_category": category, + "failure_code": code, + "failure_severity": severity, + "failure_status": status, + "implementation_version": "workstream-structural", + "input_schema": "post_submit_structural_input", + "order": order, + "platform_default": platform_default, + "provider_recovery": "none", + "required_output_roles": [], + "resources": resources, + "result_schema": "post_submit_structural_result", + "selectable": not platform_default, + "stage": "post_submit", + "state": "enabled", + "supported_claim": claim, + } + ) + return { + "catalogue_id": "workstream.post_submission_checkers", + "definitions": definitions, + "manifest_sha256": "sha256:87b454499eca2dbf10e86495e4f9b2a4440977a51d5ae5c4d3f6405672fa89a5", + "schema_version": "post_submission_checker_capability_projection", + "source_version": "v0.1", + } async def write_historical_submission(factory, context, request): @@ -92,123 +180,131 @@ async def write_historical_submission(factory, context, request): def submission_evaluation_content( task_context: TaskSubmissionContextFacts, project_context: ProjectLockedPolicyContextFacts, - packet: SubmissionPacketView, + packet, files: tuple[SubmissionBundleFile, ...], archive_sha256: str, -) -> PostSubmissionEvaluationContent: - """Project immutable pre-cutover evidence for retained historical fixtures. - - This test-only projection reconstructs the exact predecessor record shape - for migration and immutable-evidence proofs. Product callers cannot use it. - """ +) -> HistoricalRawValue: + """Build the literal predecessor JSON retained by migration fixtures.""" from app.adapters.tasks import validate_submission_policy_context validate_submission_policy_context(task_context, project_context) stamps = task_context.locked_policy - expected = ExpectedPostSubmitContext( - guide_version=stamps.locked_guide_version, - source_id=stamps.locked_guide_source_snapshot_id, - source_hash=stamps.locked_guide_source_snapshot_hash, - effective_policy_id=( - stamps.locked_effective_project_submission_artifact_policy_id - ), - effective_policy_hash=( - stamps.locked_effective_project_submission_artifact_policy_hash - ), - pre_policy_id=stamps.locked_pre_submit_checker_policy_id, - pre_policy_hash=stamps.locked_pre_submit_checker_bundle_hash, - post_policy_id=stamps.locked_post_submit_checker_policy_id, - post_policy_version=stamps.locked_post_submit_checker_policy_version, - post_policy_hash=stamps.locked_post_submit_checker_policy_hash, - review_policy_id=stamps.locked_review_policy_id, - review_generation=stamps.locked_review_policy_generation, - review_hash=stamps.locked_review_policy_hash, - revision_policy_id=stamps.locked_revision_policy_id, - revision_generation=stamps.locked_revision_policy_generation, - revision_hash=stamps.locked_revision_policy_hash, - ) + expected = { + "guide_version": stamps.locked_guide_version, + "source_id": stamps.locked_guide_source_snapshot_id, + "source_hash": stamps.locked_guide_source_snapshot_hash, + "effective_policy_id": stamps.locked_effective_project_submission_artifact_policy_id, + "effective_policy_hash": stamps.locked_effective_project_submission_artifact_policy_hash, + "pre_policy_id": stamps.locked_pre_submit_checker_policy_id, + "pre_policy_hash": stamps.locked_pre_submit_checker_bundle_hash, + "post_policy_id": stamps.locked_post_submit_checker_policy_id, + "post_policy_version": stamps.locked_post_submit_checker_policy_version, + "post_policy_hash": stamps.locked_post_submit_checker_policy_hash, + "review_policy_id": stamps.locked_review_policy_id, + "review_generation": stamps.locked_review_policy_generation, + "review_hash": stamps.locked_review_policy_hash, + "revision_policy_id": stamps.locked_revision_policy_id, + "revision_generation": stamps.locked_revision_policy_generation, + "revision_hash": stamps.locked_revision_policy_hash, + } effective = json.loads(project_context.effective_policy.value) - policy_inputs = PostSubmitPolicyInputs( - required_evidence_keys=tuple( - item["key"] - for item in effective.get("required_evidence", []) + policy_inputs = { + "required_evidence_keys": [ + item["key"] for item in effective.get("required_evidence", []) if item.get("required", True) - ), - required_artifact_paths=tuple( - item["path"] - for item in effective.get("required_artifacts", []) + ], + "required_artifact_paths": [ + item["path"] for item in effective.get("required_artifacts", []) if item.get("required", True) - ), - forbidden_artifact_patterns=tuple( - item["pattern"] - for item in effective.get("forbidden_artifacts", []) + ], + "forbidden_artifact_patterns": [ + item["pattern"] for item in effective.get("forbidden_artifacts", []) if item.get("pattern") - ), - required_attestation_terms=tuple( + ], + "required_attestation_terms": [ term for term in effective.get("attestation_terms", []) if term - ), - ) + ], + } by_path = {item.normalized_path: item for item in files} - return PostSubmissionEvaluationContent( - project_id=project_context.project_id, - expected_context=expected, - catalogue=historical_post_submit_catalogue(), - policy=CompiledPostSubmitPolicy.model_validate_json( - project_context.compiled_post_submit_policy.value - ), - structural_input=PostSubmissionStructuralInput( - summary=packet.summary, - worker_attestation=packet.contributor_attestation, - package_hash=archive_sha256, - criteria=task_context.acceptance_criteria or "", - manifest=tuple( - PostSubmitManifestEntry( - artifact=item.normalized_path, - hash=item.sha256, - size_bytes=item.byte_count, - ) + body = { + "project_id": project_context.project_id, + "expected_context": expected, + "catalogue": _historical_catalogue(), + "policy": json.loads(project_context.compiled_post_submit_policy.value), + "structural_input": { + "schema_version": "post_submit_structural_input", + "summary": packet.summary, + "worker_attestation": packet.contributor_attestation, + "package_hash": archive_sha256, + "criteria": task_context.acceptance_criteria or "", + "manifest": [ + { + "artifact": item.normalized_path, + "hash": item.sha256, + "notes": None, + "size_bytes": item.byte_count, + } for item in files - ), - evidence=tuple( - PostSubmitEvidenceEntry( - label=key, - type="file", - key=key, - uri=item.normalized_path, - hash=item.sha256, - ) - for key in policy_inputs.required_evidence_keys + ], + "evidence": [ + { + "label": key, + "uri": item.normalized_path, + "hash": item.sha256, + "type": "file", + "key": key, + "policy_key": None, + "evidence_key": None, + "required_evidence_key": None, + } + for key in policy_inputs["required_evidence_keys"] for item in (by_path.get(required_evidence_path(key)),) if item is not None - ), - policy_inputs=policy_inputs, - observed_context=ObservedPostSubmitContext(**expected.model_dump()), - ), - ) + ], + "policy_inputs": policy_inputs, + "observed_context": expected, + }, + } + return _raw(body) async def _historical_request(session, facts, created, data): """Project genuine historical inputs without creating a future reservation.""" from app.adapters.tasks import task_service from app.core.config import get_settings - from app.modules.checkers.api import SubmissionPacketView from app.modules.tasks.models import WorkstreamTask + submission = await session.get(Submission, str(created.submission_id)) task = await session.get(WorkstreamTask, submission.task_id) project = await task_service(session, settings=get_settings())._load_locked_task_context(task) _, manifest, _, digest = _archive_facts(data) content = submission_evaluation_content( - created.task_context, project.facts, - SubmissionPacketView(submission.summary, submission.worker_attestation), - manifest.file_facts(), digest, + created.task_context, + project.facts, + SimpleNamespace( + summary=submission.summary, + contributor_attestation=submission.worker_attestation, + ), + manifest.file_facts(), + digest, ) - return make_post_submit_request( - **content.model_dump(), evaluation_request_id=new_record_id(), evaluation_generation=1, - task_id=facts.task_id, assignment_id=facts.assignment_id, - submission_id=created.submission_id, submission_version=created.submission_version, - content_id=created.artifact_content_id, binding_id=created.artifact_binding_id, - content_sha256=digest, byte_count=len(data), + body = content.model_dump() | { + "schema_version": "post_submit_evaluation_request", + "evaluation_request_id": new_record_id(), + "evaluation_generation": 1, + "task_id": facts.task_id, + "assignment_id": facts.assignment_id, + "submission_id": created.submission_id, + "submission_version": created.submission_version, + "content_id": created.artifact_content_id, + "binding_id": created.artifact_binding_id, + "content_sha256": digest, + "byte_count": len(data), + } + body["request_sha256"] = canonical_json_hash( + _raw(body).model_dump() ) + return _raw(body) @asynccontextmanager From 27f47350af1125ef4c9e655c86bf80fe9b80fef8 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 13:55:06 +0100 Subject: [PATCH 209/283] test(pilot04): keep predecessor migration evidence as raw facts --- .../pilot04-workstream-default-checker.md | 18 ++++ .../execution/test_checker_retry_migration.py | 47 +++++++--- .../execution/test_material_migration.py | 15 ++-- backend/tests/historical_checker_metadata.py | 88 ------------------- .../post_submit_routing/test_requests.py | 4 +- 5 files changed, 62 insertions(+), 110 deletions(-) delete mode 100644 backend/tests/historical_checker_metadata.py diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 582d04d43..8d38bdf4a 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -802,3 +802,21 @@ exact counterfeit, simulating a faulty application. This prevents a mismatched valid AUTH digest from masking the locked-policy completeness guard. The normal request validator remains active for every other result; the final positive control uses the original complete result. No product checks are weakened. + +### Selected-only migration-test caller reconciliation + +Explicit lead/peer ownership permits test-only edits to +`backend/tests/checkers/execution/test_material_migration.py`, +`backend/tests/checkers/execution/test_checker_retry_migration.py`, +`backend/tests/tasks/post_submit_routing/test_requests.py` and removal of +`backend/tests/historical_checker_metadata.py` after its only caller is converted +by the raw predecessor-fixture owner. Preserve retained-row equality, failed +preflight rollback, observed migration/writer exclusion and the Operator-receipt +supersession guard. Archived JSON is updated and hashed as raw facts; current +product decoders never accept it. The live completion-denial fixture uses the +sole selected current-reference API. No production, migration, fingerprint, +workflow, cap or skip changes are allowed. Acceptance requires fresh full +collection after the peer raw producer checkpoint, focused current contracts, +and isolated native migration/SQL controls where the claim depends on Postgres. +This is author test reconciliation, requiring lead/QA review in the complete +candidate; it does not establish hosted readiness. diff --git a/backend/tests/checkers/execution/test_checker_retry_migration.py b/backend/tests/checkers/execution/test_checker_retry_migration.py index f578d4a92..4363a305b 100644 --- a/backend/tests/checkers/execution/test_checker_retry_migration.py +++ b/backend/tests/checkers/execution/test_checker_retry_migration.py @@ -13,13 +13,12 @@ import asyncpg import pytest from alembic import command +from sqlalchemy import text from sqlalchemy.exc import IntegrityError -from app.adapters.checkers import evaluation_coordinator +from app.core.hashing import canonical_json_hash from app.core.identifiers import new_record_id from app.db import session as db_session -from app.modules.checkers.api.post_submit import PostSubmissionEvaluationRequest -from tests.checkers.post_submit.support import change_request from tests.migration_fixtures import _config @@ -167,7 +166,7 @@ async def _retained_rows(connection): async def _source_custody(connection, submission_id): return await connection.fetchrow( """ - SELECT r.status, r.failure_code, r.result_digest, + SELECT r.id AS run_id, r.status, r.failure_code, r.result_digest, r.finalize_evidence_id IS NOT NULL AS finalized, fin.action_id='checker.post_submit.finalize' AS finalize_authority_valid, fin.event_type='SensitiveAuthorizationAllowed' AS finalize_allowed, @@ -231,10 +230,8 @@ async def test_retry_upgrade_preserves_evidence_and_installs_closure( _seed_with_historical_writer, tmp_path, isolated_database_env ) submission_id = UUID(seed["submission_id"]) - request = PostSubmissionEvaluationRequest.model_validate_json( - json.dumps(seed["request"]) - ) - assert request.submission_id == submission_id + request = seed["request"] + assert UUID(request["submission_id"]) == submission_id connection = await _connection(isolated_database_env) try: before, source = await _predecessor_evidence(connection, submission_id) @@ -274,17 +271,39 @@ async def test_retry_upgrade_preserves_evidence_and_installs_closure( finally: await connection.close() - successor = change_request( - request, - evaluation_request_id=new_record_id(), - evaluation_generation=2, - ) + # This is a raw predecessor SQL invariant, not a current runtime request. + successor_request = {key: value for key, value in request.items() if key != "request_sha256"} + successor_request.update(evaluation_request_id=str(new_record_id()), evaluation_generation=2) + successor_id = new_record_id() + request_json = json.dumps(successor_request, sort_keys=True, separators=(",", ":"), ensure_ascii=False) + successor_row = { + "id": str(successor_id), "evaluation_request_id": successor_request["evaluation_request_id"], + "evaluation_generation": 2, "request_json": request_json, + "request_digest": canonical_json_hash(successor_request), "result_id": str(new_record_id()), + "supersedes_checker_run_id": str(source["run_id"]), + "status": "queued", "outcome_source": "none", "routing_recommendation": "not_evaluated", + "worker_lease_id": None, "worker_lease_generation": 0, "worker_lease_expires_at": None, + "execute_evidence_id": None, "finalize_evidence_id": None, + "result_json": None, "result_digest": None, "material_custody": None, + "input_materialization_evidence_id": None, "completion_event_id": None, + "started_at": None, "completed_at": None, "failure_code": None, + "passed_count": 0, "warning_count": 0, "failed_count": 0, "blocking_count": 0, + } with pytest.raises( IntegrityError, match="terminal checker infrastructure retry requires Operator receipt", ): async with db_session.get_session_factory().begin() as session: - await evaluation_coordinator(session).reserve_current_evaluation(successor) + await session.execute(text(""" + INSERT INTO public.checker_runs + SELECT (jsonb_populate_record(NULL::public.checker_runs, + to_jsonb(r) || CAST(:changes AS jsonb))).* + FROM public.checker_runs r WHERE id=:source + """), {"changes": json.dumps(successor_row), "source": source["run_id"]}) + await session.execute(text(""" + UPDATE public.checker_submission_fences SET current_run_id=:successor + WHERE submission_id=:submission + """), {"successor": successor_id, "submission": submission_id}) connection = await _connection(isolated_database_env) try: assert await _retained_rows(connection) == before diff --git a/backend/tests/checkers/execution/test_material_migration.py b/backend/tests/checkers/execution/test_material_migration.py index 32a20326f..dc23dfd3a 100644 --- a/backend/tests/checkers/execution/test_material_migration.py +++ b/backend/tests/checkers/execution/test_material_migration.py @@ -8,15 +8,14 @@ from sqlalchemy import text from sqlalchemy.exc import IntegrityError +from app.core.hashing import canonical_json_hash from app.core.identifiers import new_record_id from app.db import session as db_session from tests.migration_fixtures import add_current_art_seed_column, restore_predecessor_evidence_schema from tests.migration_fixtures import _config -from tests.historical_submission_fixtures import historical_material_fixture +from tests.historical_submission_fixtures import _raw, historical_material_fixture from types import SimpleNamespace -from app.modules.checkers.post_submit_contracts import make_post_submit_result -from tests.checkers.post_submit.support import change_request from .historical_execution import ( historical_reserve, historical_lease, @@ -77,14 +76,18 @@ async def test_retained_material_upgrade( # Preserve superseded completed/failed history and a current # failure that never received material, plus later replica loss. successor = SimpleNamespace(**vars(h)) - successor.request = change_request(h.request, evaluation_generation=2, - evaluation_request_id=new_record_id()) + request_body = h.request.model_dump(exclude={"request_sha256"}) + request_body.update(evaluation_generation=2, evaluation_request_id=str(new_record_id())) + successor.request = _raw(request_body | {"request_sha256": canonical_json_hash(request_body)}) await historical_reserve(successor) next_lease = await historical_lease(successor) empty = historical_terminal_facts(successor, next_lease, "infrastructure_failed") body = empty.result.model_dump(exclude={"result_digest"}) body["infrastructure_failure_code"] = "material_unavailable" - empty = empty.model_copy(update={"result": make_post_submit_result(**body), "material": None}) + empty = empty.model_copy(update={ + "result": _raw(body | {"result_digest": canonical_json_hash(body)}), + "material": None, + }) async with h.factory() as session, session.begin(): await historical_write_terminal(session, empty, None) await session.execute(text( diff --git a/backend/tests/historical_checker_metadata.py b/backend/tests/historical_checker_metadata.py deleted file mode 100644 index 8347bcc98..000000000 --- a/backend/tests/historical_checker_metadata.py +++ /dev/null @@ -1,88 +0,0 @@ -"""Frozen pre-cutover metadata used only by retained-record migration fixtures.""" - -from app.core.hashing import canonical_json_hash -from app.modules.checkers.api.historical_post_submit import ( - POST_SUBMIT_CATALOGUE_ID, POST_SUBMIT_CATALOGUE_SCHEMA, POST_SUBMIT_IMPLEMENTATION_ID, - PostSubmitCatalogue, PostSubmitDefinition, -) - -_STRUCTURAL_DEFINITIONS = ( - ("check_submission_packet", "packet_presence", "packet_fields_missing", "submission_structure"), - ( - "check_policy_context_present", - "policy_context_consistency", - "policy_context_invalid", - "task_configuration", - ), - ("check_evidence_present", "evidence_presence", "evidence_missing", "submission_structure"), - ( - "check_evidence_integrity", - "evidence_structure", - "evidence_structure_invalid", - "submission_structure", - ), - ( - "check_required_files", - "required_path_presence", - "required_files_missing", - "submission_structure", - ), - ( - "check_forbidden_files", - "forbidden_path_detection", - "forbidden_path_present", - "submission_structure", - ), - ( - "check_confidentiality_attestation", - "attestation_presence", - "attestation_missing", - "submission_structure", - ), - ( - "check_low_quality_generated_artifacts", - "placeholder_signal_detection", - "placeholder_signal", - "submission_structure", - ), - ( - "check_acceptance_criteria_present", - "criteria_presence", - "acceptance_criteria_missing", - "task_configuration", - ), -) - - -def structural_definition(name: str) -> PostSubmitDefinition: - """Mint the code-owned metadata attached to an explicit registration entry.""" - for order, (checker_id, claim, failure, category) in enumerate(_STRUCTURAL_DEFINITIONS, 1): - if checker_id == name: - warning = name == "check_low_quality_generated_artifacts" - return PostSubmitDefinition( - capability_id=name, - implementation_version=POST_SUBMIT_IMPLEMENTATION_ID, - platform_default=order <= 8, - selectable=order == 9, - order=order, - supported_claim=claim, - failure_code=failure, - failure_category=category, - failure_status="warning" if warning else "failed", - failure_severity="medium" if warning else "high", - ) - raise ValueError("unknown structural post-submit definition") - - -def historical_post_submit_catalogue() -> PostSubmitCatalogue: - """Return code-owned immutable metadata, without execution authority.""" - definitions = tuple(structural_definition(row[0]) for row in _STRUCTURAL_DEFINITIONS) - body = { - "catalogue_id": POST_SUBMIT_CATALOGUE_ID, - "source_version": "v0.1", - "schema_version": POST_SUBMIT_CATALOGUE_SCHEMA, - "definitions": [item.model_dump(mode="json") for item in definitions], - } - return PostSubmitCatalogue(**body, manifest_sha256=canonical_json_hash(body)) - - diff --git a/backend/tests/tasks/post_submit_routing/test_requests.py b/backend/tests/tasks/post_submit_routing/test_requests.py index dd85ca052..0c00a9361 100644 --- a/backend/tests/tasks/post_submit_routing/test_requests.py +++ b/backend/tests/tasks/post_submit_routing/test_requests.py @@ -193,10 +193,10 @@ def untrusted_completion(): """Valid value shape only; empty database ensures root denial precedes owner reads.""" from app.core.identifiers import new_record_id from app.modules.checkers.api.execution import EvaluationCompletion - from app.modules.checkers.api.post_submit import PostSubmitCurrentResultReference + from app.modules.checkers.api.selected_post_submit import SelectedPostSubmitCurrentResultReference return new_record_id(), EvaluationCompletion( project_id=new_record_id(), task_id=new_record_id(), submission_id=new_record_id(), - reference=PostSubmitCurrentResultReference( + reference=SelectedPostSubmitCurrentResultReference( request_id=new_record_id(), request_digest="sha256:" + "a" * 64, attempt_id=new_record_id(), evaluation_generation=1, result_id=new_record_id(), result_digest="sha256:" + "b" * 64, From d8404c1409876d36bf04416abe5a78c9c1d50338 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 13:58:36 +0100 Subject: [PATCH 210/283] test(pilot04): reconcile selected-only canonical test inventory --- .../pilot04-workstream-default-checker.md | 29 +++++++++++++++++++ backend/scripts/test_lane_catalogue.py | 5 ---- .../tests/checkers/default/test_execution.py | 2 +- backend/tests/test_ci_lane_catalogue.py | 4 --- 4 files changed, 30 insertions(+), 10 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 8d38bdf4a..c30dca3da 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -820,3 +820,32 @@ collection after the peer raw producer checkpoint, focused current contracts, and isolated native migration/SQL controls where the claim depends on Postgres. This is author test reconciliation, requiring lead/QA review in the complete candidate; it does not establish hosted readiness. + +### Deleted-test inventory reconciliation + +Lead authorizes `backend/scripts/test_lane_catalogue.py` and +`backend/tests/test_ci_lane_catalogue.py` solely to remove the five modules +deleted above: the old phase-service test and built-in POST configuration, input, +request and result tests. Remove the matching four POST exact-set entries. All +remaining modules, exhaustive discovery, ten lanes, partition algorithm, markers, +execution caps and required CI controls remain unchanged. Canonical collection +and exact inventory tests must pass; CI/test-delta reviewers inspect the deleted +module basis in the complete candidate. No current selected/default or custody +test is omitted. + +The exact composed source `e8b5ae1d6f31c414f962e5bff1646788eed536fc` passed +the native locked-one-image/self-consistent-zero-member SQL control in 22.93 +seconds on installed `0036`. Fresh AUTH binds the same counterfeit, SQL refuses +completed custody, all run/member/completion writes roll back, and the restored +complete result finalizes. DB, role and MinIO cleanup all passed. This closes the +focused policy-completeness proof; broader native/full hosted checks remain +required. Raw evidence: `/tmp/pilot04-selected-e8b-zero-native.log` and `.json`. +The earlier installed-function syntax failure remains a failed prerequisite +attempt, not a counterfeit-result proof. + +Fresh full discovery on the raw-producer composition collected 8,731 tests with +one import error: the current default-checker test still imported its packet +from the deleted PRE DTO module. The current-consumer test scope therefore +includes `backend/tests/checkers/default/test_execution.py` for the exact neutral +`api.submission_packet.SubmissionPacketView` import correction only. All four +default checks and their controls remain required; no deleted DTO is restored. diff --git a/backend/scripts/test_lane_catalogue.py b/backend/scripts/test_lane_catalogue.py index e8d2279f2..99a0a9ce9 100644 --- a/backend/scripts/test_lane_catalogue.py +++ b/backend/scripts/test_lane_catalogue.py @@ -224,7 +224,6 @@ class TestLane: "tests/test_artifact_admission_digest.py", "tests/test_submission_bundle_admission.py", "tests/test_submission_bundle_preparation_recovery.py", - "tests/checkers/test_phase_service.py", "tests/test_submission_preparation_adapter.py", "tests/test_submission_preparation_authorization.py", "tests/test_submission_composition.py", @@ -513,12 +512,8 @@ class TestLane: "tests/tasks/test_assignment_invalidation_races.py", "tests/tasks/test_contribution_claim_races.py", "tests/tasks/test_submission_lineage.py", - "tests/checkers/post_submit/test_configuration.py", - "tests/checkers/post_submit/test_input_bounds.py", "tests/checkers/post_submit/test_public_boundary.py", - "tests/checkers/post_submit/test_request.py", "tests/checkers/post_submit/test_requirement_dispositions.py", - "tests/checkers/post_submit/test_result_contract.py", "tests/test_project_guide_compilation_contracts.py", "tests/test_review_queue_persistence.py", "tests/test_review_lease_persistence.py", diff --git a/backend/tests/checkers/default/test_execution.py b/backend/tests/checkers/default/test_execution.py index 56ed90d6d..e0e3a6cb2 100644 --- a/backend/tests/checkers/default/test_execution.py +++ b/backend/tests/checkers/default/test_execution.py @@ -29,7 +29,7 @@ evaluate_rejected_archive, evaluate_verified_archive, ) -from app.modules.checkers.api.pre_submit import SubmissionPacketView +from app.modules.checkers.api.submission_packet import SubmissionPacketView RULES_A = "sha256:" + "a" * 64 diff --git a/backend/tests/test_ci_lane_catalogue.py b/backend/tests/test_ci_lane_catalogue.py index 4ede7d2bb..1dcc698a9 100644 --- a/backend/tests/test_ci_lane_catalogue.py +++ b/backend/tests/test_ci_lane_catalogue.py @@ -356,12 +356,8 @@ def test_measured_hotspots_have_explicit_semantic_owners() -> None: "tests/tasks/test_payment_policy_migration.py", "tests/tasks/test_contribution_claim_races.py", "tests/tasks/test_submission_lineage.py", - "tests/checkers/post_submit/test_configuration.py", - "tests/checkers/post_submit/test_input_bounds.py", "tests/checkers/post_submit/test_public_boundary.py", - "tests/checkers/post_submit/test_request.py", "tests/checkers/post_submit/test_requirement_dispositions.py", - "tests/checkers/post_submit/test_result_contract.py", "tests/test_project_guide_compilation_contracts.py", "tests/test_review_lease_persistence.py", "tests/test_review_queue_persistence.py", From 056de62bb0e5528b110b9933907cbfd16eaa614c Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 13:59:09 +0100 Subject: [PATCH 211/283] test(pilot04): import the canonical neutral PRE packet --- .commitrail/changes/pilot04-workstream-default-checker.md | 2 +- backend/tests/checkers/default/test_execution.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index c30dca3da..7d2b58c83 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -847,5 +847,5 @@ Fresh full discovery on the raw-producer composition collected 8,731 tests with one import error: the current default-checker test still imported its packet from the deleted PRE DTO module. The current-consumer test scope therefore includes `backend/tests/checkers/default/test_execution.py` for the exact neutral -`api.submission_packet.SubmissionPacketView` import correction only. All four +`api.pre_submit_material.SubmissionPacketView` import correction only. All four default checks and their controls remain required; no deleted DTO is restored. diff --git a/backend/tests/checkers/default/test_execution.py b/backend/tests/checkers/default/test_execution.py index e0e3a6cb2..e4fb3215e 100644 --- a/backend/tests/checkers/default/test_execution.py +++ b/backend/tests/checkers/default/test_execution.py @@ -29,7 +29,7 @@ evaluate_rejected_archive, evaluate_verified_archive, ) -from app.modules.checkers.api.submission_packet import SubmissionPacketView +from app.modules.checkers.api.pre_submit_material import SubmissionPacketView RULES_A = "sha256:" + "a" * 64 From 43aae59ff7378323784b1fad99b81bd0a360278a Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 14:14:41 +0100 Subject: [PATCH 212/283] docs(pilot04): point cleanup proof at current default tests --- .commitrail/changes/pilot04-workstream-default-checker.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 7d2b58c83..da7156aee 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -754,7 +754,7 @@ Deleted semantic families: built-in catalogue configuration/selection, old structural request DTO field/aggregate bounds, nine-member generic result shapes, and disabled mandatory catalogue readiness. Required current proof remains in checkers/external/{test_contracts.py,test_policy.py,test_selected_pre_submit.py, -test_selected_post_submit.py}, test_workstream_default_checker.py and unified +test_selected_post_submit.py}, checkers/default/{test_contract.py,test_execution.py} and unified project guide compilation contract tests (unknown/stale/stage/typed config). Authority, callback lifetime, post-I/O revocation, cleanup failure, crossed native lineage/receipts, exact replay, complete selected member closure and review-source From b909b15d4ed33aa4370c81993d4f4d7f2f4e6320 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 14:09:42 +0100 Subject: [PATCH 213/283] test(pilot04): bind SQL completion to selected registry and image --- .../pilot04-workstream-default-checker.md | 14 ++++ .../tests/checkers/execution/test_storage.py | 73 +++++++++++++++++++ 2 files changed, 87 insertions(+) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index da7156aee..6169e39e1 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -849,3 +849,17 @@ from the deleted PRE DTO module. The current-consumer test scope therefore includes `backend/tests/checkers/default/test_execution.py` for the exact neutral `api.pre_submit_material.SubmissionPacketView` import correction only. All four default checks and their controls remain required; no deleted DTO is restored. + +### Same-count selected-result SQL identity controls + +Lead authorizes two additional native controls in the already-owned +`backend/tests/checkers/execution/test_storage.py`: a self-consistent foreign +registry UUID (outer and normalized member agree) and a substituted observed +platform image digest under the unchanged locked one-image policy. Each must +first fail the real current request validator, then simulate a faulty validator +only for that exact counterfeit. Fresh final AUTH binds the same counterfeit; +forcing all deferred constraints must refuse the write, preserve run/member/ +completion/audit facts on rollback, and permit the restored valid result. These +controls test SQL custody independently of the application guard. No product or +DDL edits, mismatched earlier AUTH evidence, fixture bypass, or weakened checks +are permitted; the sole migration author owns any reproduced SQL repair. diff --git a/backend/tests/checkers/execution/test_storage.py b/backend/tests/checkers/execution/test_storage.py index c45b53e29..12569f08b 100644 --- a/backend/tests/checkers/execution/test_storage.py +++ b/backend/tests/checkers/execution/test_storage.py @@ -259,6 +259,79 @@ def faulty_request_validator(result, request): assert await executor.finalize(valid) == valid.result +@pytest.mark.parametrize("substitution", ["registry_entry_id", "image_digest"]) +async def test_same_count_result_cannot_substitute_locked_image_identity( + tmp_path, isolated_database_env, monkeypatch, substitution +): + from app.modules.checkers.api.external import make_external_checker_execution_result + from app.modules.checkers.api.selected_post_submit import ( + SelectedPostSubmissionEvaluationResult, + make_selected_post_submit_result, + ) + from sqlalchemy import func, text + from . import material_storage_helpers + + async with material_fixture( + tmp_path, isolated_database_env, post_submit_registry_spec=post_registry_spec() + ) as h: + await reserve(h) + executor = live_executor(h) + lease, _ = await executor._claim(h.request) + valid = await final_facts(h, lease) + member, = valid.result.execution.external_members + if substitution == "registry_entry_id": + foreign_id = new_record_id() + normalized_body = member.result.model_dump(exclude={"result_digest"}) + normalized_body["registry_entry_id"] = foreign_id + changed = replace( + member, registry_entry_id=foreign_id, + result=make_external_checker_execution_result(**normalized_body), + ) + else: + foreign_image = "sha256:" + ( + "c" if member.isolation.platform_manifest_digest != "sha256:" + "c" * 64 else "d" + ) * 64 + changed = replace(member, isolation=replace( + member.isolation, platform_manifest_digest=foreign_image, + )) + body = valid.result.model_dump(exclude={"result_digest"}) + body["execution"] = replace(valid.result.execution, external_members=(changed,)) + counterfeit = make_selected_post_submit_result(**body) + assert counterfeit.execution.required_external_count == 1 + assert counterfeit.execution.policy_sha256 == h.request.policy.policy_sha256 + with pytest.raises(ValueError, match="selected POST result request mismatch"): + counterfeit.validate_request(h.request) + facts = valid.model_copy(update={"result": counterfeit}) + canonical = SelectedPostSubmissionEvaluationResult.validate_request + + def faulty_validator(result, request): + if result == counterfeit and request == h.request: + return None + return canonical(result, request) + + monkeypatch.setattr(SelectedPostSubmissionEvaluationResult, "validate_request", faulty_validator) + async with h.factory() as session: + before_audits = await session.scalar(text("SELECT count(*) FROM public.audit_events")) + await material_storage_helpers.write_terminal( + session, facts, facts.material.model_dump(mode="json"), + ) + with pytest.raises(IntegrityError): + await session.execute(text("SET CONSTRAINTS ALL IMMEDIATE")) + await session.rollback() + async with h.factory() as session: + run = await session.get(CheckerRun, str(lease.reservation.attempt_id)) + assert run.status == "running" and run.result_json is None + assert run.finalize_evidence_id is None and run.completion_event_id is None + assert await session.scalar(select(func.count()).select_from(CheckerResult)) == 0 + assert await session.scalar(text("SELECT count(*) FROM public.audit_events")) == before_audits + assert await session.scalar(text( + "SELECT count(*) FROM public.outbox_events " + "WHERE event_type='PostSubmissionEvaluationCompleted'" + )) == 0 + monkeypatch.setattr(SelectedPostSubmissionEvaluationResult, "validate_request", canonical) + assert await executor.finalize(valid) == valid.result + + async def test_infrastructure_failure_code_is_closed_in_database(tmp_path, isolated_database_env): import json from sqlalchemy import update, func, text From 5975423435353f07121ad637c283edddd882c8cb Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 14:19:01 +0100 Subject: [PATCH 214/283] docs(pilot04): reconcile canonical checker boundaries with sole image flow --- docs/architecture_checker_framework.md | 13 ++--- docs/architecture_lockdown.md | 71 +++++++++++++------------- 2 files changed, 39 insertions(+), 45 deletions(-) diff --git a/docs/architecture_checker_framework.md b/docs/architecture_checker_framework.md index dd627d122..7849da75a 100644 --- a/docs/architecture_checker_framework.md +++ b/docs/architecture_checker_framework.md @@ -49,15 +49,10 @@ immutable registry are consumed by selected hidden PRE/POST owners through an explicit Rust service adapter. Production request/completion handlers are registered; public contributor intake remains PILOT-12 work. -The following catalogue envelope documents retained pre-cutover evidence only. -Both executable catalogues and their runtime factories are removed. New requests -use the selected default-plus-external PRE contract and selected external POST -contract; retained business-version facts are not alternate execution paths. - -Retained predecessor rows preserve their original typed provenance and exact -business-version digests. Historical decoders validate those stored facts; they -do not reconstruct executable catalogue factories or dispatch new work. New -external results use the normalized contracts above. +Both executable catalogues, their runtime factories and their request/result +decoders are removed. Requests use the default-plus-external PRE contract and +external POST contract. Stored predecessor rows retain their original provenance +and business-version digests; they do not supply an alternate execution path. ## External Checker Registry And Selected Policies diff --git a/docs/architecture_lockdown.md b/docs/architecture_lockdown.md index 9cc040ab0..5d80e3bed 100644 --- a/docs/architecture_lockdown.md +++ b/docs/architecture_lockdown.md @@ -185,7 +185,13 @@ Project Manager approves the internal policy bundle before guide activation. Project owners do not approve Workstream's internal submission policy schema. -`SubmissionArtifactPolicy` defines project-level intake rules. Workstream combines it with the non-bypassable Workstream default submission artifact policy to create `EffectiveProjectSubmissionArtifactPolicy`. Workstream then generates, persists, and locks project `PreSubmitCheckerPolicy` with a compiled bundle hash from that effective project submission artifact policy. Tasks lock the applicable guide snapshot, effective project submission artifact policy hash, and pre-submit checker bundle hash before entering the contributor pipeline. +Tasks lock the approved guide and its exact PRE/POST image policies before +entering the contributor pipeline. Workstream provides one versioned default +checker: safe ZIP/resource bounds, server-verified digest and manifest, +high-confidence secret rejection, and unchanged-work rejection unless locked +rules changed. Missing summary or attestation produces warnings only. All +project checks are approved, digest-pinned external images; there is no built-in +project-rule catalogue or alternate checker runtime. Blocking pre-submit failures prevent submission creation. The mounted authorized hidden preparation route returns `pre_submission_checker_failed` @@ -196,30 +202,26 @@ submission-created audit event. ART constructs a bounded audit-ready projection; publication as a task event named `pre_submission_check_failed` remains pending. That event must contain only this closed, path-redacted projection: actor-profile ID, project ID, task ID, preparation attempt ID, effective-plan hash, terminal status, pass/warning/failure counts, -and a bounded ordered list of catalogue ID/version plus stable outcome code. +and bounded ordered default or registered-image identities plus stable outcome codes. It excludes filenames, archive paths, scratch/provider references, credentials, raw checker output, evidence content, and free-form or unbounded messages. This -is audit evidence, not a product review decision. POL-07B removes the independently invocable -JSON precheck. The internal pre-submit phase command uses ART's existing -execution or completed-evidence recovery after reservation commits. WS-ARCH-001-02I retains the -broader Submission caller migration and its downstream prerequisites. - -Hidden ART-04B2 uses XINT-06A's two-stage fixed-materializer PREP. It locks the -service/action and scalar lineage before ZIP inspection, then consumes the same -process-local handle with the server-computed semantic-manifest identity before -workspace reservation or checker execution. It reserves the complete expanded -workspace budget, verifies one canonical sealed tree against the 04A identities, -and runs only platform/default catalogue entries. The callback-scoped tree and -all paths are destroyed before bounded results return. Hidden ART-04B3 extends -that same plan and sealed-tree callback -to the locked project-policy entries, then reloads the exact task context and -persists one immutable platform-plus-project evidence set after scratch cleanup. -It creates no provider object, admission, Submission, or lifecycle effect; -AUTH activation remains XINT-06A. POL-07A commits an ART execution reservation -before invoking checks, then obtains fresh materialization authority; a prepared -AUTH handle never crosses that commit. Completed replay freshly authorizes the -stored original generation and returns evidence without another checker run or -pass capability. +is audit evidence, not a product review decision. + +ART safely expands the ZIP in bounded private scratch and independently verifies +the bytes and manifest. The default checker runs before any project PRE image. +Each image receives verified files read-only through the Rust service and its +callback-scoped grant. CHECKERS commits its execution lease before material work; +TASK custody precedes CHECKERS locks, and no authority transaction stays open +through image execution. Scratch is destroyed before finalization revalidates +the exact assignment, locked policy, material and lease. + +Only a complete PRE pass permits the existing caller-owned atomic transaction to +consume admission and commit an immutable Submission, `evaluation_pending`, and +the initial POST dispatch together. Work failures return bounded findings, +create no Submission, and leave the task `in_progress`. Infrastructure failures +remain recoverable. POST images evaluate immutable Submission material and +produce evidence for the existing governed routing operation. Exact replay +requires fresh authority and returns original immutable facts. Tasks lock to the active guide version at creation or screening time before entering `READY`. Material guide changes require a new guide version. @@ -317,19 +319,16 @@ metadata only. Decision and contribution creation perform no ART call. ### Pre-Submission Checker Boundary -CHECKERS owns the single deterministic effective pre-submission plan. The 02C -boundary exposes its public planning port and bounded result facts and migrates -the touched TASK and ART admission call path away from the catalogue, compiler, -and executor internals. ART retains exclusive ownership of byte custody, -storage scheme, evidence persistence, pass capability, and admission attachment. - -Public CHECKER results contain the plan identity, eligibility outcome, and -bounded per-definition facts only. They never expose prepared-artifact custody, -scratch state, provider details, or durable evidence identity. Concrete -catalogue and executor implementations remain CHECKER-private and meet callers -only through application composition. Existing ART materialization and evidence -imports that have not yet migrated remain frozen private-edge debt; the next -ART boundary chunk must move those exact consumers to this public surface. +CHECKERS owns the default-plus-external PRE contract, exact approved image +bindings and durable run/lease/result custody. ART owns verified bytes, bounded +scratch, immutable storage and admission attachment. Callers use typed public +ports through application composition. Both executable catalogues and their +old request/result decoders are removed. + +Contributor feedback contains bounded default/image findings and eligibility. +It conceals scratch state, provider coordinates, credentials and raw checker +output. The hidden preparation flow is implemented; public contributor +upload/finalize and CLI submit/status remain PILOT-12 work. ### Contribution Records From ad3449aee4c90dedc344f6441fc22500037381bf Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 14:20:58 +0100 Subject: [PATCH 215/283] chore(pilot04): reconcile ownership for retired checker contracts --- .ci/behavior-ownership/partition.v1.json | 32 ++++--------------- .../pilot04-workstream-default-checker.md | 9 ++++++ backend/scripts/behavior_ownership.py | 10 +++++- backend/tests/test_behavior_ownership.py | 5 +++ 4 files changed, 29 insertions(+), 27 deletions(-) diff --git a/.ci/behavior-ownership/partition.v1.json b/.ci/behavior-ownership/partition.v1.json index 1cacd2e93..8add70ea2 100644 --- a/.ci/behavior-ownership/partition.v1.json +++ b/.ci/behavior-ownership/partition.v1.json @@ -376,14 +376,6 @@ "group": "artifacts", "target": "backend/app/modules/artifacts/post_submit_selection.py" }, - { - "group": "artifacts", - "target": "backend/app/modules/artifacts/pre_submit_attempts.py" - }, - { - "group": "artifacts", - "target": "backend/app/modules/artifacts/pre_submit_evidence.py" - }, { "group": "artifacts", "target": "backend/app/modules/artifacts/preparation.py" @@ -912,6 +904,10 @@ "group": "artifacts", "target": "backend/app/modules/checkers/api/artifact_paths.py" }, + { + "group": "artifacts", + "target": "backend/app/modules/checkers/api/canonical_values.py" + }, { "group": "artifacts", "target": "backend/app/modules/checkers/api/default_checker.py" @@ -932,10 +928,6 @@ "group": "artifacts", "target": "backend/app/modules/checkers/api/external_policy.py" }, - { - "group": "artifacts", - "target": "backend/app/modules/checkers/api/historical_post_submit.py" - }, { "group": "artifacts", "target": "backend/app/modules/checkers/api/history.py" @@ -952,21 +944,13 @@ "group": "artifacts", "target": "backend/app/modules/checkers/api/output_custody.py" }, - { - "group": "artifacts", - "target": "backend/app/modules/checkers/api/policy_compilation.py" - }, { "group": "artifacts", "target": "backend/app/modules/checkers/api/policy_custody.py" }, { "group": "artifacts", - "target": "backend/app/modules/checkers/api/post_submit.py" - }, - { - "group": "artifacts", - "target": "backend/app/modules/checkers/api/pre_submit.py" + "target": "backend/app/modules/checkers/api/pre_submit_material.py" }, { "group": "artifacts", @@ -1016,10 +1000,6 @@ "group": "artifacts", "target": "backend/app/modules/checkers/models.py" }, - { - "group": "artifacts", - "target": "backend/app/modules/checkers/post_submit_contracts.py" - }, { "group": "artifacts", "target": "backend/app/modules/checkers/pre_submit_defaults.py" @@ -1933,7 +1913,7 @@ "target": "backend/scripts/validate_test_lane_evidence.py" } ], - "authority_digest": "34e9996548e3d2cb0e45ce520c93c2e3382b9854aab9271cd3732898b48b34a5", + "authority_digest": "7282f1d9d49950a7252f895b27cb91a00008da1ce3c33be7e763f399366fbcdb", "protected_base_commit": "7676ce4347db0c9694962a9b587a20765e16eac6", "schema": "workstream.behavior-ownership-partition.v1" } diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 6169e39e1..9ff79497b 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -342,6 +342,15 @@ intermediate-wait regression. ## Risk and review routing +Final cleanup also permits `backend/scripts/behavior_ownership.py`, its existing +PILOT-04 partition transition test and `.ci/behavior-ownership/partition.v1.json`. +Retire exactly the five removed checker contracts and two removed ART PRE +writers; admit only the canonical value and PRE packet owners. Regenerate the +current partition with its existing protected base. Preserve all other target +assignments and refusal of unrelated additions/removals. The focused transition +test and architecture/ownership checks verify this metadata reconciliation; +it changes no runtime behavior or test selection. + - Risk class: L1 - Required reviewers: architecture, security, authorization, product_ops, reuse_dedup, qa, test_delta, documentation, ci_integrity diff --git a/backend/scripts/behavior_ownership.py b/backend/scripts/behavior_ownership.py index e4b6d83a0..18272d20f 100644 --- a/backend/scripts/behavior_ownership.py +++ b/backend/scripts/behavior_ownership.py @@ -175,6 +175,12 @@ ) PILOT_04_RETIRED_CATALOGUE_TARGETS = frozenset( { + "backend/app/modules/artifacts/pre_submit_attempts.py", + "backend/app/modules/artifacts/pre_submit_evidence.py", + "backend/app/modules/checkers/api/historical_post_submit.py", + "backend/app/modules/checkers/api/policy_compilation.py", + "backend/app/modules/checkers/api/post_submit.py", + "backend/app/modules/checkers/api/pre_submit.py", "backend/app/modules/checkers/api/pre_submit_catalogue.py", "backend/app/modules/checkers/api/post_submit_catalogue.py", "backend/app/modules/checkers/catalogue.py", @@ -182,6 +188,7 @@ "backend/app/modules/checkers/effective_plan.py", "backend/app/modules/checkers/post_submit_catalogue.py", "backend/app/modules/checkers/post_submit_implementations.py", + "backend/app/modules/checkers/post_submit_contracts.py", "backend/app/modules/checkers/pre_submit_execution.py", "backend/app/modules/checkers/runner.py", "backend/app/modules/projects/post_submit_policy.py", @@ -193,11 +200,12 @@ "backend/app/modules/artifacts/selected_pre_submit_execution.py", "backend/app/modules/authorization/domain/pre_submit.py", "backend/app/modules/authorization/pre_submit_authorization.py", + "backend/app/modules/checkers/api/canonical_values.py", "backend/app/modules/checkers/api/evaluation_contract.py", "backend/app/modules/checkers/api/external_policy.py", - "backend/app/modules/checkers/api/historical_post_submit.py", "backend/app/modules/checkers/api/material.py", "backend/app/modules/checkers/api/policy_custody.py", + "backend/app/modules/checkers/api/pre_submit_material.py", "backend/app/modules/checkers/api/selected_post_submit.py", "backend/app/modules/checkers/api/selected_pre_submit.py", "backend/app/modules/checkers/selected_post_submit_execution.py", diff --git a/backend/tests/test_behavior_ownership.py b/backend/tests/test_behavior_ownership.py index a67e10e86..71f7d30fe 100644 --- a/backend/tests/test_behavior_ownership.py +++ b/backend/tests/test_behavior_ownership.py @@ -1957,9 +1957,14 @@ def test_pilot04_partition_allows_only_the_selected_flow_and_retired_catalogues( retired = ownership.PILOT_04_RETIRED_CATALOGUE_TARGETS trusted = _partition(sorted({retained, *retired})) selected = ownership.PILOT_04_SELECTED_FLOW_TARGETS + assert retired.isdisjoint(selected) ownership._validate_additive_partition_transition( _partition(sorted({retained, *selected})), trusted ) + with pytest.raises(ownership.BehaviorOwnershipError, match="untrusted_partition_change"): + ownership._validate_additive_partition_transition( + _partition(sorted(selected)), trusted + ) with pytest.raises(ownership.BehaviorOwnershipError, match="untrusted_partition_change"): ownership._validate_additive_partition_transition( _partition(sorted({*selected, "backend/app/modules/checkers/unreviewed.py"})), From 6a1844b0d6686833e295772095ad652ff8c682ac Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 14:21:56 +0100 Subject: [PATCH 216/283] docs(pilot04): remove retired projection claims from checker flow --- docs/architecture_checker_framework.md | 40 +++++++++++--------------- 1 file changed, 17 insertions(+), 23 deletions(-) diff --git a/docs/architecture_checker_framework.md b/docs/architecture_checker_framework.md index 7849da75a..f87040d38 100644 --- a/docs/architecture_checker_framework.md +++ b/docs/architecture_checker_framework.md @@ -461,8 +461,8 @@ runtime body and hash. Setup agents may propose registered checker names and routing classifications, but they do not produce executable runtime code and they do not decide submission outcomes at runtime. -Retained pre-cutover bodies preserve their original ordered structural entries, -classification lists and hashes for exact historical decoding. +Stored pre-cutover bodies preserve their original ordered entries and hashes +as immutable provenance, without a runtime decoder or replay executor. Those bodies are retained provenance only. New POST bodies contain the exact approved external entries and `policy_sha256`; an empty approved POST binding @@ -495,9 +495,9 @@ The flow below is not a claim that the complete journey is live in production. ```text Draft packet -> load locked task context --> load locked EffectiveProjectSubmissionArtifactPolicy hash --> load locked PreSubmitCheckerPolicy compiled bundle hash --> run pre-submit intake checks +-> safely inspect ZIP in bounded private ART scratch +-> run the four Workstream default checks with server-verified digest/manifest +-> execute every approved external PRE image against verified read-only files -> create Submission only when blocking pre-submit checks pass -> automatically lock submission -> queue automatic pre-review CheckerRun @@ -767,24 +767,18 @@ No manual execution endpoint accompanies these reads. See the ### Shared evaluation content capacity -The retained ARCH-04E1B-B5 contract provided `PostSubmissionEvaluationContent` -for pre-cutover preparation and later identified requests. Its retained value type validates the original catalogue/policy -consistency and structural field limits, plus 1 MiB minus a 1,024-byte reserve -for the finite request identity envelope. The full request retains its 1 MiB -limit and canonical digest. Catalogue and policy identities are unchanged. - -The removed preparation adapter projected every verified file and only required evidence with -matching verified `evidence/{key}` files. Missing criteria remain empty text for -the existing post-submit checker. This check does not execute evaluators or -supply authority. See [the ART admission boundary](spec_artifact_storage_service.md#evaluation-content-capacity-before-durable-admission) -for historical timing and cleanup. ARCH-04E1B-B6 used that projection with actual record -identities and reserves generation one through the required TASK guard in the -Submission transaction. The same commit retains exact creation/binding AUTH -receipts and a bounded `PostSubmissionEvaluationRequested` outbox event. -Select-only creation replay checks the original request and event without -changing the current-generation fence. PILOT-04 replaces that preparation projection with selected external policy -content and registers selected request/completion handlers. Stored intent alone -still confers no execution or acceptance authority. +ART checks the canonical selected POST content against the request capacity +before durable admission. The content binds the exact approved external policy, +verified artifact/manifest, and checked packet; the removed catalogue content +type and preparation adapter are not retained as executable alternatives. +See [the ART admission boundary](spec_artifact_storage_service.md#evaluation-content-capacity-before-durable-admission). + +The existing Submission transaction reserves generation one through the TASK +guard and retains exact creation/binding AUTH receipts and a bounded +`PostSubmissionEvaluationRequested` outbox event. Exact creation replay checks +the original request and event without changing the current-generation fence. +The selected request/completion handlers consume those facts. Stored intent +alone confers no execution or acceptance authority. Preparation has no stored Submission to observe and never replaces the TASK evaluation guard. From fc0acc554780660f31bc09d1ee6373d6c8492452 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 14:22:41 +0100 Subject: [PATCH 217/283] docs(pilot04): correct current pointer above retired checker record --- ...ec_chunk_8_submission_artifact_policy_checkers.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/spec_chunk_8_submission_artifact_policy_checkers.md b/docs/spec_chunk_8_submission_artifact_policy_checkers.md index 5c2945919..06755fd0a 100644 --- a/docs/spec_chunk_8_submission_artifact_policy_checkers.md +++ b/docs/spec_chunk_8_submission_artifact_policy_checkers.md @@ -3,12 +3,12 @@ > Historical implementation record. It does not define current sequencing or > status; later canonical specifications and merged behavior take precedence. -Current submission-bundle preparation does not revive this document's -caller-owned precheck surface or standalone registry. WS-ART-001 PLAN4 and -04B1-04B3 place these constrained policy checks in the single versioned -pre-submission catalogue after ART-owned outer-ZIP custody gates, using the -server-derived manifest and sealed workspace. Catalogue availability follows -the fail-closed mandatory/advisory semantics in ADR 0011. +Current preparation uses the four Workstream defaults followed by approved +digest-pinned external PRE images on ART-verified read-only files. Both built-in +catalogues and this document's caller-owned precheck surface are removed. +Project-specific required-file, forbidden-file and similar rules belong in the +project image. Use the [current checker framework](architecture_checker_framework.md) +for the implemented flow; the record below describes the retired implementation. ## Purpose From 6e65f8b976edb965fe2070d88b0f2214508501c2 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 14:17:56 +0100 Subject: [PATCH 218/283] test(pilot04): retain current post-policy no-execution sentinel --- .commitrail/changes/pilot04-workstream-default-checker.md | 8 ++++++++ backend/tests/projects/post_policy/test_postgresql.py | 4 ++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 9ff79497b..90dc1c8e8 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -872,3 +872,11 @@ completion/audit facts on rollback, and permit the restored valid result. These controls test SQL custody independently of the application guard. No product or DDL edits, mismatched earlier AUTH evidence, fixture bypass, or weakened checks are permitted; the sole migration author owns any reproduced SQL repair. + +Current-consumer scan found a body-local import missed by collection: the +already-owned PROJECT post-policy PostgreSQL test patched the removed phase +wrapper as its no-execution sentinel. Replace only that sentinel with +`PostSubmissionExecutor.evaluate_post_submission`. Preserve actual approved +external policy, proposal finalization, provider/document denial, derive/approval +replay and unchanged finalization state. This is a required current isolation +control, not obsolete catalogue behavior; the old wrapper is not restored. diff --git a/backend/tests/projects/post_policy/test_postgresql.py b/backend/tests/projects/post_policy/test_postgresql.py index c93366e45..9c84cf524 100644 --- a/backend/tests/projects/post_policy/test_postgresql.py +++ b/backend/tests/projects/post_policy/test_postgresql.py @@ -42,8 +42,8 @@ async def forbidden(*args, **kwargs): monkeypatch.setattr(OpenAIAgentSdkProjectGuideRuntime, 'compile_project_guide', forbidden) monkeypatch.setattr(ScopedGuideDocumentGrant, 'open', forbidden) - from app.adapters.artifacts import CheckerPhaseService - monkeypatch.setattr(CheckerPhaseService, 'evaluate_post_submission', forbidden) + from app.modules.checkers.execution import PostSubmissionExecutor + monkeypatch.setattr(PostSubmissionExecutor, 'evaluate_post_submission', forbidden) original = await stored_state(factory, command) receipts = [] for _ in range(2): From 850afbaa508e7ccc36743f459abe8cd6c47a2077 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 14:24:16 +0100 Subject: [PATCH 219/283] [PILOT-04] Bind selected terminal image identities --- .../versions/0036_selected_checker_flow.py | 44 ++++++++++++++++++- backend/tests/conftest.py | 2 +- backend/tests/test_alembic.py | 9 ++++ 3 files changed, 53 insertions(+), 2 deletions(-) diff --git a/backend/alembic/versions/0036_selected_checker_flow.py b/backend/alembic/versions/0036_selected_checker_flow.py index 2366f15a7..4f5dd46ef 100644 --- a/backend/alembic/versions/0036_selected_checker_flow.py +++ b/backend/alembic/versions/0036_selected_checker_flow.py @@ -992,7 +992,11 @@ def _replace_checker_terminal_custody() -> None: raise RuntimeError("checker terminal declaration shape changed") definition = definition.replace( declaration, - declaration.replace("envelope jsonb;", "envelope jsonb; expected_members jsonb;"), + declaration.replace( + "envelope jsonb;", + "envelope jsonb; expected_members jsonb; " + "expected_execution_members jsonb; actual_execution_members jsonb;", + ), ) mismatch = """ IF result->'member_results' IS DISTINCT FROM members OR current_run.passed_count IS DISTINCT FROM passed OR current_run.warning_count IS DISTINCT FROM warning OR current_run.failed_count IS DISTINCT FROM failed @@ -1005,6 +1009,44 @@ def _replace_checker_terminal_custody() -> None: IF result->>'schema_version' IS NOT DISTINCT FROM 'workstream.selected_post_submit_result.v1' AND result->>'outcome'='completed' THEN + SELECT coalesce(jsonb_agg(jsonb_build_object( + 'position',(entry.ordinality-1)::integer, + 'order',(entry.ordinality-1)::integer, + 'requirement_id',entry.item->>'requirement_id', + 'registry_entry_id',entry.item#>>'{registry,registry_entry_id}', + 'registry_entry_digest',entry.item#>>'{registry,entry_digest}', + 'result_registry_entry_id',entry.item#>>'{registry,registry_entry_id}', + 'result_registry_entry_digest',entry.item#>>'{registry,entry_digest}', + 'result_phase','post_submit', + 'platform_manifest_digest',entry.item#>>'{registry,image_digest}' + ) ORDER BY entry.ordinality),'[]'::jsonb) + INTO expected_execution_members + FROM jsonb_array_elements(current_run.request_json::jsonb#>'{policy,entries}') + WITH ORDINALITY entry(item,ordinality); + SELECT coalesce(jsonb_agg(jsonb_build_object( + 'position',(actual.ordinality-1)::integer, + 'order',(actual.item->>'order')::integer, + 'requirement_id',actual.item->>'requirement_id', + 'registry_entry_id',actual.item->>'registry_entry_id', + 'registry_entry_digest',actual.item->>'registry_entry_digest', + 'result_registry_entry_id',actual.item#>>'{result,registry_entry_id}', + 'result_registry_entry_digest',actual.item#>>'{result,registry_entry_digest}', + 'result_phase',actual.item#>>'{result,phase}', + 'platform_manifest_digest',actual.item#>>'{isolation,platform_manifest_digest}' + ) ORDER BY actual.ordinality),'[]'::jsonb) + INTO actual_execution_members + FROM jsonb_array_elements(result#>'{execution,external_members}') + WITH ORDINALITY actual(item,ordinality); + IF result#>>'{execution,schema_version}' IS DISTINCT FROM + 'workstream.selected_post_submit_execution.v1' + OR result#>>'{execution,policy_sha256}' IS DISTINCT FROM + current_run.request_json::jsonb#>>'{policy,policy_sha256}' + OR (result#>>'{execution,required_external_count}')::integer IS DISTINCT FROM + jsonb_array_length(current_run.request_json::jsonb#>'{policy,entries}') + OR actual_execution_members IS DISTINCT FROM expected_execution_members THEN + RAISE EXCEPTION 'checker terminal selected policy differs' + USING ERRCODE='23514'; + END IF; SELECT coalesce(jsonb_agg(jsonb_build_object( 'schema_version','post_submit_structural_result', 'checker_id',item->>'requirement_id', diff --git a/backend/tests/conftest.py b/backend/tests/conftest.py index 3c241717b..726cd1d0f 100644 --- a/backend/tests/conftest.py +++ b/backend/tests/conftest.py @@ -23,7 +23,7 @@ DDL_LOCK_DIRECTORY = Path("/tmp") # Match the PostgreSQL 16 engine used by Backend CI. Catalog identity rendering # differs across major versions; regenerate only after comparing actual objects. -EXPECTED_PUBLIC_SCHEMA_SHA256 = "a8511b13c4657acec11a612b1ab572703dbc0a1a728d2eedbf0221f769d78a99" +EXPECTED_PUBLIC_SCHEMA_SHA256 = "684c0b37e1f07bba4de4cb637d685c3df9017a0be2b5b2582d9496e0c06372bc" PROTECTED_TEST_TABLES = ( "actor_profile_migration_state", "alembic_version", diff --git a/backend/tests/test_alembic.py b/backend/tests/test_alembic.py index 7518951e5..28615bb59 100644 --- a/backend/tests/test_alembic.py +++ b/backend/tests/test_alembic.py @@ -291,6 +291,15 @@ async def installed_functions() -> dict[str, str]: assert "external_post_submit_policy.v1" in definitions[ "require_post_policy_operation" ] + assert "checker terminal selected policy differs" in definitions[ + "validate_checker_terminal_custody" + ] + assert "result_registry_entry_id" in definitions[ + "validate_checker_terminal_custody" + ] + assert "platform_manifest_digest" in definitions[ + "validate_checker_terminal_custody" + ] assert "is distinct from 'external_checker_policies.v1'" in definitions[ "external_checker_locked_policies_valid" ].lower() From 1e0a6fc66715628375d369e4444a70df57f1628e Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 14:27:59 +0100 Subject: [PATCH 220/283] fix(pilot04): render failed external checker history from normalized status --- .../pilot04-workstream-default-checker.md | 12 +++++++ backend/app/modules/checkers/api/history.py | 2 +- .../app/modules/checkers/execution_results.py | 28 ++--------------- backend/app/modules/checkers/history.py | 8 ++--- .../submission_history/test_privacy.py | 6 ++-- .../tests/checkers/execution/test_storage.py | 31 +++++++++++++++++++ 6 files changed, 54 insertions(+), 33 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 90dc1c8e8..fcaa5de23 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -342,6 +342,18 @@ intermediate-wait regression. ## Risk and review routing +The final caller trace includes `backend/app/modules/checkers/{history.py, +execution_results.py,api/history.py}`, the existing history privacy expectation, +and `backend/tests/checkers/execution/test_storage.py`. Remove retired catalogue +message lookup and severity-policy classification from history reads. Render +bounded messages from normalized status, admit the persisted selected `error` +severity, and mark required failed image members as blocking. Keep concealed +internal findings, exact parent selectors, immutable rows and read authority. +A real failed registered-image result must be readable by both contributor and +management projections without raw image messages; the regression must fail on +the prior reader. Independent authority/architecture review checks the caller +repair. Risk remains L1; no public route or stored-data rewrite is added. + Final cleanup also permits `backend/scripts/behavior_ownership.py`, its existing PILOT-04 partition transition test and `.ci/behavior-ownership/partition.v1.json`. Retire exactly the five removed checker contracts and two removed ART PRE diff --git a/backend/app/modules/checkers/api/history.py b/backend/app/modules/checkers/api/history.py index 93e5ec912..e97e1fec1 100644 --- a/backend/app/modules/checkers/api/history.py +++ b/backend/app/modules/checkers/api/history.py @@ -7,7 +7,7 @@ CheckerStatus = Literal["queued", "running", "completed", "infrastructure_failed"] CheckerResultStatus = Literal["passed", "warning", "failed"] -CheckerSeverity = Literal["info", "low", "medium", "high", "critical"] +CheckerSeverity = Literal["info", "low", "medium", "high", "critical", "error"] CheckerRoutingRecommendation = Literal["not_evaluated", "allow_review", "needs_revision", "task_setup_blocked"] CheckerOutcomeSource = Literal["none", "auto_checker"] diff --git a/backend/app/modules/checkers/execution_results.py b/backend/app/modules/checkers/execution_results.py index ed657a715..3c23adbd9 100644 --- a/backend/app/modules/checkers/execution_results.py +++ b/backend/app/modules/checkers/execution_results.py @@ -37,30 +37,8 @@ def classify_result( ) -RESULT_MESSAGES = { +RESULT_STATUS_MESSAGES = { "passed": ("Check passed.", None), - "packet_fields_missing": ( - "Required submission fields are missing.", - "Complete the required submission fields.", - ), - "policy_context_invalid": ("The locked policy context is inconsistent.", None), - "evidence_missing": ("Required evidence is missing.", "Include the required evidence."), - "evidence_structure_invalid": ( - "Evidence references are invalid.", - "Correct the evidence references.", - ), - "required_files_missing": ("Required files are missing.", "Include the required files."), - "forbidden_path_present": ( - "The submission includes a forbidden path.", - "Remove the forbidden content.", - ), - "attestation_missing": ( - "Required attestation is missing.", - "Complete the required attestation.", - ), - "placeholder_signal": ( - "A possible placeholder needs attention.", - "Check the flagged submission structure.", - ), - "acceptance_criteria_missing": ("Task acceptance criteria are missing.", None), + "warning": ("Check reported a warning.", "Review the project guide and check findings."), + "failed": ("Project check failed.", "Review the project guide and check findings."), } diff --git a/backend/app/modules/checkers/history.py b/backend/app/modules/checkers/history.py index 0d57d1964..4c61d32b7 100644 --- a/backend/app/modules/checkers/history.py +++ b/backend/app/modules/checkers/history.py @@ -1,13 +1,13 @@ """Fixed history projection from closed results and the sole currentness fence.""" -from sqlalchemy import select, literal_column, tuple_ +from sqlalchemy import select, tuple_ from app.modules.checkers.models import CheckerRun, CheckerResult, CheckerSubmissionFence from app.modules.checkers.api.history import ( ContributorCheckerHistory, ManagementCheckerHistory, ContributorCheckerResult, ManagementCheckerResult, ) -from app.modules.checkers.execution_results import RESULT_MESSAGES +from app.modules.checkers.execution_results import RESULT_STATUS_MESSAGES class CheckerHistoryRepository: @@ -40,7 +40,7 @@ async def read(self, *, submission_id, task_id, manager, run_id=None, limit=25, for row in rows[:limit]: columns = [getattr(CheckerResult, name) for name in ("id", "checker_name", "status", "severity", "code", "failure_category")] if manager: - columns.append(literal_column("(checker_results.status<>'passed' AND (checker_runs.request_json::jsonb #> '{policy,blocking_severities}') ? checker_results.severity)").label("blocks_review")) + columns.append((CheckerResult.status == "failed").label("blocks_review")) result_query = select(*columns).join(CheckerRun, CheckerRun.id == CheckerResult.checker_run_id).where( CheckerResult.checker_run_id == row["id"], CheckerResult.submission_id == str(submission_id), CheckerResult.task_id == str(task_id), @@ -53,7 +53,7 @@ async def read(self, *, submission_id, task_id, manager, run_id=None, limit=25, results = (await self._session.execute(result_query.order_by(CheckerResult.member_order))).mappings().all() projected = [] for member in results: - message, fix = RESULT_MESSAGES[member["code"]] + message, fix = RESULT_STATUS_MESSAGES[member["status"]] visible = member["failure_category"] != "task_configuration" item = {key: member[key] for key in ("id", "checker_name", "status", "severity")} item.update(worker_message=message if visible else None, worker_suggested_fix=fix if visible else None) diff --git a/backend/tests/authorization/submission_history/test_privacy.py b/backend/tests/authorization/submission_history/test_privacy.py index d263c392a..9ccf9ae55 100644 --- a/backend/tests/authorization/submission_history/test_privacy.py +++ b/backend/tests/authorization/submission_history/test_privacy.py @@ -102,7 +102,7 @@ async def forbidden(*args, **kwargs): async def test_nested_values_match_exact_stored_parents(task_client, monkeypatch, manager): from app.modules.tasks.models import EvidenceItem from app.modules.checkers.models import CheckerResult - from app.modules.checkers.execution_results import RESULT_MESSAGES + from app.modules.checkers.execution_results import RESULT_STATUS_MESSAGES project = await create_active_project(task_client) task = await create_started_task(task_client, project["id"], monkeypatch) submission = await seed_retained_submission(task["id"], complete_submission_payload()) @@ -127,11 +127,11 @@ async def test_nested_values_match_exact_stored_parents(task_client, monkeypatch if row.checker_run_id != run_id: continue assert row.task_id == task["id"] and row.submission_id == submission - message, fix = RESULT_MESSAGES[row.code] + message, fix = RESULT_STATUS_MESSAGES[row.status] entry = {field:getattr(row,field) for field in ("id","checker_name","status","severity")} entry.update(worker_message=message, worker_suggested_fix=fix) if manager: - entry.update(message=message, blocks_review=row.status=="failed" and row.severity in {"high","critical"}) + entry.update(message=message, blocks_review=row.status=="failed") expected_results[run_id].append(entry) assert expected_results[run] != expected_results[sibling] and expected_evidence set_dev_actor(monkeypatch, roles="", subject="project-manager-subject" if manager else "worker-one") diff --git a/backend/tests/checkers/execution/test_storage.py b/backend/tests/checkers/execution/test_storage.py index 12569f08b..dcc2bf5e2 100644 --- a/backend/tests/checkers/execution/test_storage.py +++ b/backend/tests/checkers/execution/test_storage.py @@ -16,6 +16,37 @@ from tests.checkers.external.support import post_registry_spec +async def test_failed_external_image_history_uses_normalized_result_status( + tmp_path, isolated_database_env, +): + from app.modules.checkers.history import CheckerHistoryRepository + + async with material_fixture( + tmp_path, isolated_database_env, post_submit_registry_spec=post_registry_spec() + ) as h: + await reserve(h) + executor = live_executor(h) + lease, _ = await executor._claim(h.request) + facts = await final_facts(h, lease, verdict="failed") + await executor.finalize(facts) + async with h.factory() as session: + for manager in (False, True): + rows, more = await CheckerHistoryRepository(session).read( + submission_id=h.request.submission_id, + task_id=h.request.task_id, + manager=manager, + ) + assert not more and len(rows) == 1 + member, = rows[0].results + assert member.checker_name == h.request.policy.entries[0].requirement_id + assert member.status == "failed" and member.severity == "error" + assert member.worker_message == "Project check failed." + assert member.worker_suggested_fix == "Review the project guide and check findings." + if manager: + assert member.blocks_review is True + assert member.message == member.worker_message + + @pytest.mark.parametrize("duplicate", ["request", "generation"]) async def test_duplicate_request_and_generation_rejected( tmp_path, isolated_database_env, duplicate From c4d590c7b706bacf926c324f587dffdaef0f4924 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 14:30:14 +0100 Subject: [PATCH 221/283] [PILOT-04] Preserve canonical selected result shape --- backend/alembic/versions/0036_selected_checker_flow.py | 4 +--- backend/tests/conftest.py | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/backend/alembic/versions/0036_selected_checker_flow.py b/backend/alembic/versions/0036_selected_checker_flow.py index 4f5dd46ef..9f4e11f4c 100644 --- a/backend/alembic/versions/0036_selected_checker_flow.py +++ b/backend/alembic/versions/0036_selected_checker_flow.py @@ -1037,9 +1037,7 @@ def _replace_checker_terminal_custody() -> None: INTO actual_execution_members FROM jsonb_array_elements(result#>'{execution,external_members}') WITH ORDINALITY actual(item,ordinality); - IF result#>>'{execution,schema_version}' IS DISTINCT FROM - 'workstream.selected_post_submit_execution.v1' - OR result#>>'{execution,policy_sha256}' IS DISTINCT FROM + IF result#>>'{execution,policy_sha256}' IS DISTINCT FROM current_run.request_json::jsonb#>>'{policy,policy_sha256}' OR (result#>>'{execution,required_external_count}')::integer IS DISTINCT FROM jsonb_array_length(current_run.request_json::jsonb#>'{policy,entries}') diff --git a/backend/tests/conftest.py b/backend/tests/conftest.py index 726cd1d0f..18ad7e064 100644 --- a/backend/tests/conftest.py +++ b/backend/tests/conftest.py @@ -23,7 +23,7 @@ DDL_LOCK_DIRECTORY = Path("/tmp") # Match the PostgreSQL 16 engine used by Backend CI. Catalog identity rendering # differs across major versions; regenerate only after comparing actual objects. -EXPECTED_PUBLIC_SCHEMA_SHA256 = "684c0b37e1f07bba4de4cb637d685c3df9017a0be2b5b2582d9496e0c06372bc" +EXPECTED_PUBLIC_SCHEMA_SHA256 = "d3919cc4929fa6c37d65175d6c9333f61df951f359b9dfee8aa439b61253c0ea" PROTECTED_TEST_TABLES = ( "actor_profile_migration_state", "alembic_version", From 6d19fe313fb69ded012b4505e6bbc8915cae792d Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 14:36:23 +0100 Subject: [PATCH 222/283] docs(pilot04): retain discriminating native history proof --- .../changes/pilot04-workstream-default-checker.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index fcaa5de23..6b8e74fa9 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -354,6 +354,19 @@ management projections without raw image messages; the regression must fail on the prior reader. Independent authority/architecture review checks the caller repair. Risk remains L1; no public route or stored-data rewrite is added. +At clean `c4d590c7b706bacf926c324f587dffdaef0f4924`, the native SQL identity +substitution controls, empty-policy production request/completion acceptance, +and failed selected-result history regression passed (4 cases, 106.13 seconds). +These tests use controlled normalized image results with real PostgreSQL, +ART material and AUTH custody; they do not replace the real Rust image journey. +Restoring only the previous history reader and message table in a temporary +checkout makes the exact history regression fail with `KeyError` (42.98 seconds). +Both runs confirmed database, role and MinIO cleanup. Raw evidence is +`/tmp/pilot04-root-current-history-identity21.{log,json}` and +`/tmp/pilot04-root-history-prior-reader-mutant21.{log,json}`; the temporary +counterfactual checkout is removed. Public history schema controls passed two +cases separately. Later changes require affected evidence reconciliation. + Final cleanup also permits `backend/scripts/behavior_ownership.py`, its existing PILOT-04 partition transition test and `.ci/behavior-ownership/partition.v1.json`. Retire exactly the five removed checker contracts and two removed ART PRE From 44a9725cdca5093a4ede2f5801ab304695461766 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 14:26:04 +0100 Subject: [PATCH 223/283] test: store archived checker execution as literal rows --- .../execution/historical_execution.py | 646 ++++++++---------- 1 file changed, 278 insertions(+), 368 deletions(-) diff --git a/backend/tests/checkers/execution/historical_execution.py b/backend/tests/checkers/execution/historical_execution.py index 726873618..9adce57ac 100644 --- a/backend/tests/checkers/execution/historical_execution.py +++ b/backend/tests/checkers/execution/historical_execution.py @@ -1,39 +1,33 @@ -"""Revision-shaped checker history for migration tests only, never current AUTH proof. +"""Literal predecessor rows for migration tests, never an execution implementation. -All predecessor database guards remain enabled. No current input receipt is -fabricated: that evidence did not exist in these schema revisions. +Callers supply archived members, counts and routing. This file only encodes those +facts and inserts them with the predecessor database constraints enabled. It does +not invoke current CHECKERS, AUTH, outbox or TASK owners on an archived schema. """ import json from contextlib import asynccontextmanager +from copy import deepcopy from datetime import timedelta from uuid import UUID -from sqlalchemy import insert, text +from sqlalchemy import text -from app.adapters.outbox import outbox_append from app.core.hashing import canonical_json_hash from app.core.identifiers import new_record_id -from app.modules.checkers.api.execution import ( - EvaluationReservation, - ExecutionLease, - VerifiedMaterialFacts, - COMPLETION_EVENT, -) -from app.modules.checkers.models import CheckerRun, CheckerResult -from app.modules.outbox.api import OutboxAppendInput -from app.modules.tasks.models import AuditEvent -from tests.historical_submission_fixtures import ( - HistoricalRawValue, - _raw, - historical_material_fixture, -) +from tests.historical_submission_fixtures import historical_material_fixture -def _canonical_text(value: HistoricalRawValue, *, exclude=frozenset()) -> str: - """Encode an archived predecessor object without invoking a product decoder.""" +def _json_uuid(value): + if isinstance(value, UUID): + return str(value) + raise TypeError(f"Non-JSON archived fact: {type(value).__name__}") + + +def _canonical_text(value, *, exclude=frozenset()): return json.dumps( - value.model_dump(exclude=exclude), + {key: item for key, item in value.items() if key not in exclude}, + default=_json_uuid, sort_keys=True, separators=(",", ":"), ensure_ascii=False, @@ -41,385 +35,301 @@ def _canonical_text(value: HistoricalRawValue, *, exclude=frozenset()) -> str: ) -async def historical_revision(session): +def _json_facts(value): + return json.loads(_canonical_text(value)) + + +async def archived_schema_revision(session): revision = await session.scalar(text("SELECT version_num FROM public.alembic_version")) - assert 8 <= int(revision[:4]) <= 28, "historical fixture used outside its predecessor schemas" - assert not await session.scalar( - text("""SELECT EXISTS(SELECT 1 FROM information_schema.columns - WHERE table_schema='public' AND table_name='checker_runs' - AND column_name='input_materialization_evidence_id')""") - ) + assert 8 <= int(revision[:4]) <= 28, "archive seeder used outside predecessor schemas" + assert not await session.scalar(text("""SELECT EXISTS( + SELECT 1 FROM information_schema.columns + WHERE table_schema='public' AND table_name='checker_runs' + AND column_name='input_materialization_evidence_id')""")) return int(revision[:4]) -async def historical_reserve(h): - r, c = h.request, h.request.expected_context +async def seed_archived_checker_request(h): + request = h.request + context = request["expected_context"] + run_id, result_id = new_record_id(), new_record_id() async with h.factory() as session, session.begin(): - await historical_revision(session) - previous = await session.scalar( - text( - "SELECT current_run_id FROM public.checker_submission_fences WHERE submission_id=:id" - ), - {"id": r.submission_id}, - ) - run_id, result_id = new_record_id(), new_record_id() - await session.execute( - insert(CheckerRun.__table__).values( - id=str(run_id), - project_id=str(r.project_id), - task_id=str(r.task_id), - submission_id=str(r.submission_id), - submission_version=r.submission_version, - evaluation_request_id=str(r.evaluation_request_id), - phase="post_submission", - evaluation_generation=r.evaluation_generation, - request_json=_canonical_text(r, exclude={"request_sha256"}), - request_digest=r.request_sha256, - result_id=str(result_id), - trigger_source="coordinated_evaluation", - status="queued", - outcome_source="none", - routing_recommendation="not_evaluated", - worker_lease_generation=0, - supersedes_checker_run_id=str(previous) if previous else None, - locked_guide_version=c.guide_version, - locked_post_submit_checker_policy_id=str(c.post_policy_id), - locked_post_submit_checker_policy_version=c.post_policy_version, - locked_post_submit_checker_policy_hash=c.post_policy_hash, - locked_review_policy_id=str(c.review_policy_id), - locked_review_policy_generation=c.review_generation, - locked_review_policy_hash=c.review_hash, - locked_revision_policy_id=str(c.revision_policy_id), - locked_revision_policy_generation=c.revision_generation, - locked_revision_policy_hash=c.revision_hash, - ) - ) - await session.execute( - text( - "INSERT INTO public.checker_submission_fences(submission_id,current_run_id) VALUES (:submission,:run)" - if previous is None else - "UPDATE public.checker_submission_fences SET current_run_id=:run WHERE submission_id=:submission" - ), - {"submission": r.submission_id, "run": run_id}, - ) - return EvaluationReservation( - request_id=r.evaluation_request_id, - request_digest=r.request_sha256, - attempt_id=run_id, - result_id=result_id, - evaluation_generation=r.evaluation_generation, - ) + await archived_schema_revision(session) + previous = await session.scalar(text( + "SELECT current_run_id FROM public.checker_submission_fences WHERE submission_id=:id" + ), {"id": UUID(str(request["submission_id"]))}) + await session.execute(text("""INSERT INTO public.checker_runs ( + id, project_id, task_id, submission_id, submission_version, + evaluation_request_id, phase, evaluation_generation, request_json, + request_digest, result_id, trigger_source, status, outcome_source, + routing_recommendation, worker_lease_generation, supersedes_checker_run_id, + locked_guide_version, locked_post_submit_checker_policy_id, + locked_post_submit_checker_policy_version, locked_post_submit_checker_policy_hash, + locked_review_policy_id, locked_review_policy_generation, locked_review_policy_hash, + locked_revision_policy_id, locked_revision_policy_generation, locked_revision_policy_hash, + passed_count, warning_count, failed_count, blocking_count + ) VALUES ( + :id, :project, :task, :submission, :version, + :request_id, 'post_submission', :generation, :request_json, + :digest, :result_id, 'coordinated_evaluation', 'queued', 'none', + 'not_evaluated', 0, :previous, + :guide, :post_id, :post_version, :post_hash, + :review_id, :review_generation, :review_hash, + :revision_id, :revision_generation, :revision_hash, 0, 0, 0, 0 + )"""), { + "id": run_id, + "project": UUID(str(request["project_id"])), + "task": UUID(str(request["task_id"])), + "submission": UUID(str(request["submission_id"])), + "version": request["submission_version"], + "request_id": UUID(str(request["evaluation_request_id"])), + "generation": request["evaluation_generation"], + "request_json": _canonical_text(request, exclude={"request_sha256"}), + "digest": request["request_sha256"], + "result_id": result_id, + "previous": previous, + "guide": context["guide_version"], + "post_id": UUID(str(context["post_policy_id"])), + "post_version": context["post_policy_version"], + "post_hash": context["post_policy_hash"], + "review_id": UUID(str(context["review_policy_id"])), + "review_generation": context["review_generation"], + "review_hash": context["review_hash"], + "revision_id": UUID(str(context["revision_policy_id"])), + "revision_generation": context["revision_generation"], + "revision_hash": context["revision_hash"], + }) + await session.execute(text( + "INSERT INTO public.checker_submission_fences(submission_id,current_run_id) " + "VALUES (:submission,:run)" if previous is None else + "UPDATE public.checker_submission_fences SET current_run_id=:run " + "WHERE submission_id=:submission" + ), {"submission": UUID(str(request["submission_id"])), "run": run_id}) + return { + "request_id": UUID(str(request["evaluation_request_id"])), + "request_digest": request["request_sha256"], + "attempt_id": run_id, + "result_id": result_id, + "evaluation_generation": request["evaluation_generation"], + } -async def _historical_receipt(session, run_id, phase, receipt_id): - """Persist the predecessor's exact SQL-validated event shape, not a live permission.""" - row = ( - ( - await session.execute( - text("""SELECT r.project_id,r.evaluation_request_id, +async def _seed_archived_receipt(session, run_id, phase, receipt_id): + """Store the then-installed SQL receipt shape as archived migration data.""" + row = (await session.execute(text("""SELECT r.project_id,r.evaluation_request_id, public.checker_post_submit_authority_digest(r,:phase) AS digest, - (SELECT id FROM public.actor_profiles WHERE service_identity='workstream.checker.post_submit') AS actor - FROM public.checker_runs r WHERE r.id=:id"""), - {"id": run_id, "phase": phase}, - ) - ) - .mappings() - .one() - ) + (SELECT id FROM public.actor_profiles + WHERE service_identity='workstream.checker.post_submit') AS actor + FROM public.checker_runs r WHERE r.id=:id"""), + {"id": run_id, "phase": phase})).mappings().one() assert row["actor"] is not None - now = await session.scalar(text("SELECT clock_timestamp()")) - await session.execute( - insert(AuditEvent.__table__).values( - id=str(receipt_id), - entity_type="authorization_decision", - entity_id=str(receipt_id), - event_type="SensitiveAuthorizationAllowed", - actor_id=str(row["actor"]), - actor_roles=[], - claim_snapshot={}, - auth_source="local_authority", - is_dev_auth=False, - event_payload={}, - event_domain="authority", - event_version=1, - occurred_at=now, - reason="authorization_evaluation", - actor_ref_kind="actor_profile", - request_id=str(row["evaluation_request_id"]), - correlation_id=str(row["evaluation_request_id"]), - action_id="checker.post_submit." + phase, - permission_id="checker.post_submit." + phase, - project_id=str(row["project_id"]), - resource_type="checker_run", - resource_id=str(run_id), - target_ref_kind="project", - target_ref_id=str(row["project_id"]), - after_facts={"allowed": True, "resource_context_digest": row["digest"]}, - ) - ) + await session.execute(text("""INSERT INTO public.audit_events ( + id, entity_type, entity_id, event_type, actor_id, actor_roles, claim_snapshot, + auth_source, is_dev_auth, event_payload, event_domain, event_version, occurred_at, + reason, actor_ref_kind, request_id, correlation_id, action_id, permission_id, + project_id, resource_type, resource_id, target_ref_kind, target_ref_id, after_facts + ) VALUES ( + :id, 'authorization_decision', :id, 'SensitiveAuthorizationAllowed', :actor, + CAST('[]' AS json), CAST('{}' AS json), 'local_authority', false, CAST('{}' AS json), + 'authority', 1, clock_timestamp(), 'authorization_evaluation', 'actor_profile', + :request, :request, :action, :action, :project, 'checker_run', :resource, + 'project', :target, CAST(:facts AS json) + )"""), { + "id": receipt_id, + "actor": str(row["actor"]), + "request": UUID(str(row["evaluation_request_id"])), + "action": "checker.post_submit." + phase, + "project": UUID(str(row["project_id"])), + "resource": str(run_id), + "target": str(row["project_id"]), + "facts": _canonical_text({"allowed": True, "resource_context_digest": row["digest"]}), + }) -async def historical_lease(h): +async def seed_archived_running_checker(h): async with h.factory() as session, session.begin(): - revision = await historical_revision(session) - r = ( - ( - await session.execute( - text("""SELECT r.* FROM public.checker_runs r - JOIN public.checker_submission_fences f ON f.current_run_id=r.id WHERE f.submission_id=:id"""), - {"id": h.request.submission_id}, - ) - ) - .mappings() - .one() - ) + revision = await archived_schema_revision(session) + row = (await session.execute(text("""SELECT r.* FROM public.checker_runs r + JOIN public.checker_submission_fences f ON f.current_run_id=r.id + WHERE f.submission_id=:id"""), + {"id": UUID(str(h.request["submission_id"]))})).mappings().one() now = await session.scalar(text("SELECT clock_timestamp()")) - lease = ExecutionLease( - reservation=EvaluationReservation( - request_id=UUID(str(r["evaluation_request_id"])), - request_digest=r["request_digest"], - attempt_id=UUID(str(r["id"])), - result_id=UUID(str(r["result_id"])), - evaluation_generation=r["evaluation_generation"], - ), - lease_id=new_record_id(), - lease_generation=1, - expires_at=now + timedelta(seconds=300), - ) - receipt_id = new_record_id() - await session.execute( - text("""UPDATE public.checker_runs SET status='running',started_at=:now, - worker_lease_id=:lease,worker_lease_generation=1,worker_lease_expires_at=:expires, - execute_evidence_id=:receipt WHERE id=:id"""), - { - "id": r["id"], - "now": now, - "lease": lease.lease_id, - "expires": lease.expires_at, - "receipt": receipt_id, + lease = { + "reservation": { + "request_id": UUID(str(row["evaluation_request_id"])), + "request_digest": row["request_digest"], + "attempt_id": UUID(str(row["id"])), + "result_id": UUID(str(row["result_id"])), + "evaluation_generation": row["evaluation_generation"], }, - ) + "lease_id": new_record_id(), + "lease_generation": 1, + "expires_at": now + timedelta(seconds=300), + "execute_evidence_id": new_record_id(), + } + await session.execute(text("""UPDATE public.checker_runs SET status='running', + started_at=:now, worker_lease_id=:lease, worker_lease_generation=1, + worker_lease_expires_at=:expires, execute_evidence_id=:receipt WHERE id=:id"""), { + "id": row["id"], "now": now, "lease": lease["lease_id"], + "expires": lease["expires_at"], "receipt": lease["execute_evidence_id"], + }) if revision >= 10: - await _historical_receipt(session, r["id"], "execute", receipt_id) + await _seed_archived_receipt(session, row["id"], "execute", lease["execute_evidence_id"]) return lease -def historical_terminal_facts(h, lease, outcome="completed"): - """Build literal result rows from the archived request facts.""" - members = tuple( - _raw( - { - "schema_version": "post_submit_structural_result", - "checker_id": entry.checker_id, - "definition_version": entry.definition_version, - "implementation_version": entry.implementation_version, - "status": "passed", - "code": "passed", - "failure_category": "none", - "severity": "info", - "counters": [], - } - ) - for entry in h.request.policy.entries - ) - body = { +def archived_terminal_rows(h, lease, *, outcome, members, counts, + routing_recommendation, failure_code, material): + """Encode supplied archived terminal facts without classifying any member.""" + request = _json_facts(h.request) + reservation = lease["reservation"] + result = _json_facts({ "schema_version": "post_submit_evaluation_result", - "request_id": h.request.evaluation_request_id, - "request_digest": h.request.request_sha256, - "attempt_id": lease.reservation.attempt_id, - "evaluation_generation": h.request.evaluation_generation, - "result_id": lease.reservation.result_id, + "request_id": request["evaluation_request_id"], + "request_digest": request["request_sha256"], + "attempt_id": reservation["attempt_id"], + "evaluation_generation": request["evaluation_generation"], + "result_id": reservation["result_id"], "outcome": outcome, - "member_results": members if outcome == "completed" else (), - "infrastructure_failure_code": ( - None if outcome == "completed" else "implementation_unavailable" - ), - } - body["result_digest"] = canonical_json_hash( - _raw(body).model_dump() - ) - return _raw( - { - "request": h.request, - "lease": lease, - "result": _raw(body), - "material": VerifiedMaterialFacts( - submission_id=h.request.submission_id, - submission_version=h.request.submission_version, - admission_id=h.created.admission_id, - binding_id=h.request.binding_id, - content_id=h.request.content_id, - replica_id=h.replica_id, - content_sha256=h.request.content_sha256, - byte_count=h.request.byte_count, - semantic_manifest_sha256=h.manifest.sha256, - ), - } - ) - - -async def historical_write_terminal(session, facts, material): - revision = await historical_revision(session) - request, result = facts.request, facts.result - run_id = result.attempt_id - execute_id = await session.scalar( - text("SELECT execute_evidence_id FROM public.checker_runs WHERE id=:id"), {"id": run_id} - ) + "member_results": members, + "infrastructure_failure_code": failure_code, + }) + result["result_digest"] = canonical_json_hash(result) final_id = new_record_id() - members = result.member_results - passed = sum(item.status == "passed" for item in members) - warning = sum(item.status == "warning" for item in members) - failed = sum(item.status == "failed" for item in members) - blocking_severities = set(request.policy.blocking_severities) - blocking = sum( - item.status != "passed" and item.severity in blocking_severities - for item in members - ) - setup = any( - item.status != "passed" and item.failure_category == "task_configuration" - for item in members - ) - routing = ( - "not_evaluated" - if result.outcome != "completed" - else "task_setup_blocked" - if setup - else "needs_revision" - if blocking - else "allow_review" - ) - for order, member in enumerate(result.member_results): - await session.execute( - insert(CheckerResult.__table__).values( - id=str(new_record_id()), - checker_run_id=str(run_id), - task_id=str(request.task_id), - submission_id=str(request.submission_id), - member_order=order, - checker_name=member.checker_id, - definition_version=member.definition_version, - implementation_version=member.implementation_version, - status=member.status, - severity=member.severity, - code=member.code, - failure_category=member.failure_category, - counters=[value.model_dump() for value in member.counters], - ) - ) - event_id = None - if result.outcome == "completed": - reference = { - "schema_version": "post_submit_current_result_reference", - "request_id": str(result.request_id), - "request_digest": result.request_digest, - "attempt_id": str(result.attempt_id), - "evaluation_generation": result.evaluation_generation, - "result_id": str(result.result_id), - "result_digest": result.result_digest, - } - event = { - "project_id": str(request.project_id), - "task_id": str(request.task_id), - "submission_id": str(request.submission_id), - "reference": reference, - "routing_recommendation": routing, + outbox = None + if outcome == "completed": + payload = { + "project_id": request["project_id"], + "task_id": request["task_id"], + "submission_id": request["submission_id"], + "reference": {"schema_version": "post_submit_current_result_reference", **{ + key: result[key] for key in ( + "request_id", "request_digest", "attempt_id", "evaluation_generation", + "result_id", "result_digest", + ) + }}, + "routing_recommendation": routing_recommendation, "output_binding_ids": [], - "execute_evidence_id": str(execute_id), + "execute_evidence_id": str(lease["execute_evidence_id"]), "finalize_evidence_id": str(final_id), } - appended = await outbox_append(session).append( - OutboxAppendInput( - event_type=COMPLETION_EVENT, - event_version=1, - aggregate_type="checker_run", - aggregate_id=run_id, - project_id=request.project_id, - correlation_id=str(request.evaluation_request_id), - idempotency_key="checker-completed:" + str(run_id), - payload=event, - ) - ) - event_id = appended.event_id + outbox = { + "event_id": new_record_id(), + "event_type": "PostSubmissionEvaluationCompleted", + "event_version": 1, + "aggregate_type": "checker_run", + "aggregate_id": reservation["attempt_id"], + "project_id": UUID(str(request["project_id"])), + "correlation_id": request["evaluation_request_id"], + "idempotency_key": "checker-completed:" + str(reservation["attempt_id"]), + "payload": payload, + "payload_digest": canonical_json_hash(payload), + } + member_rows = [{ + "id": new_record_id(), + "checker_run_id": reservation["attempt_id"], + "task_id": UUID(str(request["task_id"])), + "submission_id": UUID(str(request["submission_id"])), + "member_order": order, + "checker_name": member["checker_id"], + **{key: deepcopy(member[key]) for key in ( + "definition_version", "implementation_version", "status", "severity", "code", + "failure_category", "counters", + )}, + } for order, member in enumerate(result["member_results"])] + return { + "request": request, + "lease": deepcopy(lease), + "result": result, + "material": _json_facts(material) if material is not None else None, + "member_rows": member_rows, + "outbox": outbox, + "run": { + "id": reservation["attempt_id"], + "status": outcome, + "result_json": _canonical_text(result, exclude={"result_digest"}), + "result_digest": result["result_digest"], + "material_custody": _json_facts(material) if material is not None else None, + "finalize_evidence_id": final_id, + "routing_recommendation": routing_recommendation, + "failure_code": failure_code, + "passed_count": counts["passed"], + "warning_count": counts["warning"], + "failed_count": counts["failed"], + "blocking_count": counts["blocking"], + "completion_event_id": outbox["event_id"] if outbox is not None else None, + }, + } - await session.execute( - text("""UPDATE public.checker_runs SET status=:status, - result_json=:body,result_digest=:digest,material_custody=CAST(:material AS json), - finalize_evidence_id=:final,completed_at=clock_timestamp(),outcome_source='auto_checker', - routing_recommendation=:routing,failure_code=:failure,passed_count=:passed, - warning_count=:warning,failed_count=:failed,blocking_count=:blocking,completion_event_id=:event WHERE id=:id"""), - dict( - id=run_id, - status=result.outcome, - body=_canonical_text(result, exclude={"result_digest"}), - digest=result.result_digest, - material=json.dumps(material) if material is not None else None, - final=final_id, - routing=routing, - failure=result.infrastructure_failure_code, - passed=passed, - warning=warning, - failed=failed, - blocking=blocking, - event=event_id, - ), - ) + +async def seed_archived_terminal(session, rows): + """Insert supplied rows inside the caller's transaction; constraints decide validity.""" + revision = await archived_schema_revision(session) + for member in rows["member_rows"]: + await session.execute(text("""INSERT INTO public.checker_results ( + id, checker_run_id, task_id, submission_id, member_order, checker_name, + definition_version, implementation_version, status, severity, code, + failure_category, counters + ) VALUES ( + :id, :checker_run_id, :task_id, :submission_id, :member_order, :checker_name, + :definition_version, :implementation_version, :status, :severity, :code, + :failure_category, CAST(:counters AS json) + )"""), member | {"counters": json.dumps(member["counters"], allow_nan=False)}) + event = rows["outbox"] + if event is not None: + await session.execute(text("""INSERT INTO public.outbox_events ( + event_id, event_type, event_version, aggregate_type, aggregate_id, project_id, + correlation_id, idempotency_key, payload, payload_digest + ) VALUES ( + :event_id, :event_type, :event_version, :aggregate_type, :aggregate_id, :project_id, + :correlation_id, :idempotency_key, CAST(:payload AS jsonb), :payload_digest + )"""), event | {"payload": _canonical_text(event["payload"])}) + run = rows["run"] + await session.execute(text("""UPDATE public.checker_runs SET status=:status, + result_json=:result_json, result_digest=:result_digest, + material_custody=CAST(:material_custody AS json), + finalize_evidence_id=:finalize_evidence_id, completed_at=clock_timestamp(), + outcome_source='auto_checker', routing_recommendation=:routing_recommendation, + failure_code=:failure_code, passed_count=:passed_count, warning_count=:warning_count, + failed_count=:failed_count, blocking_count=:blocking_count, + completion_event_id=:completion_event_id WHERE id=:id"""), run | { + "material_custody": _canonical_text(run["material_custody"]) + if run["material_custody"] is not None else None, + }) if revision >= 10: - await _historical_receipt(session, run_id, "finalize", final_id) + await _seed_archived_receipt(session, run["id"], "finalize", run["finalize_evidence_id"]) @asynccontextmanager -async def historical_completed_source(tmp_path, database_url, **options): +async def archived_completed_checker_source(tmp_path, database_url, **options): async with historical_material_fixture(tmp_path, database_url, **options) as h: - await historical_reserve(h) - lease = await historical_lease(h) - facts = historical_terminal_facts(h, lease) + await seed_archived_checker_request(h) + lease = await seed_archived_running_checker(h) + rows = archived_terminal_rows( + h, lease, outcome="completed", members=h.archived_members, counts=h.archived_counts, + routing_recommendation="allow_review", failure_code=None, material=h.archived_material, + ) async with h.factory() as session, session.begin(): - await historical_write_terminal(session, facts, facts.material.model_dump(mode="json")) - h.result, h.material = facts.result, facts.material.model_dump(mode="json") + await seed_archived_terminal(session, rows) + h.result, h.material, h.completion_event = rows["result"], rows["material"], rows["outbox"] async with h.factory() as session: - r = ( - ( - await session.execute( - text("""SELECT r.*,s.task_assignment_id,s.contributor_id, - s.contribution_policy_version_id,p.human_review_required FROM public.checker_runs r - JOIN public.submissions s ON s.id=r.submission_id - JOIN public.review_policies p ON p.id=s.locked_review_policy_id WHERE r.id=:id"""), - {"id": facts.result.attempt_id}, - ) - ) - .mappings() - .one() - ) - names = ( - "project_id", - "task_id", - "submission_id", - "submission_version", - "contributor_id", - "contribution_policy_version_id", - "evaluation_request_id", - "request_digest", - "evaluation_generation", - "result_id", - "result_digest", - "completion_event_id", - "execute_evidence_id", - "finalize_evidence_id", - "human_review_required", - ) - h.source = {name: r[name] for name in names} | { + row = (await session.execute(text("""SELECT r.*,s.task_assignment_id,s.contributor_id, + s.contribution_policy_version_id,p.human_review_required FROM public.checker_runs r + JOIN public.submissions s ON s.id=r.submission_id + JOIN public.review_policies p ON p.id=s.locked_review_policy_id WHERE r.id=:id"""), + {"id": rows["run"]["id"]})).mappings().one() + h.source = {name: row[name] for name in ( + "project_id", "task_id", "submission_id", "submission_version", "contributor_id", + "contribution_policy_version_id", "evaluation_request_id", "request_digest", + "evaluation_generation", "result_id", "result_digest", "completion_event_id", + "execute_evidence_id", "finalize_evidence_id", "human_review_required", + )} | { "id": new_record_id(), - "checker_run_id": r["id"], - "assignment_id": r["task_assignment_id"], - **{ - name: h.material[name] - for name in ( - "replica_id", - "content_sha256", - "byte_count", - "semantic_manifest_sha256", - ) - }, + "checker_run_id": row["id"], + "assignment_id": row["task_assignment_id"], + **{name: h.material[name] for name in ( + "replica_id", "content_sha256", "byte_count", "semantic_manifest_sha256", + )}, } for name, value in h.source.items(): if name.endswith("_id") or name == "id": From fcc58b00e8d0ad20c333243ae62f6188f251d47c Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 14:32:56 +0100 Subject: [PATCH 224/283] test(pilot04): separate archived migration rows from current owners --- .../pilot04-workstream-default-checker.md | 24 +++ .../post_submit/test_migration.py | 16 +- .../execution/test_material_migration.py | 68 +++---- .../records/historical_support.py | 20 +-- .../contributions/records/test_migration.py | 5 +- backend/tests/migration_ancestor_rows.py | 166 ++++++++++++++++++ .../reviews/acceptance/historical_support.py | 79 +++------ .../reviews/acceptance/test_migration.py | 3 +- .../tests/reviews/decision/test_migration.py | 7 +- .../tests/reviews/lifecycle/test_migration.py | 3 - backend/tests/reviews/packet/support.py | 3 +- .../tests/reviews/packet/test_migration.py | 7 +- .../post_submit_routing/test_migration.py | 12 +- .../test_outcome_migration.py | 8 +- 14 files changed, 285 insertions(+), 136 deletions(-) create mode 100644 backend/tests/migration_ancestor_rows.py diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 6b8e74fa9..73ea64426 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -905,3 +905,27 @@ wrapper as its no-execution sentinel. Replace only that sentinel with external policy, proposal finalization, provider/document denial, derive/approval replay and unchanged finalization state. This is a required current isolation control, not obsolete catalogue behavior; the old wrapper is not restored. + +### Plain archived migration consumers + +Lead assigns migration consumers to this lane and raw execution/base producers +to the QA/backend owners. Allowed test paths: execution/test_material_migration; +authorization/post_submit/test_migration; tasks/post_submit_routing/{test_migration, +test_outcome_migration}; reviews/{packet,decision,acceptance,lifecycle}/test_migration; +contributions/records/test_migration; the existing reviews/acceptance and +contributions/records historical_support helpers; and one migration-only +`backend/tests/migration_ancestor_rows.py` for literal ancestor queue, lease, +packet and Review rows. Keep these separate from current packet/review fixtures. +No dict-versus-current compatibility switch, old model facade, archived service +subprocess, production or migration edits are allowed. Plain request/result/ +material/lease dictionaries and direct SQL carry predecessor facts only. Preserve +retained-row equality, immutability, preflight refusal and observed writer locks; +current public/native tests own current execution and economic behavior. Risks +remain L1 fixture/custody reconciliation, requiring QA/test-delta review, fresh +collection and discriminating native predecessor checks before readiness. + +The raw migration consumers no longer call the current packet fixture's alternate +factory hook. Its now-unused `completed_source_factory` parameter is removed from +`backend/tests/reviews/packet/support.py`; the current fixture always uses the +same canonical `completed_source`. This exact helper cleanup adds no raw/current +switch, changes no current source behavior and retains all current packet tests. diff --git a/backend/tests/authorization/post_submit/test_migration.py b/backend/tests/authorization/post_submit/test_migration.py index 40c183873..092f42402 100644 --- a/backend/tests/authorization/post_submit/test_migration.py +++ b/backend/tests/authorization/post_submit/test_migration.py @@ -10,7 +10,7 @@ from app.db import session as db_session from tests.migration_fixtures import add_current_art_seed_column, restore_predecessor_evidence_schema from tests.migration_fixtures import _config -from tests.checkers.execution.historical_execution import historical_lease, historical_reserve +from tests.checkers.execution.historical_execution import seed_archived_running_checker, seed_archived_checker_request from tests.checkers.execution.test_material_migration import retained_snapshot from tests.historical_submission_fixtures import historical_material_fixture @@ -34,9 +34,9 @@ async def test_actual_upgrade_preserves_or_refuses_without_repair( tmp_path, isolated_database_env, provision_checker=False ) as h: await restore_predecessor_evidence_schema(isolated_database_env, original_columns) - await historical_reserve(h) + await seed_archived_checker_request(h) if unprovable_receipt: - await historical_lease(h) + await seed_archived_running_checker(h) before = await retained_snapshot(h.factory) if unprovable_receipt: with pytest.raises(IntegrityError, match="retained checker authorization receipts are unprovable"): @@ -69,7 +69,7 @@ async def test_upgrade_excludes_writer_across_receipt_preflight( tmp_path, isolated_database_env, provision_checker=False ) as h: await restore_predecessor_evidence_schema(isolated_database_env, original_columns) - reserved = await historical_reserve(h) + reserved = await seed_archived_checker_request(h) scanned, resume = threading.Event(), threading.Event() execute = Operations.execute @@ -93,7 +93,7 @@ async def write_predecessor_receipt(): worker_lease_id=:lease,worker_lease_generation=1, worker_lease_expires_at=clock_timestamp()+interval '300 seconds', execute_evidence_id=:receipt,started_at=clock_timestamp() WHERE id=:id"""), - {"lease":new_record_id(),"receipt":new_record_id(),"id":reserved.attempt_id}) + {"lease":new_record_id(),"receipt":new_record_id(),"id":reserved["attempt_id"]}) try: assert await asyncio.to_thread(scanned.wait, 10) @@ -114,13 +114,13 @@ async def write_predecessor_receipt(): with pytest.raises(IntegrityError, match="receipt custody|foreign key"): await asyncio.wait_for(writer, 10) async with h.factory() as session: - row = (await session.execute(text("SELECT status,execute_evidence_id,worker_lease_id FROM checker_runs WHERE id=:id"), {"id": reserved.attempt_id})).one() + row = (await session.execute(text("SELECT status,execute_evidence_id,worker_lease_id FROM checker_runs WHERE id=:id"), {"id": reserved["attempt_id"]})).one() assert row == ("queued", None, None) from tests.checkers.execution.support import provision_post_submit_service await provision_post_submit_service(h.factory) - valid = await historical_lease(h) - assert valid.reservation.attempt_id == reserved.attempt_id + valid = await seed_archived_running_checker(h) + assert valid["reservation"]["attempt_id"] == reserved["attempt_id"] finally: resume.set() await asyncio.gather(migration, *([writer] if writer else []), return_exceptions=True) diff --git a/backend/tests/checkers/execution/test_material_migration.py b/backend/tests/checkers/execution/test_material_migration.py index dc23dfd3a..4cd53b83d 100644 --- a/backend/tests/checkers/execution/test_material_migration.py +++ b/backend/tests/checkers/execution/test_material_migration.py @@ -13,14 +13,14 @@ from app.db import session as db_session from tests.migration_fixtures import add_current_art_seed_column, restore_predecessor_evidence_schema from tests.migration_fixtures import _config -from tests.historical_submission_fixtures import _raw, historical_material_fixture +from tests.historical_submission_fixtures import historical_material_fixture from types import SimpleNamespace from .historical_execution import ( - historical_reserve, - historical_lease, - historical_terminal_facts, - historical_write_terminal, + seed_archived_checker_request, + seed_archived_running_checker, + archived_terminal_rows, + seed_archived_terminal, ) pytestmark = pytest.mark.postgres_schema_contract @@ -62,38 +62,43 @@ async def test_retained_material_upgrade( tmp_path, isolated_database_env, provision_checker=False ) as h: await restore_predecessor_evidence_schema(isolated_database_env, original_columns) - await historical_reserve(h) - lease = await historical_lease(h) - facts = historical_terminal_facts(h, lease, outcome) - material = facts.material.model_dump(mode="json") + await seed_archived_checker_request(h) + lease = await seed_archived_running_checker(h) + material = dict(h.archived_material) if not valid: # A real but wrong admission is covered separately in direct SQL # tests. This retained 0008 row proves no fabricated ID backfill. - material["admission_id"] = str(h.request.submission_id) + material["admission_id"] = h.request["submission_id"] + rows = archived_terminal_rows( + h, lease, outcome=outcome, + members=h.archived_members if outcome == "completed" else (), + counts=h.archived_counts if outcome == "completed" else dict(passed=0, warning=0, failed=0, blocking=0), + routing_recommendation="allow_review" if outcome == "completed" else "not_evaluated", + failure_code=None if outcome == "completed" else "implementation_unavailable", + material=material, + ) async with h.factory() as session, session.begin(): - await historical_write_terminal(session, facts, material) + await seed_archived_terminal(session, rows) if valid: # Preserve superseded completed/failed history and a current # failure that never received material, plus later replica loss. successor = SimpleNamespace(**vars(h)) - request_body = h.request.model_dump(exclude={"request_sha256"}) + request_body = {key: value for key, value in h.request.items() if key != "request_sha256"} request_body.update(evaluation_generation=2, evaluation_request_id=str(new_record_id())) - successor.request = _raw(request_body | {"request_sha256": canonical_json_hash(request_body)}) - await historical_reserve(successor) - next_lease = await historical_lease(successor) - empty = historical_terminal_facts(successor, next_lease, "infrastructure_failed") - body = empty.result.model_dump(exclude={"result_digest"}) - body["infrastructure_failure_code"] = "material_unavailable" - empty = empty.model_copy(update={ - "result": _raw(body | {"result_digest": canonical_json_hash(body)}), - "material": None, - }) + successor.request = request_body | {"request_sha256": canonical_json_hash(request_body)} + await seed_archived_checker_request(successor) + next_lease = await seed_archived_running_checker(successor) + empty = archived_terminal_rows( + successor, next_lease, outcome="infrastructure_failed", members=(), + counts=dict(passed=0, warning=0, failed=0, blocking=0), + routing_recommendation="not_evaluated", failure_code="material_unavailable", material=None, + ) async with h.factory() as session, session.begin(): - await historical_write_terminal(session, empty, None) + await seed_archived_terminal(session, empty) await session.execute(text( "update artifact_replicas set availability_state='unavailable', " "content_id=(select id from artifact_contents where id<>:content limit 1) where id=:id" - ), {"id": h.replica_id, "content": facts.material.content_id}) + ), {"id": h.replica_id, "content": h.archived_material["content_id"]}) before = await retained_snapshot(h.factory) assert before[1] == "0008_checker_execution" if valid: @@ -123,10 +128,13 @@ async def test_upgrade_excludes_writer_until_guard_is_installed( tmp_path, isolated_database_env, provision_checker=False ) as h: await restore_predecessor_evidence_schema(isolated_database_env, original_columns) - await historical_reserve(h) - lease = await historical_lease(h) - facts = historical_terminal_facts(h, lease, "completed") - material = facts.material.model_dump(mode="json") | {"admission_id": str(h.request.submission_id)} + await seed_archived_checker_request(h) + lease = await seed_archived_running_checker(h) + material = dict(h.archived_material) | {"admission_id": h.request["submission_id"]} + rows = archived_terminal_rows( + h, lease, outcome="completed", members=h.archived_members, counts=h.archived_counts, + routing_recommendation="allow_review", failure_code=None, material=material, + ) scanned, resume = threading.Event(), threading.Event() execute = Operations.execute @@ -145,7 +153,7 @@ def paused_execute(operations, sql, *args, **kwargs): async def write(): async with h.factory() as session, session.begin(): await pid.put(await session.scalar(text("select pg_backend_pid()"))) - await historical_write_terminal(session, facts, material) + await seed_archived_terminal(session, rows) try: assert await asyncio.to_thread(scanned.wait, 10), "migration did not reach preflight" @@ -167,7 +175,7 @@ async def write(): await asyncio.wait_for(writer, 10) async with h.factory() as session: assert await session.scalar(text("select status from checker_runs where id=:id"), - {"id": str(facts.result.attempt_id)}) == "running" + {"id": rows["run"]["id"]}) == "running" finally: resume.set() await asyncio.gather(migration, *([writer] if writer is not None else []), return_exceptions=True) diff --git a/backend/tests/contributions/records/historical_support.py b/backend/tests/contributions/records/historical_support.py index 1776467e8..d5d5f1c52 100644 --- a/backend/tests/contributions/records/historical_support.py +++ b/backend/tests/contributions/records/historical_support.py @@ -45,28 +45,28 @@ async def historical_contribution_source( SELECT task_assignment_id, contribution_policy_version_id, contributor_id FROM public.submissions WHERE id=:id """), - {"id": h.review.submission_id}, + {"id": h.review["submission_id"]}, ) ) .mappings() .one() ) common = dict( - project_id=h.review.project_id, - task_id=h.review.task_id, - submission_id=h.review.submission_id, - artifact_hash=h.review.artifact_hash, + project_id=h.review["project_id"], + task_id=h.review["task_id"], + submission_id=h.review["submission_id"], + artifact_hash=h.review["artifact_hash"], ) h.reviewer_record = ContributionRecordInput( **common, id=new_record_id(), contribution_type="completed_review", - contributor_id=h.review.reviewer_id, - source_review_id=h.review.id, - source_review_lease_id=h.review.review_lease_id, + contributor_id=h.review["reviewer_id"], + source_review_id=h.review["id"], + source_review_lease_id=h.review["review_lease_id"], source_final_acceptance_id=None, source_task_assignment_id=None, - contribution_policy_version_id=h.review.reviewer_contribution_policy_version_id, + contribution_policy_version_id=h.review["reviewer_contribution_policy_version_id"], ) h.submitter_record = ContributionRecordInput( **common, @@ -75,7 +75,7 @@ async def historical_contribution_source( contributor_id=UUID(str(row["contributor_id"])), source_review_id=None, source_review_lease_id=None, - source_final_acceptance_id=h.acceptance.id, + source_final_acceptance_id=h.acceptance["id"], source_task_assignment_id=UUID(str(row["task_assignment_id"])), contribution_policy_version_id=row["contribution_policy_version_id"], ) diff --git a/backend/tests/contributions/records/test_migration.py b/backend/tests/contributions/records/test_migration.py index d4c32a879..2b6968e2c 100644 --- a/backend/tests/contributions/records/test_migration.py +++ b/backend/tests/contributions/records/test_migration.py @@ -10,7 +10,6 @@ from alembic import command from sqlalchemy.exc import DBAPIError -from tests.checkers.execution.historical_execution import historical_completed_source from app.db import session as db_session from tests.contributions.records.support import ( award_values, @@ -63,7 +62,7 @@ async def test_contribution_upgrade_preserves_sources( await asyncio.to_thread(command.upgrade, _config(), "0014_final_acceptance") original_columns = await add_current_art_seed_column(isolated_database_env) async with historical_acceptance_source( - tmp_path, isolated_database_env, completed_source_factory=historical_completed_source + tmp_path, isolated_database_env ) as h: await restore_predecessor_evidence_schema(isolated_database_env, original_columns) async with h.factory() as session: @@ -130,7 +129,6 @@ async def test_completeness_upgrade_preserves_complete_retained_awards( tmp_path, isolated_database_env, paid=True, - completed_source_factory=historical_completed_source, ) as h: await restore_predecessor_evidence_schema(isolated_database_env, original_columns) async with h.factory() as session: @@ -207,7 +205,6 @@ async def test_completeness_upgrade_refuses_incomplete_retained_awards_unchanged tmp_path, isolated_database_env, paid=True, - completed_source_factory=historical_completed_source, ) as h: await restore_predecessor_evidence_schema(isolated_database_env, original_columns) async with h.factory() as session: diff --git a/backend/tests/migration_ancestor_rows.py b/backend/tests/migration_ancestor_rows.py new file mode 100644 index 000000000..8e53c067c --- /dev/null +++ b/backend/tests/migration_ancestor_rows.py @@ -0,0 +1,166 @@ +"""Literal Review ancestors for predecessor-storage migration proofs only. + +This seeder calls no current review, routing, checker or authorization service. +Installed SQL guards validate every archived relationship and digest. +""" + +from contextlib import asynccontextmanager +from datetime import timedelta +import json +from uuid import UUID + +from sqlalchemy import insert, text + +from app.core.hashing import canonical_json_hash +from app.core.identifiers import new_record_id +from app.modules.reviews.models import ReviewQueueEntry, ReviewLease +from app.modules.reviews.packet.models import ReviewPacketManifest, ReviewPacketGuideItem +from app.modules.reviews.decision.models import Review, ReviewFinding, ReviewDecisionRequest +from tests.checkers.execution.historical_execution import archived_completed_checker_source + + +def _json(value): + return json.loads(json.dumps(value, default=str)) + + +@asynccontextmanager +async def archived_packet_ancestors(tmp_path, database_url, **options): + async with archived_completed_checker_source(tmp_path, database_url, **options) as h: + await seed_packet_ancestors(h) + yield h + + +async def seed_packet_ancestors(h): + async with h.factory() as session, session.begin(): + revision = await session.scalar(text("SELECT version_num FROM public.alembic_version")) + assert 11 <= int(revision[:4]) <= 28 + submission = (await session.execute(text( + "SELECT * FROM public.submissions WHERE id=:id" + ), {"id": UUID(h.request["submission_id"])})).mappings().one() + guide = (await session.execute(text( + "SELECT * FROM public.project_guides WHERE project_id=:project AND version=:version" + ), {"project": submission["project_id"], "version": submission["locked_guide_version"]})).mappings().one() + activation = await session.scalar(text( + "SELECT response_json FROM public.guide_mutation_idempotency_records WHERE operation_id=:id" + ), {"id": guide["activation_operation_id"]}) + proposal = activation["command"]["target"]["proposal"] + documents = (await session.execute(text("""SELECT i.id AS ingest_id, + s.id AS source_item_id, s.item_order, s.media_type + FROM public.guide_source_snapshot_items s + JOIN public.guide_source_artifact_ingests i ON i.source_item_id=s.id + WHERE s.source_snapshot_id=:id ORDER BY s.item_order"""), + {"id": submission["locked_guide_source_snapshot_id"]})).mappings().all() + reviewer = await session.scalar(text("""SELECT id FROM public.actor_profiles + WHERE service_identity IS NULL AND id<>:contributor AND status='active' + ORDER BY id LIMIT 1"""), {"contributor": submission["contributor_id"]}) + assert reviewer is not None, "archived base must include a distinct human reviewer" + now = await session.scalar(text("SELECT clock_timestamp()")) + h.queue_id, h.lease_id = new_record_id(), new_record_id() + await session.execute(insert(ReviewQueueEntry).values( + id=h.queue_id, project_id=str(submission["project_id"]), task_id=str(submission["task_id"]), + submission_id=str(submission["id"]), submission_version=submission["version"], + admitting_checker_run_id=h.result["attempt_id"], routing_mode="open", + routing_reason="first_submission", queue_state="pending", active_lease_id=None, + routing_generation=1, lifecycle_generation=1, first_queued_at=now, available_since=now, + )) + await session.execute(insert(ReviewLease).values( + id=h.lease_id, review_queue_entry_id=h.queue_id, + project_id=str(submission["project_id"]), task_id=str(submission["task_id"]), + submission_id=str(submission["id"]), submission_version=submission["version"], + reviewer_id=str(reviewer), reviewer_contribution_policy_version_id=h.source["contribution_policy_version_id"], + attempt_generation=1, expires_at=now+timedelta(days=1), status="active", claimed_at=now, + )) + await session.execute(text("""UPDATE public.review_queue_entries + SET queue_state='leased',active_lease_id=:lease WHERE id=:id"""), + {"id": h.queue_id, "lease": h.lease_id}) + request = { + "project_id": str(submission["project_id"]), "task_id": str(submission["task_id"]), + "submission_id": str(submission["id"]), "submission_version": submission["version"], + "checker_run_id": h.result["attempt_id"], "result_id": h.result["result_id"], + "guide_id": str(guide["id"]), "guide_version": guide["version"], + "source_snapshot_id": str(submission["locked_guide_source_snapshot_id"]), + "project_setup_run_id": proposal["setup_run_id"], "setup_generation": proposal["setup_generation"], + } + h.packet_body = {"request": request, "submission": { + "binding_id": str(submission["artifact_binding_id"]), + "logical_role": "submission_bundle_original", "media_type": "application/zip", + }, "guide_documents": [{ + "ingest_id": str(d["ingest_id"]), "source_item_id": str(d["source_item_id"]), + "item_order": d["item_order"], "logical_role": "guide_source_original", "media_type": d["media_type"], + } for d in documents]} + h.archived_submission = dict(submission) + h.archived_reviewer_id = reviewer + + +@asynccontextmanager +async def archived_review_ancestors(tmp_path, database_url, *, decision="accept", **options): + async with archived_packet_ancestors(tmp_path, database_url, **options) as h: + await seed_review_ancestors(h, decision=decision) + yield h + + +async def seed_review_ancestors(h, *, decision): + async with h.factory() as session, session.begin(): + revision = await session.scalar(text("SELECT version_num FROM public.alembic_version")) + assert 12 <= int(revision[:4]) <= 28 + h.packet_id = new_record_id() + digest = canonical_json_hash(h.packet_body) + request = h.packet_body["request"] + await session.execute(insert(ReviewPacketManifest).values( + id=h.packet_id, review_lease_id=h.lease_id, review_queue_entry_id=h.queue_id, + packet_manifest_generation=1, packet_manifest_digest=digest, + **request, submission_binding_id=h.packet_body["submission"]["binding_id"], + submission_logical_role="submission_bundle_original", submission_media_type="application/zip", + )) + for member in h.packet_body["guide_documents"]: + await session.execute(insert(ReviewPacketGuideItem).values( + packet_id=h.packet_id, **member, + )) + s = h.archived_submission + artifact_hash = await session.scalar(text( + "SELECT sha256 FROM public.artifact_contents WHERE id=:id" + ), {"id": s["artifact_content_id"]}) + h.review = { + "id": new_record_id(), "project_id": s["project_id"], "task_id": s["task_id"], + "task_assignment_id": s["task_assignment_id"], "submission_id": s["id"], + "submission_version": s["version"], "review_queue_entry_id": h.queue_id, + "review_lease_id": h.lease_id, "packet_manifest_id": h.packet_id, + "packet_manifest_digest": digest, "artifact_hash": artifact_hash, + "reviewer_id": h.archived_reviewer_id, + "reviewer_contribution_policy_version_id": h.source["contribution_policy_version_id"], + "locked_guide_version": s["locked_guide_version"], + "locked_review_policy_id": s["locked_review_policy_id"], + "locked_review_policy_generation": s["locked_review_policy_generation"], + "locked_review_policy_hash": s["locked_review_policy_hash"], "predecessor_review_id": None, + "decision": decision, "summary": "Verified the exact submitted work.", + "findings": ([{"id": new_record_id(), "finding_kind": "blocking", "area": "Deliverable", + "issue": "Required result", "required_fix": "Correct the documented result."}] + if decision == "needs_revision" else []), "resolutions": [], + } + + +async def seed_review_row(session, review): + source = _json(review) + findings = source["findings"] + counts = {"finding_count": len(findings), + "blocking_finding_count": sum(f["finding_kind"] == "blocking" for f in findings), + "resolution_count": 0} + digest = canonical_json_hash(source | counts | {"domain": "workstream.review_source.v0.1"}) + values = {k: v for k, v in review.items() if k not in {"findings", "resolutions"}} + await session.execute(insert(Review).values(**values, **counts, aggregate_digest=digest)) + for order, member in enumerate(review["findings"]): + await session.execute(insert(ReviewFinding).values(**member, review_id=review["id"], item_order=order)) + request_body = source | counts | {"action": "review.decision", "domain": "workstream.review_decision_request.v0.1"} + request_body.pop("id") + for member in request_body["findings"]: + member.pop("id") + await session.execute(insert(ReviewDecisionRequest).values( + id=new_record_id(), operation_id=new_record_id(), project_id=review["project_id"], + reviewer_id=review["reviewer_id"], idempotency_key=new_record_id(), review_id=review["id"], + request_digest=canonical_json_hash(request_body), + )) + await session.execute(text("""UPDATE public.review_leases SET status='consumed', + close_reason='review_recorded',closed_at=clock_timestamp() WHERE id=:id"""), {"id": review["review_lease_id"]}) + await session.execute(text("""UPDATE public.review_queue_entries SET queue_state='closed', + closed_reason='review_recorded',active_lease_id=NULL,closed_at=clock_timestamp() WHERE id=:id"""), + {"id": review["review_queue_entry_id"]}) diff --git a/backend/tests/reviews/acceptance/historical_support.py b/backend/tests/reviews/acceptance/historical_support.py index 89669bed7..dc66b2765 100644 --- a/backend/tests/reviews/acceptance/historical_support.py +++ b/backend/tests/reviews/acceptance/historical_support.py @@ -1,42 +1,18 @@ -"""Pre-0029 acceptance storage for migration preservation only.""" +"""Literal predecessor acceptance storage, never current acceptance authority.""" from contextlib import asynccontextmanager -from uuid import UUID - from sqlalchemy import insert, text from app.core.identifiers import new_record_id from app.modules.reviews.acceptance.models import FinalAcceptance -from pydantic import BaseModel -from typing import Literal -from tests.reviews.decision.support import finding, insert_review, review_source - - -class HistoricalAcceptanceInput(BaseModel): - id: UUID - project_id: UUID - task_id: UUID - submission_id: UUID - acceptance_source: Literal["human_review"] - source_review_id: UUID - source_routing_manifest_id: None - accepted_submitter_id: UUID - recorded_by: UUID - policy_context_ref: UUID +from tests.migration_ancestor_rows import archived_review_ancestors, seed_review_row @asynccontextmanager async def historical_acceptance_source(tmp_path, database_url, *, decision="accept", **options): - async with review_source(tmp_path, database_url, **options) as h: - h.review = h.review.model_copy( - update={ - "decision": decision, - "findings": (finding(),) if decision == "needs_revision" else (), - } - ) - async with h.factory() as session: - await insert_review(session, h.review) - await session.commit() + async with archived_review_ancestors(tmp_path, database_url, decision=decision, **options) as h: + async with h.factory() as session, session.begin(): + await seed_review_row(session, h.review) await attach_historical_acceptance(h) yield h @@ -44,38 +20,23 @@ async def historical_acceptance_source(tmp_path, database_url, *, decision="acce async def attach_historical_acceptance(h): async with h.factory() as session: revision = await session.scalar(text("SELECT version_num FROM public.alembic_version")) - assert 13 <= int(revision[:4]) <= 28, "historical acceptance is not current authority" - contributor = await session.scalar( - text("SELECT contributor_id FROM public.submissions WHERE id=:id"), - {"id": h.review.submission_id}, - ) - h.acceptance = HistoricalAcceptanceInput( - id=new_record_id(), - project_id=h.review.project_id, - task_id=h.review.task_id, - submission_id=h.review.submission_id, - acceptance_source="human_review", - source_review_id=h.review.id, - source_routing_manifest_id=None, - accepted_submitter_id=UUID(str(contributor)), - recorded_by=h.review.reviewer_id, - policy_context_ref=h.review.locked_review_policy_id, - ) + assert 13 <= int(revision[:4]) <= 28 + contributor = await session.scalar(text( + "SELECT contributor_id FROM public.submissions WHERE id=:id" + ), {"id": h.review["submission_id"]}) + h.acceptance = { + "id": new_record_id(), "project_id": h.review["project_id"], "task_id": h.review["task_id"], + "submission_id": h.review["submission_id"], "acceptance_source": "human_review", + "source_review_id": h.review["id"], "source_routing_manifest_id": None, + "accepted_submitter_id": contributor, "recorded_by": h.review["reviewer_id"], + "policy_context_ref": h.review["locked_review_policy_id"], + } async def insert_historical_acceptance(session, source, **overrides): revision = await session.scalar(text("SELECT version_num FROM public.alembic_version")) - assert 14 <= int(revision[:4]) <= 28, "historical acceptance cannot write the current schema" - values = source.model_dump() - values.update(overrides) - for field in ( - "project_id", - "task_id", - "submission_id", - "accepted_submitter_id", - "recorded_by", - "policy_context_ref", - ): - if values[field] is not None: - values[field] = str(values[field]) + assert 14 <= int(revision[:4]) <= 28 + values = source | overrides + for field in ("project_id", "task_id", "submission_id", "accepted_submitter_id", "recorded_by", "policy_context_ref"): + values[field] = str(values[field]) await session.execute(insert(FinalAcceptance).values(**values)) diff --git a/backend/tests/reviews/acceptance/test_migration.py b/backend/tests/reviews/acceptance/test_migration.py index 256bd4e6a..bb08325ed 100644 --- a/backend/tests/reviews/acceptance/test_migration.py +++ b/backend/tests/reviews/acceptance/test_migration.py @@ -6,7 +6,6 @@ import pytest from alembic import command -from tests.checkers.execution.historical_execution import historical_completed_source from app.db import session as db_session from tests.migration_fixtures import add_current_art_seed_column, restore_predecessor_evidence_schema from tests.migration_fixtures import _config @@ -37,7 +36,7 @@ async def test_acceptance_upgrade_preserves_owners(tmp_path, isolated_database_e await asyncio.to_thread(command.upgrade, _config(), "0013_review_source") original_columns = await add_current_art_seed_column(isolated_database_env) async with historical_acceptance_source( - tmp_path, isolated_database_env, completed_source_factory=historical_completed_source + tmp_path, isolated_database_env ): await restore_predecessor_evidence_schema(isolated_database_env, original_columns) connection = await asyncpg.connect(url) diff --git a/backend/tests/reviews/decision/test_migration.py b/backend/tests/reviews/decision/test_migration.py index 9890418a5..6e1c02b50 100644 --- a/backend/tests/reviews/decision/test_migration.py +++ b/backend/tests/reviews/decision/test_migration.py @@ -6,11 +6,10 @@ import pytest from alembic import command -from tests.checkers.execution.historical_execution import historical_completed_source +from tests.migration_ancestor_rows import archived_review_ancestors from app.db import session as db_session from tests.migration_fixtures import add_current_art_seed_column, restore_predecessor_evidence_schema from tests.migration_fixtures import _config -from tests.reviews.decision.support import review_source pytestmark = pytest.mark.postgres_schema_contract @@ -45,8 +44,8 @@ async def test_review_upgrade_preserves_owners(tmp_path, isolated_database_env, await connection.close() await asyncio.to_thread(command.upgrade, _config(), "0012_review_packet") original_columns = await add_current_art_seed_column(isolated_database_env) - async with review_source( - tmp_path, isolated_database_env, completed_source_factory=historical_completed_source + async with archived_review_ancestors( + tmp_path, isolated_database_env ): await restore_predecessor_evidence_schema(isolated_database_env, original_columns) connection = await asyncpg.connect(url) diff --git a/backend/tests/reviews/lifecycle/test_migration.py b/backend/tests/reviews/lifecycle/test_migration.py index 0430253c9..cb4d92a33 100644 --- a/backend/tests/reviews/lifecycle/test_migration.py +++ b/backend/tests/reviews/lifecycle/test_migration.py @@ -9,7 +9,6 @@ import pytest from alembic import command -from tests.checkers.execution.historical_execution import historical_completed_source from app.db import session as db_session from tests.contributions.records.support import ( award_values, @@ -47,7 +46,6 @@ async def test_lifecycle_upgrade_preserves_sources(tmp_path, isolated_database_e tmp_path, isolated_database_env, paid=True, - completed_source_factory=historical_completed_source, ) as h: await restore_predecessor_evidence_schema(isolated_database_env, original_columns) async with h.factory() as session: @@ -131,7 +129,6 @@ async def test_transition_upgrade_preserves_genesis_and_retained_sources( tmp_path, isolated_database_env, paid=True, - completed_source_factory=historical_completed_source, ): await asyncio.to_thread(command.upgrade, _config(), "0027_markdown_guide_media") connection = await asyncpg.connect(url) diff --git a/backend/tests/reviews/packet/support.py b/backend/tests/reviews/packet/support.py index 5de8cb8d3..e45a6f8f6 100644 --- a/backend/tests/reviews/packet/support.py +++ b/backend/tests/reviews/packet/support.py @@ -37,10 +37,9 @@ async def packet_source( database_url, *, lease_duration=timedelta(days=1), - completed_source_factory=completed_source, **source_options, ): - async with completed_source_factory(tmp_path, database_url, **source_options) as h: + async with completed_source(tmp_path, database_url, **source_options) as h: await prepare_packet(h, lease_duration=lease_duration) yield h diff --git a/backend/tests/reviews/packet/test_migration.py b/backend/tests/reviews/packet/test_migration.py index b767a2d0b..1dee48bf8 100644 --- a/backend/tests/reviews/packet/test_migration.py +++ b/backend/tests/reviews/packet/test_migration.py @@ -7,12 +7,11 @@ import pytest from alembic import command -from tests.checkers.execution.historical_execution import historical_completed_source +from tests.migration_ancestor_rows import archived_packet_ancestors from app.db import session as db_session from tests.migration_fixtures import add_current_art_seed_column, restore_predecessor_evidence_schema from tests.migration_fixtures import _config from tests.migration_fixtures import current_schema_revision -from tests.reviews.packet.support import packet_source pytestmark = pytest.mark.postgres_schema_contract @@ -50,8 +49,8 @@ async def test_packet_upgrade_preserves_existing_owners( await connection.close() await asyncio.to_thread(command.upgrade, _config(), "0011_task_routing_source") original_columns = await add_current_art_seed_column(isolated_database_env) - async with packet_source( - tmp_path, isolated_database_env, completed_source_factory=historical_completed_source + async with archived_packet_ancestors( + tmp_path, isolated_database_env ): await restore_predecessor_evidence_schema(isolated_database_env, original_columns) connection = await asyncpg.connect(url) diff --git a/backend/tests/tasks/post_submit_routing/test_migration.py b/backend/tests/tasks/post_submit_routing/test_migration.py index 23fb7f2f9..9c3910153 100644 --- a/backend/tests/tasks/post_submit_routing/test_migration.py +++ b/backend/tests/tasks/post_submit_routing/test_migration.py @@ -10,7 +10,7 @@ from tests.migration_fixtures import add_current_art_seed_column, restore_predecessor_evidence_schema from tests.migration_fixtures import _config -from tests.checkers.execution.historical_execution import historical_completed_source +from tests.checkers.execution.historical_execution import archived_completed_checker_source pytestmark = pytest.mark.postgres_schema_contract @@ -18,13 +18,13 @@ async def _snapshot(connection, h): identifiers = { - "submission": h.request.submission_id, + "submission": h.request["submission_id"], "run": h.result.attempt_id, "execute": h.source["execute_evidence_id"], "finalize": h.source["finalize_evidence_id"], "completion": h.source["completion_event_id"], - "task": h.request.task_id, - "assignment": h.request.assignment_id, + "task": h.request["task_id"], + "assignment": h.request["assignment_id"], } return { "submission": await connection.fetchval( @@ -82,7 +82,7 @@ async def test_upgrade_preserves_existing_sources_without_publishing( await asyncio.to_thread(command.upgrade, _config(), "0010_post_submit_authority") original_columns = await add_current_art_seed_column(isolated_database_env) - async with historical_completed_source(tmp_path, isolated_database_env) as h: + async with archived_completed_checker_source(tmp_path, isolated_database_env) as h: await restore_predecessor_evidence_schema(isolated_database_env, original_columns) connection = await asyncpg.connect(url) try: @@ -125,7 +125,7 @@ async def test_request_upgrade_preserves_completed_owners( await connection.close() await asyncio.to_thread(command.upgrade, _config(), "0017_acceptance_source_contracts") original_columns = await add_current_art_seed_column(isolated_database_env) - async with historical_completed_source(tmp_path, isolated_database_env) as h: + async with archived_completed_checker_source(tmp_path, isolated_database_env) as h: await restore_predecessor_evidence_schema(isolated_database_env, original_columns) connection = await asyncpg.connect(url) try: diff --git a/backend/tests/tasks/post_submit_routing/test_outcome_migration.py b/backend/tests/tasks/post_submit_routing/test_outcome_migration.py index d62fd75a1..c1e7c49b4 100644 --- a/backend/tests/tasks/post_submit_routing/test_outcome_migration.py +++ b/backend/tests/tasks/post_submit_routing/test_outcome_migration.py @@ -9,8 +9,8 @@ from app.db import session as db_session from tests.checkers.execution.historical_execution import ( - historical_completed_source, - historical_reserve, + archived_completed_checker_source, + seed_archived_checker_request, ) from tests.historical_submission_fixtures import historical_material_fixture from tests.migration_fixtures import ( @@ -55,10 +55,10 @@ async def test_pre_authority_rows_refuse_upgrade_without_rewriting( finally: await connection.close() await asyncio.to_thread(command.upgrade, _config(), "0024_require_second_review_false") - factory = historical_completed_source if terminal else historical_material_fixture + factory = archived_completed_checker_source if terminal else historical_material_fixture async with factory(tmp_path, isolated_database_env) as h: if not terminal: - await historical_reserve(h) + await seed_archived_checker_request(h) await asyncio.to_thread(command.upgrade, _config(), "0029_external_checker_registry") connection = await asyncpg.connect(url) try: From fc55f57f78cdbf17ea102728be6f913401ff764a Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 14:34:21 +0100 Subject: [PATCH 225/283] test(pilot04): require raw JSON scalars in archived review facts --- backend/tests/migration_ancestor_rows.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/backend/tests/migration_ancestor_rows.py b/backend/tests/migration_ancestor_rows.py index 8e53c067c..743443edd 100644 --- a/backend/tests/migration_ancestor_rows.py +++ b/backend/tests/migration_ancestor_rows.py @@ -19,8 +19,14 @@ from tests.checkers.execution.historical_execution import archived_completed_checker_source +def _uuid_json(value): + if isinstance(value, UUID): + return str(value) + raise TypeError(f"Non-JSON archived fact: {type(value).__name__}") + + def _json(value): - return json.loads(json.dumps(value, default=str)) + return json.loads(json.dumps(value, default=_uuid_json, allow_nan=False)) @asynccontextmanager From 6fd3fde8025ad116cec5c7f27dfa19aef14790ae Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 14:37:45 +0100 Subject: [PATCH 226/283] [PILOT-04] Remove retired terminal aggregation --- .../versions/0036_selected_checker_flow.py | 20 +++++++++++++++++-- backend/tests/conftest.py | 2 +- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/backend/alembic/versions/0036_selected_checker_flow.py b/backend/alembic/versions/0036_selected_checker_flow.py index 9f4e11f4c..1a5fc3f39 100644 --- a/backend/alembic/versions/0036_selected_checker_flow.py +++ b/backend/alembic/versions/0036_selected_checker_flow.py @@ -992,12 +992,29 @@ def _replace_checker_terminal_custody() -> None: raise RuntimeError("checker terminal declaration shape changed") definition = definition.replace( declaration, - declaration.replace( + declaration.replace(" blocking integer; setup integer;", " blocking integer;") + .replace( "envelope jsonb;", "envelope jsonb; expected_members jsonb; " "expected_execution_members jsonb; actual_execution_members jsonb;", ), ) + old_aggregate = """ count(*) FILTER(WHERE status='passed'), count(*) FILTER(WHERE status='warning'), count(*) FILTER(WHERE status='failed'), + count(*) FILTER(WHERE status<>'passed' AND current_run.request_json::jsonb #> '{policy,blocking_severities}' ? severity), + count(*) FILTER(WHERE status<>'passed' AND failure_category='task_configuration' + AND current_run.request_json::jsonb #> '{policy,blocking_severities}' ? severity) + INTO members,passed,warning,failed,blocking,setup FROM checker_results WHERE checker_run_id=current_run.id;""" + selected_aggregate = """ count(*) FILTER(WHERE status='passed'), count(*) FILTER(WHERE status='warning'), + count(*) FILTER(WHERE status='failed') + INTO members,passed,warning,failed FROM checker_results WHERE checker_run_id=current_run.id;""" + if definition.count(old_aggregate) != 1: + raise RuntimeError("checker terminal aggregate shape changed") + definition = definition.replace(old_aggregate, selected_aggregate) + old_route = """ expected_route := CASE WHEN setup>0 THEN 'task_setup_blocked' WHEN blocking>0 THEN 'needs_revision' ELSE 'allow_review' END;""" + selected_route = """ expected_route := CASE WHEN failed>0 THEN 'needs_revision' ELSE 'allow_review' END;""" + if definition.count(old_route) != 1: + raise RuntimeError("checker terminal route shape changed") + definition = definition.replace(old_route, selected_route) mismatch = """ IF result->'member_results' IS DISTINCT FROM members OR current_run.passed_count IS DISTINCT FROM passed OR current_run.warning_count IS DISTINCT FROM warning OR current_run.failed_count IS DISTINCT FROM failed OR current_run.blocking_count IS DISTINCT FROM blocking THEN @@ -1062,7 +1079,6 @@ def _replace_checker_terminal_custody() -> None: INTO expected_members FROM jsonb_array_elements(result#>'{execution,external_members}') item; blocking := failed; - setup := 0; IF members IS DISTINCT FROM expected_members OR current_run.passed_count IS DISTINCT FROM passed OR current_run.warning_count IS DISTINCT FROM warning diff --git a/backend/tests/conftest.py b/backend/tests/conftest.py index 18ad7e064..3132d4412 100644 --- a/backend/tests/conftest.py +++ b/backend/tests/conftest.py @@ -23,7 +23,7 @@ DDL_LOCK_DIRECTORY = Path("/tmp") # Match the PostgreSQL 16 engine used by Backend CI. Catalog identity rendering # differs across major versions; regenerate only after comparing actual objects. -EXPECTED_PUBLIC_SCHEMA_SHA256 = "d3919cc4929fa6c37d65175d6c9333f61df951f359b9dfee8aa439b61253c0ea" +EXPECTED_PUBLIC_SCHEMA_SHA256 = "866ab4fb13d787cf2a96d9e9ed5357aa771f61beffae446074c77a7a8928719e" PROTECTED_TEST_TABLES = ( "actor_profile_migration_state", "alembic_version", From afcb4fdaf66bb87b19c0bd5c2a7d4164c2383466 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 14:41:19 +0100 Subject: [PATCH 227/283] refactor(pilot04): keep checker history reads to used columns --- backend/app/modules/checkers/history.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/app/modules/checkers/history.py b/backend/app/modules/checkers/history.py index 4c61d32b7..4067f5659 100644 --- a/backend/app/modules/checkers/history.py +++ b/backend/app/modules/checkers/history.py @@ -38,7 +38,7 @@ async def read(self, *, submission_id, task_id, manager, run_id=None, limit=25, rows = (await self._session.execute(statement.order_by(CheckerRun.created_at, CheckerRun.id).limit(limit + 1))).mappings().all() values = [] for row in rows[:limit]: - columns = [getattr(CheckerResult, name) for name in ("id", "checker_name", "status", "severity", "code", "failure_category")] + columns = [getattr(CheckerResult, name) for name in ("id", "checker_name", "status", "severity", "failure_category")] if manager: columns.append((CheckerResult.status == "failed").label("blocks_review")) result_query = select(*columns).join(CheckerRun, CheckerRun.id == CheckerResult.checker_run_id).where( From 9a42fd6eaaf30b2c4122fb5948930b2098a7d22f Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 14:42:46 +0100 Subject: [PATCH 228/283] test(pilot04): require the exact selected identity SQL refusal --- .../changes/pilot04-workstream-default-checker.md | 9 +++++++++ backend/tests/checkers/execution/test_storage.py | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 73ea64426..12cce11bd 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -929,3 +929,12 @@ factory hook. Its now-unused `completed_source_factory` parameter is removed fro `backend/tests/reviews/packet/support.py`; the current fixture always uses the same canonical `completed_source`. This exact helper cleanup adds no raw/current switch, changes no current source behavior and retains all current packet tests. + +The two identity controls reproduced missing native custody at clean `154062bde`: +all deferred constraints accepted the foreign registry UUID and image digest +while the current request validator rejected them. Both failed with the intended +`DID NOT RAISE` in 62.64 seconds, with complete resource cleanup. The sole schema +author supplied the exact policy identity guard; the controls now pin its +`checker terminal selected policy differs` message and SQLSTATE `23514`, not an +unrelated integrity error. Affected native replay follows that frozen DDL; the +original failed evidence is retained. diff --git a/backend/tests/checkers/execution/test_storage.py b/backend/tests/checkers/execution/test_storage.py index dcc2bf5e2..3272b4266 100644 --- a/backend/tests/checkers/execution/test_storage.py +++ b/backend/tests/checkers/execution/test_storage.py @@ -346,8 +346,9 @@ def faulty_validator(result, request): await material_storage_helpers.write_terminal( session, facts, facts.material.model_dump(mode="json"), ) - with pytest.raises(IntegrityError): + with pytest.raises(IntegrityError, match="checker terminal selected policy differs") as denied: await session.execute(text("SET CONSTRAINTS ALL IMMEDIATE")) + assert denied.value.orig.sqlstate == "23514" await session.rollback() async with h.factory() as session: run = await session.get(CheckerRun, str(lease.reservation.attempt_id)) From 2b444a01f5dd8124e87ccd4a7ba6d2f1bfc4e967 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 14:44:35 +0100 Subject: [PATCH 229/283] test(pilot04): execute registered image verdicts for current history --- .../pilot04-workstream-default-checker.md | 17 +++ .../checkers/execution/storage_fixture.py | 107 +++++++++++------- backend/tests/committed_guide_fixtures.py | 24 ++-- .../tests/projects/policy_bundle_fixtures.py | 4 +- .../tests/projects/unified_policy_fixtures.py | 4 +- backend/tests/retained_material_fixtures.py | 17 ++- backend/tests/submission_fixtures.py | 11 +- backend/tests/test_tasks.py | 12 +- 8 files changed, 126 insertions(+), 70 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 12cce11bd..8c9563d72 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -342,6 +342,23 @@ intermediate-wait regression. ## Risk and review routing +Current history and queue fixtures also replace built-in failure-name switches +with normalized registered-image verdicts. Allowed producer paths are +`backend/tests/checkers/execution/storage_fixture.py`, +`backend/tests/submission_fixtures.py`, `backend/tests/retained_material_fixtures.py`, +the project bootstrap helpers in `backend/tests/test_tasks.py`, +`backend/tests/projects/{policy_bundle_fixtures.py,unified_policy_fixtures.py}`, +and `backend/tests/committed_guide_fixtures.py`. Register and bind the exact POST +image before guide approval and TASK release. Preserve admitted immutable bytes +in the existing scripted provider for the test session factory, and traverse +current ART reads, grants, CHECKERS phase AUTH and finalization for both verdicts. +Do not retrofit locked policies, synthesize failed members, translate old names, +or add compatibility arguments. Consumer assertions remain independently owned. +Required real PostgreSQL controls cover failed/passing generations, currentness, +bounded history and review non-admissibility. Scripted provider evidence does +not claim MinIO or real container execution. Independent root review covers this +test-fixture author repair; production, DDL and public route changes are prohibited. + The final caller trace includes `backend/app/modules/checkers/{history.py, execution_results.py,api/history.py}`, the existing history privacy expectation, and `backend/tests/checkers/execution/test_storage.py`. Remove retired catalogue diff --git a/backend/tests/checkers/execution/storage_fixture.py b/backend/tests/checkers/execution/storage_fixture.py index 85a618fdc..21a24a2c8 100644 --- a/backend/tests/checkers/execution/storage_fixture.py +++ b/backend/tests/checkers/execution/storage_fixture.py @@ -5,10 +5,7 @@ from app.modules.actors.api import ServiceIdentity from app.modules.artifacts.models import SubmissionBundleAdmission -from app.modules.checkers.api.execution import ExecuteFacts, FinalizeFacts, VerifiedMaterialFacts from app.adapters.checkers import evaluation_coordinator -from app.modules.tasks.models import Submission -from tests.checkers.execution.support import selected_result from tests.checkers.execution.support import live_executor, provision_post_submit_service from types import SimpleNamespace @@ -29,56 +26,80 @@ async def storage_request(session, submission_id, *, generation=1): return make_selected_post_submit_request(**body) -async def seed_storage_run(factory, submission_id, *, failures=(), state="completed", generation=1): +class _UnavailableArchiveStore: + """Report a provider outage through the current ART byte-read boundary.""" + + def __init__(self, store): + self.identity = store.identity + + async def open(self, _ref, byte_range=None): + from app.interfaces.artifacts import ArtifactStoreUnavailableError + + raise ArtifactStoreUnavailableError() + yield # The ArtifactStore.open port is an async byte iterator. + + +async def seed_storage_run(factory, submission_id, *, verdict="passed", state="completed", generation=1): + """Execute the locked current policy with controlled image/provider outcomes.""" + from pathlib import Path + from tempfile import TemporaryDirectory + + from app.adapters.artifacts import post_submission_materialization + from app.modules.artifacts.models import ArtifactStorageNamespace + from app.modules.artifacts.preparation import ArtifactPreparationService, ArtifactScratchManager + from app.modules.artifacts.service import ArtifactStorageNamespaceSpec + from app.modules.artifacts.submission_archive import SubmissionArchiveInspector, SubmissionArchiveLimits + from tests.checkers.execution.support import ControlledSelectedExecution + from tests.retained_material_fixtures import retained_archive_store + from tests.test_checker_materialization import _limits + + assert verdict in {"passed", "failed"} + assert state in {"queued", "running", "completed", "infrastructure_failed"} + assert verdict == "passed" or state == "completed" async with factory() as session, session.begin(): request = await storage_request(session, submission_id, generation=generation) + assert verdict != "failed" or request.policy.entries, "failed verdict requires a locked registered image" receipt = await evaluation_coordinator(session).reserve_current_evaluation(request) if state == "queued": return str(receipt.attempt_id) await provision_post_submit_service(factory) - executor = live_executor(SimpleNamespace(factory=factory, service=None)) - lease, replay = await executor._claim(request) - assert replay is None if state == "running": + _, replay = await live_executor(SimpleNamespace(factory=factory, service=None))._claim(request) + assert replay is None return str(receipt.attempt_id) - assert state in {"completed", "infrastructure_failed"} - assert not failures, "removed built-in checker failures are not selected image evidence" - result = selected_result( - request, attempt_id=receipt.attempt_id, result_id=receipt.result_id, - outcome=state, - **({"execution": None, "infrastructure_failure_code": "deadline_exceeded"} - if state == "infrastructure_failed" else {}), - ) - async with factory() as session: - submission = await session.get(Submission, str(submission_id)) - admission = await session.get(SubmissionBundleAdmission, submission.submission_bundle_admission_id) - admission_id = UUID(admission.id) - material = VerifiedMaterialFacts( - submission_id=request.submission_id, - submission_version=request.submission_version, - admission_id=admission_id, - binding_id=request.binding_id, - content_id=request.content_id, - replica_id=UUID(admission.verified_replica_id), - content_sha256=request.content_sha256, - byte_count=request.byte_count, - semantic_manifest_sha256=admission.semantic_manifest_sha256, - ) await provision_post_submit_service(factory, ServiceIdentity.ARTIFACT_MATERIALIZER) - input_receipt = await authorize_stored_material( - factory, ExecuteFacts(request=request, lease=lease), material - ) - await executor.finalize( - FinalizeFacts( - request=request, - lease=lease, - result=result, - material=material, - input_materialization_evidence_id=input_receipt, - output_binding_ids=(), + async with factory() as session: + persisted = await session.get(ArtifactStorageNamespace, "primary") + namespace = ArtifactStorageNamespaceSpec( + persisted.backend, persisted.adapter, persisted.provider_profile, + persisted.namespace_descriptor, persisted.namespace_fingerprint, ) - ) - return str(receipt.attempt_id) + store = retained_archive_store(factory, namespace) + if state == "infrastructure_failed": + store = _UnavailableArchiveStore(store) + with TemporaryDirectory(prefix="retained-post-material-") as directory: + manager = ArtifactScratchManager( + root=Path(directory), + limits=_limits(reservation_ttl_seconds=300, total_deadline_seconds=180), + ) + try: + materialization = post_submission_materialization( + sessions=factory, store=store, namespace=namespace, + preparation=ArtifactPreparationService(manager), + inspector=SubmissionArchiveInspector(SubmissionArchiveLimits()), + ) + executor = live_executor( + SimpleNamespace(factory=factory, service=materialization), + selected_execution=ControlledSelectedExecution(verdict=verdict), + ) + result = await executor.evaluate_post_submission(request) + assert result.outcome == state + if state == "completed": + assert result.execution.required_external_count == len(request.policy.entries) + assert all(member.result.verdict == verdict for member in result.execution.external_members) + return str(receipt.attempt_id) + finally: + manager.close() async def authorize_stored_material(factory, execution, material): diff --git a/backend/tests/committed_guide_fixtures.py b/backend/tests/committed_guide_fixtures.py index 42592eac1..3b1ba9cb4 100644 --- a/backend/tests/committed_guide_fixtures.py +++ b/backend/tests/committed_guide_fixtures.py @@ -90,7 +90,7 @@ async def seed_setup_service_for_compiled_fixture(sessions): async def create_compiled_report_fixture( - report_id: str, source_snapshot_id: str, *, artifact_proposal=None, post_submit_required_checkers=(), + report_id: str, source_snapshot_id: str, *, artifact_proposal=None, post_submit_registry_spec=None, ) -> str: """Project a scripted unified result under real service authority and custody.""" from app.adapters.auth import guide_compilation_request_authority, guide_compilation_execution_authority, guide_sufficiency_projection_authorization, artifact_policy_projection_authorization @@ -107,6 +107,12 @@ async def create_compiled_report_fixture( from app.interfaces.project_agents import CompilationFinding, GuideEvidenceRef sessions = db_session.get_session_factory() + from tests.projects.guide_activation.source_fixtures import _register_external_checker_fixture + + post_entry = ( + await _register_external_checker_fixture(sessions, post_submit_registry_spec) + if post_submit_registry_spec is not None else None + ) await seed_setup_service_for_compiled_fixture(sessions) async with sessions() as session: report = await session.scalar(select(GuideSufficiencyReport).where(GuideSufficiencyReport.source_snapshot_id == source_snapshot_id, GuideSufficiencyReport.project_setup_run_id.is_not(None))) @@ -155,18 +161,14 @@ async def compile_project_guide(self, context, capabilities): patch = {"status": {"blocked": "guide_blocked", "passed": "draft_ready", "passed_with_warnings": "draft_ready_with_warnings"}[status], "findings": compiled_findings} if artifact_proposal is not None: patch["submission_artifact_policy"] = artifact_proposal - from app.interfaces.project_agents import AtomicGuideRequirement, PostSubmissionBindingProposal - patch["requirements"] = tuple(AtomicGuideRequirement( - requirement_id=f"post_requirement_{index}", statement="Apply the selected task evaluation requirement", - disposition="supported_post_submit", evidence_refs=refs, - ) for index, _ in enumerate(post_submit_required_checkers)) - patch["post_submit_bindings"] = tuple(PostSubmissionBindingProposal( - requirement_id=f"post_requirement_{index}", capability_id=checker, - capability_version="v0.1", stage="post_submit", parameters=(), - ) for index, checker in enumerate(post_submit_required_checkers)) if status == "blocked": patch["submission_artifact_policy"] = None - return result().model_copy(update=patch) + from tests.projects.guide_activation.source_fixtures import _external_compilation_outcome + + return _external_compilation_outcome( + result().model_copy(update=patch), + (post_entry,) if post_entry is not None else (), None, post_entry, refs, + ) execution = project_guide_compilation_execution_port( sessions, diff --git a/backend/tests/projects/policy_bundle_fixtures.py b/backend/tests/projects/policy_bundle_fixtures.py index bb6ac8da5..0ae8264fc 100644 --- a/backend/tests/projects/policy_bundle_fixtures.py +++ b/backend/tests/projects/policy_bundle_fixtures.py @@ -24,7 +24,7 @@ async def create_approved_policy_bundle( sufficiency_status: str = "passed", artifact_proposal=None, request_headers=None, - post_submit_required_checkers=None, + post_submit_registry_spec=None, ) -> dict: snapshot = await read_guide_source_snapshot(project_id, guide_id) report = await create_sufficiency_report( @@ -36,7 +36,7 @@ async def create_approved_policy_bundle( request_headers=request_headers, ) policy = await create_unified_submission_policy(report["id"], snapshot["id"], proposal=artifact_proposal, - post_submit_required_checkers=post_submit_required_checkers or ()) + post_submit_registry_spec=post_submit_registry_spec) from app.db import session as db_session from app.modules.projects.models import ProjectSetupRun from sqlalchemy import select diff --git a/backend/tests/projects/unified_policy_fixtures.py b/backend/tests/projects/unified_policy_fixtures.py index b942cb944..f4b486ac4 100644 --- a/backend/tests/projects/unified_policy_fixtures.py +++ b/backend/tests/projects/unified_policy_fixtures.py @@ -46,7 +46,7 @@ def downstream_artifact_proposal(): ) -async def create_unified_submission_policy(report_id, snapshot_id, *, proposal=None, post_submit_required_checkers=()): +async def create_unified_submission_policy(report_id, snapshot_id, *, proposal=None, post_submit_registry_spec=None): """Project the actual scripted result, with no manual policy row replacement.""" sessions = db_session.get_session_factory() proposal = proposal or downstream_artifact_proposal() @@ -54,7 +54,7 @@ async def create_unified_submission_policy(report_id, snapshot_id, *, proposal=N report_id, snapshot_id, artifact_proposal=proposal, - post_submit_required_checkers=post_submit_required_checkers, + post_submit_registry_spec=post_submit_registry_spec, ) async with sessions() as session: compilation = ( diff --git a/backend/tests/retained_material_fixtures.py b/backend/tests/retained_material_fixtures.py index a050e0377..91bd63298 100644 --- a/backend/tests/retained_material_fixtures.py +++ b/backend/tests/retained_material_fixtures.py @@ -9,6 +9,7 @@ from pathlib import Path from tempfile import TemporaryDirectory from uuid import UUID +from weakref import WeakKeyDictionary from zipfile import ZipFile from sqlalchemy import select @@ -75,9 +76,9 @@ async def execute(self, *_args, **_kwargs): class MemoryStore: """Implement the existing byte port; all database work stays in ART owners.""" - def __init__(self, namespace): + def __init__(self, namespace, *, objects=None): self.identity = ExternalServiceAdapterIdentity("artifact_store", namespace.adapter) - self.objects = {} + self.objects = {} if objects is None else objects async def put(self, source): ref = artifact_provider_object_ref(source.commitment) @@ -104,6 +105,16 @@ async def head(self, ref): return ArtifactObjectHead(ref, data is not None, len(data) if data is not None else None) +_RETAINED_OBJECTS = WeakKeyDictionary() + + +def retained_archive_store(factory, namespace): + """Keep immutable fixture bytes until their owning test factory is disposed.""" + namespaces = _RETAINED_OBJECTS.setdefault(factory, {}) + objects = namespaces.setdefault(namespace.namespace_fingerprint, {}) + return MemoryStore(namespace, objects=objects) + + def _submission_request(task, assignment, link, packet, predecessor_id, policy): content = BytesIO() paths = {entry["path"] for entry in policy["required_artifacts"] if entry.get("required", True)} @@ -231,7 +242,7 @@ async def retained_admission( ) ).effective_policy context, request = _submission_request(task, assignment, link, packet, predecessor_id, policy) - store = MemoryStore(namespace) + store = retained_archive_store(factory, namespace) with TemporaryDirectory(prefix="retained-material-") as directory: settings = _settings(Path(directory), maximum_bytes=1024 * 1024) # This fixture traverses multiple real database transactions. Its scratch diff --git a/backend/tests/submission_fixtures.py b/backend/tests/submission_fixtures.py index 78a54ebf3..55c1d6b98 100644 --- a/backend/tests/submission_fixtures.py +++ b/backend/tests/submission_fixtures.py @@ -2,7 +2,8 @@ These fixtures use ART preparation, verification and consumption owners with a scripted provider, then seed retained Submission projections with locked -lineage. They do not expose public intake or claim live post-submit authority. +lineage. CHECKERS reads these bytes with real phase authority and controlled +external-image outcomes; this is not a deployment/provider conformance proof. """ from uuid import UUID @@ -101,11 +102,11 @@ def retained_packet(**values): return submission_id -async def seed_retained_checker_run(submission_id: str, *, failures=(), state="completed", generation=1) -> str: - """Seed closed history through real CHECKERS custody, with controlled phase authority.""" +async def seed_retained_checker_run(submission_id: str, *, verdict="passed", state="completed", generation=1) -> str: + """Execute closed history with real phase custody and controlled image verdicts.""" from tests.checkers.execution.storage_fixture import seed_storage_run return await seed_storage_run(db_session.get_session_factory(), submission_id, - failures=failures, state=state, generation=generation) + verdict=verdict, state=state, generation=generation) async def route_retained_checker_remediation(submission_id: str, *, generation: int = 1) -> str: @@ -123,7 +124,7 @@ async def route_retained_checker_remediation(submission_id: str, *, generation: factory = db_session.get_session_factory() run_id = await seed_retained_checker_run( - submission_id, failures=("check_submission_packet",), generation=generation, + submission_id, verdict="failed", generation=generation, ) async with factory() as session: run = await session.get(CheckerRun, run_id) diff --git a/backend/tests/test_tasks.py b/backend/tests/test_tasks.py index 81076d016..4feb424ae 100644 --- a/backend/tests/test_tasks.py +++ b/backend/tests/test_tasks.py @@ -585,7 +585,7 @@ async def create_policy_bundle_for_guide( guide_id: str, artifact_proposal=None, *, - post_submit_required_checkers: list[str] | None = None, + post_submit_registry_spec=None, ) -> dict: for kind, body in ( ( @@ -631,7 +631,7 @@ async def create_policy_bundle_for_guide( client, project_id, guide_id, artifact_proposal=artifact_proposal or task_artifact_proposal(), request_headers=auth_headers(), - post_submit_required_checkers=post_submit_required_checkers, + post_submit_registry_spec=post_submit_registry_spec, ) @@ -685,7 +685,9 @@ def complete_submission_payload(package_hash: str = "sha256:package-v1") -> dict } -async def create_active_project(client: AsyncClient, *, slug: str = "task-queue-project") -> dict: +async def create_active_project( + client: AsyncClient, *, slug: str = "task-queue-project", post_submit_registry_spec=None, +) -> dict: project_response = await client.post( "/api/v1/projects", headers=auth_headers() | {"Idempotency-Key": str(new_record_id())}, @@ -705,7 +707,9 @@ async def create_active_project(client: AsyncClient, *, slug: str = "task-queue- ) assert guide_response.status_code == 201, guide_response.text guide = guide_response.json() - await create_policy_bundle_for_guide(client, project["id"], guide["id"]) + await create_policy_bundle_for_guide( + client, project["id"], guide["id"], post_submit_registry_spec=post_submit_registry_spec, + ) await seed_active_guide_for_downstream_test( db_session.get_session_factory(), From 45082f7a60ff3d9d96722be36ddd136339827ec5 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 14:48:14 +0100 Subject: [PATCH 230/283] test(pilot04): use external policy and verdict in current consumers --- .../pilot04-workstream-default-checker.md | 17 ++++++++++++++ .../submission_history/test_privacy.py | 22 +++++++++---------- .../submission_history/test_reads.py | 3 ++- .../task_authority/test_submission_policy.py | 15 +------------ .../tests/projects/post_submit_fixtures.py | 6 ++--- backend/tests/tasks/test_locked_context.py | 2 +- backend/tests/tasks/test_project_display.py | 8 +++---- .../tests/test_review_queue_persistence.py | 9 ++++---- backend/tests/test_tasks.py | 21 +++++------------- 9 files changed, 48 insertions(+), 55 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 8c9563d72..ee2b40bcb 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -955,3 +955,20 @@ author supplied the exact policy identity guard; the controls now pin its `checker terminal selected policy differs` message and SQLSTATE `23514`, not an unrelated integrity error. Affected native replay follows that frozen DDL; the original failed evidence is retained. + +### Current external-policy and normalized-verdict consumers + +Lead/QA handoff permits current caller changes in +`backend/tests/projects/post_submit_fixtures.py`, actual test bodies only in +`backend/tests/test_tasks.py`, `backend/tests/authorization/task_authority/test_submission_policy.py`, +`backend/tests/tasks/test_project_display.py`, `backend/tests/tasks/test_locked_context.py`, +`backend/tests/authorization/submission_history/{test_reads,test_privacy}.py` and +`backend/tests/test_review_queue_persistence.py`. QA owns producer/helper definitions +and the registry-before-activation bootstrap. Use explicit approved image specs +for work-failing/member-visible fixtures and normalized passed/failed verdicts; +never translate old built-in names or create failed evidence under an empty policy. +Remove only obsolete platform catalogue assertions, retaining exact locked policy +identity, corrupted-read refusal, zero effects, privacy, parent isolation, stable +successor display and current generation guards. Current registered capabilities +replace old catalogue labels in summaries. No source, migration, CI, cap or skip +changes are authorized. Native verification follows combined QA producer freeze. diff --git a/backend/tests/authorization/submission_history/test_privacy.py b/backend/tests/authorization/submission_history/test_privacy.py index 9ccf9ae55..2c926aeb7 100644 --- a/backend/tests/authorization/submission_history/test_privacy.py +++ b/backend/tests/authorization/submission_history/test_privacy.py @@ -1,6 +1,5 @@ """Fixed SQL projections and live grant privacy over retained checker results.""" -import json from uuid import uuid4 import pytest @@ -11,6 +10,7 @@ from app.modules.tasks.models import AuditEvent, Submission from app.modules.tasks.submission_history import SubmissionHistoryRepository from app.modules.checkers.history import CheckerHistoryRepository +from tests.checkers.external.support import post_registry_spec from tests.submission_fixtures import seed_retained_submission, seed_retained_checker_run from tests.test_tasks import (create_active_project, create_started_task, complete_submission_payload, set_dev_actor, auth_headers, actor_id) @@ -19,16 +19,14 @@ RESULT_FIELDS, MANAGER_RESULT_FIELDS, EVIDENCE_FIELDS) -@pytest.mark.parametrize("state,failures", [("completed", ()), ("completed", ("check_policy_context_present",)), ("infrastructure_failed", ())]) -async def test_fixed_projection_and_selected_columns(task_client, monkeypatch, state, failures): - project = await create_active_project(task_client) +@pytest.mark.parametrize("state,verdict", [("completed", "passed"), ("completed", "failed"), ("infrastructure_failed", "passed")]) +async def test_fixed_projection_and_selected_columns(task_client, monkeypatch, state, verdict): + project = await create_active_project(task_client, post_submit_registry_spec=post_registry_spec()) task = await create_started_task(task_client, project["id"], monkeypatch) submission = await seed_retained_submission(task["id"], complete_submission_payload()) - run = await seed_retained_checker_run(submission, state=state, failures=failures) - from app.modules.checkers.models import CheckerRun + run = await seed_retained_checker_run(submission, state=state, verdict=verdict) async with db_session.get_session_factory()() as session: - stored = await session.get(CheckerRun, run) - private_attestation = json.loads(stored.request_json)["structural_input"]["worker_attestation"] + private_attestation = (await session.get(Submission, submission)).worker_attestation assert private_attestation captured = [] def capture(conn, cursor, statement, parameters, context, executemany): @@ -54,7 +52,7 @@ def capture(conn, cursor, statement, parameters, context, executemany): nested_fields = (MANAGER_RESULT_FIELDS if manager else RESULT_FIELDS) if checker else EVIDENCE_FIELDS assert all(set(nested) == nested_fields for nested in item[nested_key]) if checker: - assert bool(item["results"]) == (state == "completed" and (manager or not failures)) + assert bool(item["results"]) == (state == "completed") # Actual selected columns, rather than searching predicates that # legitimately compute a boolean inside PostgreSQL. No raw body, # URI/hash, aggregate count, or receipt is loaded into Python. @@ -103,17 +101,17 @@ async def test_nested_values_match_exact_stored_parents(task_client, monkeypatch from app.modules.tasks.models import EvidenceItem from app.modules.checkers.models import CheckerResult from app.modules.checkers.execution_results import RESULT_STATUS_MESSAGES - project = await create_active_project(task_client) + project = await create_active_project(task_client, post_submit_registry_spec=post_registry_spec()) task = await create_started_task(task_client, project["id"], monkeypatch) submission = await seed_retained_submission(task["id"], complete_submission_payload()) run = await seed_retained_checker_run(submission) - sibling = await seed_retained_checker_run(submission, generation=2, failures=("check_submission_packet",)) + sibling = await seed_retained_checker_run(submission, generation=2, verdict="failed") foreign_task = await create_started_task(task_client, project["id"], monkeypatch, subject="foreign-nested-owner") payload = complete_submission_payload() for item in payload["evidence_items"]: item["label"] = "Foreign " + item["label"] foreign_submission = await seed_retained_submission(foreign_task["id"], payload) - foreign_run = await seed_retained_checker_run(foreign_submission, failures=("check_evidence_present",)) + foreign_run = await seed_retained_checker_run(foreign_submission, verdict="failed") async with db_session.get_session_factory()() as session: evidence = list(await session.scalars(select(EvidenceItem).order_by(EvidenceItem.id))) rows = list(await session.scalars(select(CheckerResult).order_by(CheckerResult.member_order))) diff --git a/backend/tests/authorization/submission_history/test_reads.py b/backend/tests/authorization/submission_history/test_reads.py index a5ab2bbb9..5343956ed 100644 --- a/backend/tests/authorization/submission_history/test_reads.py +++ b/backend/tests/authorization/submission_history/test_reads.py @@ -10,6 +10,7 @@ from app.modules.tasks.models import AuditEvent, Submission from app.modules.checkers.models import CheckerRun from app.modules.authorization.models import ProjectRoleGrant, AdminRoleGrant +from tests.checkers.external.support import post_registry_spec from tests.submission_fixtures import seed_retained_submission, seed_retained_checker_run from tests.test_tasks import ( create_active_project, create_started_task, complete_submission_payload, @@ -18,7 +19,7 @@ async def history_case(client, monkeypatch, *, run_status="completed"): - project = await create_active_project(client) + project = await create_active_project(client, post_submit_registry_spec=post_registry_spec()) task = await create_started_task(client, project["id"], monkeypatch) submission = await seed_retained_submission(task["id"], complete_submission_payload()) run = await seed_retained_checker_run(submission, state=run_status) diff --git a/backend/tests/authorization/task_authority/test_submission_policy.py b/backend/tests/authorization/task_authority/test_submission_policy.py index 29abf9a10..08dd1436a 100644 --- a/backend/tests/authorization/task_authority/test_submission_policy.py +++ b/backend/tests/authorization/task_authority/test_submission_policy.py @@ -307,18 +307,5 @@ async def test_submission_rejects_crossed_post_submit_policy_sidecar( assert task.status == "in_progress" assert submissions == [] assert task.locked_post_submit_checker_policy_body == locked_body - assert "check_acceptance_criteria_present" not in [ - entry["checker_id"] - for entry in locked_body["entries"] - if entry["classification"] == "project_required" - ] - assert "check_acceptance_criteria_present" not in [ - entry["checker_id"] for entry in locked_body["entries"] - ] - assert "check_required_files" in [ - entry["checker_id"] - for entry in locked_body["entries"] - if entry["classification"] == "platform_default" - ] - assert "check_required_files" in [entry["checker_id"] for entry in locked_body["entries"]] + assert checker_runs == [] diff --git a/backend/tests/projects/post_submit_fixtures.py b/backend/tests/projects/post_submit_fixtures.py index 6c21c46c0..83ef6f10f 100644 --- a/backend/tests/projects/post_submit_fixtures.py +++ b/backend/tests/projects/post_submit_fixtures.py @@ -61,9 +61,9 @@ def crossed_post_policy_read(policy_id): def loaded(_session, row): if isinstance(row, PostSubmitCheckerPolicy) and row.id == policy_id: seen.append(row.id) - set_committed_value(row, 'required_checkers', [ - *row.required_checkers, 'check_acceptance_criteria_present', - ]) + set_committed_value(row, 'policy_body', { + **row.policy_body, 'policy_sha256': 'sha256:' + '0' * 64, + }) event.listen(Session, 'loaded_as_persistent', loaded) try: diff --git a/backend/tests/tasks/test_locked_context.py b/backend/tests/tasks/test_locked_context.py index 1a610a53c..ad96eecac 100644 --- a/backend/tests/tasks/test_locked_context.py +++ b/backend/tests/tasks/test_locked_context.py @@ -38,7 +38,7 @@ def test_locked_context_contracts(): for field in REFERENCE_FIELDS } summary = PostSubmitPolicyBodySummary(schema_version="1", default_checkers=(), - required_checkers=("check_acceptance_criteria_present",), + required_checkers=("test.project_quality",), warning_checkers=(), execution_checkers=(), blocking_severities=("high",)) for cls in MODELS: kwargs = {**values, **({SUMMARY: summary} if cls is ManagementTaskLockedContext else {})} diff --git a/backend/tests/tasks/test_project_display.py b/backend/tests/tasks/test_project_display.py index ed123e861..94a506626 100644 --- a/backend/tests/tasks/test_project_display.py +++ b/backend/tests/tasks/test_project_display.py @@ -17,6 +17,7 @@ from app.modules.tasks.models import AuditEvent, WorkstreamTask from tests.authorization.task_locked_context.support import KINDS, path, grant_development_context_roles from tests.projects.locked_policy_fixtures import activated_context, frozen_request +from tests.checkers.external.support import post_registry_spec from tests.test_tasks import ( task_database_env as task_database_env, task_client as task_client, @@ -223,7 +224,7 @@ async def test_task_display_survives_guide_successor_for_contributor_and_manager await create_policy_bundle_for_guide( task_client, project["id"], successor.json()["id"], task_artifact_proposal().model_copy(update={"required_artifacts": ("v2-answer.md",)}), - post_submit_required_checkers=["check_acceptance_criteria_present"], + post_submit_registry_spec=post_registry_spec(), ) await seed_active_guide_for_downstream_test( db_session.get_session_factory(), project_id=project["id"], guide_id=successor.json()["id"], @@ -239,9 +240,8 @@ async def test_task_display_survives_guide_successor_for_contributor_and_manager PostSubmitCheckerPolicy.project_id == project["id"], PostSubmitCheckerPolicy.guide_id == active.id, )) - required = [entry["checker_id"] for entry in successor_policy.policy_body["entries"] - if entry["classification"] == "project_required"] - assert required == ["check_acceptance_criteria_present"] + required = [entry["registry"]["capability_id"] for entry in successor_policy.policy_body["entries"]] + assert required == [post_registry_spec().capability_id] assert required != original_summary["required_checkers"] effective = await session.scalar(select(EffectiveProjectSubmissionArtifactPolicy).where( EffectiveProjectSubmissionArtifactPolicy.guide_id == active.id, diff --git a/backend/tests/test_review_queue_persistence.py b/backend/tests/test_review_queue_persistence.py index f28426ad3..36be75e60 100644 --- a/backend/tests/test_review_queue_persistence.py +++ b/backend/tests/test_review_queue_persistence.py @@ -32,6 +32,7 @@ ) from app.modules.tasks.models import Submission from project_create_fixtures import grant_system_project_manager, insert_historical_project +from tests.checkers.external.support import post_registry_spec from tests.submission_fixtures import seed_retained_submission, seed_retained_checker_run from tests.test_tasks import ( auth_headers, @@ -87,7 +88,7 @@ async def _reviewable_lineage( monkeypatch: pytest.MonkeyPatch, *, checker_status: str = "completed", ) -> tuple[dict, dict, dict]: - project = await create_active_project(client) + project = await create_active_project(client, post_submit_registry_spec=post_registry_spec()) task = await create_started_task( client, project["id"], @@ -370,11 +371,11 @@ async def test_database_rejects_non_admissible_checker_and_project_mismatch( original_run = submission["checker_run_id"] # Each state rejection uses the current generation. Supersession separately # tests an otherwise admissible completed/allow_review predecessor. - for generation, state, failures in ( - (2, "running", ()), (3, "completed", ("check_submission_packet",)), + for generation, state, verdict in ( + (2, "running", "passed"), (3, "completed", "failed"), ): current = await seed_retained_checker_run(submission["id"], state=state, - failures=failures, generation=generation) + verdict=verdict, generation=generation) invalid = submission | {"checker_run_id": current} async with db_session.get_session_factory()() as session: session.add(ReviewQueueEntry(**_queue_input(project, task, invalid).model_dump())) diff --git a/backend/tests/test_tasks.py b/backend/tests/test_tasks.py index 4feb424ae..e4c8b0aa5 100644 --- a/backend/tests/test_tasks.py +++ b/backend/tests/test_tasks.py @@ -1528,20 +1528,7 @@ async def test_release_rejects_crossed_post_submit_policy_sidecar( assert persisted_task is not None assert persisted_task.status == "screening" assert persisted_task.locked_post_submit_checker_policy_body == locked_body - assert "check_acceptance_criteria_present" not in [ - entry["checker_id"] - for entry in locked_body["entries"] - if entry["classification"] == "project_required" - ] - assert "check_acceptance_criteria_present" not in [ - entry["checker_id"] for entry in locked_body["entries"] - ] - assert "check_required_files" in [ - entry["checker_id"] - for entry in locked_body["entries"] - if entry["classification"] == "platform_default" - ] - assert "check_required_files" in [entry["checker_id"] for entry in locked_body["entries"]] + async def test_worker_task_response_redacts_locked_policy_hashes( @@ -2434,7 +2421,8 @@ async def test_retained_submission_versions_are_readable_without_exposing_packet task_client: AsyncClient, monkeypatch: pytest.MonkeyPatch, ) -> None: - project = await create_active_project(task_client) + from tests.checkers.external.support import post_registry_spec + project = await create_active_project(task_client, post_submit_registry_spec=post_registry_spec()) started_task = await create_started_task(task_client, project["id"], monkeypatch) v1_payload = complete_submission_payload() v1_id = await seed_retained_submission( @@ -2543,7 +2531,8 @@ async def test_retained_version_read_does_not_rewrite_prior_finalized_packet( task_client: AsyncClient, monkeypatch: pytest.MonkeyPatch, ) -> None: - project = await create_active_project(task_client) + from tests.checkers.external.support import post_registry_spec + project = await create_active_project(task_client, post_submit_registry_spec=post_registry_spec()) started_task = await create_started_task(task_client, project["id"], monkeypatch) v1_payload = complete_submission_payload() v1_id = await seed_retained_submission( From 76b541ba3b41a04032eefbdfeef1532a3c70d642 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 15:05:36 +0100 Subject: [PATCH 231/283] test: use plain archived facts in migration consumers --- .../changes/pilot04-workstream-default-checker.md | 15 +++++++++++++++ .../tests/checkers/execution/test_migration.py | 4 ++-- .../tasks/post_submit_routing/test_migration.py | 2 +- .../tests/tasks/test_payment_policy_migration.py | 12 ++++++------ 4 files changed, 24 insertions(+), 9 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index ee2b40bcb..7466d4e9f 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -972,3 +972,18 @@ identity, corrupted-read refusal, zero effects, privacy, parent isolation, stabl successor display and current generation guards. Current registered capabilities replace old catalogue labels in summaries. No source, migration, CI, cap or skip changes are authorized. Native verification follows combined QA producer freeze. + +### Remaining raw migration callers + +Lead authorizes four final caller paths: `backend/tests/tasks/test_payment_policy_migration.py`, +`backend/tests/tasks/test_submission_lineage.py`, `backend/tests/checkers/execution/test_migration.py` +and `backend/tests/tasks/post_submit_routing/test_migration.py`. Replace attribute +access over archived request/result facts with dictionary indexing. The packet +custody upgrade uses the literal revision-0021 Submission snapshot supplied by +the backend owner, never the current preparation callback on a predecessor +schema. Preserve every retained-row, preflight, immutability and negative +assertion; no production, producer, migration, compatibility helper, test cap or +selection changes. Collection and native predecessor proof follow the frozen +literal-base handoff. Both strengthened identity controls passed at exact +clean `e947161412b1a7dcc85ffcb0a7bac75922c4cab8` in 34.94 seconds with the exact +guard message and SQLSTATE `23514`, installed schema 0036 and complete cleanup. diff --git a/backend/tests/checkers/execution/test_migration.py b/backend/tests/checkers/execution/test_migration.py index 89bac29fd..cefe5e319 100644 --- a/backend/tests/checkers/execution/test_migration.py +++ b/backend/tests/checkers/execution/test_migration.py @@ -35,7 +35,7 @@ async def test_migration_refuses_retained_history(tmp_path, isolated_database_en async with h.factory() as session, session.begin(): source = await session.scalar( text("select to_jsonb(s) from submissions s where id=:id"), - {"id": str(h.request.submission_id)}, + {"id": h.request["submission_id"]}, ) values = { key: value @@ -72,7 +72,7 @@ async def test_migration_refuses_retained_history(tmp_path, isolated_database_en trigger_auth_source="test", attempt_number=1, is_current_for_submission=True, - package_hash=h.request.content_sha256, + package_hash=h.request["content_sha256"], artifact_hash_manifest=source["artifact_hash_manifest"], artifact_manifest_hash=h.manifest.sha256, passed_count=0, diff --git a/backend/tests/tasks/post_submit_routing/test_migration.py b/backend/tests/tasks/post_submit_routing/test_migration.py index 9c3910153..9033a6bb7 100644 --- a/backend/tests/tasks/post_submit_routing/test_migration.py +++ b/backend/tests/tasks/post_submit_routing/test_migration.py @@ -19,7 +19,7 @@ async def _snapshot(connection, h): identifiers = { "submission": h.request["submission_id"], - "run": h.result.attempt_id, + "run": h.result["attempt_id"], "execute": h.source["execute_evidence_id"], "finalize": h.source["finalize_evidence_id"], "completion": h.source["completion_event_id"], diff --git a/backend/tests/tasks/test_payment_policy_migration.py b/backend/tests/tasks/test_payment_policy_migration.py index 030f41853..5d1e7c2d4 100644 --- a/backend/tests/tasks/test_payment_policy_migration.py +++ b/backend/tests/tasks/test_payment_policy_migration.py @@ -63,7 +63,7 @@ async def test_payment_cleanup_refuses_each_retained_fact_then_preserves_current async with historical_material_fixture(tmp_path, isolated_database_env) as h: async with h.engine.connect() as connection: task = await connection.scalar(text("SELECT to_jsonb(t) FROM public.workstream_tasks t WHERE id=:id"), - {"id": h.request.task_id}) + {"id": h.request["task_id"]}) await connection.rollback() cases = [ ("submission_stamp", "retained Submission payment stamp"), @@ -82,15 +82,15 @@ async def test_payment_cleanup_refuses_each_retained_fact_then_preserves_current if case in {"submission_stamp", "locked_payment_policy_version"}: await connection.execute(text("UPDATE public.workstream_tasks " "SET locked_payment_policy_version=locked_guide_version WHERE id=:id"), - {"id": h.request.task_id}) + {"id": h.request["task_id"]}) if case == "submission_stamp": await connection.execute(text("UPDATE public.submissions " "SET locked_payment_policy_version=locked_guide_version WHERE id=:id"), - {"id": h.request.submission_id}) + {"id": h.request["submission_id"]}) if case in {"base_amount", "currency", "payout_type"}: value = {"base_amount": 0, "currency": "USD", "payout_type": "fixed"}[case] await connection.execute(text(f"UPDATE public.workstream_tasks SET {case}=:value WHERE id=:id"), - {"value": value, "id": h.request.task_id}) + {"value": value, "id": h.request["task_id"]}) if case.startswith("receipt:"): _, nested, field = case.split(":") payload = {field: None} if nested == "False" else {"task": {field: None}} @@ -100,9 +100,9 @@ async def test_payment_cleanup_refuses_each_retained_fact_then_preserves_current VALUES(:id,:actor,:action,:key,:digest,:task,'committed', :assignment,:contributor,:digest,CAST(:response AS jsonb),CURRENT_TIMESTAMP)"""), {"id": new_record_id(), "actor": task["assigned_to"], "key": new_record_id(), - "digest": "sha256:" + "a" * 64, "task": h.request.task_id, + "digest": "sha256:" + "a" * 64, "task": h.request["task_id"], "action": "task.claim" if nested == "True" else "project.task.create", - "assignment": h.request.assignment_id if nested == "True" else None, + "assignment": h.request["assignment_id"] if nested == "True" else None, "contributor": task["assigned_to"] if nested == "True" else None, "response": json.dumps(payload)}) # All pre-existing FKs must pass before the intended refusal. From 713a58fb8380bdcd13e5ff7062bf9d7bd81e8f6c Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 15:06:57 +0100 Subject: [PATCH 232/283] test: use archived rows for packet custody upgrade --- .../tests/tasks/test_submission_lineage.py | 32 +++++++++---------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/backend/tests/tasks/test_submission_lineage.py b/backend/tests/tasks/test_submission_lineage.py index 4f108c102..dfd8833de 100644 --- a/backend/tests/tasks/test_submission_lineage.py +++ b/backend/tests/tasks/test_submission_lineage.py @@ -2,7 +2,7 @@ import asyncio from dataclasses import replace -from contextlib import AsyncExitStack, asynccontextmanager +from contextlib import asynccontextmanager from types import SimpleNamespace from app.core.identifiers import new_record_id @@ -252,7 +252,8 @@ async def test_packet_custody_upgrade_preserves_retained_submission( import asyncpg from alembic import command from app.db import session as db_session - from tests.migration_fixtures import _config, current_art_attempt_seed_schema + from tests.historical_submission_fixtures import historical_material_fixture + from tests.migration_fixtures import _config with migration_lock(): await db_session.dispose_engine() @@ -262,26 +263,23 @@ async def test_packet_custody_upgrade_preserves_retained_submission( finally: await connection.close() await asyncio.to_thread(command.upgrade, _config(), "0021_submission_manifest") - async with AsyncExitStack() as stack: - async with current_art_attempt_seed_schema(isolated_database_env): - h = await stack.enter_async_context(_prepared_packet(isolated_database_env, tmp_path)) - from tests.historical_submission_fixtures import write_historical_submission - created = await write_historical_submission(h.factory, h.context, h.creation) - # The predecessor allowed this mismatch. Upgrade must neither invent - # evidence nor rewrite/delete retained text, even when inconsistent. - async with h.factory.begin() as session: - await session.execute(text( - "UPDATE public.submissions SET summary = summary || ' Historical.' WHERE id=:id" - ), {"id": created.submission_id}) - before = await session.scalar(text( - "SELECT to_jsonb(s) FROM public.submissions s WHERE id=:id" - ), {"id": created.submission_id}) + async with historical_material_fixture(tmp_path, isolated_database_env) as h: + submission_id = h.request["submission_id"] + # The predecessor allowed this mismatch. Upgrade must neither invent + # evidence nor rewrite/delete retained text, even when inconsistent. + async with h.factory.begin() as session: + await session.execute(text( + "UPDATE public.submissions SET summary = summary || ' Historical.' WHERE id=:id" + ), {"id": submission_id}) + before = await session.scalar(text( + "SELECT to_jsonb(s) FROM public.submissions s WHERE id=:id" + ), {"id": submission_id}) # Bind this preservation proof to the packet-custody migration. await asyncio.to_thread(command.upgrade, _config(), "0022_submission_packet_custody") async with h.factory() as session: after = await session.scalar(text( "SELECT to_jsonb(s) FROM public.submissions s WHERE id=:id" - ), {"id": created.submission_id}) + ), {"id": submission_id}) assert after == before assert await session.scalar(text( "SELECT count(*) FROM pg_catalog.pg_trigger WHERE tgname='submission_packet_custody'" From 9a286765a7650142d21885865e35f12bb6e51bbb Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 15:10:15 +0100 Subject: [PATCH 233/283] test: consume literal archived custody fields --- .../changes/pilot04-workstream-default-checker.md | 9 +++++++-- backend/tests/checkers/execution/test_migration.py | 2 +- .../tests/tasks/submission_dispatch/test_migration.py | 2 +- backend/tests/tasks/test_payment_policy_migration.py | 4 ++-- 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 7466d4e9f..06e60f34d 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -975,9 +975,11 @@ changes are authorized. Native verification follows combined QA producer freeze. ### Remaining raw migration callers -Lead authorizes four final caller paths: `backend/tests/tasks/test_payment_policy_migration.py`, +Lead authorizes the final caller paths: `backend/tests/tasks/test_payment_policy_migration.py`, `backend/tests/tasks/test_submission_lineage.py`, `backend/tests/checkers/execution/test_migration.py` -and `backend/tests/tasks/post_submit_routing/test_migration.py`. Replace attribute +and `backend/tests/tasks/post_submit_routing/test_migration.py`. The literal +base handoff also requires the single admission-ID dictionary access in +`backend/tests/tasks/submission_dispatch/test_migration.py`. Replace attribute access over archived request/result facts with dictionary indexing. The packet custody upgrade uses the literal revision-0021 Submission snapshot supplied by the backend owner, never the current preparation callback on a predecessor @@ -987,3 +989,6 @@ selection changes. Collection and native predecessor proof follow the frozen literal-base handoff. Both strengthened identity controls passed at exact clean `e947161412b1a7dcc85ffcb0a7bac75922c4cab8` in 34.94 seconds with the exact guard message and SQLSTATE `23514`, installed schema 0036 and complete cleanup. +Plain archived material supplies its semantic manifest digest; the payment +migration uses the canonical session engine, without reintroducing fixture DTOs +or engine facades. diff --git a/backend/tests/checkers/execution/test_migration.py b/backend/tests/checkers/execution/test_migration.py index cefe5e319..d8dfae08e 100644 --- a/backend/tests/checkers/execution/test_migration.py +++ b/backend/tests/checkers/execution/test_migration.py @@ -74,7 +74,7 @@ async def test_migration_refuses_retained_history(tmp_path, isolated_database_en is_current_for_submission=True, package_hash=h.request["content_sha256"], artifact_hash_manifest=source["artifact_hash_manifest"], - artifact_manifest_hash=h.manifest.sha256, + artifact_manifest_hash=h.archived_material["semantic_manifest_sha256"], passed_count=0, warning_count=0, failed_count=0, diff --git a/backend/tests/tasks/submission_dispatch/test_migration.py b/backend/tests/tasks/submission_dispatch/test_migration.py index 51bece90d..a0c0b9a15 100644 --- a/backend/tests/tasks/submission_dispatch/test_migration.py +++ b/backend/tests/tasks/submission_dispatch/test_migration.py @@ -76,6 +76,6 @@ async def snapshot(): ) == 0 assert await connection.fetchval("SELECT count(*) FROM public.submission_dispatches") == 0 assert await connection.fetchval("SELECT count(*) FROM public.submission_binding_receipts") == 0 - assert await connection.fetchval("SELECT status FROM public.submission_bundle_admissions WHERE id=$1", h.created.admission_id) == "consumed" + assert await connection.fetchval("SELECT status FROM public.submission_bundle_admissions WHERE id=$1", h.created["admission_id"]) == "consumed" finally: await connection.close() diff --git a/backend/tests/tasks/test_payment_policy_migration.py b/backend/tests/tasks/test_payment_policy_migration.py index 5d1e7c2d4..84165b707 100644 --- a/backend/tests/tasks/test_payment_policy_migration.py +++ b/backend/tests/tasks/test_payment_policy_migration.py @@ -61,7 +61,7 @@ async def test_payment_cleanup_refuses_each_retained_fact_then_preserves_current await _drop_test_database_schema(isolated_database_env) await asyncio.to_thread(command.upgrade, _config(), "0022_submission_packet_custody") async with historical_material_fixture(tmp_path, isolated_database_env) as h: - async with h.engine.connect() as connection: + async with db_session.get_engine().connect() as connection: task = await connection.scalar(text("SELECT to_jsonb(t) FROM public.workstream_tasks t WHERE id=:id"), {"id": h.request["task_id"]}) await connection.rollback() @@ -117,7 +117,7 @@ async def test_payment_cleanup_refuses_each_retained_fact_then_preserves_current before = await _snapshot(connection) # Full Alembic upgrade: current records exist, but obsolete facts do not. await asyncio.to_thread(command.upgrade, _config(), "head") - async with h.engine.connect() as connection: + async with db_session.get_engine().connect() as connection: assert await connection.scalar(text("SELECT to_regclass('public.payment_policies')")) is None for table, fields in (("workstream_tasks", FIELDS), ("submissions", (FIELDS[-1],))): actual = set(await connection.scalars(text("SELECT column_name FROM information_schema.columns " From 14af57ec36a08cfad233be6855b2afef81d24b3f Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 15:31:51 +0100 Subject: [PATCH 234/283] docs(pilot04): bound migration snapshot restoration scope --- .../changes/pilot04-workstream-default-checker.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 06e60f34d..b8fb3aed1 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -342,6 +342,21 @@ intermediate-wait regression. ## Risk and review routing +The migration-only archive scope includes +`backend/tests/fixtures/pilot04_predecessor_rows.json.gz`, +`backend/tests/historical_submission_fixtures.py`, and the existing retry and +replacement migration tests. Replace executable pinned-source writers and the +raw DTO facade with checksum-bound stored rows and explicit snapshot selection. +Fixture restoration is restricted to an owned isolated test database. It must +restore trigger/FK settings, validate foreign keys and named material custody, +and compare every restored row before any migration assertion receives data. +Restoring terminal archive facts is setup evidence, not proof of a current or +predecessor writer. The archive records capture/schema provenance; no product +runtime, deployment, retained-row deletion or permissive current guard is added. +Wrong checksums, unowned targets, changed schema/rows and unsupported fixture +variants must refuse. Independent CI/QA review and the preserved real PostgreSQL +migration invariants verify this fixture replacement. + Current history and queue fixtures also replace built-in failure-name switches with normalized registered-image verdicts. Allowed producer paths are `backend/tests/checkers/execution/storage_fixture.py`, From a2e50b5b19d70f6358f9b1ea2e031fb0bc15e1d9 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 15:27:15 +0100 Subject: [PATCH 235/283] Replace checker migration writers with literal snapshots --- .../execution/test_checker_retry_migration.py | 96 +-- .../fixtures/pilot04_predecessor_rows.json.gz | Bin 0 -> 791277 bytes .../tests/historical_submission_fixtures.py | 571 +++++++++--------- .../test_replacement_migration.py | 114 +--- 4 files changed, 291 insertions(+), 490 deletions(-) create mode 100644 backend/tests/fixtures/pilot04_predecessor_rows.json.gz diff --git a/backend/tests/checkers/execution/test_checker_retry_migration.py b/backend/tests/checkers/execution/test_checker_retry_migration.py index 4363a305b..43e308b38 100644 --- a/backend/tests/checkers/execution/test_checker_retry_migration.py +++ b/backend/tests/checkers/execution/test_checker_retry_migration.py @@ -1,13 +1,7 @@ """0035 preserves retained checker custody and installs terminal retry closure.""" import asyncio -import io import json -import os -from pathlib import Path -import subprocess -import sys -import tarfile from uuid import UUID import asyncpg @@ -19,67 +13,13 @@ from app.core.hashing import canonical_json_hash from app.core.identifiers import new_record_id from app.db import session as db_session +from tests.historical_submission_fixtures import restore_archived_snapshot from tests.migration_fixtures import _config pytestmark = pytest.mark.postgres_schema_contract PREDECESSOR = "0034_checker_replacement" SUCCESSOR = "0035_checker_retry" -# Pin the last F3 writer: current F4 delivery reads the 0035 retry table. -HISTORICAL_WRITER = "926b4ef118db3708e50d1869db5ee78a79e5b5de" -HISTORICAL_SEED = """ -import asyncio -import json -import os -from pathlib import Path -import sys - -import pytest - -from app.adapters.artifacts import internal_workers -from app.adapters.artifacts.local import LocalStorageAdapter -from app.db import session as db_session -from app.interfaces.artifacts import ArtifactObjectMissingError -from tests.post_submit_materialization_helpers import material_fixture -from tests.tasks.evaluation_delivery.support import delivery_fixture, outcome, state -from tests.tasks.evaluation_delivery.test_worker_materialization import _worker_port - - -async def seed(): - database_url = os.environ["WS_MIGRATION_DATABASE_URL"] - tmp_path = Path(sys.argv[1]) - result_path = Path(sys.argv[2]) - - def missing(_store, _reference): - raise ArtifactObjectMissingError("controlled verified object loss") - - try: - with pytest.MonkeyPatch.context() as monkeypatch: - async with material_fixture(tmp_path, database_url, provider="local") as h: - port = _worker_port(h, monkeypatch) - try: - delivery = await delivery_fixture(h, materialization=port) - with monkeypatch.context() as patch: - patch.setattr(LocalStorageAdapter, "open", missing) - initial = await delivery.delivery.deliver( - h.created.evaluation_event_id, h.request.project_id, "retry-source", - ) - assert outcome(initial)["delivery_state"] == "acknowledged" - saved = await state(h) - assert saved["run"]["status"] == "infrastructure_failed" - assert json.loads(saved["run"]["result_json"])["infrastructure_failure_code"] == "material_unavailable" - result_path.write_text(json.dumps({ - "submission_id": str(h.created.submission_id), - "request": h.request.model_dump(mode="json"), - })) - finally: - internal_workers.shutdown_artifact_internal_runtime() - finally: - await db_session.dispose_engine() - - -asyncio.run(seed()) -""" RETAINED_TABLES = ( "submissions", "submission_dispatches", @@ -121,36 +61,6 @@ async def _reset_to_predecessor(database_url): await asyncio.to_thread(command.upgrade, _config(), PREDECESSOR) -def _historical_backend(tmp_path): - root = Path(__file__).resolve().parents[4] - archived = subprocess.run( - ["git", "archive", "--format=tar", HISTORICAL_WRITER, "backend"], - cwd=root, - capture_output=True, - check=True, - ) - source = tmp_path / "historical" - with tarfile.open(fileobj=io.BytesIO(archived.stdout), mode="r:") as archive: - archive.extractall(source, filter="data") - return source / "backend" - - -def _seed_with_historical_writer(tmp_path, database_url): - backend = _historical_backend(tmp_path) - result_path = tmp_path / "historical-seed.json" - subprocess.run( - [sys.executable, "-c", HISTORICAL_SEED, str(tmp_path), str(result_path)], - cwd=backend, - env={ - **os.environ, - "PYTHONPATH": os.pathsep.join((str(backend), str(backend / "tests"))), - "WS_MIGRATION_DATABASE_URL": database_url, - }, - check=True, - ) - return json.loads(result_path.read_text()) - - async def _retained_rows(connection): return { table: tuple( @@ -226,8 +136,8 @@ async def test_retry_upgrade_preserves_evidence_and_installs_closure( ): with migration_lock(): await _reset_to_predecessor(isolated_database_env) - seed = await asyncio.to_thread( - _seed_with_historical_writer, tmp_path, isolated_database_env + seed = await restore_archived_snapshot( + isolated_database_env, "0034_checker_retry_source" ) submission_id = UUID(seed["submission_id"]) request = seed["request"] diff --git a/backend/tests/fixtures/pilot04_predecessor_rows.json.gz b/backend/tests/fixtures/pilot04_predecessor_rows.json.gz new file mode 100644 index 0000000000000000000000000000000000000000..b1065d88435f1be944345aef61078eeacae3005f GIT binary patch literal 791277 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
pW^Jm~ll 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

i^I$sZ8hglJGb8UUER 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

4f?p4s%Wo7*1wcCl=Tt2*+gB0Q#Yn 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�P0r{{mBX~(ZHZ=_52uNVC8jiW}sqFYYuy23O| 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 z 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
onjnu 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�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%0A`~_q59Rvo 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 R{n-8nIiyU2Uf|RG@n5q|w}t=! literal 0 HcmV?d00001 diff --git a/backend/tests/historical_submission_fixtures.py b/backend/tests/historical_submission_fixtures.py index 265f3ed3a..928538227 100644 --- a/backend/tests/historical_submission_fixtures.py +++ b/backend/tests/historical_submission_fixtures.py @@ -1,318 +1,313 @@ -"""Explicit predecessor storage for migration proofs, never a current intake writer. +"""Checksum-bound predecessor rows for migration tests only. -Only migration tests call this seeder. It writes the pre-0025 row shape with all -then-installed constraints enabled; it does not invent current AUTH or dispatch -receipts. Preparation and verification still use real ART owners and ZIP bytes. +The archive is a one-time database backup from the last pre-cutover writer. It +contains data, not an executable checker implementation. Restore is confined +to an isolated predecessor database and finishes with every trigger and foreign +key setting restored before a migration test receives the fixture. """ -import json -from contextlib import AsyncExitStack, asynccontextmanager +from __future__ import annotations + +from contextlib import asynccontextmanager from copy import deepcopy +from functools import lru_cache +import gzip +import hashlib +import json +from pathlib import Path from types import SimpleNamespace -from uuid import UUID -from sqlalchemy import select, func +import asyncpg -from app.core.identifiers import new_record_id from app.core.hashing import canonical_json_hash -from app.modules.artifacts.api import SubmissionBundleFile -from app.modules.artifacts.models import ArtifactBinding, SubmissionBundleAdmission -from app.modules.checkers.api.artifact_paths import required_evidence_path -from app.modules.projects.api import ProjectLockedPolicyContextFacts -from app.modules.tasks.api import TaskSubmissionContextRequest -from app.modules.tasks.api import TaskSubmissionContextFacts -from app.modules.tasks.models import Submission -from app.modules.tasks.repository import TaskRepository -from app.modules.tasks.submission_composition import build_submission -from tests.migration_fixtures import current_art_attempt_seed_schema -from tests.post_submit_materialization_helpers import _archive_facts, _material_fixture +from app.db import session as db_session +from conftest import _assert_owned_test_database -class HistoricalRawValue(SimpleNamespace): - """Attribute access over literal predecessor JSON, never a product contract.""" +_ARCHIVE = Path(__file__).with_name("fixtures") / "pilot04_predecessor_rows.json.gz" +_ARCHIVE_SHA256 = "3dc2d3e4915697de5e0d9c2a7f6aa8d5672ec069f23cb065550413af26eeb174" +_SCHEMA_VERSION = "workstream.pilot04_predecessor_rows.v1" - def model_dump(self, *, exclude=frozenset(), **_options): - def dump(value): - if isinstance(value, HistoricalRawValue): - return {key: dump(item) for key, item in vars(value).items()} - if isinstance(value, tuple): - return [dump(item) for item in value] - if isinstance(value, UUID): - return str(value) - return deepcopy(value) - return { - key: dump(value) - for key, value in vars(self).items() - if key not in exclude - } +def _asyncpg_url(database_url: str) -> str: + return "postgresql" + database_url.removeprefix("postgresql+asyncpg") - def model_copy(self, *, update): - values = vars(self) | update - return HistoricalRawValue(**values) +def _identifier(value: str) -> str: + return '"' + value.replace('"', '""') + '"' -def _raw(value): - if isinstance(value, dict): - return HistoricalRawValue(**{key: _raw(item) for key, item in value.items()}) - if isinstance(value, list): - return tuple(_raw(item) for item in value) - return value +@lru_cache(maxsize=1) +def _snapshots() -> dict[str, dict[str, object]]: + encoded = _ARCHIVE.read_bytes() + assert hashlib.sha256(encoded).hexdigest() == _ARCHIVE_SHA256, ( + "PILOT-04 predecessor row archive checksum mismatch" + ) + body = json.loads(gzip.decompress(encoded)) + assert body["schema_version"] == _SCHEMA_VERSION + return body["snapshots"] -_HISTORICAL_DEFINITIONS = ( - ("check_submission_packet", "packet_presence", "packet_fields_missing", "submission_structure", "failed", "high", True), - ("check_policy_context_present", "policy_context_consistency", "policy_context_invalid", "task_configuration", "failed", "high", True), - ("check_evidence_present", "evidence_presence", "evidence_missing", "submission_structure", "failed", "high", True), - ("check_evidence_integrity", "evidence_structure", "evidence_structure_invalid", "submission_structure", "failed", "high", True), - ("check_required_files", "required_path_presence", "required_files_missing", "submission_structure", "failed", "high", True), - ("check_forbidden_files", "forbidden_path_detection", "forbidden_path_present", "submission_structure", "failed", "high", True), - ("check_confidentiality_attestation", "attestation_presence", "attestation_missing", "submission_structure", "failed", "high", True), - ("check_low_quality_generated_artifacts", "placeholder_signal_detection", "placeholder_signal", "submission_structure", "warning", "medium", True), - ("check_acceptance_criteria_present", "criteria_presence", "acceptance_criteria_missing", "task_configuration", "failed", "high", False), -) +async def _trigger_state(connection: asyncpg.Connection) -> tuple[tuple[object, ...], ...]: + rows = await connection.fetch(""" + SELECT n.nspname, c.relname, t.tgname, t.tgenabled + FROM pg_trigger t + JOIN pg_class c ON c.oid=t.tgrelid + JOIN pg_namespace n ON n.oid=c.relnamespace + WHERE n.nspname='public' + ORDER BY c.relname,t.tgname + """) + return tuple(tuple(row) for row in rows) -def _historical_catalogue() -> dict[str, object]: - resources = { - "deadline_ms": 5000, - "maximum_evidence_items": 1024, - "maximum_generated_output_bytes": 0, - "maximum_input_bytes": 1_048_576, - "maximum_manifest_items": 1024, - "maximum_policy_items": 256, - "maximum_result_bytes": 4096, - "maximum_results": 1, - "maximum_text_characters": 65_536, - "phase_deadline_ms": 45_000, - } - definitions = [] - for order, values in enumerate(_HISTORICAL_DEFINITIONS, 1): - capability, claim, code, category, status, severity, platform_default = values - definitions.append( - { - "capability_id": capability, - "capability_version": "v0.1", - "configuration_schema": "post_submit_empty_configuration", - "dependencies": [], - "disabled_behavior": "unavailable", - "execution_method": "deterministic", - "failure_category": category, - "failure_code": code, - "failure_severity": severity, - "failure_status": status, - "implementation_version": "workstream-structural", - "input_schema": "post_submit_structural_input", - "order": order, - "platform_default": platform_default, - "provider_recovery": "none", - "required_output_roles": [], - "resources": resources, - "result_schema": "post_submit_structural_result", - "selectable": not platform_default, - "stage": "post_submit", - "state": "enabled", - "supported_claim": claim, - } - ) - return { - "catalogue_id": "workstream.post_submission_checkers", - "definitions": definitions, - "manifest_sha256": "sha256:87b454499eca2dbf10e86495e4f9b2a4440977a51d5ae5c4d3f6405672fa89a5", - "schema_version": "post_submission_checker_capability_projection", - "source_version": "v0.1", - } - -async def write_historical_submission(factory, context, request): - """Seed only an actual predecessor schema; never bypass current constraints.""" - from sqlalchemy import text - async with factory() as session, session.begin(): - revision = await session.scalar(text("SELECT version_num FROM public.alembic_version")) - assert revision in { - "0007_checker_output_custody", "0008_checker_execution", "0009_checker_material_lineage", - "0010_post_submit_authority", "0011_task_routing_source", "0012_review_packet", - "0013_review_source", "0014_final_acceptance", "0015_contribution_awards", - "0017_acceptance_source_contracts", "0018_task_routing_request", - "0020_review_admission_lock_order", "0021_submission_manifest", - "0022_submission_packet_custody", "0023_remove_task_payment_policy", - "0024_require_second_review_false", - }, "historical seeder cannot write the current schema" - repository = TaskRepository(session) - facts, source = await repository.select_submission_context(TaskSubmissionContextRequest( - request.task_id, request.assignment_id, request.contributor_id, request.predecessor_submission_id, - )) - assert source is None - task = await repository.get_task(str(request.task_id)) - admission = await session.get(SubmissionBundleAdmission, str(request.admission_id)) - assert admission.status == "ready" and admission.actor_profile_id == str(context.actor_profile_id) - version = 1 if facts.predecessor is None else facts.predecessor.version + 1 - submission_id, binding_id = new_record_id(), new_record_id() - submission = build_submission( - submission_id=str(submission_id), task=task, contributor_id=str(request.contributor_id), - version=version, summary=request.summary, worker_attestation=request.contributor_attestation, - supersedes_submission_id=str(request.predecessor_submission_id) if request.predecessor_submission_id else None, - contribution_policy_version_id=facts.submitter_contribution_policy_version_id, - task_assignment_id=str(request.assignment_id), - ) - session.add(submission) - await session.flush() - session.add(ArtifactBinding( - id=str(binding_id), content_id=admission.artifact_content_id, project_id=admission.project_id, - resource_type="submission", resource_id=str(submission_id), logical_role="submission_bundle_original", - scope_version=1, actor_id=admission.actor_profile_id, attribution_type="contributor", - )) - consumed_at = await session.scalar(select(func.now())) - admission.status = "consumed" - admission.consumed_at = consumed_at - admission.consumed_by_submission_id = str(submission_id) - admission.consumed_by_submission_version = version - submission.submission_bundle_admission_id = admission.id - submission.artifact_binding_id = str(binding_id) - submission.artifact_content_id = admission.artifact_content_id - task.status = "submitted" - await session.flush() - return SimpleNamespace(submission_id=submission_id, submission_version=version, - admission_id=request.admission_id, artifact_binding_id=binding_id, - artifact_content_id=UUID(admission.artifact_content_id), task_context=facts) +async def _assert_database_guards_enabled(connection: asyncpg.Connection) -> None: + assert await connection.fetchval("SHOW session_replication_role") == "origin" + assert await connection.fetchval(""" + SELECT count(*) FROM pg_trigger t + JOIN pg_class c ON c.oid=t.tgrelid + JOIN pg_namespace n ON n.oid=c.relnamespace + WHERE n.nspname='public' AND NOT t.tgisinternal + AND t.tgenabled NOT IN ('O','A') + """) == 0 -def submission_evaluation_content( - task_context: TaskSubmissionContextFacts, - project_context: ProjectLockedPolicyContextFacts, - packet, - files: tuple[SubmissionBundleFile, ...], - archive_sha256: str, -) -> HistoricalRawValue: - """Build the literal predecessor JSON retained by migration fixtures.""" - from app.adapters.tasks import validate_submission_policy_context +async def _foreign_keys(connection: asyncpg.Connection) -> tuple[asyncpg.Record, ...]: + return tuple(await connection.fetch(""" + SELECT con.oid, con.conname, child.relname AS child_table, + parent.relname AS parent_table, con.condeferrable, con.condeferred, + con.confmatchtype, + array_agg(child_col.attname ORDER BY keys.ordinality) AS child_columns, + array_agg(parent_col.attname ORDER BY keys.ordinality) AS parent_columns + FROM pg_constraint con + JOIN pg_class child ON child.oid=con.conrelid + JOIN pg_class parent ON parent.oid=con.confrelid + JOIN pg_namespace n ON n.oid=con.connamespace + CROSS JOIN LATERAL unnest(con.conkey,con.confkey) + WITH ORDINALITY AS keys(child_num,parent_num,ordinality) + JOIN pg_attribute child_col + ON child_col.attrelid=con.conrelid AND child_col.attnum=keys.child_num + JOIN pg_attribute parent_col + ON parent_col.attrelid=con.confrelid AND parent_col.attnum=keys.parent_num + WHERE n.nspname='public' AND con.contype='f' + GROUP BY con.oid,con.conname,child.relname,parent.relname, + con.condeferrable,con.condeferred,con.confmatchtype + ORDER BY child.relname,con.conname + """)) - validate_submission_policy_context(task_context, project_context) - stamps = task_context.locked_policy - expected = { - "guide_version": stamps.locked_guide_version, - "source_id": stamps.locked_guide_source_snapshot_id, - "source_hash": stamps.locked_guide_source_snapshot_hash, - "effective_policy_id": stamps.locked_effective_project_submission_artifact_policy_id, - "effective_policy_hash": stamps.locked_effective_project_submission_artifact_policy_hash, - "pre_policy_id": stamps.locked_pre_submit_checker_policy_id, - "pre_policy_hash": stamps.locked_pre_submit_checker_bundle_hash, - "post_policy_id": stamps.locked_post_submit_checker_policy_id, - "post_policy_version": stamps.locked_post_submit_checker_policy_version, - "post_policy_hash": stamps.locked_post_submit_checker_policy_hash, - "review_policy_id": stamps.locked_review_policy_id, - "review_generation": stamps.locked_review_policy_generation, - "review_hash": stamps.locked_review_policy_hash, - "revision_policy_id": stamps.locked_revision_policy_id, - "revision_generation": stamps.locked_revision_policy_generation, - "revision_hash": stamps.locked_revision_policy_hash, - } - effective = json.loads(project_context.effective_policy.value) - policy_inputs = { - "required_evidence_keys": [ - item["key"] for item in effective.get("required_evidence", []) - if item.get("required", True) - ], - "required_artifact_paths": [ - item["path"] for item in effective.get("required_artifacts", []) - if item.get("required", True) - ], - "forbidden_artifact_patterns": [ - item["pattern"] for item in effective.get("forbidden_artifacts", []) - if item.get("pattern") - ], - "required_attestation_terms": [ - term for term in effective.get("attestation_terms", []) if term - ], - } - by_path = {item.normalized_path: item for item in files} - body = { - "project_id": project_context.project_id, - "expected_context": expected, - "catalogue": _historical_catalogue(), - "policy": json.loads(project_context.compiled_post_submit_policy.value), - "structural_input": { - "schema_version": "post_submit_structural_input", - "summary": packet.summary, - "worker_attestation": packet.contributor_attestation, - "package_hash": archive_sha256, - "criteria": task_context.acceptance_criteria or "", - "manifest": [ - { - "artifact": item.normalized_path, - "hash": item.sha256, - "notes": None, - "size_bytes": item.byte_count, - } - for item in files - ], - "evidence": [ - { - "label": key, - "uri": item.normalized_path, - "hash": item.sha256, - "type": "file", - "key": key, - "policy_key": None, - "evidence_key": None, - "required_evidence_key": None, - } - for key in policy_inputs["required_evidence_keys"] - for item in (by_path.get(required_evidence_path(key)),) - if item is not None - ], - "policy_inputs": policy_inputs, - "observed_context": expected, - }, - } - return _raw(body) +async def _validate_foreign_keys( + connection: asyncpg.Connection, foreign_keys: tuple[asyncpg.Record, ...] +) -> None: + """Independently reject every orphan or partial MATCH FULL archived row.""" + for constraint in foreign_keys: + child = _identifier(constraint["child_table"]) + parent = _identifier(constraint["parent_table"]) + child_columns = tuple(constraint["child_columns"]) + parent_columns = tuple(constraint["parent_columns"]) + all_present = " AND ".join( + f"c.{_identifier(column)} IS NOT NULL" for column in child_columns + ) + any_present = " OR ".join( + f"c.{_identifier(column)} IS NOT NULL" for column in child_columns + ) + any_missing = " OR ".join( + f"c.{_identifier(column)} IS NULL" for column in child_columns + ) + equal = " AND ".join( + f"p.{_identifier(parent_column)} IS NOT DISTINCT FROM " + f"c.{_identifier(child_column)}" + for child_column, parent_column in zip( + child_columns, parent_columns, strict=True + ) + ) + invalid_full = ( + f" OR (({any_present}) AND ({any_missing}))" + if constraint["confmatchtype"] == "f" + else "" + ) + count = await connection.fetchval( + f"""SELECT count(*) FROM public.{child} c + WHERE (({all_present}) AND NOT EXISTS ( + SELECT 1 FROM public.{parent} p WHERE {equal} + )){invalid_full}""" + ) + assert count == 0, f"archived rows violate {constraint['conname']}" -async def _historical_request(session, facts, created, data): - """Project genuine historical inputs without creating a future reservation.""" - from app.adapters.tasks import task_service - from app.core.config import get_settings - from app.modules.tasks.models import WorkstreamTask - submission = await session.get(Submission, str(created.submission_id)) - task = await session.get(WorkstreamTask, submission.task_id) - project = await task_service(session, settings=get_settings())._load_locked_task_context(task) - _, manifest, _, digest = _archive_facts(data) - content = submission_evaluation_content( - created.task_context, - project.facts, - SimpleNamespace( - summary=submission.summary, - contributor_attestation=submission.worker_attestation, - ), - manifest.file_facts(), - digest, - ) - body = content.model_dump() | { - "schema_version": "post_submit_evaluation_request", - "evaluation_request_id": new_record_id(), - "evaluation_generation": 1, - "task_id": facts.task_id, - "assignment_id": facts.assignment_id, - "submission_id": created.submission_id, - "submission_version": created.submission_version, - "content_id": created.artifact_content_id, - "binding_id": created.artifact_binding_id, - "content_sha256": digest, - "byte_count": len(data), - } - body["request_sha256"] = canonical_json_hash( - _raw(body).model_dump() +async def _validate_material_custody( + connection: asyncpg.Connection, seed: dict[str, object] +) -> None: + """Bind the archived request to the exact Submission and native ART rows.""" + request = seed["request"] + created = seed["created"] + request_body = {key: value for key, value in request.items() if key != "request_sha256"} + assert canonical_json_hash(request_body) == request["request_sha256"] + row = await connection.fetchrow(""" + SELECT s.id::text AS submission_id,s.version,s.task_id::text,s.task_assignment_id::text, + s.submission_bundle_admission_id::text AS admission_id, + s.artifact_binding_id::text AS binding_id,s.artifact_content_id::text AS content_id, + a.status,a.consumed_by_submission_id::text AS consumed_submission_id, + a.consumed_by_submission_version,b.resource_type,b.resource_id::text, + b.content_id::text AS binding_content_id,c.sha256, + r.content_id::text AS replica_content_id,t.status AS task_status + FROM public.submissions s + JOIN public.submission_bundle_admissions a ON a.id=s.submission_bundle_admission_id + JOIN public.artifact_bindings b ON b.id=s.artifact_binding_id + JOIN public.artifact_contents c ON c.id=s.artifact_content_id + JOIN public.artifact_replicas r ON r.id=$2::uuid + JOIN public.workstream_tasks t ON t.id=s.task_id + WHERE s.id=$1::uuid + """, created["submission_id"], seed["replica_id"]) + assert row is not None + assert row["submission_id"] == request["submission_id"] == created["submission_id"] + assert row["version"] == request["submission_version"] == created["submission_version"] + assert row["task_id"] == request["task_id"] + assert row["task_assignment_id"] == request["assignment_id"] + assert row["admission_id"] == created["admission_id"] + assert row["binding_id"] == request["binding_id"] == created["artifact_binding_id"] + assert row["content_id"] == request["content_id"] == created["artifact_content_id"] + assert row["status"] == "consumed" + assert row["consumed_submission_id"] == created["submission_id"] + assert row["consumed_by_submission_version"] == created["submission_version"] + assert (row["resource_type"], row["resource_id"]) == ( + "submission", created["submission_id"] ) - return _raw(body) + assert row["binding_content_id"] == row["replica_content_id"] == request["content_id"] + assert row["sha256"] == request["content_sha256"] + assert row["task_status"] == "submitted" + + +async def restore_archived_snapshot( + database_url: str, snapshot_name: str | None = None +) -> dict[str, object]: + """Restore literal rows into their exact isolated predecessor revision.""" + connection = await asyncpg.connect(_asyncpg_url(database_url)) + try: + await _assert_owned_test_database(connection, database_url) + await _assert_database_guards_enabled(connection) + revision = await connection.fetchval("SELECT version_num FROM public.alembic_version") + key = snapshot_name or revision + snapshot = deepcopy(_snapshots()[key]) + if snapshot_name is None: + assert key == revision + else: + assert snapshot["revision"] == revision + tables = tuple(sorted(snapshot["tables"])) + database_tables = tuple(row["tablename"] for row in await connection.fetch(""" + SELECT tablename FROM pg_tables + WHERE schemaname='public' ORDER BY tablename + """)) + assert set(tables).issubset(database_tables), "archived table inventory differs" + table_columns: dict[str, tuple[str, ...]] = {} + for table in tables: + columns = tuple(await connection.fetchval(""" + SELECT array_agg(column_name ORDER BY ordinal_position) + FROM information_schema.columns + WHERE table_schema='public' AND table_name=$1 + """, table)) + table_columns[table] = columns + assert all(set(row) == set(columns) for row in snapshot["tables"][table]), ( + f"archived columns differ for {table}" + ) + original_triggers = await _trigger_state(connection) + original_foreign_keys = await _foreign_keys(connection) + original_fk_state = tuple( + (row["oid"], row["condeferrable"], row["condeferred"]) + for row in original_foreign_keys + ) + async with connection.transaction(): + # A faithful backup restore is setup, not a current writer proof. + # User triggers resume before any migration assertion receives data. + for table in database_tables: + await connection.execute( + f"ALTER TABLE public.{_identifier(table)} DISABLE TRIGGER USER" + ) + changed_constraints: list[tuple[str, str]] = [] + for constraint in original_foreign_keys: + if not constraint["condeferrable"]: + table = _identifier(constraint["child_table"]) + name = _identifier(constraint["conname"]) + await connection.execute( + f"ALTER TABLE public.{table} ALTER CONSTRAINT {name} " + "DEFERRABLE INITIALLY DEFERRED" + ) + changed_constraints.append( + (constraint["child_table"], constraint["conname"]) + ) + await connection.execute("SET CONSTRAINTS ALL DEFERRED") + for table in database_tables: + await connection.execute(f"DELETE FROM public.{_identifier(table)}") + for table in tables: + await connection.execute( + f"INSERT INTO public.{_identifier(table)} " + f"SELECT * FROM jsonb_populate_recordset(" + f"NULL::public.{_identifier(table)},$1::jsonb)", + json.dumps( + snapshot["tables"][table], + sort_keys=True, + separators=(",", ":"), + ), + ) + await connection.execute("SET CONSTRAINTS ALL IMMEDIATE") + await _validate_foreign_keys(connection, await _foreign_keys(connection)) + for table in database_tables: + await connection.execute( + f"ALTER TABLE public.{_identifier(table)} ENABLE TRIGGER USER" + ) + for table_name, constraint_name in changed_constraints: + await connection.execute( + f"ALTER TABLE public.{_identifier(table_name)} " + f"ALTER CONSTRAINT {_identifier(constraint_name)} NOT DEFERRABLE" + ) + assert await _trigger_state(connection) == original_triggers + await _assert_database_guards_enabled(connection) + final_foreign_keys = await _foreign_keys(connection) + assert tuple( + (row["oid"], row["condeferrable"], row["condeferred"]) + for row in final_foreign_keys + ) == original_fk_state + nonempty_tables: list[str] = [] + for table in database_tables: + if await connection.fetchval( + f"SELECT EXISTS(SELECT 1 FROM public.{_identifier(table)})" + ): + nonempty_tables.append(table) + nonempty = tuple(nonempty_tables) + assert nonempty == tables, "archived nonempty table inventory differs" + for table in tables: + actual = sorted( + (json.loads(row["value"]) for row in await connection.fetch( + f"SELECT to_jsonb(r)::text AS value " + f"FROM public.{_identifier(table)} r" + )), + key=lambda row: json.dumps( + row, sort_keys=True, separators=(",", ":") + ), + ) + expected = sorted( + snapshot["tables"][table], + key=lambda row: json.dumps(row, sort_keys=True, separators=(",", ":")), + ) + assert actual == expected, f"archived rows differ for {table}" + if "archived_material" in snapshot["seed"]: + await _validate_material_custody(connection, snapshot["seed"]) + return deepcopy(snapshot["seed"]) + finally: + await connection.close() @asynccontextmanager -async def historical_material_fixture(tmp_path, database_url, **options): - async with AsyncExitStack() as stack: - async with current_art_attempt_seed_schema(database_url): - material = await stack.enter_async_context(_material_fixture( - tmp_path, database_url, write_submission=write_historical_submission, - read_request=_historical_request, **options, - )) - yield material +async def historical_material_fixture( + _tmp_path, database_url, *, snapshot_name: str | None = None +): + """Yield plain archived facts after the isolated predecessor restore closes.""" + seed = await restore_archived_snapshot(database_url, snapshot_name) + yield SimpleNamespace( + factory=db_session.get_session_factory(), + request=seed["request"], + created=seed["created"], + replica_id=seed["replica_id"], + archived_members=tuple(seed["archived_members"]), + archived_counts=seed["archived_counts"], + archived_material=seed["archived_material"], + ) diff --git a/backend/tests/tasks/submission_dispatch/test_replacement_migration.py b/backend/tests/tasks/submission_dispatch/test_replacement_migration.py index 70ad4a94a..a17ade990 100644 --- a/backend/tests/tasks/submission_dispatch/test_replacement_migration.py +++ b/backend/tests/tasks/submission_dispatch/test_replacement_migration.py @@ -1,12 +1,6 @@ """0034 preserves initial custody and refuses uncaused retained replacements.""" import asyncio -import io -import os -from pathlib import Path -import subprocess -import sys -import tarfile import asyncpg import pytest @@ -14,83 +8,13 @@ from sqlalchemy.exc import DBAPIError from app.db import session as db_session +from tests.historical_submission_fixtures import restore_archived_snapshot from tests.migration_fixtures import _config pytestmark = pytest.mark.postgres_schema_contract PREDECESSOR = "0033_contribution_reads" SUCCESSOR = "0034_checker_replacement" -# The last merged 0032 writer could produce an authorized revision without a -# persisted checker-remediation cause; current runtime deliberately cannot. -HISTORICAL_WRITER = "735cf26591e4ed616bcaa57f12eeb37cee741973" -HISTORICAL_SEED = """ -import asyncio -import os -from pathlib import Path -import sys - -from app.adapters.tasks import evaluation_completion_handler -from app.api.deps.authorization import compose_hidden_submission_creation_command -from app.core.identifiers import new_record_id -from app.db import session as db_session -from app.modules.artifacts.api import SubmissionBundlePreparationRequest -from app.modules.authorization.api import ActorIdentityFacts, ActorKind -from app.modules.outbox.api import HandlerOutcome -from app.modules.tasks.api import SubmissionCreationRequest -from tests.post_submit_materialization_helpers import material_fixture -from tests.tasks.post_submit_routing.remediation_support import remediation_source -from tests.tasks.post_submit_routing.support import revision_archive -from tests.tasks.submission_lineage_support import _verified_admission -from tests.test_default_pre_submit_execution import _bytes - - -async def seed(): - tmp_path = Path(sys.argv[2]) - database_url = os.environ["WS_MIGRATION_DATABASE_URL"] - if sys.argv[1] == "initial": - async with material_fixture(tmp_path, database_url) as h: - assert h.created.submission_version == 1 - else: - async with remediation_source(tmp_path, database_url) as h: - assert await evaluation_completion_handler(sessions=h.factory)(h.envelope) is HandlerOutcome.ACKNOWLEDGE - changed = revision_archive(h.data) - preparation = SubmissionBundlePreparationRequest( - actor=ActorIdentityFacts( - h.actor_context.actor_profile_id, - h.actor_context.identity_link_id, - ActorKind.HUMAN, - ), - request_id=new_record_id(), correlation_id=new_record_id(), - task_id=h.request.task_id, assignment_id=h.request.assignment_id, - predecessor_submission_id=h.created.submission_id, - idempotency_key=new_record_id(), - summary=h.request.structural_input.summary, - contributor_attestation=h.request.structural_input.worker_attestation, - media_type="application/zip", byte_source=_bytes(changed), - ) - admission_id = await _verified_admission( - h.factory, h.store, h.namespace, h.settings, h.actor_context, preparation, - ) - async with h.factory() as session: - created = await compose_hidden_submission_creation_command( - session, - h.actor_context.model_copy(update={ - "request_id": new_record_id(), "correlation_id": new_record_id(), - }), - request_id=new_record_id(), correlation_id=new_record_id(), - ).create(SubmissionCreationRequest( - task_id=h.request.task_id, assignment_id=h.request.assignment_id, - contributor_id=h.actor_context.actor_profile_id, - predecessor_submission_id=h.created.submission_id, - admission_id=admission_id, summary=preparation.summary, - contributor_attestation=preparation.contributor_attestation, - )) - assert created.submission_version == 2 - await db_session.dispose_engine() - - -asyncio.run(seed()) -""" RETAINED_TABLES = ( "submissions", "pre_submit_evidence_sets", @@ -122,34 +46,6 @@ async def _reset_to_predecessor(database_url): await asyncio.to_thread(command.upgrade, _config(), PREDECESSOR) -def _historical_backend(tmp_path): - root = Path(__file__).resolve().parents[4] - archived = subprocess.run( - ["git", "archive", "--format=tar", HISTORICAL_WRITER, "backend"], - cwd=root, - capture_output=True, - check=True, - ) - source = tmp_path / "historical" - with tarfile.open(fileobj=io.BytesIO(archived.stdout), mode="r:") as archive: - archive.extractall(source, filter="data") - return source / "backend" - - -def _seed_with_historical_writer(tmp_path, database_url, mode): - backend = _historical_backend(tmp_path) - subprocess.run( - [sys.executable, "-c", HISTORICAL_SEED, mode, str(tmp_path)], - cwd=backend, - env={ - **os.environ, - "PYTHONPATH": os.pathsep.join((str(backend), str(backend / "tests"))), - "WS_MIGRATION_DATABASE_URL": database_url, - }, - check=True, - ) - - async def _retained_rows(connection): """Exclude only the nullable cause columns introduced by 0034.""" return { @@ -188,8 +84,8 @@ async def test_upgrade_preserves_real_initial_rows_and_exact_receipts( ): with migration_lock(): await _reset_to_predecessor(isolated_database_env) - await asyncio.to_thread( - _seed_with_historical_writer, tmp_path, isolated_database_env, "initial" + await restore_archived_snapshot( + isolated_database_env, "0033_checker_replacement_initial" ) connection = await _connection(isolated_database_env) try: @@ -284,8 +180,8 @@ async def test_retained_uncaused_revision_refuses_upgrade_without_changes( """A real 0032 writer can retain version two without a persisted source ID.""" with migration_lock(): await _reset_to_predecessor(isolated_database_env) - await asyncio.to_thread( - _seed_with_historical_writer, tmp_path, isolated_database_env, "revision" + await restore_archived_snapshot( + isolated_database_env, "0033_checker_replacement_revision" ) await db_session.dispose_engine() From 81d409d071e5ca564f698fe733bde2f4ee031bdb Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 15:30:55 +0100 Subject: [PATCH 236/283] Qualify archived migration evidence --- .../tests/checkers/execution/test_checker_retry_migration.py | 2 +- .../tasks/submission_dispatch/test_replacement_migration.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/tests/checkers/execution/test_checker_retry_migration.py b/backend/tests/checkers/execution/test_checker_retry_migration.py index 43e308b38..8eea422a7 100644 --- a/backend/tests/checkers/execution/test_checker_retry_migration.py +++ b/backend/tests/checkers/execution/test_checker_retry_migration.py @@ -102,7 +102,7 @@ async def _source_custody(connection, submission_id): async def _predecessor_evidence(connection, submission_id): - """Verify the actual old writer's complete source before comparing its upgrade.""" + """Verify the complete archived source before comparing its upgrade.""" assert await connection.fetchval("SELECT version_num FROM public.alembic_version") == PREDECESSOR assert await connection.fetchval( "SELECT to_regclass('public.checker_retry_receipts') IS NULL" diff --git a/backend/tests/tasks/submission_dispatch/test_replacement_migration.py b/backend/tests/tasks/submission_dispatch/test_replacement_migration.py index a17ade990..4076e703e 100644 --- a/backend/tests/tasks/submission_dispatch/test_replacement_migration.py +++ b/backend/tests/tasks/submission_dispatch/test_replacement_migration.py @@ -77,7 +77,7 @@ async def _custody(connection): """) -async def test_upgrade_preserves_real_initial_rows_and_exact_receipts( +async def test_upgrade_preserves_archived_initial_rows_and_exact_receipts( tmp_path, isolated_database_env, migration_lock, @@ -177,7 +177,7 @@ async def test_retained_uncaused_revision_refuses_upgrade_without_changes( isolated_database_env, migration_lock, ): - """A real 0032 writer can retain version two without a persisted source ID.""" + """The archived predecessor can retain version two without a source ID.""" with migration_lock(): await _reset_to_predecessor(isolated_database_env) await restore_archived_snapshot( From e89551f96ed473705eff22c38e311ba300cb2c56 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 15:36:13 +0100 Subject: [PATCH 237/283] test: select paid archives without current seeding wrappers --- .../pilot04-workstream-default-checker.md | 15 ++++++++++++ .../post_submit/test_migration.py | 9 ++------ .../execution/test_material_migration.py | 9 ++------ .../checkers/execution/test_migration.py | 5 +--- .../records/historical_support.py | 23 +++++++++++-------- .../contributions/records/test_migration.py | 7 ------ .../reviews/acceptance/test_migration.py | 3 --- .../tests/reviews/decision/test_migration.py | 3 --- .../tests/reviews/lifecycle/test_migration.py | 3 --- .../tests/reviews/packet/test_migration.py | 3 --- .../post_submit_routing/test_migration.py | 5 ---- 11 files changed, 34 insertions(+), 51 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index b8fb3aed1..20c521a9e 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -1007,3 +1007,18 @@ guard message and SQLSTATE `23514`, installed schema 0036 and complete cleanup. Plain archived material supplies its semantic manifest digest; the payment migration uses the canonical session engine, without reintroducing fixture DTOs or engine facades. + +The frozen literal-base handoff removes unused `provision_checker` keywords +from the owned execution/material/AUTH migration tests. The existing +`backend/tests/contributions/records/historical_support.py` selects the explicit +paid snapshot for the actual installed predecessor revision (0015, 0018 or +0024) through the canonical session owner. Its unused award-shape and arbitrary +option parameters are removed: unsupported shapes fail at the function boundary, +not by silently dropping requested awards. Preserve the two/four exact award +assertions and complete/incomplete retained-award refusal; no runtime policy or +award synthesis, producer, schema or test-selection changes. +The same owned raw migration files remove the obsolete current-writer seeding +column/restore calls and imports. Literal snapshots must load into the exact +installed predecessor schema, without temporary current ART/remediation columns. +Every migration assertion and row/custody/lock check remains in place; the shared +helper owner removes unused definitions after its remaining consumers are traced. diff --git a/backend/tests/authorization/post_submit/test_migration.py b/backend/tests/authorization/post_submit/test_migration.py index 092f42402..7bf264db2 100644 --- a/backend/tests/authorization/post_submit/test_migration.py +++ b/backend/tests/authorization/post_submit/test_migration.py @@ -8,7 +8,6 @@ from sqlalchemy.exc import IntegrityError from app.db import session as db_session -from tests.migration_fixtures import add_current_art_seed_column, restore_predecessor_evidence_schema from tests.migration_fixtures import _config from tests.checkers.execution.historical_execution import seed_archived_running_checker, seed_archived_checker_request from tests.checkers.execution.test_material_migration import retained_snapshot @@ -29,11 +28,9 @@ async def test_actual_upgrade_preserves_or_refuses_without_repair( finally: await connection.close() await asyncio.to_thread(command.upgrade, _config(), "0009_checker_material_lineage") - original_columns = await add_current_art_seed_column(isolated_database_env) async with historical_material_fixture( - tmp_path, isolated_database_env, provision_checker=False + tmp_path, isolated_database_env ) as h: - await restore_predecessor_evidence_schema(isolated_database_env, original_columns) await seed_archived_checker_request(h) if unprovable_receipt: await seed_archived_running_checker(h) @@ -64,11 +61,9 @@ async def test_upgrade_excludes_writer_across_receipt_preflight( finally: await connection.close() await asyncio.to_thread(command.upgrade, _config(), "0009_checker_material_lineage") - original_columns = await add_current_art_seed_column(isolated_database_env) async with historical_material_fixture( - tmp_path, isolated_database_env, provision_checker=False + tmp_path, isolated_database_env ) as h: - await restore_predecessor_evidence_schema(isolated_database_env, original_columns) reserved = await seed_archived_checker_request(h) scanned, resume = threading.Event(), threading.Event() execute = Operations.execute diff --git a/backend/tests/checkers/execution/test_material_migration.py b/backend/tests/checkers/execution/test_material_migration.py index 4cd53b83d..f88256619 100644 --- a/backend/tests/checkers/execution/test_material_migration.py +++ b/backend/tests/checkers/execution/test_material_migration.py @@ -11,7 +11,6 @@ from app.core.hashing import canonical_json_hash from app.core.identifiers import new_record_id from app.db import session as db_session -from tests.migration_fixtures import add_current_art_seed_column, restore_predecessor_evidence_schema from tests.migration_fixtures import _config from tests.historical_submission_fixtures import historical_material_fixture from types import SimpleNamespace @@ -57,11 +56,9 @@ async def test_retained_material_upgrade( ): with migration_lock(): await predecessor_database(isolated_database_env) - original_columns = await add_current_art_seed_column(isolated_database_env) async with historical_material_fixture( - tmp_path, isolated_database_env, provision_checker=False + tmp_path, isolated_database_env ) as h: - await restore_predecessor_evidence_schema(isolated_database_env, original_columns) await seed_archived_checker_request(h) lease = await seed_archived_running_checker(h) material = dict(h.archived_material) @@ -123,11 +120,9 @@ async def test_upgrade_excludes_writer_until_guard_is_installed( with migration_lock(): await predecessor_database(isolated_database_env) - original_columns = await add_current_art_seed_column(isolated_database_env) async with historical_material_fixture( - tmp_path, isolated_database_env, provision_checker=False + tmp_path, isolated_database_env ) as h: - await restore_predecessor_evidence_schema(isolated_database_env, original_columns) await seed_archived_checker_request(h) lease = await seed_archived_running_checker(h) material = dict(h.archived_material) | {"admission_id": h.request["submission_id"]} diff --git a/backend/tests/checkers/execution/test_migration.py b/backend/tests/checkers/execution/test_migration.py index d8dfae08e..22b885c46 100644 --- a/backend/tests/checkers/execution/test_migration.py +++ b/backend/tests/checkers/execution/test_migration.py @@ -9,7 +9,6 @@ from sqlalchemy.exc import IntegrityError from app.core.identifiers import new_record_id -from tests.migration_fixtures import add_current_art_seed_column, restore_predecessor_evidence_schema from tests.migration_fixtures import _config, current_schema_revision from tests.historical_submission_fixtures import historical_material_fixture @@ -29,9 +28,7 @@ async def test_migration_refuses_retained_history(tmp_path, isolated_database_en finally: await conn.close() await asyncio.to_thread(command.upgrade, _config(), "0007_checker_output_custody") - original_columns = await add_current_art_seed_column(isolated_database_env) - async with historical_material_fixture(tmp_path, isolated_database_env, provision_checker=False) as h: - await restore_predecessor_evidence_schema(isolated_database_env, original_columns) + async with historical_material_fixture(tmp_path, isolated_database_env) as h: async with h.factory() as session, session.begin(): source = await session.scalar( text("select to_jsonb(s) from submissions s where id=:id"), diff --git a/backend/tests/contributions/records/historical_support.py b/backend/tests/contributions/records/historical_support.py index d5d5f1c52..b33f62180 100644 --- a/backend/tests/contributions/records/historical_support.py +++ b/backend/tests/contributions/records/historical_support.py @@ -4,6 +4,7 @@ from uuid import UUID from sqlalchemy import text from app.core.identifiers import new_record_id +from app.db import session as db_session from app.modules.contributions.records.schemas import ContributionRecordInput from tests.reviews.acceptance.historical_support import ( historical_acceptance_source, @@ -18,21 +19,25 @@ async def historical_contribution_source( *, decision="accept", paid=False, - contribution_awards=None, persist_acceptance=True, - **options, ): - frozen_awards = ( - tuple(contribution_awards) - if contribution_awards is not None - else (("money", "project_points") if paid else ()) - ) + if type(paid) is not bool: + raise ValueError("Archived contribution paid selection must be boolean") + snapshot_name = None + if paid: + async with db_session.get_session_factory()() as session: + revision = await session.scalar(text("SELECT version_num FROM public.alembic_version")) + if revision not in { + "0015_contribution_awards", "0018_task_routing_request", + "0024_require_second_review_false", + }: + raise ValueError("No archived paid contribution snapshot for this revision") + snapshot_name = revision + "_paid" async with historical_acceptance_source( tmp_path, url, decision=decision, - contribution_awards=frozen_awards, - **options, + snapshot_name=snapshot_name, ) as h: async with h.factory() as session: if decision == "accept" and persist_acceptance: diff --git a/backend/tests/contributions/records/test_migration.py b/backend/tests/contributions/records/test_migration.py index 2b6968e2c..e82b9532e 100644 --- a/backend/tests/contributions/records/test_migration.py +++ b/backend/tests/contributions/records/test_migration.py @@ -16,7 +16,6 @@ insert_award, insert_record, ) -from tests.migration_fixtures import add_current_art_seed_column, restore_predecessor_evidence_schema from tests.migration_fixtures import _config from tests.reviews.acceptance.historical_support import ( historical_acceptance_source, @@ -60,11 +59,9 @@ async def test_contribution_upgrade_preserves_sources( finally: await connection.close() await asyncio.to_thread(command.upgrade, _config(), "0014_final_acceptance") - original_columns = await add_current_art_seed_column(isolated_database_env) async with historical_acceptance_source( tmp_path, isolated_database_env ) as h: - await restore_predecessor_evidence_schema(isolated_database_env, original_columns) async with h.factory() as session: await insert_historical_acceptance(session, h.acceptance) await session.commit() @@ -124,13 +121,11 @@ async def test_completeness_upgrade_preserves_complete_retained_awards( ): with migration_lock(): await _reset_to_0018(isolated_database_env) - original_columns = await add_current_art_seed_column(isolated_database_env) async with historical_contribution_source( tmp_path, isolated_database_env, paid=True, ) as h: - await restore_predecessor_evidence_schema(isolated_database_env, original_columns) async with h.factory() as session: await insert_record(session, h.submitter_record) for award in await award_values(session, h.submitter_record): @@ -200,13 +195,11 @@ async def test_completeness_upgrade_refuses_incomplete_retained_awards_unchanged ): with migration_lock(): await _reset_to_0018(isolated_database_env) - original_columns = await add_current_art_seed_column(isolated_database_env) async with historical_contribution_source( tmp_path, isolated_database_env, paid=True, ) as h: - await restore_predecessor_evidence_schema(isolated_database_env, original_columns) async with h.factory() as session: await insert_record(session, h.submitter_record) await insert_award( diff --git a/backend/tests/reviews/acceptance/test_migration.py b/backend/tests/reviews/acceptance/test_migration.py index bb08325ed..db96ba48c 100644 --- a/backend/tests/reviews/acceptance/test_migration.py +++ b/backend/tests/reviews/acceptance/test_migration.py @@ -7,7 +7,6 @@ from alembic import command from app.db import session as db_session -from tests.migration_fixtures import add_current_art_seed_column, restore_predecessor_evidence_schema from tests.migration_fixtures import _config from tests.reviews.acceptance.historical_support import historical_acceptance_source from tests.reviews.decision.test_migration import snapshot as source_snapshot @@ -34,11 +33,9 @@ async def test_acceptance_upgrade_preserves_owners(tmp_path, isolated_database_e finally: await connection.close() await asyncio.to_thread(command.upgrade, _config(), "0013_review_source") - original_columns = await add_current_art_seed_column(isolated_database_env) async with historical_acceptance_source( tmp_path, isolated_database_env ): - await restore_predecessor_evidence_schema(isolated_database_env, original_columns) connection = await asyncpg.connect(url) try: before = await snapshot(connection) diff --git a/backend/tests/reviews/decision/test_migration.py b/backend/tests/reviews/decision/test_migration.py index 6e1c02b50..2bc72ec68 100644 --- a/backend/tests/reviews/decision/test_migration.py +++ b/backend/tests/reviews/decision/test_migration.py @@ -8,7 +8,6 @@ from tests.migration_ancestor_rows import archived_review_ancestors from app.db import session as db_session -from tests.migration_fixtures import add_current_art_seed_column, restore_predecessor_evidence_schema from tests.migration_fixtures import _config pytestmark = pytest.mark.postgres_schema_contract @@ -43,11 +42,9 @@ async def test_review_upgrade_preserves_owners(tmp_path, isolated_database_env, finally: await connection.close() await asyncio.to_thread(command.upgrade, _config(), "0012_review_packet") - original_columns = await add_current_art_seed_column(isolated_database_env) async with archived_review_ancestors( tmp_path, isolated_database_env ): - await restore_predecessor_evidence_schema(isolated_database_env, original_columns) connection = await asyncpg.connect(url) try: before = await snapshot(connection) diff --git a/backend/tests/reviews/lifecycle/test_migration.py b/backend/tests/reviews/lifecycle/test_migration.py index cb4d92a33..aa63b3654 100644 --- a/backend/tests/reviews/lifecycle/test_migration.py +++ b/backend/tests/reviews/lifecycle/test_migration.py @@ -16,7 +16,6 @@ insert_record, ) from tests.contributions.records.test_migration import snapshot as source_snapshot -from tests.migration_fixtures import add_current_art_seed_column, restore_predecessor_evidence_schema from tests.migration_fixtures import _config pytestmark = pytest.mark.postgres_schema_contract @@ -41,13 +40,11 @@ async def test_lifecycle_upgrade_preserves_sources(tmp_path, isolated_database_e finally: await connection.close() await asyncio.to_thread(command.upgrade, _config(), "0015_contribution_awards") - original_columns = await add_current_art_seed_column(isolated_database_env) async with historical_contribution_source( tmp_path, isolated_database_env, paid=True, ) as h: - await restore_predecessor_evidence_schema(isolated_database_env, original_columns) async with h.factory() as session: for record in (h.reviewer_record, h.submitter_record): await insert_record(session, record) diff --git a/backend/tests/reviews/packet/test_migration.py b/backend/tests/reviews/packet/test_migration.py index 1dee48bf8..45e73b58c 100644 --- a/backend/tests/reviews/packet/test_migration.py +++ b/backend/tests/reviews/packet/test_migration.py @@ -9,7 +9,6 @@ from tests.migration_ancestor_rows import archived_packet_ancestors from app.db import session as db_session -from tests.migration_fixtures import add_current_art_seed_column, restore_predecessor_evidence_schema from tests.migration_fixtures import _config from tests.migration_fixtures import current_schema_revision @@ -48,11 +47,9 @@ async def test_packet_upgrade_preserves_existing_owners( finally: await connection.close() await asyncio.to_thread(command.upgrade, _config(), "0011_task_routing_source") - original_columns = await add_current_art_seed_column(isolated_database_env) async with archived_packet_ancestors( tmp_path, isolated_database_env ): - await restore_predecessor_evidence_schema(isolated_database_env, original_columns) connection = await asyncpg.connect(url) try: before = await snapshot(connection) diff --git a/backend/tests/tasks/post_submit_routing/test_migration.py b/backend/tests/tasks/post_submit_routing/test_migration.py index 9033a6bb7..c2b10ede7 100644 --- a/backend/tests/tasks/post_submit_routing/test_migration.py +++ b/backend/tests/tasks/post_submit_routing/test_migration.py @@ -7,7 +7,6 @@ from alembic import command from app.db import session as db_session -from tests.migration_fixtures import add_current_art_seed_column, restore_predecessor_evidence_schema from tests.migration_fixtures import _config from tests.checkers.execution.historical_execution import archived_completed_checker_source @@ -81,9 +80,7 @@ async def test_upgrade_preserves_existing_sources_without_publishing( await connection.close() await asyncio.to_thread(command.upgrade, _config(), "0010_post_submit_authority") - original_columns = await add_current_art_seed_column(isolated_database_env) async with archived_completed_checker_source(tmp_path, isolated_database_env) as h: - await restore_predecessor_evidence_schema(isolated_database_env, original_columns) connection = await asyncpg.connect(url) try: assert await connection.fetchval( @@ -124,9 +121,7 @@ async def test_request_upgrade_preserves_completed_owners( finally: await connection.close() await asyncio.to_thread(command.upgrade, _config(), "0017_acceptance_source_contracts") - original_columns = await add_current_art_seed_column(isolated_database_env) async with archived_completed_checker_source(tmp_path, isolated_database_env) as h: - await restore_predecessor_evidence_schema(isolated_database_env, original_columns) connection = await asyncpg.connect(url) try: before = await _snapshot(connection, h) From 3f87d615adeece3e3959de4c6bd1022202cd16c5 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 15:41:40 +0100 Subject: [PATCH 238/283] Remove obsolete scratch upgrades and migration seed helpers --- .../pilot04-workstream-default-checker.md | 17 +++++++ backend/app/modules/artifacts/preparation.py | 39 ++------------- backend/tests/migration_fixtures.py | 48 ------------------- backend/tests/test_artifact_preparation.py | 15 ------ 4 files changed, 20 insertions(+), 99 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 20c521a9e..bbb719b3d 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -1022,3 +1022,20 @@ column/restore calls and imports. Literal snapshots must load into the exact installed predecessor schema, without temporary current ART/remediation columns. Every migration assertion and row/custody/lock check remains in place; the shared helper owner removes unused definitions after its remaining consumers are traced. + +### Scratch format cutover cleanup + +User explicitly requires no backward compatibility in the selected checker flow. +Allowed files: `backend/app/modules/artifacts/preparation.py` and +`backend/tests/test_artifact_preparation.py`. Remove the superseded scratch marker +upgrade, version-2 ledger coercion, and their upgrade-only test. Retain current +marker/ledger validation, concurrent initialization, bounded scratch custody and +restart recovery. No retained business data, authorization, migration schema, +provider runtime, CI selection or resource limits change. Verify the full scratch +preparation test module and independent affected source review before readiness. + +The same cleanup authorizes deleting the now-unused `add_current_art_seed_column` +and `restore_predecessor_evidence_schema` functions from +`backend/tests/migration_fixtures.py` after the raw callers were reconciled. +A repository search found no remaining callers. The separately consumed project +guide fixture context remains unchanged; no shared live consumer is deleted. diff --git a/backend/app/modules/artifacts/preparation.py b/backend/app/modules/artifacts/preparation.py index e7d13479a..b2c416832 100644 --- a/backend/app/modules/artifacts/preparation.py +++ b/backend/app/modules/artifacts/preparation.py @@ -1167,7 +1167,7 @@ def _initialize_layout_locked(self) -> None: os.fsync(self._root_fd) def _validate_existing_root_marker(self) -> None: - """Require exact limits, with a safe-empty upgrade from the prior marker.""" + """Require the exact current scratch limits marker.""" descriptor = os.open( _ROOT_MARKER, os.O_RDONLY | getattr(os, "O_NOFOLLOW", 0), @@ -1178,25 +1178,8 @@ def _validate_existing_root_marker(self) -> None: marker = os.read(descriptor, max(len(self._root_marker_content), 256) + 1) finally: os.close(descriptor) - if marker == self._root_marker_content: - return - if marker != self._legacy_marker_content(self._limits): + if marker != self._root_marker_content: raise ValueError("artifact scratch root marker is invalid") - ledger = self._read_ledger_optional() - if ledger is None or ledger["reservations"] or ledger["workspaces"]: - raise ValueError("artifact scratch root marker cannot migrate while in use") - descriptor = os.open( - _ROOT_MARKER, - os.O_WRONLY | os.O_TRUNC | getattr(os, "O_NOFOLLOW", 0), - dir_fd=self._root_fd, - ) - try: - self._assert_private_file_descriptor(descriptor, expected_mode=0o600) - self._write_all(descriptor, memoryview(self._root_marker_content)) - os.fsync(descriptor) - finally: - os.close(descriptor) - os.fsync(self._root_fd) @staticmethod def _marker_content(limits: ArtifactPreparationLimits) -> bytes: @@ -1221,7 +1204,7 @@ def _marker_content(limits: ArtifactPreparationLimits) -> bytes: ).encode("utf-8") return _ROOT_MARKER_PREFIX + hashlib.sha256(canonical).hexdigest().encode("ascii") + b"\n" - @staticmethod + def _legacy_marker_content(limits: ArtifactPreparationLimits) -> bytes: """Reconstruct the pre-04B2 marker for one safe-empty local upgrade.""" payload = { @@ -1640,22 +1623,6 @@ def _read_ledger_optional(self) -> dict[str, Any] | None: ledger = json.loads(raw.decode("utf-8")) except (UnicodeDecodeError, json.JSONDecodeError) as exc: raise ArtifactScratchIntegrityError("artifact scratch ledger is invalid") from exc - if isinstance(ledger, dict) and ledger.get("version") == 2: - if set(ledger) == {"version", "reservations"}: - ledger = {**ledger, "workspaces": []} - if set(ledger) == {"version", "reservations", "workspaces"}: - ledger = { - **ledger, - "version": _LEDGER_VERSION, - "workspaces": [ - { - **entry, - "reserved_bytes": 0, - "maximum_entries": self._limits.maximum_workspace_entries, - } - for entry in ledger["workspaces"] - ], - } self._validate_ledger(ledger) return ledger diff --git a/backend/tests/migration_fixtures.py b/backend/tests/migration_fixtures.py index edcdaf8ab..37ed595e3 100644 --- a/backend/tests/migration_fixtures.py +++ b/backend/tests/migration_fixtures.py @@ -101,51 +101,3 @@ async def current_art_attempt_seed_schema(database_url): assert await connection.fetch("SELECT to_jsonb(r)::text AS value FROM public.artifact_put_attempts r ORDER BY id") == before finally: await connection.close() - - -async def add_current_art_seed_column(database_url): - """Temporarily admit current ART columns; restore the predecessor before proof.""" - import asyncpg - connection = await asyncpg.connect(database_url.replace("+asyncpg", "")) - try: - columns = await connection.fetch("SELECT column_name FROM information_schema.columns " - "WHERE table_schema='public' AND table_name='pre_submit_evidence_sets' ORDER BY ordinal_position") - names = tuple(row[0] for row in columns) - assert "semantic_manifest_body" not in names - attempt_columns = await connection.fetch("SELECT column_name FROM information_schema.columns " - "WHERE table_schema='public' AND table_name='artifact_put_attempts' ORDER BY ordinal_position") - attempt_names = tuple(row[0] for row in attempt_columns) - assert "task_import_source_id" not in attempt_names - await connection.execute("ALTER TABLE public.pre_submit_evidence_sets ADD COLUMN semantic_manifest_body jsonb") - await connection.execute("ALTER TABLE public.artifact_put_attempts ADD COLUMN task_import_source_id uuid") - cause_originals = await _add_current_cause_seed_columns(connection) - return names, attempt_names, cause_originals - finally: - await connection.close() - - -async def restore_predecessor_evidence_schema(database_url, original_columns): - """Restore predecessor row shape before snapshots, upgrades, and concurrency probes.""" - import asyncpg - connection = await asyncpg.connect(database_url.replace("+asyncpg", "")) - try: - await _restore_current_cause_seed_columns(connection, original_columns[2]) - evidence_before = await connection.fetch("SELECT (to_jsonb(r) - 'semantic_manifest_body')::text AS value " - "FROM public.pre_submit_evidence_sets r ORDER BY id") - assert evidence_before, "historical fixture must retain actual evidence" - attempts_before = await connection.fetch("SELECT (to_jsonb(r) - 'task_import_source_id')::text AS value " - "FROM public.artifact_put_attempts r ORDER BY id") - assert await connection.fetchval("SELECT count(*) FROM public.artifact_put_attempts " - "WHERE task_import_source_id IS NOT NULL") == 0 - await connection.execute("ALTER TABLE public.pre_submit_evidence_sets DROP COLUMN semantic_manifest_body") - await connection.execute("ALTER TABLE public.artifact_put_attempts DROP COLUMN task_import_source_id") - columns = await connection.fetch("SELECT column_name FROM information_schema.columns " - "WHERE table_schema='public' AND table_name='pre_submit_evidence_sets' ORDER BY ordinal_position") - assert tuple(row[0] for row in columns) == original_columns[0] - attempt_columns = await connection.fetch("SELECT column_name FROM information_schema.columns " - "WHERE table_schema='public' AND table_name='artifact_put_attempts' ORDER BY ordinal_position") - assert tuple(row[0] for row in attempt_columns) == original_columns[1] - assert await connection.fetch("SELECT to_jsonb(r)::text AS value FROM public.pre_submit_evidence_sets r ORDER BY id") == evidence_before - assert await connection.fetch("SELECT to_jsonb(r)::text AS value FROM public.artifact_put_attempts r ORDER BY id") == attempts_before - finally: - await connection.close() diff --git a/backend/tests/test_artifact_preparation.py b/backend/tests/test_artifact_preparation.py index 246ebba3f..b4d56ecad 100644 --- a/backend/tests/test_artifact_preparation.py +++ b/backend/tests/test_artifact_preparation.py @@ -1355,21 +1355,6 @@ async def test_truncated_version_three_scratch_ledger_fails_closed(tmp_path: Pat ArtifactScratchManager(root=root, limits=preparation_limits()) -def test_legacy_safe_empty_root_marker_upgrades_once(tmp_path: Path) -> None: - """Upgrade only the exact prior marker while the scratch root is empty.""" - limits = preparation_limits() - root = tmp_path / "scratch" - initial = ArtifactScratchManager(root=root, limits=limits) - initial.close() - marker = root / ".workstream-artifact-scratch-v1" - marker.write_bytes(ArtifactScratchManager._legacy_marker_content(limits)) - - reopened = ArtifactScratchManager(root=root, limits=limits) - reopened.close() - - assert marker.read_bytes() == ArtifactScratchManager._marker_content(limits) - - @pytest.mark.asyncio async def test_ledger_read_failures_are_explicit_and_bounded(tmp_path: Path) -> None: """Reject missing, oversized, and malformed coordination documents.""" From 55492438cba8d274946a94e838b04fa54626144a Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 15:41:17 +0100 Subject: [PATCH 239/283] Project checker snapshots to predecessor schemas --- .../fixtures/pilot04_predecessor_rows.json.gz | Bin 791277 -> 787235 bytes .../tests/historical_submission_fixtures.py | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/tests/fixtures/pilot04_predecessor_rows.json.gz b/backend/tests/fixtures/pilot04_predecessor_rows.json.gz index b1065d88435f1be944345aef61078eeacae3005f..fcc80505e530e3957e127a3feaf1d33d4e10d4e5 100644 GIT binary patch delta 779749 zcmZs?Q*b6s*sUGgw#_GYCbn(ccJjowZQHhOOl;ee$t2nD_kaJ%uG(i^-3Q&(bywHA z*Sh+)3{VmdNW=#|c$c|v32dflm%u|7Gen_74Gt+CIXv|Iux*3v0uX0WM3K0E#}$?@ z?XH=#0gNOu5_*yQ~0j_2_BxknS3% zn7dxzqYneUIck#(8JozTPmYTHpe=3Btyw~29_U;5Z7_%nzBxm^fA%pNF}>E~CPe=@ zFa3kNWvCbde_p{Ojy1~l$jKfIytkO)8rhs4AwZm&!0K@93DIS)KVvm3FD;WUt*m?+ z;;CXYrya6^)-o2ZJNqrf(R+B!Zm72ZY0vxP-V_Rq>cpRwIKE7VxljyNs2DThWtQad zk}qnQ!(dJ%fg$w~;8|I7X&-jiW2ksU+%rfSj@hFwQqFYoD=KHy`&=vi8%nG=(oixr zvyFYSvV9|A>WB87+cgIE!(OoWeRh^|1&g!U9mNN|!s>F|yz9lKlbRwJ{Tug+hMEjh z!^Z$K~;D%BR2%09dmBi_Yg>87q{eBBe zCHMmagP37mgE}u#MEMwIiXq657uukb+|s+-+v0VasrF#-IstD@k=7W@@cX7Jbr~QX zoXP`r%1~x-aTA6j*K>pRz5`_=#m-NG8C4GC(2Wh=zKov?Tj#-&Xw(|TFjbfaWaxGA zdO9>ifQA0Vy6D_^$bsZ(-Svefc->{H)4_pcm8P`^4Kj>?XXzRnAE64Ta5W0nH8bgC>&}Uj z4RF_Wbiio{{HX;qqFiK9;N@r2F+nep&Oc&)xU*@x{JpLC9&g1N1{t6VruWxBO0T!_ z;Ho(SQV9(`vLnG!i2UMZra4NMc$pvgwQm#3%9Nm_r2p6H$?Z-O73-257gwNVe`==H`8h;nS@z(le|;F7TPqU zm)Hts&9bJB{>m*o+b7lBuDR89zmT2AqIVq*7q)Xr%1?rocuvJTCz&V!bI`i1ht{@I zP5?thn)r%$|7xh=Zi21;7*=Y^! z8!y$t1s~3Du+_D%+-*FSk*q4&Ar`9^C%6z953!m3-ipKYU;X z)=_%cC(l(JTYw79W!ImPrfFzFzS>a zt2_z8Cbn$4#XsYWJGgZKNta{@k*d&QeY^fNiaTxA_PWIwdI}EAP3|@&P&EikMk;2f zY^J3Y;8J^9V|@33R7a$Ft&FUG-W;BjWNjSxLln(6)c)($@{XbR9eWCZUTir!d}YHX z%^XY1DWK(YwE6(>-Shq`0H^nq^hXuZHrV{*-Sp^lY2om3g)!9&oOt{p@bYH6Sr=n0 zU}vtOXa2=(uve^H`bB4U2H+yzeDgud-NkznkF@ePzdj#Zw+9mt7Ak1m{$%i|0>C`1 zxy9ZD<|I*$+#X)_U`W>V`1|dK&i65ob83zUSoGf#q6tV_^q?%;MIFwLD2;c-?>ujH zY;l2RkaXP&LN!zYFQyL_6G!MD{JBFMo2a924SkM0V&6pIjP2p##S3VqC1B}OCfC`h zA>h3^?#w9vDyuZ(YF)f(Og>N^X>_DY2ChT#c5)8 zte@zPiM!veqDpW3b1tghmeIzx6&vx&Fr#SZdPSl#C`0U%_LJu`N1{QCdImfZL zC{?*pa3N#(SOVSfG zy(d{LOu?9RtjxXbRMB=|>O1pHGZ-a6qxcaMXa%oyR-XI7n=mS<%1n{- zu#{NvCCC2ufdV;gBer??<3knaOjuDIW70K8rZ=bIzwZu)h>xs^7jDxM=C+Kl(KO>= zX~CrkW>cy0219mm7E(wWtQPuU!Qlz2yWdCOdoIv@l&lzmP+bREtbrVs#p(E=mv6K< z=Cw#be#?3xABw_`8(eY`D0#}k-1k|p={_a87!>JQen}yzf}p&}t=8>ZxLzrE`4Bn; z)#`_Q21g6pq(7Uk>!T`WN&_DXpHub&CcODM~)arq;8 za8oXLEAyoN9fm^(p68I|=&HN)C#N{C0V*YFs+vcf)cE*xh-N`=a34k-_;5>lnl=R` zc%TKKVDRBcnNHGp9cBg!%7(l0MokhZ%FzpL$gpkDgAsj}14-)TdETIK0j^xJMK$a;}NDRODP6qv|NsHMF=2H%306`CANM?Y! zzYa^(-OX&E3K^?G-iCfTKullhc~syk=0cF8fJ?q}Rt-EhaSk>386z#`)g7iySqXP6 ze8=~3$`x}W!d${>!Q28&+^PrDmG1M|hxhA?861cwS6t2XPUf6sgD^R;o^Pl7ubC^) z&5j-KfYjpQ=~;vL$Hu=`7$r=qQhxC6=Nampf^a@$L|tUYih*+J=Y2&7p!Fr^tvXPh z=|f`DJ>T|r^;kjkRK!M`#atra_^&{$raNBYI$El9RCSU&k#`$dSmmYlaV=;v0obFd zLZP@f85NT9IRjUY1hXVCpmC#{Fi&idB$-koM$fVZ!h;$F*To7V1b zmkaTALJBDY36R<0$3qqQ+=8{wTJb?1C*hz0KlfbGQ77f|a?TA&ab9B450aBh9xXR# z$>jNR34#~)mmRZl^q{}FZY_LtBkknHRfHe4g7uc?W$t1 zT+)-XJ3UP5dd1zrhm9o&&Fa$IWtQch69iAhAuJj>&SoRd@&n;sS?o6k9?dYMtspdz z>U^2P>A*z~oo@8>-iMV-w85#lyPiMEQVs>zN5BTlI&SAVA_=G+o5iCxCM840+_b^j z=pft_FN@C6B7?kkJ{13pXfd6D+1!qZ!kfyZ9B&n^9D8=3gJ>eIsZmA)FCd+X8S z*8S`#->d7Lz1r$@zecHS9N$4ZOM6f_ zZXokPGytAg@X(oO`cF=7NGL4qzUhE)VV7~Yov?5qH z;HY@ycr;KQ*!0`~sG8rZXs9v*SZfv*0St$yGF?`HWa8P@wsHf((D{H#$5t0NA{(b6 z!`b;z#>#FEI>^3SS;sAaI#u3Ii0S&oz7V!`fT`TbhEe4vDG))!1f%n3zmYNb!b)Sq ztCq(f!8{iZ#d!`mV*=uo?i1pLzAsJE5YvbbqVPDk9XgwLb?enLZB%nRD-(6k17WZ^ zu@y>MGG=I4(W4~V9rFmoKUfy~MQFI2#Kb|PjV@~0nq8co)D;)IoOZcMRcV|m@Ra)ri>Sp@*Qc;n-Dn`<-wR)it%M z4jLFDAEkp5cV9JeWTcA7JHk*4z2K{jG3{NpVy=f@ne`S3h;=#*1$T8idzNO-yks#8 z6N19sJLOaO`uH~!sTx+icxA5>ldBs#Gu;$p1Kc}o`dX*}3#s2yv+y^bnJ#p_;Z@DESmSx5cFJh$Z>*KB6eT=I>ZOrQVnhT zRQ09b6zY?se+j%A`FHO=PJ){5`8|!W-uSt4+^IazqkMqKHDC-X^s$m=Q=)Dd7_j#Q zu%WVteY04lY7f%oQd!Srz+gntKDKP=blS4$;T>Ok9o^(}N1uq!t^S+%YV|y~K}0gG z+ojH|3SRZwDT9%-kM?A|cUH%pnchdh^Z1epr-x%Wx@X2#X+Sl8e`uxnFyW#*^)$Jx z)CLY`pWyMS#>{2jNbDbP_K1w?yy@qmMNaG2pxI*nw)O9wvyQn5VD&y$Pl3+dk-)km zxtO5f*2U|Wf%Wls>k>?3gvvy^Ww$6HwEoI{f`Jd=XT=Kq!@_i2#9VVbv5#EwrF#kx zMCFR%P21RF;&_*|RKTF=T}s5?;F|t~K!2uXc`82T-$-vXyS`RZPno1QdnGo4>m(u+#D;rH8bAOu zT6ivgN|l6Uhau9lL^>7-^$a6+HTu4 znNkJk${+P%l-N}SO^4WruQS8T3FcN33EB7ui$YMxGG3RVdPDNJ^Bj)utg~X|-x~ zQP%zQo%}(p46_M<#qMe)?vq#2C=noZWOGqrQ1LFN*|+V{=Z0A^AW!G9m$*DPF7Fyz zx*CXAAN5yDDwSAyKFMNK(o}>J*s4q0K$&g$Y{9 zhq%GY zbHNn{$XG2p9T@QYX%YnB53Yx*e?)efXsH$FsSNjgQ`x|m2m=_=$ z;AlpcZ&`2BJPvc1Nv@!b#<<~hiL1$DgVs6=B(uU~-O#>)TGYKlp_gaMC9iFa$1kaZ zaF0;iTt1>p)$Vz|wCxC}p-M%OVnVXMv~C+f z>+i8D$*gvi)|-bkp#riX3AjNi`$J6dBr5^r+05MO(r9eq!h4$428@qY8rCBES(7X3 zKM{Ck!NJUwDNONXpDuTH$`lqi-qk0ahD{7ThUXyrMRV%*s;Sz9^nd%PU*jY*lWcl4 zrZ)e4Pa@d4SI`|llR|p~Rk{;V^VJ7{orx?3#WVY^H1sPwGn* z-Ikrc2HzSEtpb&iaz6xHpob#OagAHj!C3Hwp)_)Z&68Wk8qDLNl7<^zf6;3A5NtJt z=&7>}<;gNnTp2*nw?n&cxzOGTk`iy!MKr9rv^^B?h&=6jT%7C_)Zhl*OdQ(j|Im9<&)| z&ev5uIq^4kzwEGFvs7IIG$oqGjJaNlrYra=^S6?swxC7aS~s;EjpGiO@hPbdw9k`| zS)|6Y5~nRQ*fRgdhvmAm=O+;WFG0Vm3xs;eoFfE%t$z*}{`sJnqm5N3e5t z>&pvs*sPuiYVUgUU&c;q_2iw^NXNj)nhl1po6S5-@KmbBO-C9SGv~R$CQgiL!N@-_ z+rm>vatX04^11s0Rbs6#C62qJb<%>n4yE19?oNutVc~voOw>SuUYLPE<*wh7Yj`V! z+JpFI(#DK_9MD+oRn0boJ90rK*%VjT{BP2%O5QD)6wNe2&?b=zIO&ySq)r(yB~r2c zka40@a+a6~8LK#h2ZRhYXI_00G`!U+ZZ(vZu4S{C;cNQZdGL*0tGDYM7v*cl*D|X0 zeQPlb3MV`Ev$hLya*(~i9C-3Fn#lKcS-JLFdUZTl9Ny*B(Gg-JF}^sbS;bsCV}=7t z`CzaGUS+MB|zf zn95-3AWeskssnqv5Lvn*jJ2*@UL0OBTlWJ&?rtnNb z*-n^2ve)EEw5{+cU|g_?H3n9%K*Zo57288CUYXGYFBJ<~eh}W~5X8cB_CwT=y#IZQ zTIf2etLZ8FOLJ1+!0^|0Z;nH{R?~iz)|N;*wY3&o*qB?Wz8n)swogM~Oy6c6`Zeo&e2G z1|nF1JC+anNk6$~KWt*(f{HUKE=2slPAUfFQU@GQ8pwH&M1FAXK9OEpkfFbNwu?WD z3i{bz?%g3@b%GM$Z(i%?%|SkKa}6Z}31NolXj=v0Zm6Li?La^0J??!WKLQGlQ=Sq8 zbljGFp+8hdOyVPhc2T;(O$NgZsaN(vm<{`ZrY~yp$Zhnj-J8vFg?^515wuRw2WFqm#2O|k<+1&gIX)ngL)Z^6uy3c_*X1c zR%F1LUTv@%Hfaf*ez}{_pOs`S_}~}0MCVJWy(UoN^uufSsV*)wWkw68?vzz;IPgaU zp{;E0Cpf|s?P7nB#huT0HoWCbLUC1B0V|3z@?ig%?r#15qJa4XZmE?!SO@Urn`kRh zb`)B(mCqTO>V)#ZJY4oNxOfj&kX7o&LZ72|a7xIwcjwX}){Tsx38o+Nk?h;3Sf~mGP z9c$W@{~Cdx1}M3Vu3uK?-yPdl8^Ath9Z}6zc?BakfDE?({d;$7ZwRX}6I0N{*2d~91OJH{(Esw7Q-C%bx z&^CTDBxlkeMXm@2{Dp1{chHAKVkXEkU18ImH z?L~yLM>p3n_5-@Pay$1)HTytOwkS@wILEJ`%hj!+Zj_;T@s5f$Un3`uFCAeZXFllK zM66`vPTuuJVae+wO#xN0L5%RgXM!pKRUr@jnLS((6(bKUl$D{xg!Y@Dss(!`Q@W8K z4HbmHIv*b1;5C8uJFVh*)urhzGH%b(t`m!M%UBKV%lR+I_t9052TAcvCXh&N(#3fW z4cY^VOSdBiaT$kuLoE<7WUMA6`yXlb7Sm6LPAL9Ignm4-#c<IpVQweqadpfFuDalg6F5kr@8$FN+2goigMNp9 z2Pr5VlL>whDW{k(&a?8{TR*h?ufRfu=LpoynAdK0hWxFhS$^%mtDwztlJ%yd&$1O=dM=Q-q z9tBJjN^K`fBMf^74ueF`n-(`dWp7i64Y3vmNkQPyps2#2;EsxFRw`C>igQB;k=`c^ zqX|~R;>^Zt8{h!vT1ZKPa}gIH!+b3dmX$iWu79&&Xn-r-RB=iwcMb>A4NZmk|9%&{ z23e%-sZB%|8Z=07t(L>O z*$kwaTZ}4L^39y$1sG|p+R-gIBPC>QYE(SLAlbB;>muBmnJ~OW8!AC%xCk7FZ>g;6 z(J;dI39CS=BI|-c(Bv5LvrSjXe}yw}B@19x|8o_I-CT87ET!w=^<( z0d1u(Q{WySI5z0T>-afpClnq_u0p$~GvZz}OS@CD_y~t3ocV)6Br2D6kij=pS8W%&IQ49cwRiZVP3Yh7N|tV2-d& zN*Cmr!ao}B4wO1+-hd>&xVneyIi9ymF9;#RmELLJ08lM^2KQ(-sPUBN9V<-k6rxCS zn+C?XWy{1aDiC+AQ)9F;X!#smYa00MF3B+)q(zV)&#=T{tmGOkFGjFLn{v5E9AL}Q zMAH@$h`|=LodTq-{PZg3MV>J$)}}2ESKA`(liXl85K54)5i1#nJU-ZcnkUU15zhiR z(1|G1Qml7D=2`#;tEYSDQ3|^#=1Z?47`vT~V|W4a<7K)eiC_G_3@h?C^=d@Qa}y*# zy#_Zt52;#fW@hkO$_zkzVwKe*1Jnt$KV*E2Rc-Jt6{EAsBah-%Dla418y*#RpjpGY zd9U=c*H&UtRU(gt=v@yFcDN1F677<-fyubS=*3zG`1}+KAQnI-lNzzXmB>!A;+=%X zEKpiC{Li6#p>EN~KiJ=~)d7X9Wy9zw*=TbF#QX=0OkziyO{>S1;T$JG8drJaGEs0? zH@k-1=`8}ydRe)VEtTW$9LwR;JYv3ue5lUn7oXGs+mkcYMSm4zVmaOOw$NWgg(agB zN+IBidrnI9SzI7JxyPF*P(F0vL2%VBkyyKUxuYb+m~ONwRQU4n#vwEibG=U5i6S&t z+LKeK2MVD2AaHLW3E>t%t;bzxExKE^q)ZPo5z)dbe(c5Dyr6T8H{q#3E5ubGMtYCd zL%`u?s^mN21yyK>^;93NA6D^$U~n;o8%FN0&j)0^LYGY@l=??ElnkuXTKK?iH8XP# z`1nAz@=zD0!m=VVP&3Km60>QSh29tm5VK$PiXqmRCC<1wlF+fhQoY6N>_amtIK$A~TRZnDiKMH2QfCw$aD-Fnf^gN?Yl@>?9v~27xXb z#6%8SpU22QS7oG=e2{jaHe-prA+Tq~HBvH#4Yo_F?ARJkXd3>P!DgW{iHES(5-kT2!PrU6{G(o(b)iil;yF%2}4{7!0D%=lomrvbY6h${_nlg7Um*^*^U45EB?MBa0P2o!5Hs> zIFOe&HjWhsOTi4cQ7P}=FhnfQmeIPuK!*W2b0GsoFn9t2fUmnY-bK*(mMh`{&8OXs zkB|;rXxWuAsWUWvMuo+enQS$BS=>wD(G!KjkQw8&Nd!sSfx;RVr(<%xm(IwGURTBe zwajK9CTSSoprKJlIB-KkOHQ<7st@|OC=%}pM=SFnB$H2xE?AK0qcv6{fr0|qe)oAn z2^0Q^?7=|3%crUmu1WP`b{uJ@bZMMQI)*gZmiHoXHQ&0w9{7a3&5#LU?tz~Yk`W(H zY^eU0i^$-+6H$BEW%u!K|lH5D4)ql^baVk_74~h@|s+ z7i9^;Zcwf?w{f_$)=Sa>V3C>aMvsSCL;RL#C1340x&JGM;s3T~kHjSpQ_aOD1>mJn zXIr|X)zg=i@!xn3wNN)2)yF~K>sl-R=Ra+a^)-f}kfab=S%jJD{Y`|FY7xwk9o#v> zwdK!}g0qH1jyAn&@L!^~f2m>l*Id-Ib=FI9VIh)pBIUt@Qcpo-^r$S!9I}yxa-L-t zjx%c~RI;9xHQF2j1QCTby(BBtm6g8)=RZSr?@VNMc&!-LPPdcO3uJt?E9`NE$_L`Q z;S2j9DHtSu7AN_(KOHX}t(gb5Hz&_z8q*~*K5B)bQPIV4%kz{4!RIH(Do`cl5DAXh zNXVGPHx_H_L0IX|3u$)$vZCf^nhj=@OKxq{hCfr2t71rhVG!!^gv!UXdImMle*L3d zU+G`Oqw_d_9Ro|dnkCujW6i0+g8;+?$3U7Ln>9yK0gF^+&YBB%2GgG{Oo9)zVU9Y- z`}@^N8a4%067(loNl0Wlq{snQsSr9Vxoet&FaZQwqh!(5<;Pz(MBaJ<^KPqY7%r=< zP$Q+b0M_VzVX(!;?>We5G_%4R5Mj&%%0F36;H-6x=Sdey+dLh`19fxdQwY>K)b_m1 z180*FO=y)xs#Ousey2S|2(p>3xS4h)YVTFb@A(nv$* zg~`al5|oWy*iq(%pDHmTFGf3CSojv3#av{v-c#tNl^~;&#zs2n&O{{8^j=t##1uen z&H^X@umct^5D=9!UX@P;G(@W`;I|Yy${}pE>kW9ijmP{% zO5+wv-Q=VEG#coh>#ApryimIhax-R&a1~8kIhMnQ`(c6cs^{ybC-jjAU&LZZfCVyM zyd+N;SCQC5MDd|CqziGpyFUkWk5&Xme~jJn%Q7fRt7JE#lP*Lb6|k;lhN89`KOjtd z%M_e5u*+5#>>34eRj8Ih1kK0}tt1&C=S&9_X5!e=uxqSlE^`nsCVjN9mykH5v<{Q#GN3MiumCv3Lxkg2|?Wd%p2SqfsnONDyQqV=*I%CFE1-#S`}85PYIOs~AIp3G~^!*{ymu?B%6 z0zqB8EW*p+YG-^C6$MibV@mD+BV{~!u~ zrLM9WdLDO+O8Bj?JS7oTNiyKMEX ze>q<*Mpv|muVbYV9?7nRO_m9}#7WH{?1Bo_IpMgy65Dsl?!f?PM#tdWzW_I0EMys{!{)cJG{jfqq)byavH7?!jvio2>px`$>Xg1(&0*Jn5!Ksx=H_s<|CdI`6to9aPZ|wezGiOPI&kUVxrYZK zhP>J{kKkkR;Nb5BB_9YGra={Eb>g@rF5`#_fQOMuUIAT8vLa`NZo#q8mFY3u=54l==24Eu~V9e=Okzx~%(c&1DLe`Al= z|E$6Poz|#s!g7O;{|IM%6vr4ePDY_J4d8dolqKK}r8!P6RK^(!Zk}edNo5WEq62*b z(#s4*gC$Iy(eLHJuIm&=nnkt|L) zh!+w;%vInDHkYUZWf;_%FpCzYi#8`I7-WZpXGj^Q z6BQC*F9eMDAvF^6RS>+NirpEIexi};8Vfj55j%m9A3!+(s+`76Xq_|U0JzWk{MeIs z|A{WRX3R`Sfwk_2ME}FYU6)s&#y3BNGhilv*x~te6P8MdHoH?z>-y0y-g!sWBIK8W zNX}Idi2N;R+cyKI79Qf@2(LB#pE>iGJwuxU*zmW7!7_VD*;$I|F36xn9-1eL3W~U@ z9ft`e4P*r6U_vI-X5(ev&5h4}7^(}GC^fA089gts>TI^`j><0h z&E+3=6M5@SxDpIkybYGhg=GpLNX}u;rQTknXH4oE~%1t zIhm5O*|zRGNzE%sNx&MyqIKSMiYv2+NBpgwDou3!k}bnMm8vAH+9!Ms>J2Y>)(kbNrdvFq#26A|E*!YzNjeLAyaIwpmY4G=d4K5~tb*hR((~O^w70f^W ziAJpoxO`7rn=Y`3^Vk|2!4ug#sRf*%AL(Q#2E(h8+HvGfW-e#0G13(&@v$0aB~tFy}AaMjOnRn!-1oqvf^Ala79w4 zu?++tV-hSN#76`1EQkW*1cQESlsYM226NlE&PR*C`875<{?|a-sbLLXz{Md)jQ__s zpm<_h@)ClJe4VfVXRVI8+*#oK;=!*th05dXcq^AMC7|~|Ce{8ghXzDu^N>ng8{e}E zut1jmLIa=Cwvbo}Zto=8hQg{+i6>^5Wr8kjLT^D$#(x72qk51vNm4?9pQLky1@@J< z@S=HlXdu>BK4J_Oj0Zn6plJen13`V=rHlKIs5Fw|S}ebMfvSwhys;hb;E-a^JrkW< zODCsJNr`?L>I24LhYL#M^!<2!e(s+$U$%7|3!hvS*hAY)LoVO0gnWjb3q^5PzeoI4 zmTm=ToEv~_u=4yDRGf|4GNI`<2myHeg?ukmiE@QBBtSUf+W#A4@1j_Q9DreLQxKpzlaO9vpa-jTp{Z9ZYb&tn5JJfEZ$N$R^e+bH^taBM zKN;Ki3@GSl;@1z6af|;X(%jYr@6sQl1+@Hglta-oAM#StX$Pll#Y@Mtp)!g(fD9Gad*2t4u_uhA@vpy$jXrleA*) zUKJb!#gPXhrPZzP2CX5HP7)Ey=V1tASXmPXAQ}x3=VBR>N=YgQ+#&RF`ex1MRzh@G zZv!X7YHKBMN0#OoIFMV1@8Kkn89Dd(nQm)_Rh!S;3b^I5^D*;&^E(nu@vnCSBka)5 z6134$)pf0{cj&#op}S|_zizmOKrfVr0tbL94IhB7h&Z7u)F@PEk(!`WcFC(6G4oXo z(wwSck)bqZMLCHBB?{<_9o&r6UHS3-4NpJs6>`w+}Fv<0^;dxrq)d(pw8Y^;WHCt2uv z4a(Kvk)BKkc6=DyjI2<;t4ca0k`lnP+8$-4u~Welpmc(a@rdI>%5g$fnWO3><^Q!BxY4uYUSH#10x1ukO-~TAv^-13 zwgXQN{4*l)DQmg#tcBL|A7Sk##63<$xO;P3L(u7M`I}lq(UD>=j;gHW26SvS+ruDX zr;%A2^9AZ`OIz2g@e#h0tWhC9nRQHMQ--I;_X(4Do`Acu!)=?f)|K3z%#@c&8xWDX z5vC{=Y#`G}N8xPlKjV&%ta#D7HmV@FeEXmN)^Nk6(O&8D)pp$1;9E5Rjr~`M$3d_` zGU0o(2!CL-Gf~sicF4EqOX~Q}UPM&KmuAE~dtbe0r!Fp?bP|M1ZXn{ZdK?2s$={J> zlwCgtVt|1!p;u>@N3RQ@FP}aa-~!bhIy4A(;4lFu4Z%gO1k6e>hzB@T_lM7D&WN`G z_t^$Q=7*)YKGkya(9Iff<=FcrD+RWL!U|=i)7%)UX*M65bDbBBN zJ>=@+=hxV_EOnLF+FZ)z;pNw68)p{J%}VcCAQfv{)aSMiUhDID@P2gu z_kN6w^UME1(=?^U8axa8NB=Flc)ckgE&QH3ec5Oxd(z(WHi`(KP2touZrTPy&E$Rh zyLEJf)06aylvooA>+m?WJ2L-=e;X|^c^1&z9>3YkO#j&D4<@cG|FsdI*g!7h+0oI} z^Chp%Mn#;7fL0e$-=t9xnVGlk4`nf|XSZ|s5y&puT-mu)7}<{dIhw+WtH8I`|ZMm;OpY)*Uex|aiL;tu5)#*`-oCq}0~$SGtcdpG9p#pxdExkCq7zZOOn z`ez`q+piMh@D+@oenBRFnB2d6mVhRt1BDd2=Jh{6)nE8f-0>!o@46AT8dY)eJw4CQ zDmh7zjJG~DQg8ZCI~Dcg;fCKpcKnrL!pDh_qualv?>7qElUuH$x=eui`S&++^F_~F z?dNSh3sv9wvXsE+`BqmSqiE{$8J>!UtAG7{N7B4-3spC}yBLa#vTm<} z0T6o=lCG&3id(NwFiaH{2Xo%3b+fMab^Se>A0u9D-5u{;tXCxc>BPs0(*A>sw{5?; zEY5^wU&KCL6F9s_*&cvz{$^ZWxe$GU<&tDwPwFGpzH3|Wz1Pz@Zc>3T5qJGO8^{QCwweU(8T9@I%Is(mO6P!7}%kY!*rBzCRJ+LR$41g zJq-uNg?NQQNo1_H@W!3A2>DBt%RKzQN;tmRpK(ssuu zfgLG@wb6+fh)P318=(-Wjs!h%3O0vdZq+}g|3w_;>!0dT;>Km=OFZnII4L)?h7e_k zAA<&zW3nKBS~{pwP2`QWOwqUYs5|}V=+HXqdYFUhyWPD@P_{)cIUSvQ=^1gjnB$6) zIe$8K`)+Ra64yif46;{?^$?eHTH~gQ{8+BDZZU6bkD^r1Lzb|z`7zjDK9(gdh>C@- zs35~&keh`V3$hC)Xcm77UU$BQGG3`3ENKM%08zCM995ztl*U{?3yODnZO?x>^jqWc z+n3wYxw^ps-b7B^lI>xWGPPml<|`V&gqQl z_Ppe5B_x0a2IjutF*JVE38`sbG=3wnMMzc^Q+MiffOV8pqfipQbuC6JENT?uXbmt^ zAt?jQP2<1BmVwWhReDEq9PyixR<3`VQ-bn=CJlWSKBp@MO9C?)S$*>+_!HS7Jk3lI-FL3#J;^u0r1w>E&noLqf#+cfcgG)sg@j8<8dd`Jtdt?9H#?0- zzNP^gzspxmW4%?mqTgO@{%l+@>j&r*Q^!yFg5xG2zWD<6~wr1PK&M_+0;J%5ZTkoDO&`tZ^8!MSe7PQ?H(;jwAO~Q@^&4IU(Zy z9g&N=v%Gv)hhI=RfoNlY6M5$01CPAAw|9B7^Zjq#7r7o+O!<}vC37xQN*HLd$WcqB zJ&^L$mY34SCoUv(cPgzDJI`;CXZ4>yJj+lkg)|$)Nx~9@e;DO6Wycwdp4pX40GcN4 zEgcx#R*5zxaI?6(9a8-PoF*w{<@jBKKKzxI=xQ~4s>`rx1acokfk9geA#B7*8um;@ zx411-;f8#A<_%}fuIuojx&leYzK zwcPdI-`K?6LD0Ib;x`en%o7ONAdVXJ3NP$N!;cI*i)C+xwbRW@&T{a=N7c7yW7;+$$17hICBhARO!up^ATbjxAeCU1 z$gnvU!dgUV7on|sf!>=)%Y2OPrrS6@0*iayx&7f(RXfS9}>8*GIv8S1f2Lu-;`uOKiDi5 zj9;x@n8dD)Qj=wj#L&U98K$jLKxEDV@VFZKe<9>b%-xKD8PEpiV9crx_wIQVI@6eN zqm%kUNIodoB=Pu~t9HD?r{Ec+jPcA$U`cnzQG|Ymv@^<=l(7|3;0}gPgXq|~6^%*+ znEjK7NtIck0HbOKsMTrVeyzUR+emwRE%c-oWD?IP*1_Y3+xwmdWcYlMvySruIH3$UV)~p&4NU!rA*1fjjJ38(;vP;)Z6>r6#r55%?9z*-++bo`zm27!p%dnLtd`b&6ppV2 zlRHAKNPx7ifZvRn>6Vd0F@LsW35@7K0*1xJNc;?^sXvK*x))&E#37)Z&UYMLl9W(8RYv|d9%-N8dTsSr60XZ+4c?J z5FNI=p!${~w%SnowEYBpY7)u^FqNK?V{gW;HDs(@V zO_yqqox8@dHhn{t4-^r|89549sO#3Jag8L%XuU}!sirTW%u|g9r4d8TG@axq&v`}< zkeRB5BbAeVN6Li?U*CC|9rSkvGsQ}YM+;Feb^Mn@?^0IMEvALog!#QT%s4@doK60M zWzRyqcSA)??S`5;VZ;j$zKxo5oUusEGaJlzf6qz!9vCUv_c^mAskei`g?_WmJ0 z9!j$E%Dn=6&K0yp8F~N6T2gE3Tf%rO*5%K0xbn^9jKWI@KQV8yC4dSjLsdUr0kiEaKB*)M{+UYSasA!6&E_)wsglA)_I=gH?U=4n+-`rAeL6 zGk1erk^#&3KFpD1e){$-L;EhaXIpJ7k&TbSp)GeVP?NgbRFZ!OQ`q1c z(AquG;Rk!fI+D}vxQYCfa3)w=r3O!GsI17R>W|OSY6N?Ls~hr#7x~j;f%h+0bc`Eb z%y)iX`6SJ_iUhi~wME<$gu896U6zKBHQ$9|}r%78XBVkbZzKb~48DE|+Uumi^&a zV{L?9t=Qv2s%Ke;NK0$A@iau%pHjepZjOuz>{kD`Nll&-{1Og`#DAre6|$rPT^-Ay|@A z7gtY*z=wtr;Lz0mHqMhfUekSI7`Pemv_376zWq7V_Ez?KCDMIl__6UkLn{2)?)Drp z)d4)s$LEgscwT;-v*eCD(R^MhJ>IN~xU+n2wY_z7Y>B+h1U!y7{rtQ(I=nI2>=5zV zdfz?V92fC;c^m2ZX!C3HcqIL|R=ZcviTiH+_FDzu_U!n0(IVo(-1BLEcvEsQ09-zt z9I~vZ11~koJRf(Kk4}#rz{%9`&z_@=_uI$Zve(=AT&|Z}mF*Um&l{86UmrJ?C1orh zGhJ_P)?z(R_7RdjPX>>FnD_m!m8?M~Z%^B~BW_t+yq`m+A`Z`bbHe|p*}UTT~>(ziWi_s2!Nx?lHkH~$@6_-=nW z_ly6t(Z5CBy8WKxr@VU3lsD5wyjou?rUfLP$~*E*0#=WQb+)~-UQQyW8iB?4nPnrA zw-=S%h@Ovv5GxZe+`H2nfv%UAY~`Olz=itj^0rs&*(ozP@cwwQFVfERd7FJ<37gmb zq4T)O92GcEyu)MS{?Fy>Q~NEsmw~rNCHv0pNU!J1xgFa9TYqLQ|8qxPChqzl7d5%R zpQ}59w*wXf9!-dqpD(8cP=Qa!!#|fDPjBxkxyAvX@hFiWGma+_)!(20#BT!seCxg& zA>t){H-Nk8)dBhTrvk;{I!(P zneqbO+9m2lJcs_q8$oS=yujy^+o6O=z{m2`KJMq4p=bJ82`T^X`>_dd zYW%U#b(S}#vU&N@Rq^|+3y8J?F5@0AMLbqcNJZSK4}Tg7zZ@O{$HsxPU1#n$KY^!C zzvqaHebSEfP1JXn)B4x^>WrtumQCY;<$%YIs*X+YkD2p-A<_17sIvLxt)U_K^Tn-% zP{eEXgpr_K@nl#0(H7dzz&RvI(*qQX65)NP07Fw$Wuo7#8EX22e79~l_ zD<({eE#9qC3S(o&-H^mn^Ngu$eLVYq7fE-dlc;DFMka{6R0lU)JGHSN+NXIq0Wlv( z9MO`Z78bpLBexsZl3XBvrCal&f$Su5iI0=&?TH@Jl{7b1Axb;@C2EHYX&B~+$z2d; z#C^iFE8UD-5A7!e5DuNBF;&azn7fSe0rfX;P}A5k%L#nQ@=7J4h%91`(La?0PYt-_F?%k*{Jo}39R5$8^YQv$F7ZARu! zK_-T+RP2ohe*bcETP_p_9r4y_-|e>T>|I(9``tYpTQ;a0pc=3x`Y4n$BFR5_ZWr!j zxy-F3l`PCf_|ak}7=|sg{6dZ58?=A)E1B0pIp2cExadGto{MduwS2YP7bn_?fbr|9 z>5bq%CyUM>&*gYxCKa9^!F5v4)4XB5Bd!15khLg-j`@Rd6~~@!^lXm z6{r~Nu{tz8YtstQwdok|UVZP`?kM)f71JRigC*k?Z&WM-nnu#=?^IM5g5yqCXehqA zEU0}tNILS2f*i!JRaUI|nRv{hsI{VU1HLdYH^a8hfI6sRqDn-n+QN{~R%}2PWh-6N z0{R@*@K6+feC(AZ5SKI+L0jWZ9H{-N;F+7>@g|<6=+uvNs)Z%UKFqP%LxP7sn@+I|W zcMU6d4eG|S-Gzm)a#EXS1_zq}r0ZX)wR9GHtG6PFo9%yOD>p(?%I)YZ+{N8C$yn zgriDV-R79RfX7r;!B-D8R>Q|@I68ZyVua;)-7gpS2IqgZ&T;)t+??t4JjN9I#!m@) zFIx^SO9Z$gyvFle_+#DXgq)7jYQ~(LPt;m|nnYNqAUKtzEZ5Ek@uYTuJP45kH=Sbb+3P4Cb({nr^4Eg2-jz(e&V=W(=aH77LE*LDrz7snHAJT?`PjM4)Jx|>pr@a{GWb%j$~UeHT@H= zozhSwU9o>?Zm#4G9Vmb9;1n+~o2!580qT*WD_wC@L?$0`Fc@}DrKnh<4*Cj&gYTar z+`%Sy2Cl+}W~csj8OFt@j$mey(~|vu8PXC0;V_Yu8hlhjM^Wsk7B1CBIc5O@911ntP1-Nfa z4K_kslZ`f8ysxrdDS6FdM;%#+&HZskhwGciP%P~xPWn*u>G`|>NxG^YqKtnN!kIsC zTdQ4N*57Q-n^DJ=KYa8h^j3b z-`c{y_OK|Eh1Zr?;d`vN{9{<{Ga1^Vt4AUZ&`A;SA=3G^f!$=&2240Qh&IGR+ zA>y_4+7DOWe~ir``vE!F1+U{wq^{wfr_3!s?9RV`rBAFLZ{!0cLF^-?0Qi9#W=MRw zlDj1gg(|g9>}4Kl&w{8yu|7>S5A1n`o(-NmtC86S_zXHsaqXFKyA-oaBN#Sq=NgtI zKUKg4HMTML>`qDV5uAnRtzqO`FdC2{ud7 z@$RS^YB%Gf1RFCDUG!cOaL-LW6;ctW^cIC6Cj~7);pa72I&HQQ;5+e3 zGpB|;sEejY9#OHOe|}R;VKq@|ub-uJphP52rBifohf^k)CTf~B$s&8{jxlKu^2zGS z1ZUfPduzFLvg3ccv${T*+NE`xQPtZ3L*HVwGUaK#R%+Ot-RJa_%b^w~D&cY=kIo-S z`0l>=8dpoWl80dqq=57goHdaK6$;$C-OHNd(b^e@SR#upL=-$cO{OO`PKP6kC7j(Y z%gq&w``)I&8J$@N+r0GVC6gXL<}&SAsNCD+4KZ|PQGaX2)?nl+RqUsh#j&OKVZj%C z)1L{Z&(D)cvwGJ&uketM+cj*8z-U*b5+S!9DrD7a*ypwZf+Zq!9@=UARv{X@ziScr zf5BJ=FHXxl`?`9{nRUdT_41vFAb#BD*sJz$+SGuB(l>=b!I#I>k+|y&$gYGz2n8wZ zNCIcZD@dy68=o^YKKE4xK+-ry#;oRGXCP1TfW422m&eD)veGSsfUIxk``4|6TV9%lnTRGG(poO{Oqa z^UF_zyYikg4#Plt!1h`%`ER}Q7oUvHI5fHR{WFZd~Kh4^iNIJspiPW&?E!fK8h|G;)YNT0As;qep zDR|A?#w^tL5jUI6!H9~g2dZzMi;cR7&c_No^g=>l>wj$EcnnnM zTEKW-6km-YgM{B`2j%l>2e~a=0!(+tuoi9miT>TS3aALmloY z;-b-Qg&W4r3EIC+O2!K7PjXH(Q?gSM#id|3!mGJ?oT}JNzKc!YAFFupjDj77WAaaH z2S%A)`)pao{O>x;U%a*8GhmfKxDr?W^2C~|WM9p?AY$o5JbyOSv7;YYP7r)dCsB^E z_VT9>hFzC?Uv@^x*u!f52x16%;Gq4XGTvSbfx3j2om;ESuOQ+HvlxIhhHu2wG{8#8BQV7SJSt9ZD!Zp7=GAY^sS3Te7_IRTGFw_SfVmb~|!GY03?Q zUrW?JDni4lWe!rB^gEb|Xr_P`7*3woWF=DxoyydTZzwO6wCQ%^hI<>!Pilc`eEy+# zPnXCSOzM$Lp~VVRNOt2gMOTC7^#FHebL zhbzX;`^F`u3zJK4!OeA>P>zYP?3Sec@2LbqX{Ak#)8K8bIJW9_IA?2h%26mBt|lSl zFz-{N2P>%PLskqo`?-j(MRNb7T~>!gr_V}<+S@+yL`ezgw9Vmgw5&zu74%#9IniT7 zo3i^5cQVX%@pxf;ie1Z9Xs%f!z42Pb<}yLxWmvD<(wR?@u(lrccQ!)#%0`H?#bCEWVzU1(eOpi=jHp_%7ej(LEY6wgn9 z;uOjR7qu1gi^1)rjKVc4d+eB&d76*q1SXqGWLW?cie&i3P^zwRq2Z$y}f;Wxb~ARt$__ zK)4x-8G6?Q_Gwv{GFNS{jn8D!&dUo$)wm%+RXt*Ee<}Yt=4q{P@oo?sZd9ardzZ7b z7y4YiYG-=H3neP4BnK~)Ufj`Au0?okI=EWAB ze3Sz=yRlYC5xq?ZnV6?Go5Jc}T^;gUdG1RLbYv|{dyh?$epMz*%@7kINpH3UUy{@6|45lRsOnur-%$trOs7dKkc&wq3!-) zF1OqY_#fI=-17#g$tVV;&j3L6U^U)X9d+FU%dFdCj00@7KPz|TS+CQenQa;@V|FJINOUK znT_vb(K59$kO?m6lF%brLzAps^5XgRD^aKRUE)| z94TP>q`EA;pd<_|G|6=Q(td4ec6USoy>qZ0?w=hz1g-~|*?-5g0ZrA4K|}I6vhU!- zi!i02=%yG3Yj9hkX252_wt-E_;0C3Q4a53UwEme{O727cBn{a9B=mUydHUmXSA#S# zAaA+F+~a)zokm}I!|-A2lfUD4L$-U|BUEB=Wg@U{dfC=}6A;6$OE*;C4rn=&$GwITKsR zi@tnJ|6P0lG`)zhpc60yVwUUd%O9WzBRMAuv)qR|(+1P zT=*TWYU`Izb4k&`pKSLxo8Gr@g$p}vi-}z&wav@yWIkk5`+DV6s9~w&^vb%zLsbMp@`%gU)w%BL_(z#uU)2M@1Hs!V%HY<`;r=vZ@8^a!RO}t}eD# zT_uC9P43rN{@~lZ#b9T27*+~(C$!65>P%<8MmmI2w5!`W`iv)-nDC2%nSJm86ogiW zga9+$-~vSq`6OthioeBnJm>q1z-hAB5KXSuKvy08KCkIeihIHhi{U)Z||aZTkQwNb|WGXzHu$UE_2 z*k5&`_@5<3*o#)$@6-%VT-CW){J#A{AjVoe>NA5VE332a?2tZQ0n@;ZrQjR^u3>@}n)qPe3f&})`k1;8$ zH9xQvbTz;J`B(0jpY|>Bzr$ME%f1Gi(JF%0upq$b`O(tv*@{iCop+d3CB1Oe|Ju{9 zWAQSqLD{PBzqkmP4O59-!*xPZz?YW5WgVhx(^a9JPqAFgcZ;Hw-wGO#3>nnAQUQky zolSw}^w}-#8r}@mQ)XCWU{Cs-NPH-eK0~T9f*K5g>n=);U2W|2JS9ZQl}D19ED2P6 z{df#045f%_bzm^Rh{*{#r}?pRHPdQ$Gr04Pck*VvL>eoK9v-h<$&+D(xc4%*9Gpk? zrM~X)b+=DGqD+jycY0)R`#5M0p8&DO*3R7Z)+j%mhIfePa@z`?X zX1$bYR;j>fsZ&Nf_n-8ezM&2^w<0!VOXQfcyV*1un#`Su!c>;JS32>}j2Pv^`N zRUQk)o-fOy&S>_@TFC?W4T}8eZ-sxF>_3z8xLddcN>qb9VSHKzq9!_~@sNvM9a1sp zwcvSXAQocz7)ur_n2b<`Ia)EaosG680Tzp5*;x?$IiC4N9m@XnI{w1K{ncpE6e{vD*piV$Q_IMqJ_9AH>^ja76hjcdLuu4H7NkXq`&ggVtQx%7bu`L>^wQ3_ zMPX#xk!PqML$W2vci8oS?85V>E{fU9?)~&F_0VPQhUs`kg(V>A1ax*`P)iIPJ;F>G zrhxZH-8XgcwfdDP=o46H9?rvF;&M)=kR1@TKO$&Ipmm&n;xQYCuj4y`zJf8QpL?4F z0egBIIooO3tl7Mr52|Fu!Hk-iWDxID_FbJYxKmCwR_0Wjo()p`>X+kM8LIfCm!G(8 z>^SCv3IOuJYM^mFz$Nk^xa@UZzj{Fy_9pOr=IQr*4o2#1PVdTtr7Z{wOJqvZ)r zQtky+YU9#-6%@-tjIn@6wxeO=2=C=-eP!rv-uFFWDS%zS(ZT($nwP?CRU#l|YB+jg zcjdQHk{uuvc6&$Fy;;`c4n@!K#J-tD4K7U3KXNwxV^G@|XpitJjV;_&6ZIz6)$>@z zAN7*;StiPV-93ymZ~L;-Tw@CUSD}g-NwHzGN^Ca@+>WW)tu|a>!ZBr-(B1&28rHvD zU<~mu?z}jgaB^3;BixfATvtW6%DX-O(d-_mY*-rMF>Wl_lc#hun_q!FK_x1O znt_hg(?OmDR}9)|{82?{WH?pcE4DU_!Cg_)>(?I~)j^_tUeW@m6?I#^1YWhUMGI@9 z4ied{eH1m=56NG-SV@u2$N&8Fe#rkBaAZyTvKkTiUpW0o0_ctVhTEI3f0L^lCmR98 z#_KB28T5X$@35hdn9cK{m!?#_wW8Py$!G{c+2RF|5Hr|ohpU3On%PmCY6>RW#ZnsD* z?%@wZZmRTsW9NZD^J<-F|d;cQ62UjRJ~H)A9MVlz&@3^yat%Vc?JtvOX2djU)V zZ5acEHO43~Y^%H&%;|{0dLlUw9rcxQF5)yq+8A}7B zY0?36aKBviOSL%~_A`z50U9Q=J3r;B81gd8+E_Y-wvN^#8|d_@hDO)9}MQDOak7zRgLU2bOmQ}NX7Uaexa1fHU%t5^@ zmh!r(GK>YS3pWuSFaC{9ZcPSZWe0vCi9u7Yc}QDZ6I=u0UmXYjLSz$x`MYr9#mM5d zynwQbg{s}`@2cF^-Smp75RyUQM9(@_E4M^XHo;P>Us5S74q@{0a+IaM3kBwzN z796Q*eqL{Rbs+84n7LI6;S2Y=q~#Bk`HF)oj zA~)6rUVb7Qj(Q1QftCn}`IczfCyX4Ui^D1j-X#7{%0K`==Zx4-ST(_pA(~Whg-gxp z=W2|Vr?kTVL?*7}+7=VCEcHlj2lJ41<BZa-gi* zw-sWg?OuEBYR3XM&^K7G?(>KlP$Mji2mgQ73@t*lVr0k>62>IWcKiN0g0;IAO$w zQ-}gCGh*4ee3~81dt&z8o*+*1;y?641D8|c)Hk+6S->mBjxlJ;JeKS5*Ny*C)%6$4 z`{gFP6+P2VSB@u)2UV|zdWDdOdzePPhYuKsukYLk0pHRVsUh4}hUA))9Po6%JU3o^92#ypM^8)0* zfm+;a>(`jq>I~-YdLN3#dvq`A+cJx1glp3SY=m6pTjb-F{IVNCY@I3Ap6Rbz_}0Lq z${^oAS;KmHqOb?`_KbKd({BsqG3FI$-TU6&<41RUrgt&#GCgLtTrxv}dsF^dVv*${ z&;8msviH;f?JlOl+H4DK`_265P((-J3fDSiR>h}Ie$Ce|ZPoTd>u&OoOAg3`TJKx@ zb)2{5md}QM7v1^oCz8>JUTdkyorFYNCwNd;#cI!wanX3a^JUB8kPtp>fqz*xYX^Qn zub)4B&6r|@w9i4|<+M!nP4PLWaibwL4@msyz+?%o+sp@5AojtrfIr*uV_C-jht=j0 z32LAH)o9|rx5mcx^itI)49XK-Otz&ynv@tDRDn^Ytxvw&&W?CbQt+{aS;SLt$gVfa zp~LL*QVB`3PqQ&E6^~G@gL4p2s6V~re=jmSG=DYc6n4zht9q)}abyoNti<3pRjR(Z z@tJUU&s7;wMP^YWI_!oRFWJe>XC6ag&#oV5KJQ5|h+B#Y6d*Vhc`<&+>SUAqTW^)n z@qErG6e~tz)iTdEGIO(EbV>6!%2qzxvr3C#YZu&`YRM*LrqORaNM7wSCE^KR)Kbf?AiP+7OYnU5KajH;c)dK(A7 zH)OvK_={ujv(y{_hA5mNcq#}=NkHy*g<;f6`;|+!dy`1MIMi>?8WOefkm8xDrUI)? zuG5VzXq3KH!Z{Pi7R9t%GI;=gC3mq9qn)x0-of^yC1Tu4x+#VVgfSV>4lmK2lT?=i}$FkJV7QTFnbit$&|Inp5gWq8DwuJm8;G7@J> z9J@zPD`zkE?1h3H<^szlMM-HvtLjl>_SuT;sy~*(2OEGgDgm_Y<*>+7I@qe>!uttc zbfFdPF3ec`YGE~}yy@kNM8H2mj7|>mj&e^UZPkJ)tl4;w$S0u}nXUvcB`MC{sLNb6 zElLX~PsE;fwR`|c9__8bWp=p*+0p>_)ex;_H0op`O47ODX~LaL)S`f%Aw%}b5v14` zp9rnvt_f(%*$k=^M{8xl{oNzepqHQ8Mqvx+6rKKL=H4yt}3Y*>n^D9QmtE?Y`k8#AH9|&4^ zOI_%_#)!rh9_`hbiaMP@2pOzl#>LL3@mL}+BLiCNh)S0bB=p7EQgsCmKb@XjsgQO2 z`HY`mTk$r%i_K$1g7q{)af&-ney~mFDE&4KS4>THsiqjf;zw^yXreYKw&FU{rA5`I zt)3?I1nG^$85-^~+w268ZFJY1t|8Qnb{;6vE*X>y`P}}CM?nr8@INuiauQ~ pO zV8HovrH3aGnlk<`qk@Tx4Zk7eqdHxRF1z2++i-n$&X?EqUKeS4PhMJ-sLX%?v8J9%|cZ3FW(b_({KO0~&0F?8`JCQ0#d+vJV^^F`vM#lAQCf|oi2daji z-U@&hD`hE!gXivLI@1Og-O&7jm(oLpbz`2}K&*N4-qeG3?)^2TYH^`P8h`%92=y0gcqD zzm@;K?K+p&ejrSA)}KPj9vI!+r z|5(gQ&9TD^S*5n6oJ+pT?K>?MTi!|Yt&tv@3)!k|@H8k+%w&@#Vr|f#Zt20+?@#UZ z=%Js#*J*TPfrORuiFt*Wf`Du67VzTRy}R8}TuOq45JAOF>09TafqJDxzZuWLt`S%r?AJY}q>f{0mDDRwxf zHJ|xP88wVSy?AN8qDzs zBsRmf&Q1K%?}Q=v4PmE4H!c`9Df^o)?z_x%%8ov}vD7!z>#MVa`3~`+)8M+A-+hNR zO$YeaRZo@WL@(U9Dnp6|jXxA%l95u5=@{x8tJVKxrIe4D=Zv*z{|ufK$qL%mop|W= zI>p;z^UN*)l6pvQ1Ey8aliBuAk(K<+(Kk-(ITzb?ueQnPcvCFr5cPHY{MjMgq%+cK ze$i{G4sMfU+F11~{5~s7U>!ZP^VHCEFY+x7u8^u(>5?`kZfoqOO7R34 zgFcivdi~4#a%Pug!#sBK9Qp$+1r%6Cn27dtyUTRX@NCwNn84dX0V6g6X5a4)9~1Jt z&aHD}Ekbf@q>7av=d#o#zECso+;en)04ch=%c* zmh7Z-&G1TA0;kZIIhx(Osz=5Ax~poW)p3?SqZ4LHAla(ZjN~>BjhK|)63o#$? z)?CfetP!kKL`Iu8RD#DoT*XyFuQ}#d2K7ypR&m8fsZTLn6M3-Zo?h*!a%oP{MM=T* z=J0|?{m-lxwBnh$2RD>`Y9l{{n=Y^d9)mDrk=6;R4ZjpBsg>B^+WqzVwS2jTi=!e< z2dQ)DXExT~)`eO#$;dfEN7ocNf&-)8Qp5f{(L%>G1h{pa3*NnEGHd+r3F}XDbF39! zj|+N$I{H8tQ6~o!9eaG49cGOw1kjIqEWhG{>`I8$AeR^9* zb7sGY7X+6TFguiv2?7Qw+E(_S5|)vp?@d&@nO`tXFlkt;@FFV)sZW&nI|Nu(zOdFpCN5@?Ep zEt=eMP?Hbk0vVqaQw%Qoi%vI7)Q0mm8hFhKky)34XdC-#$CeyVC`>cRsu5z;&k1h}q4_>hU70 z-SW4?+A{;+&TOhDm6_AAs@n_|u!};GL8v%SN(IpuTeoWGEstKkRGmI6-ZqatDaiPpG@k*3Rum@?o%q_*&lLJ5=5K2<@&>j zKDGWHo%bqzV`AubGcJi6AfJZ;!#-FYDXD!qu9y=xHWsX&xYnRVct$rU$kh0r3Y&6l zo;sVnSk+-V_vgk7laWSkR38f=iU>wyOI+=`*gci_xXYO!a0I6+S{Q!kIIf>Jq~n*Gf_Z$O5dEm4L>6NIKUB4-2{KgVDP45E44=v$^efMRQQ-C1_u5Ejz zBXb)hQ~jdb?C9(khGKEPkSE20tg^8;!Kg^`E593pRwR8VC3aN?h1!yjO~+^bi(OzM zluO5xubiCeOI+EB=1!)UbnDD6=e^3L-$1gIu` z87VPFyXbCdl5pGd61wd8P<*Yn?bc19>+(xvZP@TYL+XZ9>L+2E_2iPn#Tv@6y{+v# zU`g=`UdImhX=2*MJf9G@2*2_tvcIM zy8hB$>kdLXZ7hMJnq#%8g}l6cOg0O^0lpMJDAuIxJiTcgm=TkAeli#u)8=7VqVOTc zorsSbWemsj;1UIFNy9Tk!3NE6&5*+i+pAVLc?JMHNH;gF#6AuS0!;g-_(hjQlm7al zMu+u`Ge4!4Q3`}ShM-nLv@GT)@?(d)C;InqDc+WqxDda_^KCNh2U(9zF-+?au)eOX zs(q<=)#xJoL1?y++ddvhB-;cCuR_1LW!KQgVJExsWq2e>S@D z2hwtjPRJf94vF)Jb@n{!AIOBYvzGy(MfBHik8S>VaHkR~53!2oZ3N0rppoHLia91i z(v{{UfC=!|RTf`#8`g1k9e~I<>9)FX63EwXzskfom%=!sL&?Saav3t0_id^}e1ts) zzOxZiY}(VAXwlu!kd*39%Alt%_4BIzPM@ZKfOTp|})u{2Q9`wOUa~B*pz!Qu`ME?z$tyhIdx+ z9#%$wZ7kqs&b~&ETb-5PrMP}vdR^Qvf||Ox$+8R#1f2?AZOhWBZPPH)Y zK%O0AVJTb2K}>L#>D4t<1?noVInBCFA@YNR+mnNNZaV%aA`!3^AA2uq$C()n4gv+| zVc9Sj9-y(_ z#X!nMkRr}KG~View=`M!z*BzIpKnYB?#~W|UVWwmw}6J9kN?I08zR5@s92sfEoe-u zXg6HSDmzyQ?)M@O?affmCCV_zSY%Nfebz3ZK%(A#}JMh!QoY-6+< zQAs4?f<#rN>XRnz4cB#3#kc4j6}A6DU)hWVkB2#yUhdQXV%851bnFVT6tiHTv~~8~ zaVuKbC{RBh# zNBkYnip|xkF;+;MmwmC#s0KT!jig1B?+tA^tnKa*)!iQZbM0TUWe|DdCr&UkN&)l7 zyhMYR_$+Zws){2aNIjvOJ%zifB<4gQx8aOv@lhx4L?E$TNajAb@MX(SbGy#4^H8^^ zf#UOQR7BurI_~Yi5cvP_KZrT}qQvfAWBx#*JbsRs8f=O%80m8amMkU_c5<1xx(@qc zl-@Dz=8O3CgG747o4CsH}2Vi5ze#vN3Cjj7o~Kq=5^DIH44LAAU$mp9q2v z^>40o0}1R&GSZ2U^=_=%?FDW86%Q6Fw8{l`**qiRaNG4cj6KJsc$H>j)P3oZ$puis zkUw0Rk#cU_g>F90#C3`TP$Jd+n}aCcqBNa0U$eX+GM2mOU)VnbD0JSvEiaKSgk5=O z-2CkfkN=!>V!xd6JybJ3P|up!>UB$Gy^g%8>qA4dcbE_ra-1R;y|!8kqAm>Tf@{(2u!pWBmZ(DTNy&`(&ttws|sb&dEmoIJKiKDvjVTDs=CmA{&LpfW~< zjwH<=c?QC?6YxzK5%Cx}GY3j&P%EWICW(6H{S!s1TR0qv-R13zDC zlqiXh6c`3ssg|(M2xQ$TPM%FYlE-{#Arae4@8tt*}lVmOzVG zS-yb=ZBNZN0r4LQrW zPI{H)wii_?dLwe7VmGLYM0Fg`rOR8N{gj|bY+tEW{%WE*W?Kj?m(e3G+`kW$jew(y z>Z}8}OpdK$9^@9|`HPS;J?0CX4%xnR?Q(7NG3!AKay0uQacp!ita$KPx;o>Z0yLz> zta0c7NRgey>1JF^Vrh$}3?mEA)#|J)5F+`PU9eZ9D~ZHfUPBxQ-cveW+YFM>hdG~6 ztu(4|E*E=mI?e;%7e99{Leb{*U%+oUK8@bfSnk$pwC5ejp`NQ>rfT%3FHHdp zca6ia(}7vNzQN=B2=k^=$3_J!yXJ^CvF7@U(?+`HA?Qvplkz5;SOcw`(-2fCrmRLw zxTX2h$iuv@`w)bO;K}qFcrZ%Mw>eZR#o+7Kk+MN_dVWoqn80yMkg#X(T+eH=YX|?7 zgh~=V55Z*~g3;x|)P`>zO`X(e{CWVtwRkf^%#XxO&@?8mecgdB=<)&#hA7!f?>*&2Ez4BxhmZ$pxSSW)ax$)LUkE5U&i&pvv;7*VFSy*SRk{?*x?BeSu z!VA*im(KB~Ck&8+EEpMrZs-0_a=H|UaCOLl@?)>Ku>YJ_*8m^>kgtR>(*B8h#e2TX z0m`g9MvkW|VX?V%8m_RJfvR?Kj=wjY&C_8&7*r+~2!P~}*Qc5Km}Jd!>mKmku$$cpxN#1jt(=yTmuz5DkTd`MjU;TG?uKEe zO1Rl|9?h&H>N=nVX=Ih= z(~kJL^~ws1BLQ1nH*0an#|8eMbJezh^N7QnFI1lBLmB6bV^2RG?} zH*;x|L4kaHo&7;EmVP`IX?ORdE#gJ5Rtxv&x0w^irYeQVMv^aZdFy+Ye$2-|^1B`n z?-<)^Rbe|41yzFv%kB2Gw0@Y`b*oVVSuE_9oB(?jn`_F_w(%9crgrW1o!3vamvG7e z^gf?}*uA`HH5*uWiGuREY-rC}FFYJzM4V8NhwX#^H(DjNBo%18CjR8Io)V;AFOfQ- z_62oqzh#Q;*ZzoNnwlQyOB(OkNw6!N{h=#bWA5d<1iCaO2A3~W21;sA|5w>+oE}c~ z_M~WfqcRqKcRBiJn=7$0QJou3tyfLu=fi@|%q#UQkr=Rr+yeLfpOiSO1BNV&56mO6 zd9^lQ$z46{>0ufHuq2OF zKWdAQ?a@wughQueUG&&fE{L8CtBI`c*0$eLaA0zYEcb)>vl7xMp~A-}6WndN{Xba4v)LzAxWQ)1}&k)c6huL4x$@QX`SQ-P016>2tu%_<%E8#};? za1{h)k{iXq{KH7Y=SBZ}@K-5zF6cS$2d8IXJPh|=8>qtawQPZ*Rh@F4*@izSIpNht z)KYXppt^=yV($xJQKs)3(5j=4Ub~sDc(8Cfn-^uo3>bBnBES4B>oihAkw>aYf*%i} zw`>69?14J%SiV`bQu+GhcPhZ|7cH8=KJJ@I8-jmb+GEY}b}#oF_Z>$I@j~~&xzhjO z@BNLB>g3Ac^#>xM2ef}sz#Ttyw9{FmLv2;N68e+oq;4dYHG#Ja+>$|&41lY6Kt5N( zK?H3{GMCmD$p=&2X|a+q6ut&&U6aQG=V{SKS`fQ8k2A*YS;@_K zuVv7tx)`!-%_lJ_-=d~;e=a!VR)kTX@RZn7b3(-Og&;oyS7;F5+) zns+HXpngUSajr_-FH|H4WZKWP3ro14-+d|uVTvtwy7+1=^4T(vH$5a^6ES%Km$5?# zXRht)dpw3v3tjfxaF~$cQ3g18TX%5EUrlW3#8KcPliW`o%fFDfrM0v&*f9KMx}5s$ zjYcyvnL({p%U$ zoQ+FX%+X1Wh->!@ywqt$#E&>feOc!nhK@aG`v;^*{tR$bfp2evYh3cw;Z$|NjeBf7 zmqI(Lwsqip+T|C~23S}oAJ^4a%;NLjB`3;So)W`!S&x%&naqS@Ws3d=R35mun+w!< zEAZcl=26!{2xiY0a!YE^r=2bi(GG&OgH3)nA6N98G*n&Ml8X@DM@p+h~@kv}< z+wk{{APfh0j*v%cwP3Ld_gQ2@K&UBGpF`%Z`#DuN;}V{ z5(Kl`-taqz1$4;;RYf&W*yI7#Ik+;0PcQv^PkeZPEIRJQb&YPpQrG$TxBoc3?pNmn zdc~5tIk()>Ru`OJYM8_7ZfAAVFQNIt@_O+o)L(S)$&YT{e<5iJ-_G0?_$K+hDTp3x zBfBm+&)d(1IJ=)8(FnaWS>_qGCb}<)X;uv#&3Lg0yem%&+wd|0vU(2Nhv;CVBOyJX zxQ`^)e-Ep0{XTg#H)K&rc(`y=wC9sLrd#>1rLDS-bIXOV3YMR*c;_!O8lkO-zqXd{ zaUi!)mIKRQV?nnvU!8*~DmAJ8@}{rfqzkRmQT5y+KK|Z6bC>fbFI*~wv^Zv8Tb;+G zT{atST${cB^PYMMSiYJEm}kQlNyztTT|CUcMSa9wtW#e&kaBIwIKMXvYv^XwV)&>p zTc2tPZ6ed`#~yz7e2SHmkbAJVg031_A;irD=w?r^urduo5F>2TioSvl4}4BHyP%$( zH*r6|#X=R}p#($!^gh|!9)a$-jcYn(qO~9$b8m9(Oggs)(jtO;ZU=Lx;S%MRgLLbk zk9c2Q{vPuO>mR*sUpPH8mQ1VsrIM&b-lhPO*7HhV!?{W6o0bqVH(Ht25bn$dh1%O|m~wPcm_^LU%Mc$z!f5;4Z=) z8a$MMGW0*UMPa?45SRXU5;PTHrQWC+!k*ZwLQA7$hOUC8s6(|d?ioVTYZAxdd-Eb_ zhOlFn-`WyZOiv|Mu~{!?#UEP1-v>ah-M^nk;?t5%U6p^rLRQ5*<|chs1wLsnRLbzO z^m#Dt-?To@CWO6L2K+*bj9odgo=m}D2eVcKLd#t05OX_;h%=2g-qsz>4EMSfB^SMa0gLZkl53gY+oQ$PF$V*--frVl<9bNHAuDd-KNH2 zVXk{l*qwU*Mg1I`>RrC+0{NX6o{#qz<)gv$@u?iD;9N|X~|94CIdX@r`&X7->Vd;TY?v!>I#43wI+F|+aC)!pp-`L2BdYU0-j z*ZZ(Z7FO2rrqsC0srVtrswR4|kB;=yAc-+-LOdSQ>3g~VSX-8JSX&No|06JuHksf_ zHsy8?c}Qm##v+Z=n-c1BRZ!kchM8p;F^^y%TD-K@ian2|L2GU1D&mgwR(M_#l^jTuYRO+8s@-*k-5Jp_c(5|VV6lmm_6|vtV z_Rm(I&N;-tzqDP#izdk3VlKP??4*(lMrJu4moA|AVkq&MoMaoxHKc6ZS3M-F0ui7# zOL~_c;;mvUt%MVVQWrW=hoDZEI#K7}*tWTGHtkAnfY3wI#9Zh-B7eqT$V2=PI5K3;o+au@ z6x7;O)eW1?v+~SVYdM9DSW&{0#WRlPKXU_hi!jZd=FNLo&mkaM7H7o7DC7VUroObu zd|B0e!QuTsZjW>wj|iiS5f>?by1ADNO-y7x0Q*Kx4)-XyRZd*31FxqrY)M`U`ab9gw}HIka^gC(hvx%_l! zxH~_ifKxnZe!v^~ndz6f*qb3ex1M?cm^dBmXNDyj6m)v^M&Og5PVU|O9{kwz_>9oepOM!9aHBQ?PX5A4 z416BVpI!Tn>{z8b9f75<8Cs1Ka$j$J*ty~5toEc#ro@RP2`SSRDYha#QpS4Ska>a1 z=Wnf#J#qHRHOcQ_DCNU;{dB`JMgmI&P5ctZO-vs=mZ>&K!>6meQFH26b0lwgdO*Bt*Bn_d@KB_~>IKlG%Cc5{S`?u+hw@t^fbJ%-9UVHNjA?*qh_@-JjqbP;77x6ySS@`EcT6 zB6+rn?MZKO>6$+7u>lw$=0u8f*_#W9tk@mpey}O0MW?FIue5yTe-f zFI_!A!>F#M#o|<2R54RPN#Vl?3k<3vV@k;$c2@$Ig!H4u!>&z>awBIm%ZndN9@;}Zt8wskDgSH9+!_^FPvL@<$tnjw`uF(XKG_Pth@nM%Z@pE2PW$8 zPx+rJGbe_xoVpa#L;o*)4hhtack;2l*`YPb8DO;gUzTc*myj%fB>tk&22aQm)k+C2)FZg%kc#y(nmq!;?xmT4HB>ikRnOi||7RS~eTL;e8G1ScdS+fSpun|6dlVK|V*LIW<8sH#2YMOZ zHnZhH;0ujW7S@?ke-Ul^^AnbpTTWZO`(FNpAd8)ZA%?#=M+#Cq;JU!)EFU6$>r5jy; zKfi!OdOF%>RpvqUTtRxMI)-Tasd-^y&bBmB3)_>*x^2@60Xu8kFoOp0}H z`2l^dCcna51>O_ERYpjl{q4Ef=Y2n3rd}#4CR|z{^B& z)5X78IXqrtcx>cQ%3M$%tsd!f{|3}zC$xWKxXm+X1c@`i75H6O!&Ae9G>p|Cd1AHe zH2naem|-%(hU?m=WbrNun^%6XnUjvUnw&PMu9ITzH=jyJcBJ?oC7nWGHJ@O|yI4+g z;fY<*xOH;~XYrgW=b2^5EhhhN=58v90@10nT|0RnO|YFFcO#F9lDqy%j0G(CgNI02 zDtA+ZSJKcxNClm1u^$EQ6)CfX=^zAVl&aKoI!&Is+OJ2-T;DDtiVvxX_H}V*q@%B$ z;wrB-+QOY;s$&_|q=!%Mctp;O-nJ0vG?FU4y}1O0M!=qo_xe)tQQL&>YaV)^iX9`i z=Q$svBqW4jM=)>f{r6dbRLRSH-Dj0v+mrW|h0x|W;FfC09;P1WwxCf7asNQ7Ib}0J zg=4sd4|@|Wb93`tYf~L{?C0TUY_neTYy2=g)T*fsukGvTv&W*rJ~8>CL+KiuaR+|e zNhZkOR))7l6b>``hW9JYeMU2jsR@8C9oq6yyunFa8GlZdKDpm<^dHF6CDvAY?hN9vc zbc>DOS6!6m)XVfZP1C-?#^XK9-N$-wWY<;p5eIIAWKeIW7Ddz1c*?w1)WObZw=vr0 z&TxCsJC^cc-QQ4XCwk{!5#C(0!Pe8(y}Gkg-A>t&C=K16c&RmYrs_eD{LwRm zZ=1VR%#cN}iCthKuC=CID9F^((*nvm8`j?EuDOs`Pa7AA0p1mklPBKUfmsV9W&O$A zNP@;YC>Q)YDS+RD^JE_2X}`PIq#ra%=etW0ahm(}u?|RBSXIkWo4T&8;|10Yl0LkP z9~F(h&^i)okH*dnM+UzQmgMH@Ui`G-Y4Rz|i_j^2NsT5RB-l0Ma<`|GlceOncp{<} zj^v)5th?TNNynVI;HYK$cHWnI&r7xUclSfbZ;8qE-Vnhp?Y%U;@10nLMdKjT_fMn^ zNt+z5T{HqW5fotOK*8AviXkg?uFVmrP5Ah$e4eH+MvW(QQ z%d^EdO`VO;_sgjB!;)jBjtB4pCNJtRR!}t ziIY)InF}|bEd5=3Pdr3120YSCs!|k$znG%V?}b_J)h#(BU0xrFg?y(~oex1vxF}^< z;sK0;fu9llflXpBI19(z)AQ5kExFF|hrrt1SsO(@ven}lIGG6p*=)~9C!EBzgxRRg z1z2svEfZd*6+-wZyR2f=f#bkBA+2v`mou zkEY!ZX(u@ziz^S7!uy~ZUD$i9Y_9CObD*pQN%>bHBW?cot+eYSpYQYYU+cWX4asU3 za1nV)*haFx48I%54B)hkhNsZPE0$Xp{Uald!q!(dvv}-_#X>6~ZM`kg9@Nkb#_Bo2 z_tD!}Q@Sx2NYXOd)Fj`%h*)6C>~8VrB3Jof5otcBDsErA=wk_W^{70r!p0~6CeL|~*OQq2%9imRl(ncuMW%bVi zaJBE#bQIVz*aS(mPT6JhV=^Q%KnT>TdRG+PaSx`!fukqur^kAsmsgPWm=W_ChJhE) zg`@>p4-*sSCX)YNZT@tX+M9`748WD=JcHRTp`CK_?az)ME#}-@x^*XS zd$lLl#~w@jUtts?q_&kB!RAED4lvo7w;W~`1@`XizssR!_P?eg(0GkiKaAZiqN58R zA6MA1^P+eB;K+c-h$8&=(zcidmV!z%ESilGlv&uCyBKl1B}I zH=S_!*&g>0fbmMcK^Ja+vHy%_8LeqEa1pGh25{#Q$yokI_-)u-RFV={P;_%NrF@yR zXw=p@ez=;`F`b&>YfH0L zH8aiKjU^p*FN{;kNukqWa70GSD;a@4V!0Q5EG=W3A=$%{Fx?y3T+g8V(1}O0XC`*1 zs<|X;?|4McW!fLSlGHsG<8&e{6f zy5--BBRjU%-U)oQXK`+wfptrJL5@UF{Kxo%gZJtaLQ-VHll@Ji;g(e)J1&5IFVr-Y z`N3p?YEtB(fXntpM}#Va$YJv>=sJoZ);C7@Kk*W*zC5pUGkuk) z;fW(OMO+7DHro?nMGz}!BSt9!Fyv|pWziMJM)7`P;PNvyFtSu7e|)QyVqGC;1^F%1 zWC~f%FoTQFV=%}~24WFExc>pJ{`GmHScs!KR0BUK-RUfdEP^GqY)hP|iz*;8!YY~L z`0o3NXE2j=u@K#o@kU0JIrrpt6l+MzkOvC$LY;}B2lKyi!G!KlQG@7++bnYvpMNRd ziCm=7XUr61|8;`Rkgb$ifr1%p7Agt1QX`YA4mAJH;=aJ6iq>wrMr{G)qx0at@$*6- zWd=Uzc0yTXPBZ}}uHF#$m#dL8|3K8;4t^+M*f_W&5-WsSuVz78yh4C`QQJI{c}w_( z1)dbBUwlu0Y=3XX004KWy8v1cOuqv(6n&&K83pk*sY5!vtJ7R{0pU$S@0TS}{pt#^ zm}{7-fh6u8upXzvwpakAXc=3>M3LD^Fs*FY*b-vAyoedXxas_|IOm439K5Lk8W`o9U;LSFyLcyBVt}lkIzdN(#=LK z*(fySefvJ&9l{jIl8Jso6i_=(`h`eoO9$1Lu4O-uel+^F+aWIVRf+Z=AzOgK8J!*Y zAH{6=5r0E^3d8EIf*;v)%GTuwzHHP#2*_(grXh+$Be>u*Xvhjj;N-E@yXA``v(ReG zn~>)j@}L((mG$gu^a zq`{SFyAc)-$X}ym(xxEHr#(=B70Ta{*0Nz>mAysdNuOuAT5Cc7hZvhG8}^5F{84uf zw1tfN)zgYqtA|0+4?gtV&3Yk1o~Ta2zSWI_+C9Jo82&_;diq=Mmhe_s_YMdR17qVi z1w7FFnR|(v)VJ-BpC}y;;y0N+Wt;!rc792G@N(z8Lh=LETbrj4T$W%R73xH6&Ktq% z{C=yaMe26fOi+5s_{ly7dlL!jo69Hf6(k=`jn^{n1G;p1N3CH`gJQk-DqycYJ4oh! z|9m=uI#TYais zgB+Q?NJ5vW-uMcLSg9;tuo~?@b`HCJLya5($HcO)V2uW!fU;+&EUQm{OT$+Ygi*$;%y8rFxiB-M&`Lr=kxAQ)J+;Yp5PPa}9pRiuT{G=07?)Rv zc@Qnp^>H-^9U~G%ujDx0CtuObJzCiFn=Nuj4=zp_wc4`qY|;o50HTI5H6kk6KL`OZ zbTIA)R5qiww9Cs|DezVmYaX%u0mEv&dsmdxSW0!^dJgZ+Bwc_g_iPtHFfJ@7edQK z;#JeP?eB@|me*3e1NoD}^2|czl+**T`Og#PMbb^X{Nrk%KmfrT+0^gJLDgXuGf)sf z2o;-I)e_FS`V-OFatoK_Ng&9WJlCFg#Svrs(<{@=EpdO8S|o0wE|TfHQRJCVB>#tv zoxrt2q4p-QPcb6^yL%8?H9V@D%2WynRNI(URCJhCwQA_7$a+(~@Sb&~CjyZrLWP z2Ne&)m>(SML$$xck^46kYxMk+)0qIUil!_K3l>Y0L;7(VHwei9u2?!{`;{cOEm~qqgkFF2A5_Hu3a~B-$jgQ z+TLBouAoyF>-Kb1A>~|-#n~FFKv3xWa!nT3e(4`u+zI?N+U*SIZXmJ7fzf+6dRzLp z+(Yms`wxyaUBiq{7D+9t&Qp76x@6?EL;eI-i;S6fLx=FtaQU_J+xN8?kjy#U&Fzo% zwqK=vFsXBjjAO4%85Va|b!>E_6TRw3F)YPO_$@>339WF%qmuE0dlB-_>GQca;8f1K z4x1`ABIT&2IBuRhr@-LF!@C|dw_WC9W?9$6eZ;&L!&2PXZ%usu&g`363&bYd z6L5Fmt_Sn4rXlz?b>J2iy`aEcG@!dl&~n5vtQsO0NrdN;nDuzV`f+Z|5cgNx~=?m?;?$x~f{WM@s-v(l6lPM^Fq=X3_ z;xMe1yd68<{Scvzv8o}4D2F+->qR2KMNPasy?@vX31}p~pTG~gBq$b@?9w(ffdXIA zZ^9DGbz3nzu#S|^4VYJj!QynbGRe^|Ry_=0T;RAa64#LmMO|9k3V?%9_rIsPAwC`-+YP&&I|@46(;XY{85%mc=1?qzNsY66EkD7N^*RGtb++pP z)LC%<)F{UF13=O1g`gpl$uIL=M}p7Jh~>}g7m%mgK_#nVjQ>TbMGI@}w#}$T6fr=S zd@bfLh@aiDu3q6#EHoc=k6b<%`i z-HCcJx4wm6U6{y@HdyFbGA}n~9xJniaXa6d|03h7ZhBcgmVa@(zK$iG4P5|`vAoG( ztEC!~&GBQ`*uojgf6$UC2H|z-_t6mTMVHOE?`n3=Ptd=1Xy^_yx}>!<)W+O1ymlZA zjc$wRzqyWc=rW;o6LE>nbJ?QR@OZ6@QOiPglX^&fjF4z>^HAy4RLaT+G`N(ld@qp1 zu6JMRS-~k@m&j~=7fIqN{wSsZV?q+sg4*UTFuHh?*qxt9WQ{ZI|Mc5vF3~tx|3<^zB=5U8TfiC`D7#j_l{2NM|{;l6|#93Ng{p{ zOq*ndHfp>^lrE={5JEhq#7lq)Q@*0f*t~l#WL6W`byM_=u9alk7+$iZt?zSu9ycxb zU_O0LlQoh(UswnW96<;Fk%xbp-cPci%Lt zl&P=PorxoKQ?_dEY#{U|z$8nG{8T`<&+c-2>W!nHQ5|+guohZ3nQ9n7zv1 zQe;H}BEGRDY1XQ!bpCGI*p5J2bmn?a7HEtcrZ(XnY;jDqC~dmYG-(iXx{y>D6Sb9& zhqC0j&Bh$mFrZc6cJW$cMBXM_Wc^YKp)EWpQ{0(b6Sv70E&6T%dKPTUIXxr9vrg0k zpHjo~N`a1@NNq_7h%6WfwV@yVXGm}@`+XXv$zCT&R{c)p`qLDrw74c<%?1A7t5fUX z@EgZvgI#QC5oV#}2B0v@jn=SA2eW;Gxyu+XY%`CC2Tn_uy^I^f90w-tJEsMG7qem- zb;HO|v4-7g3?s9=sN#wxD8C_+38>Uu$=if0f-rgy9Y+Jm>8t8(fAOz`f=yi}lz+7a z7C6%6K6I>j_|k~Vd`}5%2kifDfwG_@QigT0al$1!BXo0r3W4}MB6x{>Sg}?|O5E>l zueQXrFQAI!tK^o&A$Ea}xFIl4$twRftNGxFq}DNXkb;)-;?K+_=tYrnsh8Ro=w z$d|HQaf{D3(f&2g|6^jH9Cw5A_K$`?C|cckv48tipE%N`^|D?gP47&_yA!gd!*6Q<_Y&EyaH$3FMC*#et0rlOoSI zX=Z0rZCf&usH?;nM!}s@4WcUMr)i6^kHjxQ9EzgFGYAHwfA@RnZOQm?*xb~)DJs9B znuQG{Nc#R{zNJz|s$Mf?_xje<;RKa|Qvsh()!~l>D27Xefs~AK?%MF3yf@j#?Rt4` z!KU+d`v(ydwjExfrI#;=fejI;Snk*y*esj>uwgVi9s}P5JudM8agUCmId_;Dp?X#s zu^C8K5hu#o#P7{ycXoSCn}lsit{V}XGG+#9mZ-zbAhuO*dqlS5%$IP#k@nxb?4bG} zDuT_rD~s~h{MuKalKFMN49-Jc&ZOTBO24!+wB-`LGMJ|qI_mZKb*>*hY-zg)T|}WZ zS6=QsJ3lVnx4Ij9fp<@WX;!F(u(#+Jjh`B&r)Ees(@Q zJdDkczXg+z6nhFMcU(K{a*`QSP5rJKYQm(12#ymZU1m;T#H{Qp&PXu3TM&z?s+J{e z<8@a(%@#r-9~h@f5jQ4!wMOK>IHCo7l|sJeQkP7d5bWWL9b8vt7N?D3fU5jD;=*n` zS7CQ09X`mA5BmD1nL!#oK#MBk0tGN3`zfLiSFFfKBISk3%?;zs)2a)Kku3j#4seq` z5{@P3uGg-$4icOBBBRtgjo z$bW`tR_M$d#X>sksuvEn;sK!8U~}DUlOQDc+&W>ptr(I$*g-KmA?d{mW9na@5Jn<_BRKJ7+&VIv)q%gUaz z63uoQxRcSWWuA*CJjW)Ck}EhO$$3KV!}Jy) zEpCU6`CSx2T3m^GG1`(M2qiFnxVWp{)n>amT~AAel9d+7Hbx_vMa00VP*D!y)Uh!q zM$-EnOMG+q-m&_J^T?%yj*7x!<^^G+6G*HGD8{>eWW=D$9Rv4alp6G% zwF&NqUm^aS+1ZT#wHrCP)e+o{2mSRw;uNgOTc|JXUz__?< zhbWY!>#d0efQ7;4`Mp;TgXPWc4CgVLTRVqZ))%b+17-ug)EX%Wz06#p3>7@j(iY{A zlgUri5)`EiS^DPDiW*`jha7)OyI`5?J9;DZG;l&|$%LdW!OHNGIQJ^yWry3C z2m)~USP3JI6etq{=;o78+7G80x4d>V>oFqB7%}7ik}LL9!!cs@1cT9sm((TmHhP)e zcM*L6$ckO;|H2v+y860Gj62rBPU})q^BwuCxc|70yhG60pN^AzxO&$A%Q~0CBICw< z;-#+Q_^q$*;!qs&|;dp%!vb@0IewBp?-L~4S6gK4cn~IsKV*W-2pV8C4^={kPWqv7qnI7T#k~Ur%#=h^2 zBJ)UiIwZq9^?30@5S47!An3nIn)6l&BZ43F#qvJ`?r8bWao+x!XQ?q$q@A6 z&-N*xv;OAf3J=!$L^sb@kXp&E5!wrlRifi0V=0!R+dJaXZuqO?VpniLIEKd;GWS5) zT$Dx97gV$?i{&9aipH70Jjwr-sBy6#Se+b~+N}Uwy5wm1U5u-iA3Vn1SSu5CHja@3 zz6rD1W(M(7PM4CS&6R%r_dMNg}9f2pOEME=5F)Pmv5Xd3LMeux|>g0^DKb z3bve6$cHVMKBQ1XTI##R|QVL7Jm*Lh7rG~UNtxVZ-wF( zE)^7ZjP$ewvi4jg!0%49H1!+!OJv)PD;_CaJ z+1Q3L@)$7PQAJM45C5sQxURCPR%tJra0ASYeje}NuhWGape)AC$X?oqMlTf?hs1N5 zi;$=hsyyqKm!B^ZD5Hu1Q(P^HU@*{&kw==f->I7!+1R97X#P@6(?+chsp>U6 z2ol+matJ;DveL=FeKQY~qs=eb)Xlf-erbJre~&xo3#V!*`oXA~z4v^E2c3`7()O_D zBJTejL0H8Ka2FCh-iB=O3O+amTJwQI!ngs88HUULZN*2wd|7uRf(f-k_3!h^ikEo7 ziM|!ekfuSEGhQC`AS!S)f%DrG(CSuH2x(Qc63(B>Y7;+)N6R65 z@ZcXx2{E=-YxqkZH8Jbm{u!|)vQc7fxXZ*$i*wE_aiFBV3gbhv5wz}cvTmbS;VHz+ z`{~ZThJ)n%FE4?bn&u*{MyN`830gra;;OnRMOitU%t9MMIhslXua>UcK+qVq03AMr z0z20LFjfM$Ax0nGl=~eq2T`njKq20Zm(To&P}6kPM5H+02b=r+j&@}}0SW4Etv#$P z8doTSr_kLN=Scdst4S55#`}JjH*ZuX*dE*we9U{%)6s;d#-l_-z@ro~@+!~-R!1;i4YM2$zs%Vw7~E@FCcu9nSD5t3 zNwctc^i%0WXJ-8z$vQ5=MSj4@q-}fIZ?zq2sSnvN0(Xz0sLU!-*PQrw16%V*&gfB` zzN~_FBrARxhT=G6sE8qnCsxF*UptZY9BQ0l=?J1pq_w`F1a-`}q|spg+yrzh7r+{b zEB0sMJts|F6JQj%D4hxEjFX)Bnptj-SZ@-Jvea^DgqHey(w6vP@6hfL-lU|pv*Z91 zjSC8;J&)gRb@w#&@%p>lVZGzt<8;Y&wov$OiF6hs!-O6j$Cu|71&3e0xK@P5!H16z zyo|@Rw93zxI_b{=x`U;qtIOvyO+W$4$my+PYhU4hc?8Z(6Y*h_>A!Iec2q-+|Ky}o zXU~`x?LT;(I`^L{(|(jTsgH15;_=Lo6K=X52q%Xu#31t6OMT>gi}bH9q=Nx>UhNUu zsw_QqXT0&~$K|3zVYc=o!&5gT=}&RCxP_cJMLnl>=xMGS^&aYnzfQCz0I;�`SO4 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 #zFSkvZ?9&wn2{l`fAq2dmxW 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

jiTfM8P%m34GB|A@gCsXZ|ptdw(4Z;d@|lK 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 delta 783237 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

&vQIN-{sEY4LF& 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%0A17arrZtIQZ0b@n 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

wbz_Ot6r8dtT(Eqj3we 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

PwD*A?~}}FA{B_R`cZU(y)084 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%0A7_M;4<`Ic;AJn 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 FeVyZpv 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 Date: Mon, 12 Oct 2026 15:43:17 +0100 Subject: [PATCH 240/283] Retire obsolete version-two scratch normalization test --- .../pilot04-workstream-default-checker.md | 4 ++ backend/tests/test_artifact_preparation.py | 44 ------------------- 2 files changed, 4 insertions(+), 44 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index bbb719b3d..537a43632 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -1039,3 +1039,7 @@ and `restore_predecessor_evidence_schema` functions from `backend/tests/migration_fixtures.py` after the raw callers were reconciled. A repository search found no remaining callers. The separately consumed project guide fixture context remains unchanged; no shared live consumer is deleted. + +The first scratch-module run passed 93 current cases and exposed one remaining +obsolete version-two normalization test. Remove that upgrade-only test as part +of the same authorized cutover; rerun the complete current scratch module. diff --git a/backend/tests/test_artifact_preparation.py b/backend/tests/test_artifact_preparation.py index b4d56ecad..68eebf8e9 100644 --- a/backend/tests/test_artifact_preparation.py +++ b/backend/tests/test_artifact_preparation.py @@ -1296,50 +1296,6 @@ async def test_malformed_ledger_and_layout_fail_closed(tmp_path: Path) -> None: ArtifactScratchManager(root=unsafe_root, limits=preparation_limits()) -@pytest.mark.asyncio -async def test_version_two_scratch_ledger_is_normalized_on_reopen(tmp_path: Path) -> None: - """Preserve restart compatibility for the genuine version-two ledger.""" - root = tmp_path / "scratch" - initial = ArtifactScratchManager(root=root, limits=preparation_limits()) - owner_process_identity = initial._owner_process_identity - initial.close() - ledger_path = root / ".ledger.json" - ledger = json.loads(ledger_path.read_text(encoding="utf-8")) - ledger["version"] = 2 - workspace_name = f"extract_{'a' * 32}" - (root / "workspaces" / workspace_name).mkdir(mode=0o700) - ledger["workspaces"] = [ - { - "workspace_name": workspace_name, - "created_at_unix_ns": 1, - "expires_at_unix_ns": 10**20, - "owner_pid": os.getpid(), - "owner_process_identity": owner_process_identity, - } - ] - ledger_path.write_text(json.dumps(ledger), encoding="utf-8") - - reopened = ArtifactScratchManager(root=root, limits=preparation_limits()) - reservation, descriptor = await reopened.allocate() - os.close(descriptor) - await reopened.release(reservation) - - normalized = json.loads(ledger_path.read_text(encoding="utf-8")) - assert normalized["version"] == 3 - assert normalized["workspaces"] == [ - { - "workspace_name": workspace_name, - "reserved_bytes": 0, - "maximum_entries": preparation_limits().maximum_workspace_entries, - "created_at_unix_ns": 1, - "expires_at_unix_ns": 10**20, - "owner_pid": os.getpid(), - "owner_process_identity": owner_process_identity, - } - ] - reopened.close() - - @pytest.mark.asyncio async def test_truncated_version_three_scratch_ledger_fails_closed(tmp_path: Path) -> None: """Reject a current-version ledger missing workspace custody state.""" From 0a675cc224143ddbf9eb687cf266bcf8bf1906e9 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 15:43:56 +0100 Subject: [PATCH 241/283] Remove the retired scratch marker generator --- backend/app/modules/artifacts/preparation.py | 21 -------------------- 1 file changed, 21 deletions(-) diff --git a/backend/app/modules/artifacts/preparation.py b/backend/app/modules/artifacts/preparation.py index b2c416832..c7ef816b1 100644 --- a/backend/app/modules/artifacts/preparation.py +++ b/backend/app/modules/artifacts/preparation.py @@ -1205,27 +1205,6 @@ def _marker_content(limits: ArtifactPreparationLimits) -> bytes: return _ROOT_MARKER_PREFIX + hashlib.sha256(canonical).hexdigest().encode("ascii") + b"\n" - def _legacy_marker_content(limits: ArtifactPreparationLimits) -> bytes: - """Reconstruct the pre-04B2 marker for one safe-empty local upgrade.""" - payload = { - "aggregate_reserved_bytes": limits.aggregate_reserved_bytes, - "cleanup_margin_seconds": float(limits.cleanup_margin_seconds), - "maximum_concurrency": limits.maximum_concurrency, - "maximum_files": limits.maximum_files, - "maximum_source_bytes": limits.maximum_source_bytes, - "minimum_free_bytes": limits.minimum_free_bytes, - "reservation_ttl_seconds": float(limits.reservation_ttl_seconds), - "stream_buffer_bytes": limits.stream_buffer_bytes, - "total_deadline_seconds": float(limits.total_deadline_seconds), - } - canonical = json.dumps( - payload, - allow_nan=False, - separators=(",", ":"), - sort_keys=True, - ).encode("utf-8") - return _ROOT_MARKER_PREFIX + hashlib.sha256(canonical).hexdigest().encode("ascii") + b"\n" - @staticmethod def _validate_layout_entries( entries: set[str], From 389f5caacaba414ca5ba6d3628ee28c6e0215068 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 15:50:47 +0100 Subject: [PATCH 242/283] Verify exact additive selected custody without retained backfill --- .../pilot04-workstream-default-checker.md | 11 ++++++ .../submission_dispatch/test_migration.py | 36 +++++++++++++------ 2 files changed, 36 insertions(+), 11 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 537a43632..2ac76c058 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -1043,3 +1043,14 @@ guide fixture context remains unchanged; no shared live consumer is deleted. The first scratch-module run passed 93 current cases and exposed one remaining obsolete version-two normalization test. Remove that upgrade-only test as part of the same authorized cutover; rerun the complete current scratch module. + +### Retained dispatch upgrade assertion reconciliation + +The composed native batch passed three retry/replacement migration controls and +exposed the dispatch test's outdated additive-column assertion after upgrading +to current 0036. In `backend/tests/tasks/submission_dispatch/test_migration.py`, +replace the single 0034-column allowlist with the exact 0034/0036 columns on +Admissions, Submissions and CheckerRuns. Every added value must remain NULL; +all retained rows/values, counts, authority and no-dispatch assertions remain +exact. No automatic/dynamic column exclusion, backfill, schema change, relaxed +selection or skip. Rerun the failed node and independently review the delta. diff --git a/backend/tests/tasks/submission_dispatch/test_migration.py b/backend/tests/tasks/submission_dispatch/test_migration.py index a0c0b9a15..8617d0144 100644 --- a/backend/tests/tasks/submission_dispatch/test_migration.py +++ b/backend/tests/tasks/submission_dispatch/test_migration.py @@ -36,17 +36,31 @@ async def snapshot(): before = await snapshot() await asyncio.to_thread(command.upgrade, _config(), current_schema_revision()) after = await snapshot() - before_admissions = json.loads(before.pop("submission_bundle_admissions")) - after_admissions = json.loads(after.pop("submission_bundle_admissions")) - assert len(after_admissions) == len(before_admissions) - for retained, upgraded in zip( - before_admissions, after_admissions, strict=True - ): - assert set(upgraded) == set(retained) | { - "checker_remediation_manifest_id" - } - assert upgraded.pop("checker_remediation_manifest_id") is None - assert upgraded == retained + added_columns = { + "submissions": { + "selected_post_submit_policy_sha256", "selected_post_submit_policy_body", + }, + "checker_runs": { + "selected_post_submit_policy_sha256", "selected_post_submit_policy_body", + }, + "submission_bundle_admissions": { + "checker_remediation_manifest_id", "selected_pre_submit_run_id", + "guide_id", "guide_version", "source_snapshot_id", "source_snapshot_sha256", + "effective_policy_id", "effective_policy_sha256", "pre_submit_policy_id", + "pre_submit_policy_sha256", "effective_plan_sha256", "selected_rules_sha256", + "selected_post_submit_policy_sha256", "selected_post_submit_policy_body", + "packet_sha256", "semantic_manifest_body", + }, + } + for table, columns_added in added_columns.items(): + retained_rows = sorted(json.loads(before.pop(table)), key=lambda row: row["id"]) + upgraded_rows = sorted(json.loads(after.pop(table)), key=lambda row: row["id"]) + assert len(upgraded_rows) == len(retained_rows) + for retained, upgraded in zip(retained_rows, upgraded_rows, strict=True): + assert set(upgraded) == set(retained) | columns_added + for column in columns_added: + assert upgraded.pop(column) is None + assert upgraded == retained assert after == before columns = await connection.fetch(""" SELECT table_name,data_type,is_nullable From 1009454b5b6ab8ea00d1a24bf5f733e25a10556a Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 16:01:24 +0100 Subject: [PATCH 243/283] [PILOT-04] Retire legacy pre-submit writers --- .../pilot04-workstream-default-checker.md | 20 ++++ .../versions/0036_selected_checker_flow.py | 111 +++++++++--------- .../execution/test_checker_retry_migration.py | 100 ++++++++++++++++ backend/tests/conftest.py | 2 +- backend/tests/test_alembic.py | 28 +++++ 5 files changed, 203 insertions(+), 58 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 2ac76c058..a5dad4e47 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -1054,3 +1054,23 @@ Admissions, Submissions and CheckerRuns. Every added value must remain NULL; all retained rows/values, counts, authority and no-dispatch assertions remain exact. No automatic/dynamic column exclusion, backfill, schema change, relaxed selection or skip. Rerun the failed node and independently review the delta. + +### Retired PRE database write refusal + +The current-schema cutover now refuses every new write through the retained PRE +attempt/evidence tables while preserving their immutable rows for historical +inspection. New bundle intent and admission rows must carry selected PRE lineage; +valid archived evidence can no longer open the removed writer path. The five +legacy trigger functions are reduced to unconditional SQLSTATE 55000 retained-data +refusals, so no catalogue reconstruction or attempt-completion implementation +remains executable at the current head. An archived 0034 source regression clones +each old row shape and proves intent, admission, attempt, evidence, result and +attempt-update refusal with byte-exact retained-row equality. The installed-body +test validates every PL/pgSQL function and asserts these functions contain only +the refusal contract. A fresh PG16 install reached the canonical fingerprint +boundary after all function validators and measured +`f510310623f222209cbbee89291edb8e1582d65ddaf9d173d534dd796ab68991` in +199.51 seconds; isolated database, role and MinIO cleanup all completed. This +measurement used the uncommitted repair tree and is fingerprint evidence, not a +frozen-head positive runtime claim. Current selected PRE/Submission/POST native +flow must pass again after integration. diff --git a/backend/alembic/versions/0036_selected_checker_flow.py b/backend/alembic/versions/0036_selected_checker_flow.py index 1a5fc3f39..ad5e838c9 100644 --- a/backend/alembic/versions/0036_selected_checker_flow.py +++ b/backend/alembic/versions/0036_selected_checker_flow.py @@ -182,8 +182,12 @@ def _replace_admission_guards() -> None: raise exception 'submission bundle durable intent requires submission_bundle put attempt' using errcode='23514'; end if; - if new.selected_pre_submit_run_id is not null then - select count(*) into selected_matches + if new.pre_submit_evidence_set_id is not null + or new.selected_pre_submit_run_id is null then + raise exception 'submission bundle durable intent requires selected PRE lineage' + using errcode='23514'; + end if; + select count(*) into selected_matches from public.selected_pre_submit_runs r join public.artifact_put_attempts a on a.id=new.put_attempt_id where r.id=new.selected_pre_submit_run_id and r.status='completed' and r.eligible @@ -195,9 +199,8 @@ def _replace_admission_guards() -> None: and a.project_id=r.project_id and a.task_id=r.task_id and a.sha256=r.archive_sha256 and a.byte_count=r.archive_byte_count and a.media_type='application/zip'; - if selected_matches<>1 then - raise exception 'selected PRE durable intent custody mismatch' using errcode='23514'; - end if; + if selected_matches<>1 then + raise exception 'selected PRE durable intent custody mismatch' using errcode='23514'; end if; return new; end $$ @@ -224,57 +227,12 @@ def _replace_admission_guards() -> None: returns trigger language plpgsql set search_path=pg_catalog,public,pg_temp as $$ declare matches integer; begin - if new.pre_submit_evidence_set_id is not null then - select count(*) into matches - from public.submission_bundle_durable_intents intent - join public.pre_submit_evidence_sets evidence on evidence.id=intent.pre_submit_evidence_set_id - join public.artifact_put_attempts attempt on attempt.id=intent.put_attempt_id - join public.artifact_replicas replica on replica.id=attempt.replica_id - join public.artifact_contents content on content.id=replica.content_id - join public.artifact_verification_jobs job - on job.originating_put_attempt_id=attempt.id and job.replica_id=replica.id - join public.artifact_verification_receipts verification on verification.verification_job_id=job.id - where intent.id=new.durable_intent_id and evidence.id=new.pre_submit_evidence_set_id - and attempt.id=new.put_attempt_id and content.id=new.artifact_content_id - and replica.id=new.verified_replica_id and verification.id=new.verification_receipt_id - and attempt.producer_request_type='submission_bundle' - and attempt.producer_type='actor_profile' and attempt.producer_ref=evidence.actor_profile_id::text - and attempt.project_id=evidence.project_id and attempt.task_id=evidence.task_id - and attempt.media_type='application/zip' and content.media_type='application/zip' - and attempt.status='object_confirmed' and evidence.terminal_status='passed' and evidence.eligible - and replica.verification_state='verified' and replica.availability_state='available' - and replica.integrity_state='valid' and verification.outcome='verified' - and verification.execution_generation=job.execution_generation - and verification.observed_sha256=attempt.sha256 - and verification.observed_sha256=content.sha256 - and verification.observed_sha256=evidence.archive_sha256 - and verification.observed_byte_count=attempt.byte_count - and verification.observed_byte_count=content.byte_count - and verification.observed_byte_count=evidence.archive_byte_count - and new.actor_profile_id=evidence.actor_profile_id - and new.identity_link_id=evidence.identity_link_id - and new.project_id=evidence.project_id and new.task_id=evidence.task_id - and new.assignment_id=evidence.assignment_id - and new.predecessor_submission_id is not distinct from evidence.predecessor_submission_id - and new.predecessor_submission_version is not distinct from evidence.predecessor_submission_version - and new.checker_remediation_manifest_id is not distinct from - evidence.checker_remediation_manifest_id - and new.locked_policy_context_hash=evidence.locked_policy_context_hash - and new.semantic_manifest_id=evidence.semantic_manifest_id - and new.semantic_manifest_sha256=evidence.semantic_manifest_sha256 - and new.archive_sha256=evidence.archive_sha256 and new.archive_byte_count=evidence.archive_byte_count - and ((new.put_operation_receipt_id is not null and exists( - select 1 from public.artifact_operation_receipts receipt - where receipt.id=new.put_operation_receipt_id and receipt.put_attempt_id=attempt.id - and receipt.replica_id=replica.id and receipt.outcome='stored_pending_verification')) - or (new.put_observation_receipt_id is not null and exists( - select 1 from public.artifact_put_observation_receipts observation - where observation.id=new.put_observation_receipt_id and observation.put_attempt_id=attempt.id - and observation.outcome='observed_confirmed' - and observation.observed_sha256=attempt.sha256 - and observation.observed_byte_count=attempt.byte_count))); - else - select count(*) into matches + if new.pre_submit_evidence_set_id is not null + or new.selected_pre_submit_run_id is null then + raise exception 'submission bundle admission requires selected PRE lineage' + using errcode='23514'; + end if; + select count(*) into matches from public.submission_bundle_durable_intents intent join public.selected_pre_submit_runs r on r.id=intent.selected_pre_submit_run_id join public.artifact_put_attempts attempt on attempt.id=intent.put_attempt_id @@ -338,7 +296,6 @@ def _replace_admission_guards() -> None: and observation.outcome='observed_confirmed' and observation.observed_sha256=attempt.sha256 and observation.observed_byte_count=attempt.byte_count))); - end if; if matches<>1 then raise exception 'submission bundle admission verified lineage mismatch' using errcode='23514'; end if; @@ -346,6 +303,45 @@ def _replace_admission_guards() -> None: end $$ """) + +def _retire_legacy_pre_submit_writers() -> None: + op.execute(r""" +create or replace function public.guard_pre_submit_attempt() +returns trigger language plpgsql set search_path=pg_catalog,public,pg_temp as $$ +begin + raise exception 'retained pre-submit attempts are immutable' using errcode='55000'; +end $$ +""") + op.execute(r""" +create or replace function public.guard_pre_submit_evidence_set_creation() +returns trigger language plpgsql set search_path=pg_catalog,public,pg_temp as $$ +begin + raise exception 'retained pre-submit evidence is immutable' using errcode='55000'; +end $$ +""") + op.execute(r""" +create or replace function public.guard_pre_submit_evidence_result_membership() +returns trigger language plpgsql set search_path=pg_catalog,public,pg_temp as $$ +begin + raise exception 'retained pre-submit evidence results are immutable' using errcode='55000'; +end $$ +""") + op.execute(r""" +create or replace function public.require_pre_submit_attempt_evidence() +returns trigger language plpgsql set search_path=pg_catalog,public,pg_temp as $$ +begin + raise exception 'retained pre-submit evidence is immutable' using errcode='55000'; +end $$ +""") + op.execute(r""" +create or replace function public.require_pre_submit_result_reconstruction() +returns trigger language plpgsql set search_path=pg_catalog,public,pg_temp as $$ +begin + raise exception 'retained pre-submit evidence results are immutable' using errcode='55000'; +end $$ +""") + + def _selected_run_guards() -> None: op.execute(r""" create function public.guard_selected_pre_submit_run_insert() returns trigger @@ -1126,6 +1122,7 @@ def upgrade() -> None: _create_selected_run_table() _alter_selected_lineage() _replace_admission_guards() + _retire_legacy_pre_submit_writers() _selected_run_guards() _replace_guide_approval_custody() _replace_post_policy_custody() diff --git a/backend/tests/checkers/execution/test_checker_retry_migration.py b/backend/tests/checkers/execution/test_checker_retry_migration.py index 8eea422a7..0e6f76b4c 100644 --- a/backend/tests/checkers/execution/test_checker_retry_migration.py +++ b/backend/tests/checkers/execution/test_checker_retry_migration.py @@ -223,3 +223,103 @@ async def test_retry_upgrade_preserves_evidence_and_installs_closure( ) finally: await connection.close() + +async def test_current_schema_refuses_new_archived_pre_submit_lineage( + isolated_database_env, + migration_lock, +): + """Retain archived rows while refusing every new old-lineage insertion.""" + with migration_lock(): + await _reset_to_predecessor(isolated_database_env) + await restore_archived_snapshot( + isolated_database_env, "0034_checker_retry_source" + ) + await db_session.dispose_engine() + await asyncio.to_thread(command.upgrade, _config(), "head") + connection = await _connection(isolated_database_env) + try: + before = await _retained_rows(connection) + intent_id = await connection.fetchval(""" + SELECT id FROM public.submission_bundle_durable_intents + WHERE pre_submit_evidence_set_id IS NOT NULL + """) + admission_id = await connection.fetchval(""" + SELECT id FROM public.submission_bundle_admissions + WHERE pre_submit_evidence_set_id IS NOT NULL + """) + attempt_id = await connection.fetchval( + "SELECT id FROM public.pre_submit_execution_attempts" + ) + evidence_id = await connection.fetchval( + "SELECT id FROM public.pre_submit_evidence_sets" + ) + result_id = await connection.fetchval( + "SELECT id FROM public.pre_submit_evidence_results ORDER BY result_order LIMIT 1" + ) + assert all((intent_id, admission_id, attempt_id, evidence_id, result_id)) + with pytest.raises( + asyncpg.CheckViolationError, + match="submission bundle durable intent requires selected PRE lineage", + ): + async with connection.transaction(): + await connection.execute(""" + INSERT INTO public.submission_bundle_durable_intents + SELECT (jsonb_populate_record( + NULL::public.submission_bundle_durable_intents, + to_jsonb(value) || jsonb_build_object('id',$1::uuid) + )).* FROM public.submission_bundle_durable_intents value + WHERE value.id=$2::uuid + """, new_record_id(), intent_id) + with pytest.raises( + asyncpg.CheckViolationError, + match="submission bundle admission requires selected PRE lineage", + ): + async with connection.transaction(): + await connection.execute(""" + INSERT INTO public.submission_bundle_admissions + SELECT (jsonb_populate_record( + NULL::public.submission_bundle_admissions, + to_jsonb(value) || jsonb_build_object('id',$1::uuid) + )).* FROM public.submission_bundle_admissions value + WHERE value.id=$2::uuid + """, new_record_id(), admission_id) + for table, source_id, message in ( + ( + "pre_submit_execution_attempts", + attempt_id, + "retained pre-submit attempts are immutable", + ), + ( + "pre_submit_evidence_sets", + evidence_id, + "retained pre-submit evidence is immutable", + ), + ( + "pre_submit_evidence_results", + result_id, + "retained pre-submit evidence results are immutable", + ), + ): + with pytest.raises(asyncpg.PostgresError, match=message) as refused: + async with connection.transaction(): + await connection.execute(f""" + INSERT INTO public.{table} + SELECT (jsonb_populate_record( + NULL::public.{table}, + to_jsonb(value) || jsonb_build_object('id',$1::uuid) + )).* FROM public.{table} value WHERE value.id=$2::uuid + """, new_record_id(), source_id) + assert refused.value.sqlstate == "55000" + with pytest.raises( + asyncpg.PostgresError, + match="retained pre-submit attempts are immutable", + ) as refused: + async with connection.transaction(): + await connection.execute(""" + UPDATE public.pre_submit_execution_attempts + SET status=status WHERE id=$1::uuid + """, attempt_id) + assert refused.value.sqlstate == "55000" + assert await _retained_rows(connection) == before + finally: + await connection.close() diff --git a/backend/tests/conftest.py b/backend/tests/conftest.py index 3132d4412..c01f1b6f4 100644 --- a/backend/tests/conftest.py +++ b/backend/tests/conftest.py @@ -23,7 +23,7 @@ DDL_LOCK_DIRECTORY = Path("/tmp") # Match the PostgreSQL 16 engine used by Backend CI. Catalog identity rendering # differs across major versions; regenerate only after comparing actual objects. -EXPECTED_PUBLIC_SCHEMA_SHA256 = "866ab4fb13d787cf2a96d9e9ed5357aa771f61beffae446074c77a7a8928719e" +EXPECTED_PUBLIC_SCHEMA_SHA256 = "f510310623f222209cbbee89291edb8e1582d65ddaf9d173d534dd796ab68991" PROTECTED_TEST_TABLES = ( "actor_profile_migration_state", "alembic_version", diff --git a/backend/tests/test_alembic.py b/backend/tests/test_alembic.py index 28615bb59..2f66f6e10 100644 --- a/backend/tests/test_alembic.py +++ b/backend/tests/test_alembic.py @@ -251,6 +251,11 @@ async def installed_functions() -> dict[str, str]: "external_checker_locked_policies_valid", "require_guide_proposal_approval", "require_post_policy_operation", + "guard_pre_submit_attempt", + "guard_pre_submit_evidence_set_creation", + "guard_pre_submit_evidence_result_membership", + "require_pre_submit_attempt_evidence", + "require_pre_submit_result_reconstruction", ], ) await _assert_canonical_test_schema(connection) @@ -268,6 +273,11 @@ async def installed_functions() -> dict[str, str]: "external_checker_locked_policies_valid", "require_guide_proposal_approval", "require_post_policy_operation", + "guard_pre_submit_attempt", + "guard_pre_submit_evidence_set_creation", + "guard_pre_submit_evidence_result_membership", + "require_pre_submit_attempt_evidence", + "require_pre_submit_result_reconstruction", } for name in ( "protect_checker_run_custody", @@ -303,6 +313,24 @@ async def installed_functions() -> dict[str, str]: assert "is distinct from 'external_checker_policies.v1'" in definitions[ "external_checker_locked_policies_valid" ].lower() + retired = { + "guard_pre_submit_attempt": "retained pre-submit attempts are immutable", + "guard_pre_submit_evidence_set_creation": ( + "retained pre-submit evidence is immutable" + ), + "guard_pre_submit_evidence_result_membership": ( + "retained pre-submit evidence results are immutable" + ), + "require_pre_submit_attempt_evidence": ( + "retained pre-submit evidence is immutable" + ), + "require_pre_submit_result_reconstruction": ( + "retained pre-submit evidence results are immutable" + ), + } + for name, message in retired.items(): + assert message in definitions[name] + assert " select " not in definitions[name].lower() def test_current_head_installs_submission_lineage_contract( From 857f0c69a94214f60a8ee9d5746274881d1c31df Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 16:04:13 +0100 Subject: [PATCH 244/283] [PILOT-04] Encode archived member protocol envelope --- .../changes/pilot04-workstream-default-checker.md | 10 ++++++++++ .../checkers/execution/historical_execution.py | 14 +++++++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index a5dad4e47..21d6e3d90 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -1074,3 +1074,13 @@ boundary after all function validators and measured measurement used the uncommitted repair tree and is fingerprint evidence, not a frozen-head positive runtime claim. Current selected PRE/Submission/POST native flow must pass again after integration. + +### Archived terminal member envelope + +The literal terminal fixture now encodes raw archived member columns with the +required `post_submit_structural_result` protocol tag, matching the predecessor +0008 SQL reconstruction. Supplied counts, routing, severity and material remain +literal; a conflicting supplied tag refuses. The pure bare-member control passes +and fails on the prior helper at the intended envelope equality assertion. +Ruff and diff checks pass. This repairs fixture serialization only; the completed +0008 native migration discriminator remains required before claiming that path. diff --git a/backend/tests/checkers/execution/historical_execution.py b/backend/tests/checkers/execution/historical_execution.py index 9adce57ac..8e0a1c731 100644 --- a/backend/tests/checkers/execution/historical_execution.py +++ b/backend/tests/checkers/execution/historical_execution.py @@ -183,6 +183,18 @@ def archived_terminal_rows(h, lease, *, outcome, members, counts, """Encode supplied archived terminal facts without classifying any member.""" request = _json_facts(h.request) reservation = lease["reservation"] + serialized_members = [] + for member in members: + assert member.get("schema_version", "post_submit_structural_result") == ( + "post_submit_structural_result" + ), "archived member protocol tag differs from predecessor SQL" + serialized_members.append({ + "schema_version": "post_submit_structural_result", + **{key: deepcopy(member[key]) for key in ( + "checker_id", "definition_version", "implementation_version", "status", + "code", "failure_category", "severity", "counters", + )}, + }) result = _json_facts({ "schema_version": "post_submit_evaluation_result", "request_id": request["evaluation_request_id"], @@ -191,7 +203,7 @@ def archived_terminal_rows(h, lease, *, outcome, members, counts, "evaluation_generation": request["evaluation_generation"], "result_id": reservation["result_id"], "outcome": outcome, - "member_results": members, + "member_results": serialized_members, "infrastructure_failure_code": failure_code, }) result["result_digest"] = canonical_json_hash(result) From 835737909aa3844d6cda1a0605a3098ed73781c1 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 16:05:18 +0100 Subject: [PATCH 245/283] [PILOT-04] Complete predecessor service facts --- .../pilot04-workstream-default-checker.md | 15 +++++++++++++++ .../fixtures/pilot04_predecessor_rows.json.gz | Bin 787235 -> 789150 bytes .../tests/historical_submission_fixtures.py | 13 ++++++++----- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 21d6e3d90..c1453182e 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -1084,3 +1084,18 @@ literal; a conflicting supplied tag refuses. The pure bare-member control passes and fails on the prior helper at the intended envelope equality assertion. Ruff and diff checks pass. This repairs fixture serialization only; the completed 0008 native migration discriminator remains required before claiming that path. + +### Captured service principal prerequisites + +The static predecessor archive now carries the exact project-neutral POST service +actor `01a13047-9e70-7b29-a0c9-f30981caec3b` and active identity link +`01a13047-9e71-7f5e-88ea-ee2d1b04ac68` in the 15 applicable 0010-through-0024 +snapshots. Both rows were captured by writer `926b4ef118db3708e50d1869db5ee78a79e5b5de` +in the named `0034_checker_retry_source` snapshot; provenance therefore describes +these snapshots as composite captures rather than claiming every row came from +one fresh database. No retry run, audit, grant, receipt or project-bound row is +copied. A decoded old/new comparison proves exactly 30 supplemental rows and +identical seeds, revisions, tables and values everywhere else. The archive is +checksum-bound at `25560b75796f84cff46bb506abdcd4b9cc2b7535411096fdbbec921d245d95e9`. +This supplies a retained predecessor identity prerequisite; canonical migration +and receipt proof remains required. diff --git a/backend/tests/fixtures/pilot04_predecessor_rows.json.gz b/backend/tests/fixtures/pilot04_predecessor_rows.json.gz index fcc80505e530e3957e127a3feaf1d33d4e10d4e5..a344c1b3e40d324afd5f5367998ec626552eb813 100644 GIT binary patch delta 770908 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%0A_$;nV$9=xa4*fA{P{ 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

q+CL^5oSr7M8mD&UQ$OT6VQ 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

iTRXfjaeO!VPy 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ß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öiuI&WAE|0L>U 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ȿMF~?vA#RdC6f73J>=&0 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 z zjx@iI=9g&Tp!A*-Av@vuZ!A5Q3T`#F zoY2}o%GkPB7O#VtNo_0px8$gzsFB*Pki_Jr`;70wg0VF`?@IBjH}2E7dl`B66Kq#E zr-Q{ls^T|0YXcyEUf-NwhIu}qoSC#U#7Cr5E@`<|`zD+87HVj0wy=9VohIUj855l0 zEIerKTBqlS8t`(fyH9$xZM2jG2c+b41-d4qM*#UcZyz?=A13>rw`H@tqYsClC}s5s z#qZki-B(3$_0DXc7QK5T`D}jPI?EnVSZ!$M$9b6T%U0EYo~O0hgBoq5P?+K}Z1|$v z45w`??W}IeT)aDl;7Px&J8of_Bxw~NGjYoTlWHsr42sy)8l}@Vr()E&jfZD;T5Dn> zGwJ$P`Y6Z@IP2mnyy>@ayItru`iuOak~W~1qbDEjES$cf;E=axOV#^&{gJ`tJH&^K z_EBcnu^3ZLq)aryRo(e3$MouRWB>1wZPwR=MBbx9+*qMe3M zPRjX@G&9|smTcr)CH1 z)S+f-C4vvz+TsAM&GRfT!oeE)wnEJ$?O^KOsC=9%75`}jK;egZ7*SY54B9o5UZ)xn#&?x%`dM<*^jr* zbe9@@__Y}tX&CEhiB9IUxtUL{FV0R!Azgh3ei-#&h@yQ=2ZlEK4xENqPTTtnkojVN z>-RS!0&lGYL7Z}&yYctC2zU^6In6EIO&N4xr#3$B>?~XnY#=#A`R_-OvfGy9J_R~D z5w=CZ-B$`>XyWNa(YinB{ra=+L;9)?@7rshrK9km9?>T;wwq^vX}TZSP4Nu9L`U!AN8o*YGDk`CtX(fp;BtBn z-kc}d$~@H8>f^o2AI6(8y}iwq(TDMk{204T>K%seUi))pX702^?`VH+u_kZv47__E z84jK%Nx}Y#mV1*FJlNs*kW-w``vl+}i7=A?Hg+S7$fZL-6M~DNwq&%F82W z8*x(YtE;TuZ76piRkchc^M9igilYZw;jn)5p^;@5XJ_;4Jvm|Q301n*n+F+pJ}<4& zTuf5WjOoX7Dtc6#SS4?CRMLB^we;&*m(qO)9Dg4g%(e>MU8|?L>)b9Rjc#lzqKT!t zCNiI$m0p;ZDi0Z(otzJ;C@eSlixQ1^9j)@&R8ObMoaVgPZ1IFP(%Dj@i3QS=b0_Ge z^y|AM&ka__$VAK-foCZvBNH=dNHJqoGPXb-LO`1UX2`W5`<Slp&yt;l{UiCwK)h+8V=RF*RlpD^;({xTguzwD< zq;Mq`CUTJ_Xia5|tMExM?OBi-0+^TVqqL3)%Nr%LgLGAfJLTKd@wX%l8}q;fUA^lk zeRg#-Ie|Y++EVRol!2V+$MtgFFGF8K084o=eMzY)xRxMnL6waX13z#VbbK-Tk^@eg zsvyEtZJ=Z-1F%*>@B`~hK~+gysDIE@T1k;gQZ`7Y473-_4U<)cZj;>UTmsAxR`Gw* z%M^?##p=80OVw7K6*)(!-WnmL3jVbzQs6z4kWqyT$Ca`o^Xe#G`V?vLZlRZG;&U3;KHYXEI@`y

g%;O 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
JdUD~@{=PCjˤNy*;5 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

)fEW+8QopOR6~k)=%GT&# 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�ziL!CEG#@p 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 diff --git a/backend/tests/historical_submission_fixtures.py b/backend/tests/historical_submission_fixtures.py index 4c1625a19..8839240ec 100644 --- a/backend/tests/historical_submission_fixtures.py +++ b/backend/tests/historical_submission_fixtures.py @@ -1,9 +1,12 @@ """Checksum-bound predecessor rows for migration tests only. -The archive is a one-time database backup from the last pre-cutover writer. It -contains data, not an executable checker implementation. Restore is confined -to an isolated predecessor database and finishes with every trigger and foreign -key setting restored before a migration test receives the fixture. +The archive projects one-time predecessor captures to their declared schemas. +Snapshots from 0010 through 0024 also include the exact project-neutral POST +service actor and link captured by the same writer in the 0034 source snapshot; +the archive provenance names those two supplemental row IDs. It contains data, +not an executable checker implementation. Restore is confined to an isolated +predecessor database and finishes with every trigger and foreign key setting +restored before a migration test receives the fixture. """ from __future__ import annotations @@ -25,7 +28,7 @@ _ARCHIVE = Path(__file__).with_name("fixtures") / "pilot04_predecessor_rows.json.gz" -_ARCHIVE_SHA256 = "a3dd109d6f25e49ff47746906561fccf4ec7e2bd3e40dd3cb984ce8e0ddc2e37" +_ARCHIVE_SHA256 = "25560b75796f84cff46bb506abdcd4b9cc2b7535411096fdbbec921d245d95e9" _SCHEMA_VERSION = "workstream.pilot04_predecessor_rows.v1" From 99432809649a92243b9040e35eb3d2481a99b923 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 16:22:16 +0100 Subject: [PATCH 246/283] test: derive archived project from stored task --- .../changes/pilot04-workstream-default-checker.md | 10 ++++++++++ backend/tests/migration_ancestor_rows.py | 3 ++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index c1453182e..1eb8c7c1f 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -1055,6 +1055,16 @@ all retained rows/values, counts, authority and no-dispatch assertions remain exact. No automatic/dynamic column exclusion, backfill, schema change, relaxed selection or skip. Rerun the failed node and independently review the delta. +### Archived project ownership query + +The native paid-0018 discriminator at clean `70424eedb` passed archive and checker +source preparation but stopped on a fixture assumption that Submission stores a +project ID. The raw ancestor query now joins its stored TASK for that field, +matching the schema owner without a request fallback or invented column. Every +remaining Submission field used by this helper is checked against the canonical +model. All migration assertions and actual SQL guards remain unchanged; only the +same paid discriminator is rerun after this repair. + ### Retired PRE database write refusal The current-schema cutover now refuses every new write through the retained PRE diff --git a/backend/tests/migration_ancestor_rows.py b/backend/tests/migration_ancestor_rows.py index 743443edd..bd28bf6e1 100644 --- a/backend/tests/migration_ancestor_rows.py +++ b/backend/tests/migration_ancestor_rows.py @@ -41,7 +41,8 @@ async def seed_packet_ancestors(h): revision = await session.scalar(text("SELECT version_num FROM public.alembic_version")) assert 11 <= int(revision[:4]) <= 28 submission = (await session.execute(text( - "SELECT * FROM public.submissions WHERE id=:id" + "SELECT s.*,t.project_id FROM public.submissions s " + "JOIN public.workstream_tasks t ON t.id=s.task_id WHERE s.id=:id" ), {"id": UUID(h.request["submission_id"])})).mappings().one() guide = (await session.execute(text( "SELECT * FROM public.project_guides WHERE project_id=:project AND version=:version" From 82c00e8ab28f3a16be43fb442fcda26fe8f45b96 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 16:29:59 +0100 Subject: [PATCH 247/283] test: commit archived pending review queue before lease claim --- .../changes/pilot04-workstream-default-checker.md | 12 ++++++++++++ backend/tests/migration_ancestor_rows.py | 3 +++ 2 files changed, 15 insertions(+) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 1eb8c7c1f..e46b2b365 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -1065,6 +1065,18 @@ remaining Submission field used by this helper is checked against the canonical model. All migration assertions and actual SQL guards remain unchanged; only the same paid discriminator is rerun after this repair. +### Archived queue and claim custody + +The subsequent paid discriminator at clean `d524a4090` reached the raw queue +fixture and correctly refused its pending-insert deferred event after an active +lease was added in the same transaction. In the same allowed raw ancestor helper, +commit the literal pending queue without a lease, then claim that stored queue in +a separate transaction by inserting its lease and updating the queue pointer. +This matches the predecessor SQL lifecycle without disabling guards or invoking +a current Review service. Audit the remaining queue/lease enums, packet identity, +review counts/digests and terminal updates against the installed predecessor +guards before rerunning only the paid discriminator; retain all assertions. + ### Retired PRE database write refusal The current-schema cutover now refuses every new write through the retained PRE diff --git a/backend/tests/migration_ancestor_rows.py b/backend/tests/migration_ancestor_rows.py index bd28bf6e1..768c21ccf 100644 --- a/backend/tests/migration_ancestor_rows.py +++ b/backend/tests/migration_ancestor_rows.py @@ -70,6 +70,9 @@ async def seed_packet_ancestors(h): routing_reason="first_submission", queue_state="pending", active_lease_id=None, routing_generation=1, lifecycle_generation=1, first_queued_at=now, available_since=now, )) + # The pending-insert deferred guard must see the committed queue without a + # lease before the separate claim transaction creates its active lease. + async with h.factory() as session, session.begin(): await session.execute(insert(ReviewLease).values( id=h.lease_id, review_queue_entry_id=h.queue_id, project_id=str(submission["project_id"]), task_id=str(submission["task_id"]), From e644e7041bdc23a8ba9f28e7b0542899672b4341 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 16:34:35 +0100 Subject: [PATCH 248/283] [PILOT-04] Record frozen cutover and retained-data proofs --- .../pilot04-workstream-default-checker.md | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index e46b2b365..f0bb0ff57 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -1121,3 +1121,36 @@ identical seeds, revisions, tables and values everywhere else. The archive is checksum-bound at `25560b75796f84cff46bb506abdcd4b9cc2b7535411096fdbbec921d245d95e9`. This supplies a retained predecessor identity prerequisite; canonical migration and receipt proof remains required. + +### Frozen cutover verification before publication + +At clean `835737909aa3844d6cda1a0605a3098ed73781c1`, the canonical isolated +PostgreSQL/MinIO runner passed three current-schema controls in 245.53 seconds: +all installed PL/pgSQL functions compile; new writes through retired PRE shapes +are refused with exact SQLSTATE and retained-row equality; and the current +selected admission/dispatch/empty-POST production completion path reaches shared +false-policy acceptance with complete contribution/award facts and exact replay. +Runner exit was zero and database, role and object-store cleanup completed. +Installed fingerprint is `f510310623f222209cbbee89291edb8e1582d65ddaf9d173d534dd796ab68991`. + +Independent SQL/TASK/ART source reviews and archive review passed their named +frozen heads. The full current scratch module passed 93 tests after both format +upgrade implementations and upgrade-only tests were removed. Ruff and all six +current documentation/process gates passed. Canonical collection at `835737909` +found 8,754 unique tests across ten lanes with no exclusions; this is collection, +not exhaustive execution. + +The repaired completed-0008 discriminator passed at clean `70424eedb` in 90.06 +seconds; its prior exact-source control failed with the intended terminal-member +error in 89.96 seconds. Paid-0018 preservation passed at clean `0749dfb10` in 96.33 +seconds, reaching the actual submitter record and exact two awards through 0019. +Both canonical runners exited zero with full database/role/object-store cleanup. +Fixture join and queue/claim transaction repairs received independent test-delta +review without changing retained-value, refusal, count or zero-effect assertions. +Prior fixture failures and bounded runner timeouts remain qualified in raw logs; +a timed-out runner is never counted as a pass even when its pytest log completed. + +Remaining raw migration controls, a fresh final image drill and full required +hosted CI remain necessary before human merge approval. The actual Rust image +proof at `6fd3fde80` uses local runc/docker-dev and does not claim hosted gVisor, +public contributor upload/CLI or an exhaustive suite. No deployment or merge. From ef2c9604dd45bdee7f2abaa3bbffca88a867fcf6 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 17:05:59 +0100 Subject: [PATCH 249/283] [PILOT-04] Restore direct SQL approval custody controls --- .../tests/projects/post_policy/test_guards.py | 130 ++++++++++++++++++ 1 file changed, 130 insertions(+) diff --git a/backend/tests/projects/post_policy/test_guards.py b/backend/tests/projects/post_policy/test_guards.py index 4abb43339..bd7373acf 100644 --- a/backend/tests/projects/post_policy/test_guards.py +++ b/backend/tests/projects/post_policy/test_guards.py @@ -1,22 +1,29 @@ """Reachable downstream negatives with complete finalized and approved source custody.""" +import json from dataclasses import replace +from datetime import UTC, datetime from uuid import uuid4 import pytest from sqlalchemy import text from sqlalchemy.exc import DBAPIError +from app.core.identifiers import new_record_id from app.modules.projects.api.guide_proposals import GuideProposalError, GuideProposalSelection from app.modules.projects.api.post_policy import ( PostPolicyApproval, PostPolicyDerive, post_policy_human_authorization_selector, ) +from app.modules.projects.post_policy.models import PostPolicyOperation from app.modules.projects.post_policy.service import PostPolicyService +from tests.checkers.external.support import post_registry_spec +from tests.projects.guide_activation.source_fixtures import source_case from tests.projects.guide_compilation.helpers import service_actor from tests.projects.guide_compilation.proposals.pg_support import proposal_case, revoke_review_grant from .pg_support import PostAuthority, operate, prepare_post_policy +from .test_authority import foreign_manager, state async def test_valid_finalization_without_upstream_approval_cannot_project(clean_postgres_database): @@ -66,6 +73,129 @@ async def omit_only_operation(*args): assert (await operate(factory, actor, command.project_id, grant, 'approve', payload)).kind == 'approve' +@pytest.mark.parametrize('change,error', [ + ('output_digest', 'post-policy operation lineage mismatch'), + ('foreign_grant', 'guide proposal current authority missing'), + ('wrong_action', 'post-policy authority evidence mismatch'), +]) +async def test_direct_sql_rejects_one_substituted_external_policy_commitment( + clean_postgres_database, monkeypatch, change, error, +): + selected_spec = post_registry_spec() + async with source_case( + clean_postgres_database, + post_submit_registry_spec=selected_spec, + ) as (values, factory, command, actor, grant): + _, projected = await prepare_post_policy(factory, command, actor, grant, service_actor(values)) + async with factory() as session: + stored = ( + await session.execute( + text( + 'SELECT policy.policy_body, registry.id AS registry_entry_id, ' + 'registry.entry_digest FROM checker_policies policy ' + 'JOIN external_checker_registry_entries registry ' + 'ON registry.capability_id=:capability_id ' + 'AND registry.capability_version=:capability_version ' + "AND registry.phase='post_submit' WHERE policy.id=:policy_id" + ), + dict( + capability_id=selected_spec.capability_id, + capability_version=selected_spec.capability_version, + policy_id=str(projected.target.policy_id), + ), + ) + ).mappings().one() + policy_body = stored['policy_body'] + assert policy_body['schema_version'] == 'external_post_submit_policy.v1' + assert len(policy_body['entries']) == 1 + locked_registry = policy_body['entries'][0]['registry'] + assert locked_registry['capability_id'] == selected_spec.capability_id + assert locked_registry['registry_entry_id'] == str(stored['registry_entry_id']) + assert locked_registry['entry_digest'] == stored['entry_digest'] + _, _, _, foreign_grant = await foreign_manager(factory, actor) + payload = PostPolicyApproval(target=projected.target, idempotency_key=uuid4()) + before = await state(factory) + async with factory() as session: + await session.begin() + captured = [] + original_add = session.add + + def capture_operation(row, **kwargs): + if isinstance(row, PostPolicyOperation): + captured.append(row) + else: + original_add(row, **kwargs) + + try: + with monkeypatch.context() as patch: + patch.setattr(session, 'add', capture_operation) + service = PostPolicyService( + session, + PostAuthority(session, actor, command.project_id, grant), + ) + receipt = await service.approve(payload, actor=actor, request_id=uuid4()) + assert len(captured) == 1 + row = { + column.name: getattr(captured[0], column.name) + for column in PostPolicyOperation.__table__.columns + } + row['created_at'] = datetime.now(UTC) + assert row['operation_id'] == receipt.operation_id + if change == 'output_digest': + row['output_digest'] = 'sha256:' + 'b' * 64 + elif change == 'foreign_grant': + row['admin_role_grant_id'] = foreign_grant + else: + wrong_event = str(new_record_id()) + await session.execute( + text( + 'INSERT INTO audit_events SELECT ' + '(jsonb_populate_record(NULL::audit_events, ' + 'to_jsonb(source)||CAST(:patch AS jsonb))).* ' + 'FROM audit_events source WHERE id=:id' + ), + dict( + id=row['authorization_decision_event_id'], + patch=json.dumps(dict( + id=wrong_event, + entity_id=wrong_event, + action_id='project.post_submit_checker_policy.correction.request', + )), + ), + ) + row['authorization_decision_event_id'] = wrong_event + await session.execute( + text( + 'INSERT INTO project_post_policy_operations SELECT ' + '(jsonb_populate_record(' + 'NULL::project_post_policy_operations, CAST(:row AS jsonb))).*' + ), + dict(row=json.dumps(row, default=str)), + ) + with pytest.raises(DBAPIError, match=error) as refused: + await session.execute( + text('SET CONSTRAINTS post_policy_operation_custody IMMEDIATE') + ) + assert refused.value.orig.sqlstate == '23514' + finally: + await session.rollback() + assert await state(factory) == before + recovered = await operate(factory, actor, command.project_id, grant, 'approve', payload) + assert recovered.kind == 'approve' + assert recovered.operation_id != receipt.operation_id + async with factory() as session: + durable = ( + await session.execute( + text( + "SELECT operation_id,authorization_decision_event_id FROM " + "project_post_policy_operations WHERE kind='approve'" + ) + ) + ).mappings().one() + assert durable['operation_id'] == recovered.operation_id + assert durable['authorization_decision_event_id'] != row['authorization_decision_event_id'] + + async def test_revoked_manager_cannot_approve_or_replay(clean_postgres_database): async with proposal_case(clean_postgres_database) as (values, factory, command, actor, grant): _, projected = await prepare_post_policy(factory, command, actor, grant, service_actor(values)) From f42ff698e5b94f7ddbd7cc2a224c4db28b999ffa Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 17:14:46 +0100 Subject: [PATCH 250/283] [PILOT-04] Reconcile selected admission and transport test custody --- .../pilot04-workstream-default-checker.md | 34 ++++++ .../test_selected_pre_submit_coordination.py | 4 +- backend/tests/projects/policy_read_faults.py | 4 +- .../evaluation_delivery/test_completion.py | 15 ++- .../tasks/test_payment_policy_migration.py | 9 ++ backend/tests/test_artifact_bindings.py | 111 ++++++++---------- backend/tests/test_artifact_bindings_db.py | 14 +-- .../tests/test_post_submit_materialization.py | 5 +- backend/tests/test_post_submit_selection.py | 2 + backend/tests/test_submission_composition.py | 5 +- .../test_submission_preparation_adapter.py | 4 +- 11 files changed, 129 insertions(+), 78 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index f0bb0ff57..88ea03b99 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -59,6 +59,40 @@ cleanup. ### Allowed +- Current selected-custody fixture closure also permits + `backend/tests/checkers/external/test_selected_pre_submit_coordination.py`, + `backend/tests/test_post_submit_selection.py`, + `backend/tests/test_post_submit_materialization.py`, + `backend/tests/projects/policy_read_faults.py` and + `backend/tests/tasks/test_payment_policy_migration.py`. + Remove obsolete call signatures/evidence-set joins and use the current + selected manifest, grant location and full context hash. Replace the old + catalogue-rule corruption with a hash-consistent invalid default identity. + Migration assertions must preserve every original value while explicitly + checking the exact additive current columns; no wildcard tolerance or row + rewrite. Keep all authority, immutable evidence and recovery assertions. + +- Hosted ART-binding fixture reconciliation permits + `backend/tests/test_artifact_bindings.py`, + `backend/tests/test_artifact_bindings_db.py`, + `backend/tests/test_submission_composition.py` and + `backend/tests/test_submission_preparation_adapter.py`, plus this record. + Replace superseded evidence-set fixtures with complete current selected-run + admission facts and exact authority inputs. Retain denial, immutable packet, + stale lineage, concurrent single consumption, rollback and fresh replay + proofs. Diagnose any database lock failure before changing cleanup; never + hide it with retry, disabling guards or adding a second admission path. + No production/schema changes are authorized by this fixture repair. Focused + pure tests and real PostgreSQL controls precede independent review/full CI. + +- The hosted transport-budget test repair permits + `backend/tests/tasks/evaluation_delivery/test_completion.py` and this record. + Configure an explicit test-owned in-memory broker before importing the actual + Celery task and clear settings custody after the check. Preserve every timeout, + lease and actual task hard-limit assertion; no production setting, worker + topology, CI cap or execution behavior changes. Acceptance is the isolated + no-broker test and existing worker topology controls, followed by full CI. + - Final dead-contract removal permits the obsolete CHECKERS modules `api/pre_submit.py`, `api/post_submit.py`, `api/historical_post_submit.py`, `api/policy_compilation.py` and `post_submit_contracts.py`, their unused exports diff --git a/backend/tests/checkers/external/test_selected_pre_submit_coordination.py b/backend/tests/checkers/external/test_selected_pre_submit_coordination.py index 0e91025a6..cc5cbff4a 100644 --- a/backend/tests/checkers/external/test_selected_pre_submit_coordination.py +++ b/backend/tests/checkers/external/test_selected_pre_submit_coordination.py @@ -438,7 +438,7 @@ def test_submission_artifact_request_selects_exactly_one_pre_lineage() -> None: replace(request, selected_terminal_digest=None) -def test_selected_ready_admission_no_longer_requires_legacy_evidence() -> None: +def test_selected_ready_admission_binds_selected_run() -> None: run_id = new_record_id() admission = SimpleNamespace( id=str(new_record_id()), @@ -480,7 +480,7 @@ def test_selected_ready_admission_no_longer_requires_legacy_evidence() -> None: submission_version=1, ) - assert SubmissionAdmissionConsumptionService._art_lineage_is_intact(admission, None, content) + assert SubmissionAdmissionConsumptionService._art_lineage_is_intact(admission, content) facts = SubmissionAdmissionConsumptionService._authority_facts(admission, request) assert facts.evidence_set_id is None assert facts.selected_pre_submit_run_id == run_id diff --git a/backend/tests/projects/policy_read_faults.py b/backend/tests/projects/policy_read_faults.py index 252819c13..7d0773635 100644 --- a/backend/tests/projects/policy_read_faults.py +++ b/backend/tests/projects/policy_read_faults.py @@ -52,9 +52,7 @@ async def corrupt_locked_policy_reads(monkeypatch, task_id, mutation): "package_required": "yes", "allowed_package_formats": "zip", } elif mutation == "bundle": - pre.compiled_bundle["rules"] = [ - rule for rule in pre.compiled_bundle["rules"] if rule["primitive"] != "require_file" - ] + pre.compiled_bundle["workstream_default"]["checker_version"] = "unsupported-default" elif mutation == "stale_effective": effective.effective_policy["required_evidence"] = [] elif mutation == "stale_bundle": diff --git a/backend/tests/tasks/evaluation_delivery/test_completion.py b/backend/tests/tasks/evaluation_delivery/test_completion.py index 18f1a7eeb..0d7f62a1e 100644 --- a/backend/tests/tasks/evaluation_delivery/test_completion.py +++ b/backend/tests/tasks/evaluation_delivery/test_completion.py @@ -172,7 +172,20 @@ def test_completion_handler_is_registered_in_production_registry(): assert delivery._options_for(COMPLETION_EVENT, 1) == DeliveryOptions() -def test_production_request_transport_covers_maximum_selected_execution(): +def test_production_request_transport_covers_maximum_selected_execution(monkeypatch): + from app.core.config import get_settings + + # This checks the actual task declaration without publishing to a broker. + monkeypatch.setenv("WORKSTREAM_CELERY_BROKER_URL", "memory://") + monkeypatch.setenv("WORKSTREAM_ARTIFACT_STORE_BACKEND", "disabled") + get_settings.cache_clear() + try: + _assert_production_request_transport_budget() + finally: + get_settings.cache_clear() + + +def _assert_production_request_transport_budget(): from app.workers.outbox import deliver_event from app.workers.outbox_topology import OUTBOX_PROCESS_SHUTDOWN_MARGIN_SECONDS diff --git a/backend/tests/tasks/test_payment_policy_migration.py b/backend/tests/tasks/test_payment_policy_migration.py index 84165b707..02ce3ff00 100644 --- a/backend/tests/tasks/test_payment_policy_migration.py +++ b/backend/tests/tasks/test_payment_policy_migration.py @@ -128,6 +128,15 @@ async def test_payment_cleanup_refuses_each_retained_fact_then_preserves_current f"SELECT to_jsonb(t) FROM public.{table} t ORDER BY to_jsonb(t)::text"))) removed = FIELDS if table == "workstream_tasks" else (FIELDS[-1],) if table == "submissions" else () expected = [{k: v for k, v in row.items() if k not in removed} for row in before[0][table]] + if table == "submissions": + added = {"selected_post_submit_policy_sha256", "selected_post_submit_policy_body"} + actual.sort(key=lambda row: row["id"]) + expected.sort(key=lambda row: row["id"]) + assert len(actual) == len(expected) + for upgraded, retained in zip(actual, expected, strict=True): + assert set(upgraded) == set(retained) | added + for column in added: + assert upgraded.pop(column) is None assert actual == expected, table assert ( await connection.scalar(text("SELECT version_num FROM public.alembic_version")) diff --git a/backend/tests/test_artifact_bindings.py b/backend/tests/test_artifact_bindings.py index b4f6d2f39..20ceea031 100644 --- a/backend/tests/test_artifact_bindings.py +++ b/backend/tests/test_artifact_bindings.py @@ -7,6 +7,8 @@ from datetime import UTC, datetime from dataclasses import replace from app.modules.checkers.api import SubmissionPacketView +from app.core.hashing import canonical_json_hash +from app.modules.checkers.api.external_policy import LockedExternalPostSubmitPolicy from types import SimpleNamespace from unittest.mock import AsyncMock, Mock from uuid import UUID @@ -65,7 +67,10 @@ def _lineage(request: SubmissionAdmissionConsumptionRequest): refs = context.locked_project_context manifest = _manifest(_archive([("answer.txt", b"verified")])) content_id = str(new_record_id()) - evidence_id = str(new_record_id()) + policy_body = {"schema_version": "external_post_submit_policy.v1", "entries": []} + policy = LockedExternalPostSubmitPolicy.model_validate({ + **policy_body, "policy_sha256": canonical_json_hash(policy_body), + }) admission = SimpleNamespace( id=str(request.admission_id), status="ready", @@ -76,12 +81,19 @@ def _lineage(request: SubmissionAdmissionConsumptionRequest): predecessor_submission_id=None, predecessor_submission_version=None, checker_remediation_manifest_id=None, - pre_submit_evidence_set_id=evidence_id, + pre_submit_evidence_set_id=None, + selected_pre_submit_run_id=str(new_record_id()), identity_link_id=str(new_record_id()), artifact_content_id=content_id, locked_policy_context_hash=_sha("5"), semantic_manifest_id=str(new_record_id()), semantic_manifest_sha256=manifest.sha256, + semantic_manifest_body=manifest.as_dict(), + packet_sha256=request.packet_sha256, + effective_plan_sha256=_sha("6"), + selected_rules_sha256=_sha("7"), + selected_post_submit_policy_body=policy.model_dump(mode="json"), + selected_post_submit_policy_sha256=policy.policy_sha256, archive_sha256=_sha("4"), archive_byte_count=9, consumed_at=None, @@ -89,41 +101,21 @@ def _lineage(request: SubmissionAdmissionConsumptionRequest): consumed_by_submission_version=None, stale_at=None, stale_reason=None, - ) - evidence = SimpleNamespace( - packet_sha256=request.packet_sha256, - id=evidence_id, - actor_profile_id=admission.actor_profile_id, - identity_link_id=admission.identity_link_id, - project_id=admission.project_id, - task_id=admission.task_id, - assignment_id=admission.assignment_id, - predecessor_submission_id=admission.predecessor_submission_id, - predecessor_submission_version=admission.predecessor_submission_version, - checker_remediation_manifest_id=None, guide_version=refs.guide_version, source_snapshot_id=str(refs.source_snapshot_id), source_snapshot_sha256=refs.source_snapshot_hash, effective_policy_id=str(refs.effective_policy_id), - locked_artifact_policy_sha256=refs.effective_policy_hash, + effective_policy_sha256=refs.effective_policy_hash, pre_submit_policy_id=str(refs.pre_submit_policy_id), - locked_checker_policy_sha256=refs.pre_submit_policy_bundle_hash, - locked_policy_context_hash=admission.locked_policy_context_hash, - semantic_manifest_id=admission.semantic_manifest_id, - semantic_manifest_sha256=admission.semantic_manifest_sha256, - semantic_manifest_body=manifest.as_dict(), - archive_sha256=admission.archive_sha256, - archive_byte_count=admission.archive_byte_count, + pre_submit_policy_sha256=refs.pre_submit_policy_bundle_hash, guide_id=str(new_record_id()), - terminal_status="passed", - eligible=True, ) content = SimpleNamespace( id=content_id, sha256=admission.archive_sha256, byte_count=admission.archive_byte_count, ) - return admission, evidence, content + return admission, content class _Allow: @@ -174,9 +166,9 @@ async def test_explicit_denial_precedes_admission_disclosure() -> None: @pytest.mark.asyncio async def test_ready_admission_creates_exact_binding_and_consumes_once() -> None: request = _request() - admission, evidence, content = _lineage(request) + admission, content = _lineage(request) now = datetime.now(UTC) - session = _session(admission, evidence, content, None, now) + session = _session(admission, content, None, now) authority = _Allow() result = await SubmissionAdmissionConsumptionService(session, authority).consume(request) @@ -195,7 +187,8 @@ async def test_ready_admission_creates_exact_binding_and_consumes_once() -> None assert admission.consumed_at == now facts = authority.consume.await_args.args[0] assert facts.admission_id == request.admission_id - assert facts.evidence_set_id.hex == evidence.id.replace("-", "") + assert facts.evidence_set_id is None + assert facts.selected_pre_submit_run_id == UUID(admission.selected_pre_submit_run_id) assert facts.actor_profile_id == request.task_context.contributor_id assert facts.identity_link_id.hex == admission.identity_link_id.replace("-", "") assert facts.project_id == request.task_context.locked_project_context.project_id @@ -205,17 +198,17 @@ async def test_ready_admission_creates_exact_binding_and_consumes_once() -> None assert facts.predecessor_submission_version is None assert facts.submission_id == request.submission_id assert facts.submission_version == request.submission_version - assert facts.guide_id.hex == evidence.guide_id.replace("-", "") - assert facts.guide_version == evidence.guide_version - assert facts.source_snapshot_id.hex == evidence.source_snapshot_id.replace("-", "") - assert facts.source_snapshot_sha256 == evidence.source_snapshot_sha256 - assert facts.effective_policy_id.hex == evidence.effective_policy_id.replace("-", "") - assert facts.effective_policy_sha256 == evidence.locked_artifact_policy_sha256 - assert facts.pre_submit_policy_id.hex == evidence.pre_submit_policy_id.replace("-", "") - assert facts.pre_submit_policy_sha256 == evidence.locked_checker_policy_sha256 - assert facts.locked_policy_context_hash == evidence.locked_policy_context_hash - assert facts.semantic_manifest_id.hex == evidence.semantic_manifest_id.replace("-", "") - assert facts.semantic_manifest_sha256 == evidence.semantic_manifest_sha256 + assert facts.guide_id.hex == admission.guide_id.replace("-", "") + assert facts.guide_version == admission.guide_version + assert facts.source_snapshot_id.hex == admission.source_snapshot_id.replace("-", "") + assert facts.source_snapshot_sha256 == admission.source_snapshot_sha256 + assert facts.effective_policy_id.hex == admission.effective_policy_id.replace("-", "") + assert facts.effective_policy_sha256 == admission.effective_policy_sha256 + assert facts.pre_submit_policy_id.hex == admission.pre_submit_policy_id.replace("-", "") + assert facts.pre_submit_policy_sha256 == admission.pre_submit_policy_sha256 + assert facts.locked_policy_context_hash == admission.locked_policy_context_hash + assert facts.semantic_manifest_id.hex == admission.semantic_manifest_id.replace("-", "") + assert facts.semantic_manifest_sha256 == admission.semantic_manifest_sha256 assert facts.content_id == result.content_id assert facts.sha256 == admission.archive_sha256 assert facts.byte_count == admission.archive_byte_count @@ -231,9 +224,9 @@ async def test_ready_admission_creates_exact_binding_and_consumes_once() -> None @pytest.mark.asyncio async def test_final_authority_denial_leaves_ready_admission_unchanged() -> None: request = _request() - admission, evidence, content = _lineage(request) + admission, content = _lineage(request) authority = _DenyFinal() - session = _session(admission, evidence, content, None) + session = _session(admission, content, None) with pytest.raises( SubmissionAdmissionConsumptionError, @@ -251,10 +244,10 @@ async def test_final_authority_denial_leaves_ready_admission_unchanged() -> None @pytest.mark.asyncio async def test_proven_task_lineage_change_marks_ready_admission_stale() -> None: request = _request() - admission, evidence, content = _lineage(request) - evidence.source_snapshot_sha256 = _sha("9") + admission, content = _lineage(request) + admission.source_snapshot_sha256 = _sha("9") now = datetime.now(UTC) - session = _session(admission, evidence, content, now) + session = _session(admission, content, now) authority = _Allow() result = await SubmissionAdmissionConsumptionService(session, authority).consume(request) @@ -271,9 +264,9 @@ async def test_proven_task_lineage_change_marks_ready_admission_stale() -> None: @pytest.mark.asyncio async def test_broken_art_lineage_denies_without_staling_admission() -> None: request = _request() - admission, evidence, content = _lineage(request) + admission, content = _lineage(request) content.sha256 = _sha("9") - session = _session(admission, evidence, content) + session = _session(admission, content) authority = _Allow() with pytest.raises( @@ -292,13 +285,13 @@ async def test_broken_art_lineage_denies_without_staling_admission() -> None: @pytest.mark.asyncio async def test_matching_consumed_admission_replays_exact_binding() -> None: request = _request() - admission, evidence, content = _lineage(request) + admission, content = _lineage(request) admission.status = "consumed" decision_id = new_record_id() admission.consumed_by_submission_id = str(request.submission_id) admission.consumed_by_submission_version = request.submission_version binding = SimpleNamespace(id=str(new_record_id()), content_id=admission.artifact_content_id) - session = _session(admission, evidence, content, binding) + session = _session(admission, content, binding) session.get.return_value = SimpleNamespace(binding_id=binding.id, decision_id=str(decision_id)) authority = _Allow() @@ -317,7 +310,7 @@ async def test_matching_consumed_admission_replays_exact_binding() -> None: @pytest.mark.asyncio async def test_consumed_admission_rejects_different_submission() -> None: request = _request() - admission, _, _ = _lineage(request) + admission, _ = _lineage(request) admission.status = "consumed" admission.consumed_by_submission_id = str(new_record_id()) admission.consumed_by_submission_version = request.submission_version @@ -343,11 +336,11 @@ async def test_consumed_admission_rejects_wrong_submission_version() -> None: submission_version=2, task_context=original.task_context, ) - admission, evidence, content = _lineage(original) + admission, content = _lineage(original) admission.status = "consumed" admission.consumed_by_submission_id = str(original.submission_id) admission.consumed_by_submission_version = original.submission_version - session = _session(admission, evidence, content, None) + session = _session(admission, content, None) with pytest.raises( SubmissionAdmissionConsumptionError, @@ -359,7 +352,7 @@ async def test_consumed_admission_rejects_wrong_submission_version() -> None: @pytest.mark.asyncio async def test_stale_admission_is_terminal_without_art_mutation() -> None: request = _request() - admission, _, _ = _lineage(request) + admission, _ = _lineage(request) admission.status = "stale" admission.stale_at = datetime.now(UTC) admission.stale_reason = "locked_submission_context_changed" @@ -394,14 +387,14 @@ async def test_consumption_requires_caller_owned_root_transaction() -> None: @pytest.mark.parametrize("corruption", ["absent", "file_hash", "foreign_body"]) async def test_consumption_rejects_invalid_manifest_before_binding(corruption): request = _request() - admission, evidence, content = _lineage(request) + admission, content = _lineage(request) if corruption == "absent": - evidence.semantic_manifest_body = None + admission.semantic_manifest_body = None elif corruption == "file_hash": - evidence.semantic_manifest_body["entries"][0]["sha256"] = "sha256:" + "f" * 64 + admission.semantic_manifest_body["entries"][0]["sha256"] = "sha256:" + "f" * 64 else: - evidence.semantic_manifest_body = _manifest(_archive([("foreign.txt", b"other")])).as_dict() - session = _session(admission, evidence, content) + admission.semantic_manifest_body = _manifest(_archive([("foreign.txt", b"other")])).as_dict() + session = _session(admission, content) authority = _Allow() with pytest.raises(SubmissionAdmissionConsumptionError, match="submission_bundle_admission_unavailable"): await SubmissionAdmissionConsumptionService(session, authority).consume(request) @@ -415,7 +408,7 @@ async def test_consumption_rejects_invalid_manifest_before_binding(corruption): @pytest.mark.parametrize("field", ["summary", "contributor_attestation"]) async def test_changed_packet_denies_before_binding_or_consumed_replay(status, field): original = _request() - admission, evidence, content = _lineage(original) + admission, content = _lineage(original) admission.status = status if status == "consumed": admission.consumed_by_submission_id = str(original.submission_id) @@ -425,7 +418,7 @@ async def test_changed_packet_denies_before_binding_or_consumed_replay(status, f request = replace(original, packet_sha256=changed.sha256) binding = SimpleNamespace(id=str(new_record_id()), content_id=admission.artifact_content_id) continuation = (binding,) if status == "consumed" else (None, datetime.now(UTC)) - session = _session(admission, evidence, content, *continuation) + session = _session(admission, content, *continuation) session.get.return_value = SimpleNamespace(binding_id=UUID(binding.id), decision_id=new_record_id()) authority = _Allow() expected = "submission_bundle_admission_unavailable" if status == "ready" else "submission_bundle_admission_context_changed" diff --git a/backend/tests/test_artifact_bindings_db.py b/backend/tests/test_artifact_bindings_db.py index b20650790..545970ef2 100644 --- a/backend/tests/test_artifact_bindings_db.py +++ b/backend/tests/test_artifact_bindings_db.py @@ -14,7 +14,6 @@ from app.modules.artifacts.models import ( ArtifactBinding, ArtifactContent, - PreSubmitEvidenceSet, SubmissionBundleAdmission, SubmissionBindingReceipt, ) from app.modules.artifacts.submission_bindings import ( @@ -33,7 +32,6 @@ _TABLES = ( ArtifactContent.__table__, - PreSubmitEvidenceSet.__table__, SubmissionBundleAdmission.__table__, ArtifactBinding.__table__, Submission.__table__, @@ -113,7 +111,7 @@ async def _set_schema(session, schema: str) -> None: async def _seed(session, schema: str, request) -> None: - admission, evidence, content = _lineage(request) + admission, content = _lineage(request) await _set_schema(session, schema) await session.execute( ArtifactContent.__table__.insert().values( @@ -122,9 +120,6 @@ async def _seed(session, schema: str, request) -> None: byte_count=content.byte_count, ) ) - await session.execute( - PreSubmitEvidenceSet.__table__.insert().values(**vars(evidence)) - ) await session.execute( SubmissionBundleAdmission.__table__.insert().values( **vars(admission), durable_intent_id=str(new_record_id()), put_attempt_id=str(new_record_id()), @@ -248,7 +243,12 @@ async def consume_once(): assert exc.code == "submission_bundle_admission_already_consumed" return None - outcomes = await asyncio.gather(consume_once(), consume_once()) + contenders = [asyncio.create_task(consume_once()) for _ in range(2)] + try: + outcomes = await asyncio.gather(*contenders) + finally: + # Join both transactions before schema teardown even if one fails. + await asyncio.gather(*contenders, return_exceptions=True) assert sum(result is not None for result in outcomes) == 1 original = next(result for result in outcomes if result is not None) async with factory.begin() as session: diff --git a/backend/tests/test_post_submit_materialization.py b/backend/tests/test_post_submit_materialization.py index b1ea62ec8..9d52a0587 100644 --- a/backend/tests/test_post_submit_materialization.py +++ b/backend/tests/test_post_submit_materialization.py @@ -91,7 +91,7 @@ async def evaluate(self, request, view): await super().evaluate(request, view) external_request = self.external_request(view.external_checker_material) with view.external_checker_grant(external_request) as grant: - self.grant_path = view._workspace.parent / grant.grant_id + self.grant_path = view._preparation._root / "workspaces" / grant.grant_id self.manifest = json.loads( (self.grant_path / ".external-checker-grant.json").read_text() ) @@ -428,7 +428,6 @@ async def capture(service, request): ] async with h.factory() as session: body = await session.scalar(text( - "select e.semantic_manifest_body from pre_submit_evidence_sets e " - "join submission_bundle_admissions a on a.pre_submit_evidence_set_id=e.id where a.id=:id" + "select semantic_manifest_body from submission_bundle_admissions where id=:id" ), {"id": str(h.created.admission_id)}) assert body == h.manifest.as_dict() diff --git a/backend/tests/test_post_submit_selection.py b/backend/tests/test_post_submit_selection.py index a117ef0dd..55fff9acf 100644 --- a/backend/tests/test_post_submit_selection.py +++ b/backend/tests/test_post_submit_selection.py @@ -63,6 +63,8 @@ def observe(connection, cursor, statement, parameters, context, executemany): "review_generation": "locked_review_policy_generation", "review_hash": "locked_review_policy_hash", "revision_policy_id": "locked_revision_policy_id", "revision_generation": "locked_revision_policy_generation", "revision_hash": "locked_revision_policy_hash", + "selected_post_policy_hash": "selected_post_submit_policy_sha256", + "selected_post_policy_body": "selected_post_submit_policy_body", } assert {key: str(value) for key, value in asdict(facts.context).items()} == { key: str(row[column]) for key, column in mapping.items() diff --git a/backend/tests/test_submission_composition.py b/backend/tests/test_submission_composition.py index bf5a324cb..f2ce5fcce 100644 --- a/backend/tests/test_submission_composition.py +++ b/backend/tests/test_submission_composition.py @@ -251,7 +251,7 @@ async def add_submission(self, submission): persisted.append(submission) service._repository = Repository() # This test isolates ART result validation, not policy validation behavior. service._contexts = SimpleNamespace(_load_locked_task_context=AsyncMock()) - with pytest.raises(RuntimeError, match="exact binding facts"): + with pytest.raises(SubmissionCreationUnavailable, match="submission creation is unavailable"): await service.create(request) assert events == ["authorize", "prepare", "art"] assert len(persisted) == 1 @@ -331,9 +331,10 @@ def _consumption_values(*, binding=False, remediation=False): ) if binding: values.update({name: str(new_record_id()) for name in ( - "evidence_set_id", "project_id", "guide_id", "semantic_manifest_id", "content_id", + "selected_pre_submit_run_id", "project_id", "guide_id", "semantic_manifest_id", "content_id", )}) values.update( + evidence_set_id=None, resource_type="submission_binding", resource_id=values["admission_id"], locked_policy_context_hash="sha256:" + "2" * 64, semantic_manifest_sha256="sha256:" + "3" * 64, diff --git a/backend/tests/test_submission_preparation_adapter.py b/backend/tests/test_submission_preparation_adapter.py index 58c2b6c79..ad608ab78 100644 --- a/backend/tests/test_submission_preparation_adapter.py +++ b/backend/tests/test_submission_preparation_adapter.py @@ -50,7 +50,9 @@ async def test_final_preparation_rejects_cross_request_facts() -> None: assignment_id=new_record_id(), predecessor_submission_id=None, predecessor_submission_version=None, - pre_submit_evidence_set_id=new_record_id(), + pre_submit_evidence_set_id=None, + selected_pre_submit_run_id=new_record_id(), + selected_terminal_digest=_sha("9"), prepared_generation_id=new_record_id(), guide_id=new_record_id(), guide_version="v1", From 10e46153d34dc92ef62e5974566ae6212b350402 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 17:20:30 +0100 Subject: [PATCH 251/283] [PILOT-04] Bound concurrent fixture cleanup and grant lookup --- .../changes/pilot04-workstream-default-checker.md | 5 +++++ backend/tests/test_artifact_bindings_db.py | 12 ++++++++---- backend/tests/test_post_submit_materialization.py | 7 ++++--- backend/tests/test_submission_predecessor_custody.py | 1 + 4 files changed, 18 insertions(+), 7 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 88ea03b99..79e0f26ab 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -59,6 +59,11 @@ cleanup. ### Allowed +- `backend/tests/test_submission_predecessor_custody.py` may replace the + unavailable-provider test double with the actual async-iterable `open` port. + Preserve the infrastructure-failure result and denial before replacement + byte access; no production provider behavior or outcome change. + - Current selected-custody fixture closure also permits `backend/tests/checkers/external/test_selected_pre_submit_coordination.py`, `backend/tests/test_post_submit_selection.py`, diff --git a/backend/tests/test_artifact_bindings_db.py b/backend/tests/test_artifact_bindings_db.py index 545970ef2..4663f625d 100644 --- a/backend/tests/test_artifact_bindings_db.py +++ b/backend/tests/test_artifact_bindings_db.py @@ -289,10 +289,14 @@ async def consume_competing(value): SubmissionBundleAdmission, str(value.admission_id) )).status - outcomes = await asyncio.gather( - consume_competing(first_competing), - consume_competing(competing), - ) + contenders = [ + asyncio.create_task(consume_competing(first_competing)), + asyncio.create_task(consume_competing(competing)), + ] + try: + outcomes = await asyncio.gather(*contenders) + finally: + await asyncio.gather(*contenders, return_exceptions=True) assert sorted(outcomes) == [ "consumed", "stale", diff --git a/backend/tests/test_post_submit_materialization.py b/backend/tests/test_post_submit_materialization.py index 9d52a0587..cc069b63b 100644 --- a/backend/tests/test_post_submit_materialization.py +++ b/backend/tests/test_post_submit_materialization.py @@ -53,9 +53,10 @@ async def evaluate(self, request, view): class ExternalGrantConsumer(Consumer): """Exercise the real POST lineage through ART's callback-scoped grant.""" - def __init__(self, files, execution): + def __init__(self, files, execution, scratch): super().__init__(files) self.execution = execution + self.scratch = scratch self.grant_path = None self.manifest = None @@ -91,7 +92,7 @@ async def evaluate(self, request, view): await super().evaluate(request, view) external_request = self.external_request(view.external_checker_material) with view.external_checker_grant(external_request) as grant: - self.grant_path = view._preparation._root / "workspaces" / grant.grant_id + self.grant_path = self.scratch / "workspaces" / grant.grant_id self.manifest = json.loads( (self.grant_path / ".external-checker-grant.json").read_text() ) @@ -161,7 +162,7 @@ async def test_exact_materialization_reads_verified_original_and_revokes_view(tm async def test_post_external_grant_binds_native_submission_art_and_lease(tmp_path, isolated_database_env): async with material_fixture(tmp_path, isolated_database_env) as h: execution = await material_execution(h) - consumer = ExternalGrantConsumer(h.files, execution) + consumer = ExternalGrantConsumer(h.files, execution, h.scratch) material = await h.service.materialize(execution, consumer) assert material.evaluation.outcome == "completed" assert consumer.manifest["lease_id"] == str(execution.lease.lease_id) diff --git a/backend/tests/test_submission_predecessor_custody.py b/backend/tests/test_submission_predecessor_custody.py index 995844829..e698417d0 100644 --- a/backend/tests/test_submission_predecessor_custody.py +++ b/backend/tests/test_submission_predecessor_custody.py @@ -920,6 +920,7 @@ async def test_nonremediation_outcome_cannot_authorize_replacement_before_bytes( async def unavailable(*_args, **_kwargs): raise ArtifactStoreUnavailableError("selected input unavailable") + yield b"" # Preserve ArtifactStore.open's async-iterator port. failure.setattr(h.store, "open", unavailable) result = await live_executor(h).evaluate_post_submission(h.request) From a1fc30e3094cd50015cc741c847340c53d12939f Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 17:29:32 +0100 Subject: [PATCH 252/283] [PILOT-04] Assert immediate grant revocation and outer cleanup separately --- backend/tests/test_post_submit_materialization.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/backend/tests/test_post_submit_materialization.py b/backend/tests/test_post_submit_materialization.py index cc069b63b..cd64eb660 100644 --- a/backend/tests/test_post_submit_materialization.py +++ b/backend/tests/test_post_submit_materialization.py @@ -100,7 +100,10 @@ async def evaluate(self, request, view): assert self.manifest["submission_id"] == str(request.submission_id) assert self.manifest["request_digest"] == external_request.request_digest assert self.manifest["binding_digest"] == grant.binding_digest - assert not self.grant_path.exists() + # Revocation removes the service grant immediately; the outer material + # callback still owns its workspace until materialization completes. + assert self.grant_path.is_dir() + assert not (self.grant_path / ".external-checker-grant.json").exists() changed = view.external_checker_material.model_copy( update={"binding_id": new_record_id()} From bd73e8c71a6893d6994459e34f9bb0fc93e60b42 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 17:36:54 +0100 Subject: [PATCH 253/283] [PILOT-04] Enter the grant context when testing material substitution --- backend/tests/test_post_submit_materialization.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/backend/tests/test_post_submit_materialization.py b/backend/tests/test_post_submit_materialization.py index cd64eb660..14a63ae39 100644 --- a/backend/tests/test_post_submit_materialization.py +++ b/backend/tests/test_post_submit_materialization.py @@ -109,7 +109,8 @@ async def evaluate(self, request, view): update={"binding_id": new_record_id()} ) with pytest.raises(ArtifactScratchIntegrityError, match="material identity differs"): - view.external_checker_grant(self.external_request(changed)) + with view.external_checker_grant(self.external_request(changed)): + pytest.fail("substituted material acquired an external grant") return result(request) From e7eac6eadf8f2b588b80956bbaa64fce206f6bd2 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 17:12:20 +0100 Subject: [PATCH 254/283] [PILOT-04] Reconcile shared selected checker fixtures --- .../changes/pilot04-workstream-default-checker.md | 13 +++++++++++++ backend/tests/checker_output_admission_helpers.py | 6 ++---- backend/tests/test_artifact_admission_digest.py | 1 + 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 79e0f26ab..fb30590a4 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -98,6 +98,19 @@ cleanup. topology, CI cap or execution behavior changes. Acceptance is the isolated no-broker test and existing worker topology controls, followed by full CI. +- The bounded hosted shared-fixture repair permits only + `backend/tests/checker_output_admission_helpers.py`, + `backend/tests/test_artifact_admission_digest.py` and this record. Reconstruct + the current selected POST request through the CHECKERS repository's strict + stored-request owner, including its separately retained digest, and include + the selected PRE run's explicit null slot in the guide admission digest + expectation. Preserve real stored CHECKERS rows, ART authority, storage, + recovery, replay and immutable lineage assertions. No production, schema, + migration, compatibility decoder, old checker contract, test selection, skip + or cap change is allowed. Acceptance is focused collection, Ruff, the affected + real PostgreSQL fixture consumers and the unchanged guide replay proof. Risk + is L0 because the repair only aligns shared test inputs with current owners. + - Final dead-contract removal permits the obsolete CHECKERS modules `api/pre_submit.py`, `api/post_submit.py`, `api/historical_post_submit.py`, `api/policy_compilation.py` and `post_submit_contracts.py`, their unused exports diff --git a/backend/tests/checker_output_admission_helpers.py b/backend/tests/checker_output_admission_helpers.py index 2a1ce4c24..e9376dd50 100644 --- a/backend/tests/checker_output_admission_helpers.py +++ b/backend/tests/checker_output_admission_helpers.py @@ -26,8 +26,8 @@ CheckerOutputReservation, CheckerOutputSlot, ) +from app.modules.checkers.execution_repository import stored_request from app.modules.checkers.models import CheckerRun -from app.modules.checkers.api.evaluation_contract import validate_execution_request from app.modules.tasks.models import Submission, WorkstreamTask @@ -53,9 +53,7 @@ async def make_checker_output_reservation( ) task = await session.get(WorkstreamTask, checker_run.task_id) assert submission is not None and task is not None - import json - - evaluation = validate_execution_request(json.loads(checker_run.request_json)) + evaluation = stored_request(checker_run) assert (evaluation.project_id, evaluation.task_id, evaluation.submission_id, evaluation.submission_version, evaluation.assignment_id) == ( UUID(task.project_id), UUID(task.id), UUID(submission.id), diff --git a/backend/tests/test_artifact_admission_digest.py b/backend/tests/test_artifact_admission_digest.py index 5716d580f..5870248d9 100644 --- a/backend/tests/test_artifact_admission_digest.py +++ b/backend/tests/test_artifact_admission_digest.py @@ -79,6 +79,7 @@ async def test_guide_replay_preserves_canonical_producer_digest( "checker_run_id": None, "logical_role": None, "pre_submit_evidence_set_id": None, + "selected_pre_submit_run_id": None, "sha256": source.commitment.sha256, "byte_count": source.commitment.byte_count, "media_type": source.commitment.media_type, From 3acc7f0a0e5347bac639da7128da16f67480a5cf Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 17:15:18 +0100 Subject: [PATCH 255/283] [PILOT-04] Reconcile shared authorization deadline fixtures --- .../pilot04-workstream-default-checker.md | 23 +++++++++++++++ .../authorization/post_submit/test_timeout.py | 29 +++++++++++++++---- .../setup_finalization/test_catalogue.py | 1 + .../test_assignment_invalidation_contract.py | 9 ++++-- 4 files changed, 54 insertions(+), 8 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index fb30590a4..72b3ab61b 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -1159,6 +1159,29 @@ and fails on the prior helper at the intended envelope equality assertion. Ruff and diff checks pass. This repairs fixture serialization only; the completed 0008 native migration discriminator remains required before claiming that path. +### Shared authorization contract replay + +Reconcile the current exact action inventory and fixed-service binding snapshots +in `authorization/setup_finalization/test_catalogue.py` and +`authorization/test_assignment_invalidation_contract.py` with the selected PRE +actions/context. Diagnose and repair the controlled executor deadline fixture in +`authorization/post_submit/test_timeout.py` while retaining revocation, replica +drift, cancellation, source/workspace/projection cleanup and zero-terminal-effect +controls. The boundary waiter must expose an executor failure that occurs before +the consumer rather than report only its own timeout. Scope is these tests and +necessary shared test support; no production authorization, timing cap, schema or +runtime behavior is authorized to change by this fixture reconciliation. + +The diagnostic exposes `checker lease progression is invalid` before the consumer: +the old 12,345-second sentinel also extended the real selected execution lease +beyond its installed one-hour guard. Use a controlled 300-second budget and its +existing finalization margin; the event-armed real timeout and ten-second test +boundary remain unchanged. The diagnostic failed its intended native node in +113.79 seconds with database/role cleanup complete (683 producer with the waiter +change, not a frozen-head replay). Both current pure modules pass all 35 cases; +Ruff and diff checks pass. The complete deadline module must pass on the frozen +repair before closing its cancellation and cleanup proof. + ### Captured service principal prerequisites The static predecessor archive now carries the exact project-neutral POST service diff --git a/backend/tests/authorization/post_submit/test_timeout.py b/backend/tests/authorization/post_submit/test_timeout.py index f8d74fdd4..52656f64c 100644 --- a/backend/tests/authorization/post_submit/test_timeout.py +++ b/backend/tests/authorization/post_submit/test_timeout.py @@ -12,6 +12,22 @@ from .test_receipt_custody import snapshot +async def wait_for_boundary(task, entered): + """Surface an early executor failure instead of hiding it behind the waiter.""" + waiter = asyncio.create_task(entered.wait()) + try: + done, _ = await asyncio.wait( + (task, waiter), timeout=10, return_when=asyncio.FIRST_COMPLETED, + ) + if task in done: + await task + raise AssertionError("executor completed before the controlled boundary") + assert waiter in done, "executor did not reach the controlled boundary" + finally: + waiter.cancel() + await asyncio.gather(waiter, return_exceptions=True) + + @pytest.mark.parametrize("consumer_failure", ["cancel", "runtime_error", "timeout_error"]) @pytest.mark.parametrize("change", ["revoked", "replica_unavailable", "unchanged"]) async def test_outer_deadline_revalidates_material_after_cleanup(tmp_path, isolated_database_env, monkeypatch, change, consumer_failure): @@ -35,7 +51,7 @@ async def paused(consumer, request, material): deadlines = controlled_deadline(monkeypatch, execution) task = asyncio.create_task(live_executor(h).evaluate_post_submission(h.request)) try: - await asyncio.wait_for(entered.wait(), 10) + await wait_for_boundary(task, entered) before = await snapshot(h) if change == "revoked": await service_link_state(h.factory, ServiceIdentity.ARTIFACT_MATERIALIZER, active=False) @@ -68,13 +84,16 @@ async def paused(consumer, request, material): def controlled_deadline(monkeypatch, execution): """Use the real timeout, armed only after the boundary under test is reached.""" + # This budget also determines the durable lease. Keep its finalization margin + # inside the installed one-hour lease guard while disarming only this timer. + controlled_seconds = 300 original_timeout, deadlines = asyncio.timeout, [] def timeout(seconds): - timer = original_timeout(None if seconds == 12345 else seconds) - if seconds == 12345: + timer = original_timeout(None if seconds == controlled_seconds else seconds) + if seconds == controlled_seconds: deadlines.append(timer) return timer - monkeypatch.setattr(execution.PostSubmissionExecutor, "_execution_budget_seconds", staticmethod(lambda request: 12345)) + monkeypatch.setattr(execution.PostSubmissionExecutor, "_execution_budget_seconds", staticmethod(lambda request: controlled_seconds)) monkeypatch.setattr(asyncio, "timeout", timeout) return deadlines @@ -118,7 +137,7 @@ def failed_workspace(name): deadlines = controlled_deadline(monkeypatch, execution) task = asyncio.create_task(live_executor(h).evaluate_post_submission(h.request)) try: - await asyncio.wait_for(entered.wait(), 10) + await wait_for_boundary(task, entered) before = await snapshot(h) deadlines[0].reschedule(asyncio.get_running_loop().time()) for _ in range(10): diff --git a/backend/tests/authorization/setup_finalization/test_catalogue.py b/backend/tests/authorization/setup_finalization/test_catalogue.py index a849c84f0..49ee8ff9f 100644 --- a/backend/tests/authorization/setup_finalization/test_catalogue.py +++ b/backend/tests/authorization/setup_finalization/test_catalogue.py @@ -130,6 +130,7 @@ def test_exact_active_action_inventory(): if definition.availability is ActionAvailability.ACTIVE } == { ActionId.CONTRIBUTION_READ_SELF, ActionId.CONTRIBUTION_READ_PROJECT, + ActionId.CHECKER_PRE_SUBMIT_EXECUTE, ActionId.CHECKER_PRE_SUBMIT_FINALIZE, ActionId.CHECKER_POST_SUBMIT_EXECUTE, ActionId.CHECKER_POST_SUBMIT_FINALIZE, ActionId.OPERATIONS_CHECKER_RETRY, ActionId.CHECKER_REGISTRY_REGISTER, diff --git a/backend/tests/authorization/test_assignment_invalidation_contract.py b/backend/tests/authorization/test_assignment_invalidation_contract.py index 181b1a6dc..ae37061b9 100644 --- a/backend/tests/authorization/test_assignment_invalidation_contract.py +++ b/backend/tests/authorization/test_assignment_invalidation_contract.py @@ -104,13 +104,16 @@ def test_fixed_service_bindings_preserve_both_exact_contracts(): assignment = prepared_fixed_service_bindings( ActionId.TASK_ASSIGNMENT_AUTHORITY_RECONCILE, resource.model_dump(mode="json"), ValueError, ) - assert assignment == {"assignment_invalidation_context": resource, "outbox_dispatch_digest": None, "post_submit_prepare_context": None} + assert assignment == {"assignment_invalidation_context": resource, "outbox_dispatch_digest": None, + "post_submit_prepare_context": None, "pre_submit_prepare_context": None} digest = "sha256:" + "a" * 64 assert prepared_fixed_service_bindings(ActionId.OUTBOX_DISPATCH, {"outbox_dispatch_digest": digest}, ValueError) == { - "assignment_invalidation_context": None, "outbox_dispatch_digest": digest, "post_submit_prepare_context": None, + "assignment_invalidation_context": None, "outbox_dispatch_digest": digest, + "post_submit_prepare_context": None, "pre_submit_prepare_context": None, } assert prepared_fixed_service_bindings(ActionId.ACTOR_PROFILE_READ_SELF, {}, ValueError) == { - "assignment_invalidation_context": None, "outbox_dispatch_digest": None, "post_submit_prepare_context": None, + "assignment_invalidation_context": None, "outbox_dispatch_digest": None, + "post_submit_prepare_context": None, "pre_submit_prepare_context": None, } for action, message in ( (ActionId.TASK_ASSIGNMENT_AUTHORITY_RECONCILE, "invalid assignment reconciliation authority"), From 953d39ce008b367e1cabc3d36254d64ade109362 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 17:22:40 +0100 Subject: [PATCH 256/283] test: align checker execution fixtures with selected leases and results --- .../pilot04-workstream-default-checker.md | 29 +++++++++++++++++++ .../checkers/execution/test_checker_retry.py | 16 ++++++---- .../test_checker_retry_history_replay.py | 13 +++++++++ .../checkers/execution/test_concurrency.py | 14 ++++++--- .../checkers/execution/test_execution.py | 13 ++++++--- .../tests/checkers/execution/test_storage.py | 8 +++-- .../tests/checkers/external/test_registry.py | 11 ++++++- 7 files changed, 87 insertions(+), 17 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 72b3ab61b..febbca95d 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -1229,3 +1229,32 @@ Remaining raw migration controls, a fresh final image drill and full required hosted CI remain necessary before human merge approval. The actual Rust image proof at `6fd3fde80` uses local runc/docker-dev and does not claim hosted gVisor, public contributor upload/CLI or an exhaustive suite. No deployment or merge. + +### Hosted checker execution fixture reconciliation + +Lead-authorized test-only scope: `backend/tests/checkers/execution/` files +`test_checker_retry.py`, `test_concurrency.py`, `test_execution.py`, +`test_storage.py`, `test_checker_retry_history_replay.py`, plus +`backend/tests/checkers/external/test_registry.py` and this existing record. +The hosted 683 logs retain the exact failed nodes. Production, migrations, +fingerprints, workflow caps, skips, inventories and shared producers are prohibited. + +The former lease constant no longer controls a selected policy lease. Arrange a +short first lease through the actual budget/margin inputs in a scoped test patch, +then wait for its persisted expiry using the real database clock. Restore normal +budgets before takeover; all native expiry, generation, AUTH and stale-finalizer +guards stay enabled. Completed retry negatives use the supported failed-image +`needs_revision` outcome instead of the removed built-in setup classification. +Unreadable bytes forbid the current selected consumer, not a retired registry. +Storage negatives require the current exact guard message and SQLSTATE 23514, +retained-row rollback and valid recovery. The retry-history journey supplies a +controlled selected executor before handler composition and requires a stored +completed successor before deriving its completion source; it retains actual ART, +AUTH, governed remediation, replacement and no-byte-reopen replay. The registry +mock implements only the current exact-row read and keeps all conflict assertions. + +Risk: bounded test fixture changes can otherwise hide a lifecycle failure; require +lead/independent test-delta review, focused pure registry controls and canonical +isolated native retry/takeover, byte-failure, storage and later-Submission replay +cases with exact heads and complete DB/role/MinIO cleanup. No current failure +boundary, assertion, cap or test selection is removed to obtain a pass. diff --git a/backend/tests/checkers/execution/test_checker_retry.py b/backend/tests/checkers/execution/test_checker_retry.py index e7572452c..90c2339e6 100644 --- a/backend/tests/checkers/execution/test_checker_retry.py +++ b/backend/tests/checkers/execution/test_checker_retry.py @@ -893,7 +893,7 @@ async def test_running_source_reaches_valid_task_guard_then_refuses_terminal_ret await _assert_nonterminal_source_reaches_guard(h, monkeypatch, "running") -@pytest.mark.parametrize("recommendation", ["allow_review", "task_setup_blocked"]) +@pytest.mark.parametrize("recommendation", ["allow_review", "needs_revision"]) async def test_completed_source_reaches_valid_task_guard_then_refuses_terminal_retry( tmp_path, isolated_database_env, monkeypatch, recommendation, ): @@ -910,12 +910,18 @@ async def test_expired_unfinished_transport_reclaims_same_run_without_retry_rece async with material_fixture(tmp_path, isolated_database_env) as h: await reserve(h) executor = live_executor(h) - monkeypatch.setattr(execution, "LEASE_SECONDS", 1) - first, replay = await executor._claim(h.request) + with monkeypatch.context() as patch: + patch.setattr(executor, "_execution_budget_seconds", lambda _request: 1) + patch.setattr(execution, "SELECTED_POST_FINALIZATION_MARGIN_MS", 9_000) + first, replay = await executor._claim(h.request) assert replay is None async with h.factory() as session: - await session.execute(text("select pg_sleep(1.05)")) - monkeypatch.setattr(execution, "LEASE_SECONDS", 300) + await session.execute(text( + "SELECT pg_sleep(GREATEST(EXTRACT(EPOCH FROM " + "CAST(:expiry AS timestamptz)-clock_timestamp()),0)+0.05)" + ), {"expiry": first.expires_at}) + assert await session.scalar(text("SELECT clock_timestamp()>=:expiry"), + {"expiry": first.expires_at}) second, replay = await executor._claim(h.request) assert replay is None assert second.reservation == first.reservation diff --git a/backend/tests/checkers/execution/test_checker_retry_history_replay.py b/backend/tests/checkers/execution/test_checker_retry_history_replay.py index 7b34a5dee..709d41a12 100644 --- a/backend/tests/checkers/execution/test_checker_retry_history_replay.py +++ b/backend/tests/checkers/execution/test_checker_retry_history_replay.py @@ -10,6 +10,8 @@ from app.modules.outbox.api import HandlerOutcome from tests.authorization.post_submit_routing.support import provision_router from tests.checkers.external.support import post_registry_spec +from tests.checkers.execution.support import ControlledSelectedExecution +from app.modules.checkers.models import CheckerRun from tests.checkers.execution.test_checker_retry import _command, _failed_source, _operator_for from tests.tasks.evaluation_delivery.support import outcome from tests.tasks.post_submit_routing.outcome_support import invoked_completion @@ -24,6 +26,11 @@ async def test_retry_replays_after_real_later_submission_without_reopening_old_source( tmp_path, isolated_database_env, monkeypatch, ): + selected_execution = ControlledSelectedExecution(verdict="failed") + monkeypatch.setattr( + "app.adapters.checkers.configured_external_checker_execution", + lambda _settings: selected_execution, + ) async with _failed_source( tmp_path, isolated_database_env, @@ -43,6 +50,12 @@ async def test_retry_replays_after_real_later_submission_without_reopening_old_s created.successor.event_id, h.request.project_id, "retry-remediation", ) assert outcome(delivered)["delivery_state"] == "acknowledged" + assert len(selected_execution.requests) == 1 + async with h.factory() as session: + successor = await session.get(CheckerRun, str(created.successor.run_id)) + assert successor.status == "completed" + assert successor.routing_recommendation == "needs_revision" + assert successor.completion_event_id is not None async with h.factory.begin() as session: accepted = await session.execute(text( "UPDATE public.task_assignments SET accepted_at=clock_timestamp() " diff --git a/backend/tests/checkers/execution/test_concurrency.py b/backend/tests/checkers/execution/test_concurrency.py index e77bba29e..00e9d4d04 100644 --- a/backend/tests/checkers/execution/test_concurrency.py +++ b/backend/tests/checkers/execution/test_concurrency.py @@ -110,12 +110,18 @@ async def test_stale_worker_cannot_finalize_after_takeover( async with material_fixture(tmp_path, isolated_database_env) as h: await reserve(h) executor = live_executor(h) - monkeypatch.setattr(execution, "LEASE_SECONDS", 1) - old, _ = await executor._claim(h.request) + with monkeypatch.context() as patch: + patch.setattr(executor, "_execution_budget_seconds", lambda _request: 1) + patch.setattr(execution, "SELECTED_POST_FINALIZATION_MARGIN_MS", 9_000) + old, _ = await executor._claim(h.request) old_facts = await final_facts(h, old) async with h.factory() as session: - await session.execute(text("select pg_sleep(1.05)")) - monkeypatch.setattr(execution, "LEASE_SECONDS", 300) + await session.execute(text( + "SELECT pg_sleep(GREATEST(EXTRACT(EPOCH FROM " + "CAST(:expiry AS timestamptz)-clock_timestamp()),0)+0.05)" + ), {"expiry": old.expires_at}) + assert await session.scalar(text("SELECT clock_timestamp()>=:expiry"), + {"expiry": old.expires_at}) current, _ = await executor._claim(h.request) assert ( current.reservation == old.reservation diff --git a/backend/tests/checkers/execution/test_execution.py b/backend/tests/checkers/execution/test_execution.py index 5081d924d..b174d68a7 100644 --- a/backend/tests/checkers/execution/test_execution.py +++ b/backend/tests/checkers/execution/test_execution.py @@ -8,7 +8,8 @@ from app.modules.checkers.models import CheckerRun, CheckerResult from app.modules.outbox.models import OutboxEvent from tests.post_submit_materialization_helpers import material_fixture -from .support import live_executor, reserve, service_link_state +from .support import ControlledSelectedExecution, live_executor, reserve, service_link_state +from tests.checkers.external.support import post_registry_spec from app.modules.actors.api import ServiceIdentity @@ -333,7 +334,10 @@ async def test_unreadable_stored_bytes_terminalize_and_replay( ): from tests.test_local_artifact_store import object_path - async with material_fixture(tmp_path, isolated_database_env) as h: + async with material_fixture( + tmp_path, isolated_database_env, post_submit_registry_spec=post_registry_spec(), + ) as h: + assert len(h.request.policy.entries) == 1 reservation = await reserve(h) digest = h.request.content_sha256 path = object_path(h.settings.artifact_local_root, f"sha256/{digest[7:9]}/{digest[9:]}") @@ -344,12 +348,13 @@ async def test_unreadable_stored_bytes_terminalize_and_replay( path.chmod(0o600) path.write_bytes(bytes([h.data[0] ^ 1]) + h.data[1:]) path.chmod(0o400) - executor = live_executor(h) + selected_execution = ControlledSelectedExecution() + executor = live_executor(h, selected_execution=selected_execution) async def forbidden_checker(*args, **kwargs): pytest.fail("unverified stored bytes reached a checker") - monkeypatch.setattr(executor._registry, "run", forbidden_checker) + monkeypatch.setattr(selected_execution, "execute", forbidden_checker) # The byte failure cannot bypass the separate finalization authority. pending = [] finalize = executor.finalize diff --git a/backend/tests/checkers/execution/test_storage.py b/backend/tests/checkers/execution/test_storage.py index 3272b4266..73907c9ec 100644 --- a/backend/tests/checkers/execution/test_storage.py +++ b/backend/tests/checkers/execution/test_storage.py @@ -124,15 +124,16 @@ async def test_execution_custody_rejects_mutation(tmp_path, isolated_database_en original = await session.get(CheckerRun, str(receipt.attempt_id)) before = getattr(original, field) replacement = ( - "{}" + request_text(change_request(h.request, evaluation_request_id=new_record_id())) if field == "request_json" else 2 if field == "evaluation_generation" else str(new_record_id()) ) setattr(original, field, replacement) - with pytest.raises(IntegrityError, match="checker run custody is immutable"): + with pytest.raises(IntegrityError, match="checker run custody is immutable") as refused: await session.flush() + assert refused.value.orig.sqlstate == "23514" await session.rollback() assert getattr(await session.get(CheckerRun, str(receipt.attempt_id)), field) == before @@ -270,8 +271,9 @@ def faulty_request_validator(result, request): await material_storage_helpers.write_terminal( session, facts, facts.material.model_dump(mode="json"), ) - with pytest.raises(IntegrityError, match="checker completed custody or routing invalid"): + with pytest.raises(IntegrityError, match="checker terminal selected policy differs") as refused: await session.execute(text("SET CONSTRAINTS public.checker_terminal_custody IMMEDIATE")) + assert refused.value.orig.sqlstate == "23514" await session.rollback() async with h.factory() as session: assert ( diff --git a/backend/tests/checkers/external/test_registry.py b/backend/tests/checkers/external/test_registry.py index a02ce7730..51b52b075 100644 --- a/backend/tests/checkers/external/test_registry.py +++ b/backend/tests/checkers/external/test_registry.py @@ -35,6 +35,13 @@ class _Session: def __init__(self, active: bool = True) -> None: self.root = SimpleNamespace(is_active=active) if active else None self.sync_session = self + self.rows = [] + + async def get(self, model, entry_id, *, populate_existing): + from app.modules.checkers.models import ExternalCheckerRegistryEntryRecord + + assert model is ExternalCheckerRegistryEntryRecord and populate_existing is True + return next((row for row in self.rows if row.id == entry_id), None) def get_transaction(self): return self.root @@ -116,8 +123,10 @@ async def by_exact_id(self, entry_id): def _service(active: bool = True): authority = _Authority() - service = ExternalCheckerRegistryService(_Session(active), authority) # type: ignore[arg-type] + session = _Session(active) + service = ExternalCheckerRegistryService(session, authority) # type: ignore[arg-type] repository = _Repository() + session.rows = repository.rows service._repository = repository # type: ignore[assignment] return service, authority, repository From c88cbaad5f13aa94eaff8020bb02626ac653be86 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 17:58:46 +0100 Subject: [PATCH 257/283] Complete external policy project fixtures --- .../pilot04-workstream-default-checker.md | 18 ++++ .../app/modules/projects/api/locked_policy.py | 45 ++++----- .../modules/projects/authorization_reads.py | 31 ++++-- .../guide_compilation/approval_custody.py | 63 +++--------- backend/app/modules/projects/service.py | 22 ++--- .../proposals/test_postgresql.py | 47 ++++----- .../test_capability_growth.py | 11 +-- .../test_capability_growth_postgresql.py | 9 +- .../test_compilation_storage_limit.py | 4 +- .../guide_compilation/test_context_builder.py | 6 +- .../guide_compilation/test_live_worker.py | 5 +- .../tests/projects/policy_read_fixtures.py | 39 +++++++- .../projects/test_policy_read_composition.py | 96 ++++++++++++++++--- backend/tests/test_projects.py | 2 +- 14 files changed, 239 insertions(+), 159 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index febbca95d..1408382af 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -1258,3 +1258,21 @@ lead/independent test-delta review, focused pure registry controls and canonical isolated native retry/takeover, byte-failure, storage and later-Submission replay cases with exact heads and complete DB/role/MinIO cleanup. No current failure boundary, assertion, cap or test selection is removed to obtain a pass. + +### Hosted PROJECT fixture reconciliation + +Allowed scope is limited to current external-policy PROJECT test fixtures and +their assertions: `tests/projects/guide_compilation/test_capability_growth.py`, +`test_capability_growth_postgresql.py`, `test_compilation_storage_limit.py`, +`test_live_worker.py`, `test_context_builder.py`, +`proposals/test_postgresql.py`, the active-guide read fixtures and activation +tests, and the matching assertions in `tests/test_projects.py`. The batch may +update current registered capability projections, strict worker error fakes, +current proposal fields and current compiler identifiers. It must not restore a +built-in checker catalogue, legacy decoder, execution fallback, migration or +product compatibility path. The bounded production repair may update only +`app/modules/projects/authorization_reads.py`, `service.py`, +`guide_compilation/approval_custody.py`, and `api/locked_policy.py` to require +the sole current external pre/post policy schemas and their self-excluding +digests. It removes generic canonical-hash and old-plan fallbacks without +rewriting retained rows. diff --git a/backend/app/modules/projects/api/locked_policy.py b/backend/app/modules/projects/api/locked_policy.py index 263262d8d..9b5b27d67 100644 --- a/backend/app/modules/projects/api/locked_policy.py +++ b/backend/app/modules/projects/api/locked_policy.py @@ -222,34 +222,25 @@ def __post_init__(self) -> None: ): raise ValueError("project display facts differ from locked context") target, upstream = receipt.command.target.proposal, receipt.command.target.upstream - external_body = json.loads(self.external_checker_policies.value) - if external_body.get("schema_version") == "external_checker_policies.v1": - from app.modules.checkers.api.external_policy import ( - validate_stored_external_checker_policies, - ) + from app.modules.checkers.api.external_policy import ( + validate_stored_external_checker_policies, + ) - external_policies = validate_stored_external_checker_policies(external_body) - pre_body = json.loads(self.compiled_pre_submit_bundle.value) - post_body = json.loads(self.compiled_post_submit_policy.value) - external_hashes_match = ( - external_policies.policies_sha256 - == receipt.command.target.upstream.effective_pre_submit_plan_hash - and external_policies.pre_submit.model_dump(mode="json") == pre_body - and external_policies.pre_submit.policy_sha256 - == self.pre_submit_policy_bundle_hash - and external_policies.post_submit.model_dump(mode="json") == post_body - and external_policies.post_submit.policy_sha256 - == receipt.command.target.policy_hash - ) - else: - external_hashes_match = ( - self.compiled_pre_submit_bundle.sha256 - == self.pre_submit_policy_bundle_hash - and self.compiled_post_submit_policy.sha256 - == receipt.command.target.policy_hash - and self.external_checker_policies.sha256 - == receipt.command.target.upstream.effective_pre_submit_plan_hash - ) + external_policies = validate_stored_external_checker_policies( + json.loads(self.external_checker_policies.value) + ) + pre_body = json.loads(self.compiled_pre_submit_bundle.value) + post_body = json.loads(self.compiled_post_submit_policy.value) + external_hashes_match = ( + external_policies.policies_sha256 + == receipt.command.target.upstream.effective_pre_submit_plan_hash + and external_policies.pre_submit.model_dump(mode="json") == pre_body + and external_policies.pre_submit.policy_sha256 + == self.pre_submit_policy_bundle_hash + and external_policies.post_submit.model_dump(mode="json") == post_body + and external_policies.post_submit.policy_sha256 + == receipt.command.target.policy_hash + ) if ( ( self.project_id, diff --git a/backend/app/modules/projects/authorization_reads.py b/backend/app/modules/projects/authorization_reads.py index d38654f39..a5efe2ce1 100644 --- a/backend/app/modules/projects/authorization_reads.py +++ b/backend/app/modules/projects/authorization_reads.py @@ -37,6 +37,7 @@ ProjectService, ProjectServiceError, ) +from app.modules.checkers.api.external_policy import validate_stored_external_pre_policy DiagnosticRecord: TypeAlias = ProjectSetupRun | GuideSufficiencyReport | SubmissionArtifactPolicy DiagnosticResult: TypeAlias = ( @@ -78,9 +79,8 @@ def _effective_policy_chain_is_consistent( ) ) if not common_matches or checker is None: - return common_matches - if not isinstance(checker.compiled_bundle, dict): return False + compiled = validate_stored_external_pre_policy(checker.compiled_bundle) return all( ( checker.project_id == project_id, @@ -91,7 +91,7 @@ def _effective_policy_chain_is_consistent( checker.effective_policy_id == effective.id, checker.effective_policy_hash == effective.effective_policy_hash, checker.lifecycle_status == "compiled", - canonical_json_hash(checker.compiled_bundle) == checker.compiled_bundle_hash, + compiled.policy_sha256 == checker.compiled_bundle_hash, ) ) except (AttributeError, TypeError, ValueError): @@ -149,7 +149,6 @@ async def authorize_project_policy_read( effective is not None and effective.guide_id == guide_id and effective.source_snapshot_hash == snapshot.bundle_hash - and action_id is ActionId.PROJECT_PRE_SUBMIT_CHECKER_POLICY_READ ): checker = await repository.lock_compiled_pre_submit_checker_policy(effective.id) except ProjectRepositoryIntegrityError: @@ -236,9 +235,27 @@ async def authorize_project_policy_read( effective_policy_id=UUID(effective.id) if target_exists else None, effective_policy_hash=effective.effective_policy_hash if target_exists else None, effective_policy_status=effective.lifecycle_status if target_exists else None, - checker_policy_id=UUID(checker.id) if checker is not None and target_exists else None, - checker_policy_status=(checker.lifecycle_status if checker is not None and target_exists else None), - checker_bundle_hash=(checker.compiled_bundle_hash if checker is not None and target_exists else None), + checker_policy_id=( + UUID(checker.id) + if checker is not None + and target_exists + and action_id is ActionId.PROJECT_PRE_SUBMIT_CHECKER_POLICY_READ + else None + ), + checker_policy_status=( + checker.lifecycle_status + if checker is not None + and target_exists + and action_id is ActionId.PROJECT_PRE_SUBMIT_CHECKER_POLICY_READ + else None + ), + checker_bundle_hash=( + checker.compiled_bundle_hash + if checker is not None + and target_exists + and action_id is ActionId.PROJECT_PRE_SUBMIT_CHECKER_POLICY_READ + else None + ), target_binding_digest=binding_digest, ), ) diff --git a/backend/app/modules/projects/guide_compilation/approval_custody.py b/backend/app/modules/projects/guide_compilation/approval_custody.py index b6d39cf59..8b44ca350 100644 --- a/backend/app/modules/projects/guide_compilation/approval_custody.py +++ b/backend/app/modules/projects/guide_compilation/approval_custody.py @@ -88,7 +88,7 @@ async def load_approval_custody(session, policy_id: str | None) -> ApprovalCusto def _approval_projection_matches( - view, custody, target, receipt, policy, external_plan_hash, external_pre_hash + view, custody, target, receipt, policy, external_policies ) -> bool: """Compare every immutable target, receipt, reservation and policy fact.""" operation, reservation, effective, pre = ( @@ -137,23 +137,13 @@ def _approval_projection_matches( or effective.effective_policy_hash != receipt.effective_policy_hash or canonical_json_hash(effective.effective_policy) != receipt.effective_policy_hash or pre.compiled_bundle_hash != receipt.pre_submit_bundle_hash - or ( - external_pre_hash - if external_pre_hash is not None - else canonical_json_hash(pre.compiled_bundle) - ) - != receipt.pre_submit_bundle_hash + or external_policies.pre_submit.policy_sha256 != receipt.pre_submit_bundle_hash or effective.submission_artifact_policy_id != policy.id or effective.submission_artifact_policy_hash != policy.policy_hash or pre.effective_policy_id != effective.id or pre.effective_policy_hash != effective.effective_policy_hash or operation.effective_pre_submit_plan_hash != receipt.effective_pre_submit_plan_hash - or ( - external_plan_hash - if external_plan_hash is not None - else canonical_json_hash(operation.effective_pre_submit_plan) - ) - != receipt.effective_pre_submit_plan_hash + or external_policies.policies_sha256 != receipt.effective_pre_submit_plan_hash ): return False return True @@ -172,17 +162,11 @@ def approved_projection_digest(view) -> str: ) target = GuideProposalTarget.model_validate(operation.target_json) receipt = GuideProposalApprovalReceipt.model_validate(operation.receipt_json) - external_plan_hash = external_pre_hash = None - if operation.effective_pre_submit_plan.get("schema_version") == ( - "external_checker_policies.v1" - ): - external_policies = validate_stored_external_checker_policies( - operation.effective_pre_submit_plan - ) - external_plan_hash = external_policies.policies_sha256 - external_pre_hash = external_policies.pre_submit.policy_sha256 + external_policies = validate_stored_external_checker_policies( + operation.effective_pre_submit_plan + ) if not _approval_projection_matches( - view, custody, target, receipt, policy, external_plan_hash, external_pre_hash + view, custody, target, receipt, policy, external_policies ): raise ValueError("approved proposal custody mismatch") lifecycle = (policy.lifecycle_status, effective.lifecycle_status, pre.lifecycle_status) @@ -221,34 +205,11 @@ def _require_plan_and_provenance(view, custody, target) -> None: custody.pre, view.policy, ) - expected_lineage = { - "project_id": str(target.project_id), - "guide_id": str(target.guide_id), - "guide_version": target.guide_version, - "source_snapshot_id": str(target.source_snapshot_id), - "source_snapshot_hash": target.source_snapshot_hash, - "effective_policy_id": effective.id, - "effective_policy_hash": effective.effective_policy_hash, - "pre_submit_policy_id": pre.id, - "pre_submit_policy_bundle_hash": pre.compiled_bundle_hash, - } - expected_catalogue = { - "id": target.pre_catalogue_id, - "version": target.pre_catalogue_version, - "schema_version": target.pre_catalogue_schema_version, - "manifest_sha256": target.pre_catalogue_manifest_hash, - } - if operation.effective_pre_submit_plan.get("schema_version") == "external_checker_policies.v1": - policies = validate_stored_external_checker_policies( - operation.effective_pre_submit_plan - ) - if policies.pre_submit.model_dump(mode="json") != pre.compiled_bundle: - raise ValueError("approved external checker policy mismatch") - elif ( - operation.effective_pre_submit_plan.get("lineage") != expected_lineage - or operation.effective_pre_submit_plan.get("catalogue") != expected_catalogue - ): - raise ValueError("approved proposal plan lineage mismatch") + policies = validate_stored_external_checker_policies( + operation.effective_pre_submit_plan + ) + if policies.pre_submit.model_dump(mode="json") != pre.compiled_bundle: + raise ValueError("approved external checker policy mismatch") for name in ( "pre_catalogue_id", "pre_catalogue_version", diff --git a/backend/app/modules/projects/service.py b/backend/app/modules/projects/service.py index e2cd6a936..bc030fadc 100644 --- a/backend/app/modules/projects/service.py +++ b/backend/app/modules/projects/service.py @@ -1187,22 +1187,18 @@ def validate_activation_ready( ) if not isinstance(pre_submit_checker_policy.compiled_bundle, dict): raise GuideActivationBlocked("pre-submit checker compiled bundle must be an object") - if pre_submit_checker_policy.compiled_bundle.get("schema_version") == ( - "external_pre_submit_policy.v1" - ): - from app.modules.checkers.api.external_policy import ( - validate_stored_external_pre_policy, - ) - + from app.modules.checkers.api.external_policy import ( + validate_stored_external_pre_policy, + ) + try: compiled_pre = validate_stored_external_pre_policy( pre_submit_checker_policy.compiled_bundle ) - compiled_pre_hash = compiled_pre.policy_sha256 - else: - compiled_pre_hash = self._hash_canonical_json( - pre_submit_checker_policy.compiled_bundle - ) - if compiled_pre_hash != pre_submit_checker_policy.compiled_bundle_hash: + except ValueError as exc: + raise GuideActivationBlocked( + "external pre-submit checker policy is required" + ) from exc + if compiled_pre.policy_sha256 != pre_submit_checker_policy.compiled_bundle_hash: raise GuideActivationBlocked("pre-submit checker compiled bundle hash mismatch") from .post_policy.custody import validate_activation_post_policy try: diff --git a/backend/tests/projects/guide_compilation/proposals/test_postgresql.py b/backend/tests/projects/guide_compilation/proposals/test_postgresql.py index f62b5a2a4..fef4bec78 100644 --- a/backend/tests/projects/guide_compilation/proposals/test_postgresql.py +++ b/backend/tests/projects/guide_compilation/proposals/test_postgresql.py @@ -82,13 +82,7 @@ async def test_review_package_is_exact_complete_and_redacted(clean_postgres_data dict( requirement_id="packet", statement="Limit artifact file size.", - disposition="supported_pre_submit", - evidence_refs=evidence, - ), - dict( - requirement_id="coverage", - statement="Check acceptance criteria coverage.", - disposition="supported_post_submit", + disposition="pre_submit_capability_gap", evidence_refs=evidence, ), dict( @@ -98,31 +92,23 @@ async def test_review_package_is_exact_complete_and_redacted(clean_postgres_data evidence_refs=evidence, ), ], - pre_submit_bindings=[ + pre_submit_bindings=[], + post_submit_bindings=[], + capability_suggestions=[ dict( requirement_id="packet", - capability_id="policy.file_size.limit", - capability_version="v1", stage="pre_submit", - ) - ], - post_submit_bindings=[ - dict( - requirement_id="coverage", - capability_id="check_acceptance_criteria_present", - capability_version="v0.1", - stage="post_submit", - parameters=[], - ) - ], - capability_suggestions=[ + title="Artifact size checker", + rationale="Register a checker for the exact package size requirement.", + evidence_refs=evidence, + ), dict( requirement_id="semantic", stage="post_submit", title="Specialist correctness evaluator", - rationale="The catalogue lacks this evaluation.", + rationale="No registered external checker covers this evaluation.", evidence_refs=evidence, - ) + ), ], setup_notes=["A project manager must review the specialist evaluation gap."], ) @@ -903,7 +889,9 @@ async def test_approval_preserves_opaque_guide_version(clean_postgres_database, assert await approve(factory, command, actor, grant, payload) == receipt async with factory() as session: operation = await session.get(ProjectGuideProposalApproval, receipt.operation_id) - assert operation.effective_pre_submit_plan["lineage"]["guide_version"] == guide_version + assert operation.effective_pre_submit_plan["schema_version"] == ( + "external_checker_policies.v1" + ) assert operation.target_json["guide_version"] == guide_version await finalize(factory, values, command) @@ -1093,6 +1081,11 @@ async def test_database_approval_requires_guide_to_remain_draft( ) with expected: async with factory() as session, session.begin(): + from app.adapters.checkers import ( + external_checker_capability_projection, + external_checker_registry_reader, + ) + if activate_before_commit: # Transaction rollback restores these unrelated activation prerequisites. for trigger in ( @@ -1102,10 +1095,6 @@ async def test_database_approval_requires_guide_to_remain_draft( await session.execute( text(f"ALTER TABLE project_guides DISABLE TRIGGER {trigger}") ) - from app.adapters.checkers import ( - external_checker_capability_projection, - external_checker_registry_reader, - ) await GuideProposalService( session, ProposalAuthority(session, actor, command.project_id, grant), diff --git a/backend/tests/projects/guide_compilation/test_capability_growth.py b/backend/tests/projects/guide_compilation/test_capability_growth.py index c69d3f565..9a6c230a5 100644 --- a/backend/tests/projects/guide_compilation/test_capability_growth.py +++ b/backend/tests/projects/guide_compilation/test_capability_growth.py @@ -97,7 +97,7 @@ def growth_report(*, gaps=True): "findings": ( CompilationFinding( severity="warning" if gaps else "info", - code="catalogue.coverage", + code="external_checker.coverage", message="Required automation is unavailable." if gaps else "All checks are supported.", @@ -199,17 +199,10 @@ def test_non_automated_requirements_need_no_suggestion(disposition): @pytest.mark.parametrize( "fault", ["missing", "duplicate", "unknown", "stale", "stage", "configuration"] ) -def test_blocked_matches_still_require_exact_catalogue_validation(stage, fault): +def test_blocked_matches_still_require_exact_external_capability_validation(stage, fault): report = growth_report() field = f"{stage}_bindings" binding = getattr(report, field)[0] - if fault == "configuration" and stage == "pre_submit": - payload = binding.model_dump(mode="json") | { - "parameters": [{"name": "invented", "value": 1}] - } - with pytest.raises(ValidationError, match="parameters"): - PreSubmissionBindingProposal.model_validate(payload) - return updates = { "unknown": {"capability_id": "invented"}, "stale": {"capability_version": "absent"}, diff --git a/backend/tests/projects/guide_compilation/test_capability_growth_postgresql.py b/backend/tests/projects/guide_compilation/test_capability_growth_postgresql.py index cd8144c3b..860db2ccb 100644 --- a/backend/tests/projects/guide_compilation/test_capability_growth_postgresql.py +++ b/backend/tests/projects/guide_compilation/test_capability_growth_postgresql.py @@ -1,4 +1,4 @@ -"""Persist blocked catalogue handoffs and terminalize oversized output without inference replay.""" +"""Persist external-capability gap handoffs and terminalize oversized output.""" import json import pytest @@ -26,6 +26,13 @@ async def test_handoff_persistence_and_terminal_replay(automatic_source, monkeyp from app.workers import project_setup as worker factory, actor, setup_id, snapshot = automatic_source + from tests.checkers.external.support import registry_spec + from tests.projects.guide_activation.source_fixtures import ( + _register_external_checker_fixture, + ) + + await _register_external_checker_fixture(factory, registry_spec("pre_submit")) + await _register_external_checker_fixture(factory, registry_spec("post_submit")) await create_committed_document_fixture(snapshot["id"]) delivery = await _delivery(factory, setup_id) runtime = ScriptedGuideRuntime() diff --git a/backend/tests/projects/guide_compilation/test_compilation_storage_limit.py b/backend/tests/projects/guide_compilation/test_compilation_storage_limit.py index 89a0e7127..6b1ed56b4 100644 --- a/backend/tests/projects/guide_compilation/test_compilation_storage_limit.py +++ b/backend/tests/projects/guide_compilation/test_compilation_storage_limit.py @@ -9,7 +9,7 @@ project_guide_compilation_result_storage_bytes, validate_project_guide_compilation_result, ) from .helpers import context, ids -from .test_capability_growth import growth_report +from .test_capability_growth import _context as growth_context, growth_report def large_report(length): @@ -62,7 +62,7 @@ def test_actual_sdk_parser_accepts_current_handoff(gaps): schema = AgentOutputSchema(ProjectGuideCompilationResult) # Strict SDK parsing sees every field, including explicit linkage and evidence. parsed = schema.validate_json(growth_report(gaps=gaps).model_dump_json()) - validate_project_guide_compilation_result(context(ids()), parsed) + validate_project_guide_compilation_result(growth_context(), parsed) assert len(parsed.capability_suggestions) == (2 if gaps else 0) diff --git a/backend/tests/projects/guide_compilation/test_context_builder.py b/backend/tests/projects/guide_compilation/test_context_builder.py index 00a18ee59..b4279ab10 100644 --- a/backend/tests/projects/guide_compilation/test_context_builder.py +++ b/backend/tests/projects/guide_compilation/test_context_builder.py @@ -86,9 +86,9 @@ async def test_context_drift_fails_before_dispatch( ) async with factory() as session: state = await load_compilation_execution_state(session, request.attempt_id) - drifted_capabilities = context(values).checker_capabilities.model_copy( - update={"manifest_sha256": "sha256:" + "f" * 64} - ) + from tests.checkers.external.support import capability_projection, registry_entry + + drifted_capabilities = capability_projection(registry_entry("pre_submit")) async with factory() as session: with pytest.raises(GuideCompilationIntegrityError, match="identity mismatch"): await build_project_guide_compilation_context( diff --git a/backend/tests/projects/guide_compilation/test_live_worker.py b/backend/tests/projects/guide_compilation/test_live_worker.py index 4c0435e7a..d914a5629 100644 --- a/backend/tests/projects/guide_compilation/test_live_worker.py +++ b/backend/tests/projects/guide_compilation/test_live_worker.py @@ -116,7 +116,10 @@ async def run(self, delivery): raise ProjectGuideCompilationDeliveryError() monkeypatch.setattr(worker, "get_database_url", lambda: "postgresql+asyncpg://localhost/unit_test") - monkeypatch.setattr(worker, "_coordinator", lambda sessions: Coordinator()) + async def coordinator(_sessions): + return Coordinator() + + monkeypatch.setattr(worker, "_coordinator", coordinator) def forbidden(**kwargs): pytest.fail("stale delivery reached transport retry") diff --git a/backend/tests/projects/policy_read_fixtures.py b/backend/tests/projects/policy_read_fixtures.py index e7f5cc76f..17997151b 100644 --- a/backend/tests/projects/policy_read_fixtures.py +++ b/backend/tests/projects/policy_read_fixtures.py @@ -8,6 +8,35 @@ from uuid import uuid4 from app.core.hashing import canonical_json_hash +from app.modules.checkers.api.external_policy import ( + LockedExternalPostSubmitPolicy, + LockedExternalPreSubmitPolicy, + LockedWorkstreamDefault, +) + + +def _empty_external_pre_policy() -> LockedExternalPreSubmitPolicy: + default = LockedWorkstreamDefault() + payload = { + "schema_version": "external_pre_submit_policy.v1", + "workstream_default": default.model_dump(mode="json"), + "entries": [], + } + return LockedExternalPreSubmitPolicy( + **payload, + policy_sha256=canonical_json_hash(payload), + ) + + +def _empty_external_post_policy() -> LockedExternalPostSubmitPolicy: + payload = { + "schema_version": "external_post_submit_policy.v1", + "entries": [], + } + return LockedExternalPostSubmitPolicy( + **payload, + policy_sha256=canonical_json_hash(payload), + ) class _PolicyReadRepository: @@ -60,7 +89,8 @@ def _initialize_source(self) -> None: def _initialize_intake(self) -> None: submission_body = {"allowed": ["zip"]} effective_body = {"allowed": ["zip"], "max_bytes": 10} - checker_bundle = {"checkers": ["safe"]} + checker_policy = _empty_external_pre_policy() + checker_bundle = checker_policy.model_dump(mode="json") self.effective = types.SimpleNamespace( id=str(uuid4()), project_id=self.project_id, @@ -85,7 +115,7 @@ def _initialize_intake(self) -> None: effective_policy_hash=self.effective.effective_policy_hash, lifecycle_status="compiled", compiled_bundle=checker_bundle, - compiled_bundle_hash=canonical_json_hash(checker_bundle), + compiled_bundle_hash=checker_policy.policy_sha256, ) self.submission = types.SimpleNamespace( id=self.effective.submission_artifact_policy_id, @@ -115,7 +145,8 @@ def _initialize_review(self) -> None: warnings_acknowledged_at=None, warnings_acknowledged_by_role=None, ) - post_body = {"required_checkers": ["safe"]} + post_policy = _empty_external_post_policy() + post_body = post_policy.model_dump(mode="json") self.post_submit = types.SimpleNamespace( id=str(uuid4()), project_id=self.project_id, @@ -132,7 +163,7 @@ def _initialize_review(self) -> None: projection_operation_id=uuid4(), approved_at=datetime.now(UTC), policy_body=post_body, - policy_hash=canonical_json_hash(post_body), + policy_hash=post_policy.policy_sha256, ) self.review = types.SimpleNamespace( id=str(uuid4()), diff --git a/backend/tests/projects/test_policy_read_composition.py b/backend/tests/projects/test_policy_read_composition.py index 5d2a9ce58..aa49829f0 100644 --- a/backend/tests/projects/test_policy_read_composition.py +++ b/backend/tests/projects/test_policy_read_composition.py @@ -41,11 +41,12 @@ async def test_policy_read_binds_exact_target_facts(action: ActionId) -> None: """Bind the exact returned row to all authorization resource facts.""" repository = _PolicyReadRepository() authorization = SimpleNamespace(require=AsyncMock()) - checker = ( - repository.checker - if action is ActionId.PROJECT_PRE_SUBMIT_CHECKER_POLICY_READ else None + checker = repository.checker + target = ( + checker + if action is ActionId.PROJECT_PRE_SUBMIT_CHECKER_POLICY_READ + else repository.effective ) - target = checker if checker is not None else repository.effective result = await _read(repository, authorization, action) @@ -70,9 +71,21 @@ async def test_policy_read_binds_exact_target_facts(action: ActionId) -> None: "effective_policy_id": repository.effective.id, "effective_policy_hash": repository.effective.effective_policy_hash, "effective_policy_status": "approved", - "checker_policy_id": checker.id if checker is not None else None, - "checker_policy_status": "compiled" if checker is not None else None, - "checker_bundle_hash": checker.compiled_bundle_hash if checker is not None else None, + "checker_policy_id": ( + checker.id + if action is ActionId.PROJECT_PRE_SUBMIT_CHECKER_POLICY_READ + else None + ), + "checker_policy_status": ( + "compiled" + if action is ActionId.PROJECT_PRE_SUBMIT_CHECKER_POLICY_READ + else None + ), + "checker_bundle_hash": ( + checker.compiled_bundle_hash + if action is ActionId.PROJECT_PRE_SUBMIT_CHECKER_POLICY_READ + else None + ), } @@ -89,10 +102,11 @@ async def test_policy_read_binds_exact_digest(action: ActionId) -> None: repository.effective.id, repository.effective.effective_policy_hash, "approved", ], "submission": [repository.submission.id, repository.submission.policy_hash], - "checker": ( - [repository.checker.id, "compiled", repository.checker.compiled_bundle_hash] - if action is ActionId.PROJECT_PRE_SUBMIT_CHECKER_POLICY_READ else None - ), + "checker": [ + repository.checker.id, + "compiled", + repository.checker.compiled_bundle_hash, + ], }) await _read(repository, authorization, action) @@ -134,6 +148,28 @@ async def test_policy_read_rejects_changed_lineage(row: str, field: str, action: assert context.target_binding_digest is None +@pytest.mark.asyncio +async def test_policy_read_rejects_generic_hash_valid_checker_bundle() -> None: + """A canonical hash cannot turn an obsolete checker body into a current policy.""" + repository = _PolicyReadRepository() + authorization = SimpleNamespace(require=AsyncMock()) + repository.checker.compiled_bundle = {"checkers": ["safe"]} + repository.checker.compiled_bundle_hash = canonical_json_hash( + repository.checker.compiled_bundle + ) + + with pytest.raises(RuntimeError, match="missing policy authorization unexpectedly allowed"): + await _read( + repository, + authorization, + ActionId.PROJECT_PRE_SUBMIT_CHECKER_POLICY_READ, + ) + + context = authorization.require.await_args.args[1] + assert context.target_exists is False + assert context.target_binding_digest is None + + @pytest.mark.asyncio @pytest.mark.parametrize("action", POLICY_ACTIONS) async def test_policy_read_propagates_authorizer_exception(action: ActionId) -> None: @@ -172,3 +208,41 @@ def test_activation_readiness_normalizes_hash_valid_malformed_policy_body() -> N effective=repository.effective, pre=repository.checker, ), ) + + +def test_activation_readiness_rejects_hash_valid_obsolete_checker_bundle( + monkeypatch: pytest.MonkeyPatch, +) -> None: + repository = _PolicyReadRepository() + repository.submission.derivation_source = "unified_compilation" + repository.checker.compiled_bundle = {"checkers": ["safe"]} + repository.checker.compiled_bundle_hash = canonical_json_hash( + repository.checker.compiled_bundle + ) + service = ProjectService(cast(Any, None)) + monkeypatch.setattr( + service, + "_merge_effective_submission_artifact_policy", + lambda _body: repository.effective.effective_policy, + ) + + with pytest.raises( + GuideActivationBlocked, + match="external pre-submit checker policy is required", + ): + service.validate_activation_ready( + repository.guide, + repository.snapshot, + repository.sufficiency, + repository.submission, + repository.effective, + repository.checker, + repository.post_submit, + repository.review, + repository.revision, + approval_custody=SimpleNamespace( + operation=SimpleNamespace(artifact_policy_id=repository.submission.id), + effective=repository.effective, + pre=repository.checker, + ), + ) diff --git a/backend/tests/test_projects.py b/backend/tests/test_projects.py index e35151ba5..04c5b6bbf 100644 --- a/backend/tests/test_projects.py +++ b/backend/tests/test_projects.py @@ -4004,7 +4004,7 @@ async def test_submission_artifact_policy_approval_persists_effective_policy_has assert pre_submit_checker_policy is not None assert pre_submit_checker_policy.lifecycle_status == "compiled" assert pre_submit_checker_policy.effective_policy_hash == effective["effective_policy_hash"] - assert pre_submit_checker_policy.compiler_version == "workstream-pre-submit-compiler-v0.1" + assert pre_submit_checker_policy.compiler_version == "external_checker_policy.v1" assert pre_submit_checker_policy.compiled_bundle_hash is not None assert ( pre_submit_checker_policy.compiled_bundle["effective_policy_hash"] From e7465426f77eecab40c12b48de0d08aa90cb8096 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 18:02:55 +0100 Subject: [PATCH 258/283] Retain external checker review package coverage --- .../pilot04-workstream-default-checker.md | 3 +- .../finalization/pg_support.py | 16 ++++- .../guide_compilation/proposals/pg_support.py | 15 ++++- .../proposals/test_postgresql.py | 60 +++++-------------- 4 files changed, 45 insertions(+), 49 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 1408382af..490562ed9 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -1266,7 +1266,8 @@ their assertions: `tests/projects/guide_compilation/test_capability_growth.py`, `test_capability_growth_postgresql.py`, `test_compilation_storage_limit.py`, `test_live_worker.py`, `test_context_builder.py`, `proposals/test_postgresql.py`, the active-guide read fixtures and activation -tests, and the matching assertions in `tests/test_projects.py`. The batch may +tests, their proposal/finalization context helpers, and the matching assertions +in `tests/test_projects.py`. The batch may update current registered capability projections, strict worker error fakes, current proposal fields and current compiler identifiers. It must not restore a built-in checker catalogue, legacy decoder, execution fallback, migration or diff --git a/backend/tests/projects/guide_compilation/finalization/pg_support.py b/backend/tests/projects/guide_compilation/finalization/pg_support.py index 6468a738e..3279ee67b 100644 --- a/backend/tests/projects/guide_compilation/finalization/pg_support.py +++ b/backend/tests/projects/guide_compilation/finalization/pg_support.py @@ -182,14 +182,26 @@ async def prepare_setup_finalization(self, locator): @asynccontextmanager -async def database_case(url, *, classification="draft_ready", project=True, guide_version="v1", outcome=None): +async def database_case( + url, + *, + classification="draft_ready", + project=True, + guide_version="v1", + outcome=None, + checker_capabilities=None, +): values = await seed_database(url, guide_version=guide_version) engine = create_async_engine(url) factory = async_sessionmaker(engine, expire_on_commit=False) try: command = await compilation_and_projections( url, factory, values, classification=classification, project=project, - compilation_context=context(values, guide_version=guide_version), + compilation_context=context( + values, + guide_version=guide_version, + checker_capabilities=checker_capabilities, + ), outcome=outcome ) yield values, factory, command diff --git a/backend/tests/projects/guide_compilation/proposals/pg_support.py b/backend/tests/projects/guide_compilation/proposals/pg_support.py index 13de3035f..b5c18a252 100644 --- a/backend/tests/projects/guide_compilation/proposals/pg_support.py +++ b/backend/tests/projects/guide_compilation/proposals/pg_support.py @@ -174,9 +174,20 @@ async def prepare_proposal_operation(self, locator): @asynccontextmanager -async def proposal_case(url, *, classification="draft_ready", guide_version="v1", outcome=None): +async def proposal_case( + url, + *, + classification="draft_ready", + guide_version="v1", + outcome=None, + checker_capabilities=None, +): async with database_case( - url, classification=classification, guide_version=guide_version, outcome=outcome + url, + classification=classification, + guide_version=guide_version, + outcome=outcome, + checker_capabilities=checker_capabilities, ) as (values, factory, command): await finalize(factory, values, command) async with factory() as session: diff --git a/backend/tests/projects/guide_compilation/proposals/test_postgresql.py b/backend/tests/projects/guide_compilation/proposals/test_postgresql.py index fef4bec78..312f1762d 100644 --- a/backend/tests/projects/guide_compilation/proposals/test_postgresql.py +++ b/backend/tests/projects/guide_compilation/proposals/test_postgresql.py @@ -70,58 +70,30 @@ async def correct(factory, command, actor, grant, payload, *, authority_resource async def test_review_package_is_exact_complete_and_redacted(clean_postgres_database): - from app.interfaces.project_agents import ProjectGuideCompilationResult - from tests.projects.guide_compilation.helpers import result - - body = result().model_dump(mode="json") - evidence = body["findings"][0]["evidence_refs"] - body.update( - status="guide_blocked", - submission_artifact_policy=None, - requirements=[ - dict( - requirement_id="packet", - statement="Limit artifact file size.", - disposition="pre_submit_capability_gap", - evidence_refs=evidence, - ), - dict( - requirement_id="semantic", - statement="Evaluate specialist correctness.", - disposition="post_submit_capability_gap", - evidence_refs=evidence, - ), - ], - pre_submit_bindings=[], - post_submit_bindings=[], - capability_suggestions=[ - dict( - requirement_id="packet", - stage="pre_submit", - title="Artifact size checker", - rationale="Register a checker for the exact package size requirement.", - evidence_refs=evidence, - ), - dict( - requirement_id="semantic", - stage="post_submit", - title="Specialist correctness evaluator", - rationale="No registered external checker covers this evaluation.", - evidence_refs=evidence, - ), - ], - setup_notes=["A project manager must review the specialist evaluation gap."], + from tests.projects.guide_compilation.test_capability_growth import ( + _context as growth_context, + growth_report, ) - body["findings"][0]["severity"] = "blocking_gap" - outcome = ProjectGuideCompilationResult.model_validate(body) + + outcome = growth_report() + capabilities = growth_context().checker_capabilities async with proposal_case( - clean_postgres_database, classification="guide_blocked", outcome=outcome + clean_postgres_database, + classification=outcome.status, + outcome=outcome, + checker_capabilities=capabilities, ) as (_, factory, command, actor, grant): package = await read_package(factory, command, actor, grant) assert package.target.compilation_id == command.compilation_id assert package.target.setup_run_id == command.setup_run_id assert package.current is True expected = outcome.model_dump(mode="json") + assert len(expected["pre_submit_bindings"]) == 1 + assert len(expected["post_submit_bindings"]) == 1 + assert {item["stage"] for item in expected["capability_suggestions"]} == { + "pre_submit", + "post_submit", + } for section in ("findings", "requirements", "capability_suggestions"): for item in expected[section]: item["evidence_refs"] = [ From 7550fe8c6c780578f4f71c36a4bd1dc4f2a9bc84 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 18:07:47 +0100 Subject: [PATCH 259/283] Repair current external policy project assertions --- .../pilot04-workstream-default-checker.md | 6 ++-- backend/tests/projects/policy_read_faults.py | 15 +++++++--- .../projects/test_policy_read_composition.py | 30 ++++++++++++++++++- backend/tests/test_projects.py | 13 +++++--- 4 files changed, 53 insertions(+), 11 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 490562ed9..46a61d92f 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -1266,8 +1266,10 @@ their assertions: `tests/projects/guide_compilation/test_capability_growth.py`, `test_capability_growth_postgresql.py`, `test_compilation_storage_limit.py`, `test_live_worker.py`, `test_context_builder.py`, `proposals/test_postgresql.py`, the active-guide read fixtures and activation -tests, their proposal/finalization context helpers, and the matching assertions -in `tests/test_projects.py`. The batch may +tests, `tests/projects/policy_read_fixtures.py`, +`tests/projects/policy_read_faults.py`, +`tests/projects/test_policy_read_composition.py`, their proposal/finalization +context helpers, and the matching assertions in `tests/test_projects.py`. The batch may update current registered capability projections, strict worker error fakes, current proposal fields and current compiler identifiers. It must not restore a built-in checker catalogue, legacy decoder, execution fallback, migration or diff --git a/backend/tests/projects/policy_read_faults.py b/backend/tests/projects/policy_read_faults.py index 7d0773635..66423aabe 100644 --- a/backend/tests/projects/policy_read_faults.py +++ b/backend/tests/projects/policy_read_faults.py @@ -52,19 +52,26 @@ async def corrupt_locked_policy_reads(monkeypatch, task_id, mutation): "package_required": "yes", "allowed_package_formats": "zip", } elif mutation == "bundle": - pre.compiled_bundle["workstream_default"]["checker_version"] = "unsupported-default" + pre.compiled_bundle["workstream_default"]["behavior_sha256"] = ( + f"sha256:{'f' * 64}" + ) elif mutation == "stale_effective": effective.effective_policy["required_evidence"] = [] elif mutation == "stale_bundle": pre.compiled_bundle["tampered"] = True else: raise ValueError("unknown policy read fault") - if mutation in {"schema", "evidence", "packaging", "bundle"}: + if mutation in {"schema", "evidence", "packaging"}: effective.effective_policy_hash = canonical_json_hash(effective.effective_policy) pre.effective_policy_hash = effective.effective_policy_hash - pre.compiled_bundle["effective_policy_hash"] = effective.effective_policy_hash - pre.compiled_bundle_hash = canonical_json_hash(pre.compiled_bundle) task.locked_effective_project_submission_artifact_policy_hash = effective.effective_policy_hash + if mutation == "bundle": + pre.compiled_bundle["policy_sha256"] = canonical_json_hash({ + key: value + for key, value in pre.compiled_bundle.items() + if key != "policy_sha256" + }) + pre.compiled_bundle_hash = pre.compiled_bundle["policy_sha256"] task.locked_pre_submit_checker_bundle_hash = pre.compiled_bundle_hash def replace_read(owner, name, row): diff --git a/backend/tests/projects/test_policy_read_composition.py b/backend/tests/projects/test_policy_read_composition.py index aa49829f0..dbc0eebde 100644 --- a/backend/tests/projects/test_policy_read_composition.py +++ b/backend/tests/projects/test_policy_read_composition.py @@ -61,7 +61,11 @@ async def test_policy_read_binds_exact_target_facts(action: ActionId) -> None: "guide_id": repository.guide_id, "guide_version": "v1", "guide_status": "active", - "target_kind": "pre_submit_checker_policy" if checker is not None else "effective_policy", + "target_kind": ( + "pre_submit_checker_policy" + if action is ActionId.PROJECT_PRE_SUBMIT_CHECKER_POLICY_READ + else "effective_policy" + ), "project_exists": True, "project_status": "active", "guide_exists": True, @@ -170,6 +174,30 @@ async def test_policy_read_rejects_generic_hash_valid_checker_bundle() -> None: assert context.target_binding_digest is None +@pytest.mark.asyncio +async def test_effective_policy_read_conceals_chain_missing_current_pre_policy() -> None: + """The effective row is not readable without its current selected PRE policy.""" + repository = _PolicyReadRepository() + repository.checker = None + authorization = SimpleNamespace(require=AsyncMock()) + + with pytest.raises(RuntimeError, match="missing policy authorization unexpectedly allowed"): + await _read( + repository, + authorization, + ActionId.PROJECT_EFFECTIVE_SUBMISSION_ARTIFACT_POLICY_READ, + ) + + authorization.require.assert_awaited_once() + action, context = authorization.require.await_args.args + assert action is ActionId.PROJECT_EFFECTIVE_SUBMISSION_ARTIFACT_POLICY_READ + assert context.target_kind == "effective_policy" + assert context.target_exists is False + assert context.target_binding_digest is None + assert context.checker_policy_id is None + assert context.checker_bundle_hash is None + + @pytest.mark.asyncio @pytest.mark.parametrize("action", POLICY_ACTIONS) async def test_policy_read_propagates_authorizer_exception(action: ActionId) -> None: diff --git a/backend/tests/test_projects.py b/backend/tests/test_projects.py index 04c5b6bbf..0be4facc0 100644 --- a/backend/tests/test_projects.py +++ b/backend/tests/test_projects.py @@ -33,6 +33,8 @@ from app.core.config import get_settings from app.core.hashing import canonical_json_hash from app.core.identifiers import new_record_id +from app.modules.checkers.api.default_checker import WORKSTREAM_DEFAULT_BEHAVIOR_SHA256 +from app.modules.checkers.api.external_policy import validate_stored_external_pre_policy from app.db import session as db_session from app.db.base import Base from app.main import create_app @@ -4006,11 +4008,14 @@ async def test_submission_artifact_policy_approval_persists_effective_policy_has assert pre_submit_checker_policy.effective_policy_hash == effective["effective_policy_hash"] assert pre_submit_checker_policy.compiler_version == "external_checker_policy.v1" assert pre_submit_checker_policy.compiled_bundle_hash is not None - assert ( - pre_submit_checker_policy.compiled_bundle["effective_policy_hash"] - == (effective["effective_policy_hash"]) + locked_pre_policy = validate_stored_external_pre_policy( + pre_submit_checker_policy.compiled_bundle + ) + assert locked_pre_policy.policy_sha256 == pre_submit_checker_policy.compiled_bundle_hash + assert locked_pre_policy.workstream_default.behavior_sha256 == ( + WORKSTREAM_DEFAULT_BEHAVIOR_SHA256 ) - assert "require_file" in pre_submit_checker_policy.checker_configs + assert locked_pre_policy.entries == () async def test_approved_submission_artifact_policy_cannot_be_updated( From ec0731c34b4f34a4e346731362ca366e2245908b Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 17:46:40 +0100 Subject: [PATCH 260/283] docs: bound complete-source custody inventory optimization --- .../pilot04-workstream-default-checker.md | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 46a61d92f..6b33a9ef2 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -1279,3 +1279,29 @@ product compatibility path. The bounded production repair may update only the sole current external pre/post policy schemas and their self-excluding digests. It removes generic canonical-hash and old-plan fallbacks without rewriting retained rows. + +### Complete-source custody inventory performance + +Lead-authorized bounded test-only performance scope: this existing record and +`backend/tests/test_artifact_architecture.py`. The schema lane timed out before +finishing its exact sorted execution plan; the first remaining node was a custody +import-spelling negative. A single unchanged node passed locally in 41.82 seconds. +No per-node hosted duration was captured, so this identifies avoidable repeated +source parsing rather than proving the sole timeout cause. + +Freeze a complete actual APP Python-source import inventory once per test module, +using immutable module-name sets. The positive still validates every discovered +source path and exact custody consumer set plus composition annotations. Each of +the ten spelling negatives rebuilds the real `app/main.py` import inventory with +its injected import and replaces only that path in a copied complete inventory; +no shared AST or fixture may be mutated. Require a valid unmodified inventory +before each injected negative so an unrelated baseline error cannot satisfy it. + +Prohibited: production files, workflow/runner/schema caps, selectors, skips, +whitelists, reduced discovery, mutable cached ASTs, or synthetic inventories that +bypass actual source. Risk is lost structural enforcement. Acceptance requires +all existing complete-module tests and ten spelling negatives, same-source +before/after complete-module timings, and discriminating rejection of an actual +extra custody consumer with unchanged exact expected consumer sets. Lead and QA +review the immutable inventory and negative non-vacuity; human review focuses on +complete discovery, spelling coverage and isolation between parameter cases. From 0e362598784de42085fcd78402e467cbd3996e78 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 17:49:26 +0100 Subject: [PATCH 261/283] test: reuse immutable complete custody import inventory --- backend/tests/test_artifact_architecture.py | 69 +++++++++++++-------- 1 file changed, 44 insertions(+), 25 deletions(-) diff --git a/backend/tests/test_artifact_architecture.py b/backend/tests/test_artifact_architecture.py index 2e492215e..9cb135704 100644 --- a/backend/tests/test_artifact_architecture.py +++ b/backend/tests/test_artifact_architecture.py @@ -638,8 +638,28 @@ def test_checker_materialization_contract_has_one_canonical_consumer_owner() -> assert "Materialization" not in artifact_api.read_text(encoding="utf-8") -def test_checker_custody_ports_have_exact_owner_and_art_consumers() -> None: - """Allow only named CHECKERS consumers and ART implementations of custody ports.""" +def _imported_modules(path: Path, tree: ast.Module) -> frozenset[str]: + modules: set[str] = set() + for node in ast.walk(tree): + if isinstance(node, ast.ImportFrom): + package = ".".join(path.parent.relative_to(BACKEND_ROOT).parts) + module = resolve_name("." * node.level + (node.module or ""), package) + modules.add(module) + modules.update(f"{module}.{alias.name}" for alias in node.names) + elif isinstance(node, ast.Import): + modules.update(alias.name for alias in node.names) + return frozenset(modules) + + +@pytest.fixture(scope="module") +def checker_custody_import_inventory() -> tuple[tuple[Path, frozenset[str]], ...]: + """Freeze imports from every actual APP source without sharing mutable ASTs.""" + return tuple((path, _imported_modules(path, _tree(path))) for path in _python_files(APP_ROOT)) + + +def _assert_checker_custody_consumers( + inventory: tuple[tuple[Path, frozenset[str]], ...], +) -> None: expected = { "app.modules.checkers.api.output_custody": { "app/adapters/artifacts/__init__.py", @@ -663,16 +683,7 @@ def test_checker_custody_ports_have_exact_owner_and_art_consumers() -> None: }, } actual = {module: set() for module in expected} - for path in _python_files(APP_ROOT): - modules: set[str] = set() - for node in ast.walk(_tree(path)): - if isinstance(node, ast.ImportFrom): - package = ".".join(path.parent.relative_to(BACKEND_ROOT).parts) - module = resolve_name("." * node.level + (node.module or ""), package) - modules.add(module) - modules.update(f"{module}.{alias.name}" for alias in node.names) - elif isinstance(node, ast.Import): - modules.update(alias.name for alias in node.names) + for path, modules in inventory: for module in modules & expected.keys(): actual[module].add(path.relative_to(BACKEND_ROOT).as_posix()) assert actual == expected @@ -695,12 +706,19 @@ def test_checker_custody_ports_have_exact_owner_and_art_consumers() -> None: } +def test_checker_custody_ports_have_exact_owner_and_art_consumers( + checker_custody_import_inventory, +) -> None: + """Allow only named CHECKERS consumers and ART implementations of custody ports.""" + _assert_checker_custody_consumers(checker_custody_import_inventory) + + @pytest.mark.parametrize("port", ["output_custody", "materialization"]) @pytest.mark.parametrize("form", ["symbol", "module", "parent", "relative", "relative_parent"]) -def test_checker_custody_inventory_rejects_unregistered_import(monkeypatch, port, form): +def test_checker_custody_inventory_rejects_unregistered_import( + checker_custody_import_inventory, port, form, +): """Alternate import spelling must not conceal an additional API consumer.""" - import sys - statement = { "symbol": f"from app.modules.checkers.api.{port} import AnyContract", "module": f"import app.modules.checkers.api.{port} as custody", @@ -708,17 +726,18 @@ def test_checker_custody_inventory_rejects_unregistered_import(monkeypatch, port "relative": f"from .modules.checkers.api.{port} import AnyContract", "relative_parent": f"from .modules.checkers.api import {port} as custody", }[form] - original = _tree - - def injected(path): - tree = original(path) - if path == APP_ROOT / "main.py": - tree.body.extend(ast.parse(statement).body) - return tree - - monkeypatch.setattr(sys.modules[__name__], "_tree", injected) + _assert_checker_custody_consumers(checker_custody_import_inventory) + main = APP_ROOT / "main.py" + assert main in {path for path, _ in checker_custody_import_inventory} + injected_tree = _tree(main) + injected_tree.body.extend(ast.parse(statement).body) + injected_modules = _imported_modules(main, injected_tree) + injected_inventory = tuple( + (path, injected_modules if path == main else modules) + for path, modules in checker_custody_import_inventory + ) with pytest.raises(AssertionError): - test_checker_custody_ports_have_exact_owner_and_art_consumers() + _assert_checker_custody_consumers(injected_inventory) def test_submission_preparation_http_request_never_carries_prepared_authority() -> None: From b1bb8ff8a9d284fd577188df5936eeda1b8c24fa Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 18:04:42 +0100 Subject: [PATCH 262/283] test: reuse complete composition inventory for alias probes --- .../pilot04-workstream-default-checker.md | 12 +++++++ backend/tests/test_artifact_architecture.py | 34 ++++++++++++++----- 2 files changed, 37 insertions(+), 9 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 6b33a9ef2..a40d03320 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -1305,3 +1305,15 @@ before/after complete-module timings, and discriminating rejection of an actual extra custody consumer with unchanged exact expected consumer sets. Lead and QA review the immutable inventory and negative non-vacuity; human review focuses on complete discovery, spelling coverage and isolation between parameter cases. + +The unchanged complete module passed all 35 cases at clean `95d410810`: +767.93 seconds within pytest and 812.541 seconds including process lifetime. +Its ten custody negatives consumed 243.92 seconds and five composition negatives +198.39 seconds under host contention; these are local measurements, not inferred +hosted timings. The same allowed module now also freezes actual complete-source +composition imports and ordered call names once. Call multiplicity stays intact, +including the three observability constructions. Each of the five existing alias +negatives validates the actual baseline then appends only its freshly parsed +injected file to an immutable inventory copy. All exact owner paths, construction +counts, spelling variants and required assertions remain. Require the same 35-case +module and discriminating composition/custody mutants before claiming this repair. diff --git a/backend/tests/test_artifact_architecture.py b/backend/tests/test_artifact_architecture.py index 9cb135704..535ff9376 100644 --- a/backend/tests/test_artifact_architecture.py +++ b/backend/tests/test_artifact_architecture.py @@ -282,7 +282,19 @@ def test_project_domain_does_not_query_artifact_persistence_models() -> None: assert violations == [] -def test_concrete_adapter_construction_has_one_composition_path() -> None: +@pytest.fixture(scope="module") +def adapter_composition_inventory() -> tuple[tuple[Path, frozenset[str], tuple[str, ...]], ...]: + """Freeze complete-source imports and ordered calls, preserving multiplicity.""" + inventory = [] + for path in _python_files(APP_ROOT): + imports, calls = imported_symbols_and_calls(_tree(path)) + inventory.append((path, frozenset(imports), tuple(calls))) + return tuple(inventory) + + +def _assert_concrete_adapter_composition( + inventory: tuple[tuple[Path, frozenset[str], tuple[str, ...]], ...], +) -> None: factory_calls: list[Path] = [] adapter_calls: list[Path] = [] concrete_imports: list[Path] = [] @@ -290,8 +302,7 @@ def test_concrete_adapter_construction_has_one_composition_path() -> None: agent_calls: list[Path] = [] observability_imports: list[Path] = [] observability_calls: list[Path] = [] - for path in _python_files(APP_ROOT): - imports, calls = imported_symbols_and_calls(_tree(path)) + for path, imports, calls in inventory: if imports & CONCRETE_ADAPTER_MODULES: concrete_imports.append(path) if AGENT_ADAPTER_MODULE in imports: @@ -330,6 +341,10 @@ def test_concrete_adapter_construction_has_one_composition_path() -> None: assert observability_calls == [OBSERVABILITY_COMPOSITION_ROOT] * 3 +def test_concrete_adapter_construction_has_one_composition_path(adapter_composition_inventory) -> None: + _assert_concrete_adapter_composition(adapter_composition_inventory) + + @pytest.mark.parametrize("source", [ "from app.interfaces.external_services import ExternalServiceAdapterFactory as factory\nfactory[object]('extra')\n", "from app.interfaces.external_services import ExternalServiceAdapterFactory\nfactory: object = ExternalServiceAdapterFactory\nfactory[object]('extra')\n", @@ -337,15 +352,16 @@ def test_concrete_adapter_construction_has_one_composition_path() -> None: "from app.adapters.project_agents.openai_agent_sdk import OpenAIAgentSdkProjectGuideRuntime as runtime\nruntime(configuration)\n", "import app.adapters.project_agents.openai_agent_sdk as sdk\nsdk.OpenAIAgentSdkProjectGuideRuntime(configuration)\n", ]) -def test_composition_proof_rejects_aliased_factories_and_concrete_runtimes(tmp_path, monkeypatch, source): - import sys - - paths = _python_files(APP_ROOT) +def test_composition_proof_rejects_aliased_factories_and_concrete_runtimes( + tmp_path, adapter_composition_inventory, source, +): + _assert_concrete_adapter_composition(adapter_composition_inventory) injected = tmp_path / "extra.py" injected.write_text(source) - monkeypatch.setattr(sys.modules[__name__], "_python_files", lambda *_: (*paths, injected)) + imports, calls = imported_symbols_and_calls(_tree(injected)) + injected_inventory = (*adapter_composition_inventory, (injected, frozenset(imports), tuple(calls))) with pytest.raises(AssertionError): - test_concrete_adapter_construction_has_one_composition_path() + _assert_concrete_adapter_composition(injected_inventory) def test_s3_adapter_exposes_only_required_immutable_object_operations() -> None: From be263cfc9bef6febbbd64d2ed9ce0e5019d805a6 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 18:04:58 +0100 Subject: [PATCH 263/283] docs: record exact custody probe duration sum --- .commitrail/changes/pilot04-workstream-default-checker.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index a40d03320..a37801952 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -1308,7 +1308,7 @@ complete discovery, spelling coverage and isolation between parameter cases. The unchanged complete module passed all 35 cases at clean `95d410810`: 767.93 seconds within pytest and 812.541 seconds including process lifetime. -Its ten custody negatives consumed 243.92 seconds and five composition negatives +Its ten custody negatives consumed 228.93 seconds and five composition negatives 198.39 seconds under host contention; these are local measurements, not inferred hosted timings. The same allowed module now also freezes actual complete-source composition imports and ordered call names once. Call multiplicity stays intact, From 51a7bd079b30d80ca8d0e2ef798b2fd75ebcb54a Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 18:10:10 +0100 Subject: [PATCH 264/283] docs: retain complete inventory performance and mutant evidence --- .../pilot04-workstream-default-checker.md | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index a37801952..8297abee7 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -1317,3 +1317,26 @@ negatives validates the actual baseline then appends only its freshly parsed injected file to an immutable inventory copy. All exact owner paths, construction counts, spelling variants and required assertions remain. Require the same 35-case module and discriminating composition/custody mutants before claiming this repair. + +At clean `7cd949a646b115b265a4dd723a17366c291edf5e`, the same complete +35-case module passed in 118.99 seconds within pytest and 140.073 seconds including +process lifetime. Both baseline and optimized subprocesses exited zero within the +unchanged 1200-second bound and had identical start/end heads and clean trees. +Host contention and cache conditions differed, so these are measured local runs, +not a guaranteed hosted speedup. The optimized complete-source fixture setup took +17.87 seconds for composition and 9.62 for custody; the fifteen injected negative +calls took 0.02–0.12 seconds each. No test, spelling, exact consumer path, call +multiplicity or assertion was removed. + +An out-of-tree CPU probe compiled the actual parser, validators and negative test +functions from that frozen source and read all 507 actual APP files. It confirmed +that inventory summaries contain only immutable scalar containers, both complete +baselines validate, all fifteen ordinary negatives pass, and no inventory changes +between cases. Changing custody consumer equality to keys-only and disabling the +eight composition ownership assertions caused the expected `DID NOT RAISE` failure +for every one of the ten custody and five composition negatives. This is a pure +source/mutation discriminator, separately qualified from the complete pytest run; +it makes no database, native lifecycle or exhaustive hosted-suite claim. Raw +before/after and mutant evidence remains available to the lead. Independent QA +source review covered the complete discovery and custody extraction; composition +addendum review remains necessary for the final union. Ruff and diff checks pass. From 414b8aba7e3640e15d89d9bacd4d60b50bf49515 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 18:24:36 +0100 Subject: [PATCH 265/283] Use literal routing migration snapshot --- .../pilot04-workstream-default-checker.md | 27 +++++++ .../fixtures/pilot04_predecessor_rows.json.gz | Bin 789150 -> 862803 bytes .../tests/historical_submission_fixtures.py | 2 +- .../test_remediation_migration.py | 69 ++---------------- 4 files changed, 34 insertions(+), 64 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 8297abee7..cd3fc24af 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -1197,6 +1197,33 @@ checksum-bound at `25560b75796f84cff46bb506abdcd4b9cc2b7535411096fdbbec921d245d9 This supplies a retained predecessor identity prerequisite; canonical migration and receipt proof remains required. +### Literal routing-success predecessor fixture + +The retained 0031-to-0032 routing upgrade control must not execute the removed +checker or routing runtime against a predecessor schema. A one-time isolated +capture at source commit `3e2d59ba426a950e64b8e1632f4587c3265b0ea7` +produced one genuine human-review outcome and one genuine automatic-acceptance +outcome, restored every temporary current-only seed column, and then proved the +original receipt, context, governed outcome and acceptance predicates before +the existing upgrade passed. The committed +`0031_routing_success_true_false` snapshot contains all 579 rows across the 76 +nonempty public tables in that exact predecessor database. Its provenance names +the source revision, producer, capture shape and the two manifest IDs. + +Allowed scope is limited to the checksum-bound predecessor archive and loader, +`tests/tasks/post_submit_routing/test_remediation_migration.py`, and this record. +The migration test restores literal rows into an owned isolated 0031 database, +revalidates both complete success closures before upgrade, upgrades to 0032, +and requires byte-identical retained owners plus the exact new recommendation. +No archived writer, old request/result decoder, checker service, temporary +current column, guard bypass or compatibility API remains in the committed test. +The one-time generator passed the original migration control in 173.92 seconds +with complete database, role and object-store cleanup. The first current-loader +replay passed in 110.52 seconds with the same complete cleanup; its metadata +identifies the clean parent because the archive/test repair was not committed +yet, so this is qualified working-tree evidence. A clean frozen-head replay and +independent archive/test review remain required. + ### Frozen cutover verification before publication At clean `835737909aa3844d6cda1a0605a3098ed73781c1`, the canonical isolated diff --git a/backend/tests/fixtures/pilot04_predecessor_rows.json.gz b/backend/tests/fixtures/pilot04_predecessor_rows.json.gz index a344c1b3e40d324afd5f5367998ec626552eb813..71374c80e33375afae54385e831864cb9f8c3e45 100644 GIT binary patch delta 822550 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

>G$mB#4*F4N90p*^f!8bY`KXg1jeROYF= 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Øh>=}rh+C&XqD0cMGJf+uk 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%0A63H&xX(P9)%U!s7 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

-;XE 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

_&3KZL7kcC|)J^_EG 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 qJ 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
^s(pyuRnwZ|z*_g5Wjy>6O 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 @Yuu_pK*|M_2^`cA@spQd*(3c}5&&dj7f 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

rqs5KN`9IX%?l;; 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

  • qzC_CJCjAxWgAUK+gDcei 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

    KrQA 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%0Alpz zMobep`be(uukZHkwQ`-Jf86t$!NTT#I$T|Eq%h7$PP5)A6Rml-H2z$k*U^}1>Cvwh zYr?{hX5Yky=1S6=WNx=^qMoG2s3Vi|(Ues!kgypqCW@h%2cxjwu|wQ%1;bx5;m-{r zZKfPP)g<2GCzIqYD6bqMRGmsS160Ez{{XlA#)7B5x8qIq+PBKqk;0rn5m1=Y#-%aN zooYkgmI$Z3paCZX(3URvO0jCDY|aTT$uw)@h(D*EM(Jpk8DT(cH`Q4sW*-XXq>vCP zTocL3dOrTxW|<`RkbxxgC5ExV!jZVK^3VMc+bOrJUWQMUJm*0U^f$0f-!o%=q=rEU*h)Tq};aJGHsWZtquyRz@{U6QGrWXAS z=!aFvtIDa=#ANO>qxTA`qyzEv?5)M$LI!Pa`OL72@OpU_H77(O6$>m+I0hexs0=<{ zt+3^t5gO*Cb|}5kM(m5bzmizsB9WCb>qI| z3=@N-AjUasJA|;&q_KIf95Xk0p*<7+ep7iuOl{M;PUri&0aBb5UO1q}-k8iKae$7+ zvVz$*2WG>@-3BS7XZS{G`99HzuKPP2O_Tjg(*IS5V5Fcv%}g zy9LG{Ug3BNoxX2dlJ-?SkiiM;V>C2#7Jz#;dWciZ6%|J{>kw zan3*86w1+rIYQ9Te(5HWdfOa4-SRLkG{C_(QHMDxl#a#cXE7|KGW`h$b)42Lt>)*L zamx5t)Vew%x!iy|zPw^TxN0AYAazxH(a%&2(8x!={$3%#CQ% zh9_F&AB0w-2>_h4Z1*`$bH)uu^n4H#`hY~xBxZkC^VXWOiclMfJ*KLqD9wx+75gCg zEfa%~RtP)-LumXp)(CGs?BXJJZcq$ps0BAz!Z(L3fFDW~&MZUEk~h2M?0BiQs@*LU zxFY%t)O?kVy}Be;k`WMbe@#;j_1vp_0mC_FTg7)f1K5$?(D4c}Ycfh22li*eSWb@H zxb_BocJ9NF@;MQ}hkZaDv~#Bq^--(jy#Ompfg()7-fxs|IB`)8S$3O>fOJ3aFBG3ij3{MZd^A58mfC$ zYvLAh0X$}9)1%hYX=3(|kvKP<;xXaW1x383GBR3tEw(W}bxV<%ibHc4rGu#!m~6?+ zW4vDN9i^mnB8S%&(Q^{%*PY4@0<+EJ1DbbbWCkX;HWV#C%1J}wi@_)n$8d6dBZq!83 z!uk`xi9_@0&VVbs;gIv*;@LLbvyhh+#&TUg+E8;Cs+V9Mn5QTNkr*2|!L}~U0E?j} z2BTU>v!

    2hp0Zv59qUADhy!R9Oh86yyK- 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

    bn4V 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�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û?!AnV`Bk~_DYBaL{2;Alp` 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

    Y2QTU~?V&5iD^%ni&D-m; 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

    xR3c??(frK3%<{4HK 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 diff --git a/backend/tests/historical_submission_fixtures.py b/backend/tests/historical_submission_fixtures.py index 848567f8d..3fcac7710 100644 --- a/backend/tests/historical_submission_fixtures.py +++ b/backend/tests/historical_submission_fixtures.py @@ -28,7 +28,7 @@ _ARCHIVE = Path(__file__).with_name("fixtures") / "pilot04_predecessor_rows.json.gz" -_ARCHIVE_SHA256 = "3a874b8eb30c86d82f11093f839167c9841194027e3c6b1dfbae99b5fc510a96" +_ARCHIVE_SHA256 = "e24ab79e764452f92d41bf93ecb00c6a9e08fae427145c51a3e55160108ed054" _SCHEMA_VERSION = "workstream.pilot04_predecessor_rows.v1" diff --git a/backend/tests/migration_fixtures.py b/backend/tests/migration_fixtures.py index 37ed595e3..7734b8d19 100644 --- a/backend/tests/migration_fixtures.py +++ b/backend/tests/migration_fixtures.py @@ -1,7 +1,6 @@ """Canonical current-head lookup for current-schema assertions.""" from pathlib import Path -from contextlib import asynccontextmanager from alembic.config import Config from alembic.script import ScriptDirectory @@ -16,88 +15,3 @@ def current_schema_revision(): heads = ScriptDirectory.from_config(_config()).get_heads() assert len(heads) == 1 return heads[0] - - -_CAUSE_SEED_TABLES = ( - ("pre_submit_evidence_sets", "id"), - ("submission_bundle_admissions", "id"), - ("submission_dispatches", "submission_id"), -) - - -async def _add_current_cause_seed_columns(connection): - """Let the current initial writer seed older tables without inventing a cause.""" - originals = {} - for table, _ in _CAUSE_SEED_TABLES: - columns = await connection.fetch( - "SELECT column_name FROM information_schema.columns " - "WHERE table_schema='public' AND table_name=$1 ORDER BY ordinal_position", table, - ) - names = tuple(row[0] for row in columns) - if names and "checker_remediation_manifest_id" not in names: - revision = await connection.fetchval("SELECT version_num FROM public.alembic_version") - assert int(revision[:4]) < 33, "only a predecessor may need seeding columns" - await connection.execute( - f"ALTER TABLE public.{table} ADD COLUMN checker_remediation_manifest_id uuid" - ) - originals[table] = names - return originals - - -async def _restore_current_cause_seed_columns(connection, originals): - for table, names in originals.items(): - key = next(order for name, order in _CAUSE_SEED_TABLES if name == table) - assert await connection.fetchval( - f"SELECT count(*) FROM public.{table} " - "WHERE checker_remediation_manifest_id IS NOT NULL" - ) == 0 - before = await connection.fetch( - f"SELECT (to_jsonb(r) - 'checker_remediation_manifest_id')::text AS value " - f"FROM public.{table} r ORDER BY {key}" - ) - await connection.execute( - f"ALTER TABLE public.{table} DROP COLUMN checker_remediation_manifest_id" - ) - columns = await connection.fetch( - "SELECT column_name FROM information_schema.columns " - "WHERE table_schema='public' AND table_name=$1 ORDER BY ordinal_position", table, - ) - assert tuple(row[0] for row in columns) == names - assert await connection.fetch( - f"SELECT to_jsonb(r)::text AS value FROM public.{table} r ORDER BY {key}" - ) == before - - -@asynccontextmanager -async def current_art_attempt_seed_schema(database_url): - """Restore a predecessor's attempt shape before the migration under test.""" - import asyncpg - connection = await asyncpg.connect(database_url.replace("+asyncpg", "")) - owned = False - cause_originals = {} - try: - columns = await connection.fetch("SELECT column_name FROM information_schema.columns " - "WHERE table_schema='public' AND table_name='artifact_put_attempts' ORDER BY ordinal_position") - names = tuple(row[0] for row in columns) - if "task_import_source_id" not in names: - revision = await connection.fetchval("SELECT version_num FROM public.alembic_version") - assert int(revision[:4]) < 31 and names, "only a populated predecessor may need seeding columns" - await connection.execute("ALTER TABLE public.artifact_put_attempts ADD COLUMN task_import_source_id uuid") - owned = True - cause_originals = await _add_current_cause_seed_columns(connection) - yield - finally: - try: - await _restore_current_cause_seed_columns(connection, cause_originals) - if owned: - assert await connection.fetchval("SELECT count(*) FROM public.artifact_put_attempts " - "WHERE task_import_source_id IS NOT NULL") == 0 - before = await connection.fetch("SELECT (to_jsonb(r) - 'task_import_source_id')::text AS value " - "FROM public.artifact_put_attempts r ORDER BY id") - await connection.execute("ALTER TABLE public.artifact_put_attempts DROP COLUMN task_import_source_id") - restored = await connection.fetch("SELECT column_name FROM information_schema.columns " - "WHERE table_schema='public' AND table_name='artifact_put_attempts' ORDER BY ordinal_position") - assert tuple(row[0] for row in restored) == names - assert await connection.fetch("SELECT to_jsonb(r)::text AS value FROM public.artifact_put_attempts r ORDER BY id") == before - finally: - await connection.close() diff --git a/backend/tests/projects/guide_activation/source_fixtures.py b/backend/tests/projects/guide_activation/source_fixtures.py index 0fe2dac25..72d991b09 100644 --- a/backend/tests/projects/guide_activation/source_fixtures.py +++ b/backend/tests/projects/guide_activation/source_fixtures.py @@ -27,7 +27,6 @@ seed_setup_service_for_compiled_fixture, ) from tests.project_create_fixtures import seed_authorized_project -from tests.migration_fixtures import current_art_attempt_seed_schema from tests.projects.guide_compilation.helpers import ids, context, result from tests.projects.guide_compilation.finalization.pg_prerequisites import ( compilation_and_projections, @@ -269,17 +268,16 @@ async def source_case( if post_submit_registry_spec is not None else None ) - async with current_art_attempt_seed_schema(url): - values, finalization = await create_compiled_guide( - factory, - values, - actor, - version=guide_version, - artifact_proposal=artifact_proposal, - pre_submit_registry_entry=pre_registry_entry, - post_submit_registry_entry=post_registry_entry, - compilation_outcome=compilation_outcome, - ) + values, finalization = await create_compiled_guide( + factory, + values, + actor, + version=guide_version, + artifact_proposal=artifact_proposal, + pre_submit_registry_entry=pre_registry_entry, + post_submit_registry_entry=post_registry_entry, + compilation_outcome=compilation_outcome, + ) yield values, factory, finalization, actor, grant finally: await engine.dispose() diff --git a/backend/tests/projects/review_policy/test_migration.py b/backend/tests/projects/review_policy/test_migration.py index d32d8889c..e8a04c88a 100644 --- a/backend/tests/projects/review_policy/test_migration.py +++ b/backend/tests/projects/review_policy/test_migration.py @@ -3,7 +3,6 @@ import asyncio from pathlib import Path import runpy -from uuid import uuid4 from alembic import command from alembic.migration import MigrationContext @@ -13,36 +12,13 @@ from sqlalchemy.exc import IntegrityError from app.db import session as db_session -from app.modules.actors.models import ActorIdentityLink, ActorProfile -from app.modules.actors.service import ResolvedActor -from app.modules.authorization.kernel import AuthorizationService -from app.modules.authorization.prepared import PreparedAuthorizationService -from app.modules.authorization.repository import AdminAuthorizationRepository -from app.modules.authorization.runtime import ( - ActorKind, - ActorStatus, - HumanAuthorizationContext, - IdentityLinkStatus, -) -from app.modules.projects.api.policy_lineage import ReviewPolicySemantics -from app.modules.projects.policy_mutation_service import ( - NO_CURRENT_POLICY_ETAG, - ProjectPolicyMutationService, -) -from app.modules.projects.schemas import ReviewPolicyInput, ReviewPolicyResponse from tests.conftest import _drop_test_database_schema +from tests.historical_submission_fixtures import restore_archived_snapshot from tests.migration_fixtures import _config, current_schema_revision -from tests.projects.guide_activation.source_fixtures import source_case pytestmark = pytest.mark.postgres_schema_contract -class _PreInvariantReviewPolicyResponse(ReviewPolicyResponse): - """Decode the predecessor's once-permitted retained true value.""" - - requires_second_review: bool - - def _upgrade(connection) -> None: migration = runpy.run_path( str( @@ -54,62 +30,6 @@ def _upgrade(connection) -> None: migration["upgrade"]() -async def _seed_review_policy(factory, command_context, actor, *, retained_true: bool) -> None: - async with factory() as session: - resolved = ResolvedActor( - await session.get(ActorProfile, str(actor.actor_profile_id)), - await session.get(ActorIdentityLink, str(actor.identity_link_id)), - ) - context = HumanAuthorizationContext( - actor_profile_id=actor.actor_profile_id, - actor_kind=ActorKind.HUMAN, - actor_status=ActorStatus.ACTIVE, - identity_link_id=actor.identity_link_id, - identity_link_status=IdentityLinkStatus.ACTIVE, - request_id=uuid4(), - correlation_id=uuid4(), - ) - repository = AdminAuthorizationRepository(session) - kernel = AuthorizationService(session, context, admin_repository=repository) - prepared = PreparedAuthorizationService(session, context, kernel, repository) - service = ProjectPolicyMutationService(session) - values = ReviewPolicyInput( - review_preference_window_seconds=3600, - review_lease_duration_seconds=1800, - allowed_decisions=["accept", "needs_revision", "reject"], - ).model_dump() - if retained_true: - values["requires_second_review"] = True - values["allowed_decisions"] = tuple(values["allowed_decisions"]) - values["minimum_finding_fields"] = tuple(values["minimum_finding_fields"]) - # Construct the exact predecessor semantics to create a committed - # historical fact through the real writer, authority, and custody - # transaction. Current validation is exercised separately. - semantics = ReviewPolicySemantics.model_construct(**values) - await service._replace( - "review", - resolved, - prepared, - uuid4(), - NO_CURRENT_POLICY_ETAG, - command_context.project_id, - command_context.guide_id, - semantics, - _PreInvariantReviewPolicyResponse, - ) - else: - await service.replace_review_policy( - resolved, - prepared, - uuid4(), - NO_CURRENT_POLICY_ETAG, - command_context.project_id, - command_context.guide_id, - ReviewPolicyInput.model_validate(values), - ) - await session.commit() - - async def _snapshot(connection) -> dict[str, object]: return { "policies": list( @@ -147,24 +67,20 @@ async def test_upgrade_refuses_retained_true_without_changing_its_lineage( await asyncio.to_thread( command.upgrade, _config(), "0023_remove_task_payment_policy" ) - async with source_case(isolated_database_env) as ( - _values, - factory, - command_context, - actor, - _grant, - ): - await _seed_review_policy(factory, command_context, actor, retained_true=True) - async with factory.kw["bind"].connect() as connection, connection.begin(): - before = await _snapshot(connection) - assert before["policies"][0]["requires_second_review"] is True - with pytest.raises( - IntegrityError, - match="retained requires_second_review=true policy", - ): - async with connection.begin_nested(): - await connection.run_sync(_upgrade) - assert await _snapshot(connection) == before + await restore_archived_snapshot( + isolated_database_env, + snapshot_name="0023_review_policy_second_review_true", + ) + async with db_session.get_engine().connect() as connection, connection.begin(): + before = await _snapshot(connection) + assert before["policies"][0]["requires_second_review"] is True + with pytest.raises( + IntegrityError, + match="retained requires_second_review=true policy", + ): + async with connection.begin_nested(): + await connection.run_sync(_upgrade) + assert await _snapshot(connection) == before async def test_upgrade_installs_false_guard_without_changing_hash_or_lineage( @@ -177,30 +93,27 @@ async def test_upgrade_installs_false_guard_without_changing_hash_or_lineage( await asyncio.to_thread( command.upgrade, _config(), "0023_remove_task_payment_policy" ) - async with source_case(isolated_database_env) as ( - _values, - factory, - command_context, - actor, - _grant, - ): - await _seed_review_policy(factory, command_context, actor, retained_true=False) - async with factory.kw["bind"].connect() as connection: - before = await _snapshot(connection) - await connection.rollback() - await asyncio.to_thread(command.upgrade, _config(), "head") - async with factory.kw["bind"].connect() as connection: - after = await _snapshot(connection) - constraint = await connection.scalar( - text( - "select pg_get_constraintdef(oid) from pg_constraint " - "where conrelid='public.review_policies'::regclass " - "and conname=" - "'ck_review_policies_review_policy_second_review_disabled'" - ) + await restore_archived_snapshot( + isolated_database_env, + snapshot_name="0023_review_policy_second_review_false", + ) + async with db_session.get_engine().connect() as connection: + before = await _snapshot(connection) + await connection.rollback() + await db_session.dispose_engine() + await asyncio.to_thread(command.upgrade, _config(), "head") + async with db_session.get_engine().connect() as connection: + after = await _snapshot(connection) + constraint = await connection.scalar( + text( + "select pg_get_constraintdef(oid) from pg_constraint " + "where conrelid='public.review_policies'::regclass " + "and conname=" + "'ck_review_policies_review_policy_second_review_disabled'" ) - assert before["policies"] == after["policies"] - assert before["selectors"] == after["selectors"] - assert before["version"] == "0023_remove_task_payment_policy" - assert after["version"] == current_schema_revision() - assert constraint == "CHECK ((NOT requires_second_review))" + ) + assert before["policies"] == after["policies"] + assert before["selectors"] == after["selectors"] + assert before["version"] == "0023_remove_task_payment_policy" + assert after["version"] == current_schema_revision() + assert constraint == "CHECK ((NOT requires_second_review))" From da76eabed9dd8889c4ca7443e880e6b066f6f43e Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 19:05:31 +0100 Subject: [PATCH 275/283] Require real selected policy rows in both migration controls --- .../tests/projects/review_policy/test_migration.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/backend/tests/projects/review_policy/test_migration.py b/backend/tests/projects/review_policy/test_migration.py index e8a04c88a..204145cf5 100644 --- a/backend/tests/projects/review_policy/test_migration.py +++ b/backend/tests/projects/review_policy/test_migration.py @@ -57,6 +57,16 @@ async def _snapshot(connection) -> dict[str, object]: } +def _require_retained_policy(snapshot, *, requires_second_review): + """Prevent an empty or unselected fixture from satisfying preservation.""" + assert len(snapshot["policies"]) == len(snapshot["selectors"]) == 1 + policy, selector = snapshot["policies"][0], snapshot["selectors"][0] + assert policy["requires_second_review"] is requires_second_review + assert selector["policy_id"] == policy["id"] + assert selector["generation"] == policy["policy_generation"] + assert selector["hash"] == policy["policy_hash"] + + async def test_upgrade_refuses_retained_true_without_changing_its_lineage( isolated_database_env, migration_lock, @@ -73,7 +83,7 @@ async def test_upgrade_refuses_retained_true_without_changing_its_lineage( ) async with db_session.get_engine().connect() as connection, connection.begin(): before = await _snapshot(connection) - assert before["policies"][0]["requires_second_review"] is True + _require_retained_policy(before, requires_second_review=True) with pytest.raises( IntegrityError, match="retained requires_second_review=true policy", @@ -99,6 +109,7 @@ async def test_upgrade_installs_false_guard_without_changing_hash_or_lineage( ) async with db_session.get_engine().connect() as connection: before = await _snapshot(connection) + _require_retained_policy(before, requires_second_review=False) await connection.rollback() await db_session.dispose_engine() await asyncio.to_thread(command.upgrade, _config(), "head") From 6fc12eeec37f37fc274dc90c3e1ee01a89fe6a2e Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 19:36:35 +0100 Subject: [PATCH 276/283] test: align capability growth draft handoff --- .../pilot04-workstream-default-checker.md | 11 +++ .../test_capability_growth_postgresql.py | 68 ++++++++++++++----- 2 files changed, 62 insertions(+), 17 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index e67c933cf..c80e1d76b 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -1368,6 +1368,17 @@ the sole current external pre/post policy schemas and their self-excluding digests. It removes generic canonical-hash and old-plan fallbacks without rewriting retained rows. +The final hosted capability-growth repair is limited to this record and +`tests/projects/guide_compilation/test_capability_growth_postgresql.py`. Its +non-oversized branch must expect the current `policy_draft_ready` handoff: one +immutable sufficiency report, one draft submission-artifact policy and the two +exact linked projection operations. It must retain both original gap requirement +IDs and stages while proving that no effective, PRE or POST checker policy exists +before project-manager approval. The oversized terminal branch, canonical byte +measurement, single runtime call, stored-result replay, audit count and +provider-construction refusal remain unchanged. No product, schema, guard, +workflow selection or timeout change is authorized by this repair. + ### Complete-source custody inventory performance Lead-authorized bounded test-only performance scope: this existing record and diff --git a/backend/tests/projects/guide_compilation/test_capability_growth_postgresql.py b/backend/tests/projects/guide_compilation/test_capability_growth_postgresql.py index 860db2ccb..f2c9f4172 100644 --- a/backend/tests/projects/guide_compilation/test_capability_growth_postgresql.py +++ b/backend/tests/projects/guide_compilation/test_capability_growth_postgresql.py @@ -60,7 +60,9 @@ async def compile_project_guide(self, context, capabilities): monkeypatch.setattr(worker, "create_project_guide_runtime", lambda configuration: runtime) monkeypatch.setattr(worker, "project_guide_runtime_configuration", lambda settings: runtime_configuration()) first = await (await worker._coordinator(factory)).run(delivery) - assert first["status"] == ("compilation_invalid_terminal" if oversized else "sufficiency_blocked") + assert first["status"] == ( + "compilation_invalid_terminal" if oversized else "policy_draft_ready" + ) if oversized: assert first["error_code"] == "schema_invalid" assert runtime.calls == 1 @@ -78,15 +80,16 @@ async def compile_project_guide(self, context, capabilities): assert len(parsed.pre_submit_bindings) == len(parsed.post_submit_bindings) == 1 assert {s.stage.value for s in parsed.capability_suggestions} == {"pre_submit", "post_submit"} assert {s.requirement_id for s in parsed.capability_suggestions} == {"gap_pre_submit", "gap_post_submit"} - final = (await session.execute(text( - "select artifact_policy_id, artifact_policy_operation_id, artifact_policy_output_digest " - "from project_guide_setup_finalizations" - ))).one() - assert tuple(final) == (None, None, None) await _assert_projection_state(session, setup_id, oversized) - for table in ("project_guide_compilations", "project_guide_component_projection_operations", - "project_guide_setup_finalizations"): - assert await session.scalar(text(f"select count(*) from {table}")) == (0 if oversized else 1) + expected_counts = { + "project_guide_compilations": 1, + "project_guide_component_projection_operations": 2, + "project_guide_setup_finalizations": 1, + } + for table, expected in expected_counts.items(): + assert await session.scalar(text(f"select count(*) from {table}")) == ( + 0 if oversized else expected + ) def forbidden(*args): pytest.fail("terminal replay constructed a provider runtime") @@ -113,23 +116,54 @@ async def test_driver_json_byte_measure_matches_postgresql(automatic_source): async def _assert_projection_state(session, setup_id, oversized): - """Observe both checker stages and the exact sole sufficiency output before/after replay.""" - for table in ("submission_artifact_policies", "effective_project_submission_artifact_policies", - "pre_submit_checker_policies", "checker_policies"): + """Observe the current draft handoff or exact terminal absence before/after replay.""" + policy_ids = ( + await session.execute(text("select id from submission_artifact_policies order by id")) + ).scalars().all() + assert len(policy_ids) == (0 if oversized else 1) + for table in ( + "effective_project_submission_artifact_policies", + "pre_submit_checker_policies", + "checker_policies", + ): assert await session.scalar(text(f"select count(*) from {table}")) == 0 outputs = (await session.execute(text( - "select output_sufficiency_report_id, output_submission_artifact_policy_id, " - "output_post_submit_checker_policy_id from project_setup_runs where id=:id" + "select status,current_step,output_sufficiency_report_id, " + "output_submission_artifact_policy_id,output_post_submit_checker_policy_id " + "from project_setup_runs where id=:id" ), {"id": str(setup_id)})).one() - assert outputs.output_submission_artifact_policy_id is None assert outputs.output_post_submit_checker_policy_id is None reports = (await session.execute(text("select id from guide_sufficiency_reports"))).scalars().all() projections = (await session.execute(text( - "select component,report_id,policy_id from project_guide_component_projection_operations" + "select operation_id,component,report_id,policy_id " + "from project_guide_component_projection_operations order by component" ))).all() if oversized: + assert (outputs.status, outputs.current_step) == ("queued", "queued") assert reports == [] and projections == [] assert outputs.output_sufficiency_report_id is None + assert outputs.output_submission_artifact_policy_id is None else: + assert (outputs.status, outputs.current_step) == ( + "policy_draft_ready", + "submission_artifact_policy_derivation", + ) assert reports == [outputs.output_sufficiency_report_id] - assert projections == [("guide_sufficiency", outputs.output_sufficiency_report_id, None)] + assert policy_ids == [outputs.output_submission_artifact_policy_id] + assert [tuple(row)[1:] for row in projections] == [ + ("guide_sufficiency", outputs.output_sufficiency_report_id, None), + ("submission_artifact_policy", None, outputs.output_submission_artifact_policy_id), + ] + final = (await session.execute(text( + "select sufficiency_report_id,artifact_policy_id,sufficiency_operation_id," + "artifact_policy_operation_id,sufficiency_output_digest," + "artifact_policy_output_digest from project_guide_setup_finalizations" + ))).one() + assert tuple(final[:4]) == ( + outputs.output_sufficiency_report_id, + outputs.output_submission_artifact_policy_id, + projections[0].operation_id, + projections[1].operation_id, + ) + assert final.sufficiency_output_digest.startswith("sha256:") + assert final.artifact_policy_output_digest.startswith("sha256:") From 0b74a63d2c642e329048e25edb6a328a0f571b45 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 19:41:03 +0100 Subject: [PATCH 277/283] test: align shared authority expectations with selected pre actions --- .../pilot04-workstream-default-checker.md | 28 +++++++++++++++++++ .../test_grant_reads_postgresql.py | 2 +- .../tests/authorization/catalogue_fixtures.py | 2 ++ 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index c80e1d76b..bfc62e1ba 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -1485,3 +1485,31 @@ missing compiled rows, null stored hashes and substituted default behavior even with a recomputed valid outer policy digest. Independent QA reviewed that frozen source and ledger with no required finding. This is pure structural/test evidence; PROJECT native custody and the complete hosted suite remain separate obligations. + +### Exact selected PRE catalogue expectations in shared foundation tests + +Lead-authorized test-only scope: this existing record, +`backend/tests/authorization/admin_access/test_grant_reads_postgresql.py`, and +`backend/tests/authorization/catalogue_fixtures.py`. Fresh hosted shared-A evidence +at `da76eabed` fails only stale expectations for the two current selected PRE +execute/finalize permissions and active actions. The catalogue defines 80 +permissions; the system-auditor read test still expects 78. The separate explicit +audit-allowed action set omits `checker.pre_submit.execute` and +`checker.pre_submit.finalize`, although both are active and their fixed-service +expectations are already exact. + +Update only 78 to 80 in the exact public permission total/items comparison and +add those two literal action strings to the independent audit expectation. Keep +five role definitions, grant/profile/link identities, exact scope, denial and +zero-effect assertions unchanged. Preserve the actual audit-schema test body, +including permission/action mismatch, planned-action refusal, missing/unknown +action, decision evidence and digest validators. No production, authority grants, +DDL, ledger/limits, skipped tests or dynamically derived expected inventory. + +Risk: masking an authority expansion through a count-only fix. Verify the exact +two catalogue additions and unchanged fixed-service bindings, pure audit contract +and missing/extra expected-set discriminators, plus the actual PostgreSQL-backed +system-auditor permission read and write refusal through signed public callers. +Native verification is serial with the other owner and uses only isolated owned +resources. Lead CI/test-delta review and complete hosted CI remain required; no +publication, merge or full-suite claim follows from these fixture repairs. diff --git a/backend/tests/authorization/admin_access/test_grant_reads_postgresql.py b/backend/tests/authorization/admin_access/test_grant_reads_postgresql.py index aa13ff32d..7fcfef61b 100644 --- a/backend/tests/authorization/admin_access/test_grant_reads_postgresql.py +++ b/backend/tests/authorization/admin_access/test_grant_reads_postgresql.py @@ -92,7 +92,7 @@ async def test_system_auditor_has_exact_read_surface( assert response.status_code == 200, response.text body = response.json() if surface in {"permissions", "definitions"}: - assert body["total"] == len(body["items"]) == (78 if surface == "permissions" else 5) + assert body["total"] == len(body["items"]) == (80 if surface == "permissions" else 5) elif surface in {"list", "history"}: expected = {grant_id, access.bootstrap_grant_id} if surface == "list" else {grant_id} assert body["total"] == len(expected) diff --git a/backend/tests/authorization/catalogue_fixtures.py b/backend/tests/authorization/catalogue_fixtures.py index 56ee6e5ac..3ae8dee57 100644 --- a/backend/tests/authorization/catalogue_fixtures.py +++ b/backend/tests/authorization/catalogue_fixtures.py @@ -451,6 +451,8 @@ AUDIT_ALLOWED_ACTION_VALUES = { + "checker.pre_submit.execute", + "checker.pre_submit.finalize", "operations.checker.retry", "contribution.read_self", "contribution.read_project", From 85b0832798500f7b858513068ae061be361693b8 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 19:46:53 +0100 Subject: [PATCH 278/283] Use current lease budget seam in receipt expiry controls --- .../pilot04-workstream-default-checker.md | 34 +++++++++++++++++++ backend/app/modules/checkers/execution.py | 4 --- .../post_submit/test_receipt_custody.py | 33 +++++++++++++----- .../tasks/evaluation_delivery/test_custody.py | 12 +++++-- 4 files changed, 69 insertions(+), 14 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index bfc62e1ba..9d4a2d21a 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -1513,3 +1513,37 @@ system-auditor permission read and write refusal through signed public callers. Native verification is serial with the other owner and uses only isolated owned resources. Lead CI/test-delta review and complete hosted CI remain required; no publication, merge or full-suite claim follows from these fixture repairs. + +### Receipt-expiry fixture repair after the schema-lane cap + +Allowed scope is the current receipt-custody fixture in +`backend/tests/authorization/post_submit/test_receipt_custody.py`, the expired +execution delivery control in `backend/tests/tasks/evaluation_delivery/test_custody.py`, +the two unused constants in `backend/app/modules/checkers/execution.py`, and this record. +The six AUTH expiry controls patch an unused `LEASE_SECONDS` name while the +current owner derives its lease from the selected execution budget and finalization +margin. Hosted SQL timestamps show six real expiry waits of roughly 120 seconds +each, contributing to the unchanged 1200-second schema-lane cap. + +Use a scoped one-second initial execution budget and nine-second finalization +margin, then restore the current owner settings before takeover/finalization. +Wait for the persisted database expiry and assert database time has reached it; +retain genuine AUTH receipt substitution, exact rollback, valid recovery and +expired-delivery refusal controls. Remove the unused `LEASE_SECONDS` and +`EXECUTION_TIMEOUT_SECONDS` declarations; no executing owner reads either name. +Do not change production budgets, database facts/guards, lane placement, caps, +nodes, skips or exemptions. Required validation is Ruff/diff, exact seven-node +collection, independent source review and serialized real PostgreSQL controls. +This is an author repair; no completed native or full hosted-suite result is +claimed before those checks finish. + +The changed sources pass Ruff, Python parsing and `git diff --check`. +Focused collection retains exactly seven nodes: the five execute-receipt +substitutions, finalization's execute-chain substitution, and expired delivery +execution. Exact-word scans find no remaining references to either removed +constant. Neither changed test file nor the execution owner has a protected +structural-debt entry; the existing behavior ownership target is unchanged. +Lead source review found no issue with scoped setting restoration, persisted +ten-second duration, real database expiry or retained custody/refusal assertions. +Serialized PostgreSQL execution remains pending; this validation does not claim +the schema lane or the full hosted suite passed. diff --git a/backend/app/modules/checkers/execution.py b/backend/app/modules/checkers/execution.py index b5f5edc45..354f0cc7f 100644 --- a/backend/app/modules/checkers/execution.py +++ b/backend/app/modules/checkers/execution.py @@ -61,10 +61,6 @@ from app.modules.outbox.api import OutboxAppendPort from app.modules.outbox.api import OutboxAppendInput -LEASE_SECONDS = 300 -EXECUTION_TIMEOUT_SECONDS = 240 - - def _lease(run): """Recover the exact persisted lease, including its database expiry.""" return ExecutionLease( diff --git a/backend/tests/authorization/post_submit/test_receipt_custody.py b/backend/tests/authorization/post_submit/test_receipt_custody.py index ceb30b649..458aaa3c3 100644 --- a/backend/tests/authorization/post_submit/test_receipt_custody.py +++ b/backend/tests/authorization/post_submit/test_receipt_custody.py @@ -35,6 +35,24 @@ async def snapshot(h): ) +async def claim_expiring_lease(h, monkeypatch): + """Claim a genuine ten-second lease, restoring owner budgets before takeover.""" + import app.modules.checkers.execution as execution + + executor = live_executor(h) + with monkeypatch.context() as patch: + patch.setattr(executor, "_execution_budget_seconds", lambda _request: 1) + patch.setattr(execution, "SELECTED_POST_FINALIZATION_MARGIN_MS", 9_000) + lease, replay = await executor._claim(h.request) + assert replay is None + async with h.factory() as session: + assert await session.scalar(text( + "SELECT EXTRACT(EPOCH FROM worker_lease_expires_at-started_at) " + "FROM public.checker_runs WHERE id=:id" + ), {"id": lease.reservation.attempt_id}) == 10 + return lease + + async def next_lease(h, borrowed=None, *, shadow=False): """Simulate a faulty owner attaching a different real receipt after AUTH consumption.""" async with h.factory() as session, session.begin(): @@ -71,11 +89,9 @@ async def next_lease(h, borrowed=None, *, shadow=False): ["previous_lease", "foreign_attempt", "material_read", "nonexistent", "shadow_tables"], ) async def test_execute_receipt_substitution_rejected(tmp_path, isolated_database_env, substitution, monkeypatch): - import app.modules.checkers.execution as execution - monkeypatch.setattr(execution, "LEASE_SECONDS", 5) async with material_fixture(tmp_path / "one", isolated_database_env) as h: await reserve(h) - lease, _ = await live_executor(h)._claim(h.request) + lease = await claim_expiring_lease(h, monkeypatch) async with h.factory() as session: run = await session.get(CheckerRun, str(lease.reservation.attempt_id)) borrowed = UUID(run.execute_evidence_id) @@ -108,13 +124,12 @@ async def test_execute_receipt_substitution_rejected(tmp_path, isolated_database async def test_final_receipt_commits_only_exact_outcome( tmp_path, isolated_database_env, substitution, monkeypatch ): - import app.modules.checkers.execution as execution - - if substitution == "execute_chain": - monkeypatch.setattr(execution, "LEASE_SECONDS", 1) async with material_fixture(tmp_path, isolated_database_env) as h: await reserve(h) - lease, _ = await live_executor(h)._claim(h.request) + if substitution == "execute_chain": + lease = await claim_expiring_lease(h, monkeypatch) + else: + lease, _ = await live_executor(h)._claim(h.request) old_execute = None if substitution == "execute_chain": async with h.factory() as session: @@ -167,6 +182,8 @@ async def wait_for_expiry(h, lease): await session.execute(text( "select pg_sleep(greatest(0,extract(epoch from cast(:expiry as timestamptz)-clock_timestamp()))+0.02)" ), {"expiry": lease.expires_at}) + assert await session.scalar(text("SELECT clock_timestamp()>=:expiry"), + {"expiry": lease.expires_at}) @pytest.mark.parametrize("outcome", ["completed", "infrastructure_failed"]) diff --git a/backend/tests/tasks/evaluation_delivery/test_custody.py b/backend/tests/tasks/evaluation_delivery/test_custody.py index b50059d10..b65e4ef22 100644 --- a/backend/tests/tasks/evaluation_delivery/test_custody.py +++ b/backend/tests/tasks/evaluation_delivery/test_custody.py @@ -30,15 +30,23 @@ async def test_expired_execution_is_not_renewed(tmp_path, isolated_database_env, async with material_fixture(tmp_path, isolated_database_env) as h: d = await delivery_fixture(h) envelope = await invoked(h, d) + executor = d.handler._executor(envelope, h.request) with monkeypatch.context() as patch: - patch.setattr(execution, "LEASE_SECONDS", 1) - lease, replay = await d.handler._executor(envelope, h.request)._claim(h.request) + patch.setattr(executor, "_execution_budget_seconds", lambda _request: 1) + patch.setattr(execution, "SELECTED_POST_FINALIZATION_MARGIN_MS", 9_000) + lease, replay = await executor._claim(h.request) assert replay is None and lease.lease_generation == 1 before = await state(h) async with h.factory() as session: + assert await session.scalar(text( + "SELECT EXTRACT(EPOCH FROM worker_lease_expires_at-started_at) " + "FROM public.checker_runs WHERE id=:id" + ), {"id": lease.reservation.attempt_id}) == 10 await session.execute(text("select pg_sleep(greatest(0, extract(epoch from " "(:deadline - clock_timestamp()))) + 0.02)"), {"deadline": lease.expires_at}) + assert await session.scalar(text("SELECT clock_timestamp()>=:expiry"), + {"expiry": lease.expires_at}) with pytest.raises(CheckerExecutionUnavailable, match="checker_delivery_execution_unavailable"): await d.handler(envelope) assert await state(h) == before and not h.store.opens and not h.preparation._active From 62b661bd83479a7a8258c55da76031dd23fce85d Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 20:05:20 +0100 Subject: [PATCH 279/283] docs: record exact checker cutover repair evidence --- .../pilot04-workstream-default-checker.md | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 9d4a2d21a..022f7a844 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -1547,3 +1547,41 @@ Lead source review found no issue with scoped setting restoration, persisted ten-second duration, real database expiry or retained custody/refusal assertions. Serialized PostgreSQL execution remains pending; this validation does not claim the schema lane or the full hosted suite passed. + + +### Final hosted-failure repair verification + +The first full hosted run at candidate `da76eabed` (tested merge reference +`7b9a2f3a`) passed seven backend lanes. Shared A failed only the stale permission +count and missing PRE audit-action literals; project B failed only the stale +capability-growth draft expectation. Schema execution reached its unchanged +1200-second cap while making progress; six obsolete lease patches caused roughly +720 seconds of real expiry waits. These are diagnosed failures, not a full-suite +pass. The repair batch leaves every lane, node, CI limit and production execution +budget unchanged. + +At clean `7e17883e`, both capability-growth PostgreSQL cases passed in 183.83 +seconds: exact current draft output/projection/finalization links, retained +capability gaps, no effective PRE/POST policies, oversized terminal refusal and +exact replay without provider construction. At clean `9813a7b0`, twelve pure +audit contracts passed, the independent inventory discriminators rejected missing +and extra actions, and two signed public PostgreSQL read/write-denial controls +passed in 27.78 seconds. At clean `c5d28178`, all seven receipt/delivery controls +passed in 545.95 seconds within the unchanged 600-second local bound, proving +persisted ten-second initial leases, real database expiry, exact AUTH receipt +rejection, rollback, valid recovery and expired-delivery refusal. All three native +runners installed `0036_selected_checker_flow` and verified owned database/role +and MinIO namespace cleanup. The receipt fixtures use the current local ART +provider; this is not a new real-image or MinIO byte proof. + +The integrated source at clean `85b083279` is byte-identical to those reviewed +repair files. Lead and independent peer source/test-delta review passed, including +review of the reviewer-authored receipt changes. Ruff and Commitrail checks pass. +Canonical collection at that exact head contains 8,776 unique nodes in all ten +lanes, zero skips/deselections, and no exclusions; collection is not execution +evidence. Removing two unreferenced executor constants adds no runtime behavior. +The exact `da76eabed` Rust/PostgreSQL/MinIO image drill and capability-activation +proof remain separate earlier-head evidence. Fresh full hosted CI on the +published repair candidate and authenticated completed-node evidence verification +are still required before merge readiness. No deployment or merge is authorized +by these local results. From 90971c476145c6ef76ca8c652b5c247c2dff6a9f Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 20:24:39 +0100 Subject: [PATCH 280/283] test: reconcile identifier classifications with selected owners --- .../pilot04-workstream-default-checker.md | 27 +++++++++++++++++++ ...identifier_generation_classifications.json | 7 +++-- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 022f7a844..300949e0a 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -1585,3 +1585,30 @@ proof remain separate earlier-head evidence. Fresh full hosted CI on the published repair candidate and authenticated completed-node evidence verification are still required before merge readiness. No deployment or merge is authorized by these local results. + +### Exact identifier classifications after obsolete-owner removal + +Lead-authorized metadata-only scope: this existing record and +`backend/scripts/identifier_generation_classifications.json`. Published `62b661bd` +hosted schema evidence reports exactly three unclassified generation sites and +four stale classifications. The semantic-manifest UUIDv5 owner moved from deleted +`pre_submit_evidence.py` to `submission_manifest.py` without changing its digest +identity expression. The deleted `PreSubmitAttemptStore.reserve` UUIDv4 nonce has +no current generation site. Two `OutboxDelivery._finalize` UUIDv4 calls remain +AUTH request/correlation transport tokens; reviewed expiry checks changed the +exact enclosing AsyncWith fingerprints. + +Remove only those four stale keys and register the three observed exact keys. +Keep the manifest's `uuid5:call:content_identity` and both outbox calls' +`uuid4:call:transport_token` meanings. Verify the manifest remains a canonical +content identity supplied to current selected ART admission, while the outbox +values are passed only as request/correlation IDs to the current authority port. +Do not add a category, generic owner wildcard, suppressed generation site, +scanner/policy change, production/test/DDL edit, skip or weakened UUID assertion. + +Risk: incorrectly classifying a row surrogate as a token or hiding future code +movement. Acceptance requires all 24 unchanged identifier-inventory pure tests, +zero current unresolved/string-UUID references, exact missing-current and +stale-key mutation refusals, and unchanged unrelated classification entries. +Lead CI/test-delta review checks exact owner/key/category fidelity. No native +runtime or full hosted-suite claim is made by this metadata reconciliation. diff --git a/backend/scripts/identifier_generation_classifications.json b/backend/scripts/identifier_generation_classifications.json index 25c0a9962..2c0283bfb 100644 --- a/backend/scripts/identifier_generation_classifications.json +++ b/backend/scripts/identifier_generation_classifications.json @@ -28,8 +28,7 @@ "app/core/celery_observability.py|_task_prerun|Assign:88407f6b1931d9af|0": "uuid4:call:transport_token", "app/modules/actors/legacy_classification.py|_expected_actor_id|Return:dd984f00544f3859|0": "uuid5:call:external_identity_locator", "app/modules/artifacts/guide_document_access.py|ScopedGuideDocumentGrant.open|Assign:7e2866b7f96cc72a|0": "uuid4:call:transport_token", - "app/modules/artifacts/pre_submit_attempts.py|PreSubmitAttemptStore.reserve|Assign:dab8af3d0ea944db|0": "uuid4:call:lease_nonce", - "app/modules/artifacts/pre_submit_evidence.py|semantic_manifest_identity|Return:5c9bbd8b3ebba527|0": "uuid5:call:content_identity", + "app/modules/artifacts/submission_manifest.py|semantic_manifest_identity|Return:5c9bbd8b3ebba527|0": "uuid5:call:content_identity", "app/modules/authorization/admin_service.py|AdminRoleGrantService.bootstrap|Expr:efeb2a327e5efb1b|0": "uuid4:call:transport_token", "app/modules/authorization/admin_service.py|AdminRoleGrantService.bootstrap|Expr:687ae4c0e2b2fec8|0": "uuid4:call:transport_token", "app/modules/authorization/admin_service.py|AdminRoleGrantService.record_bootstrap_conflict|Expr:d5e0d0cc05ec64f2|0": "uuid4:call:transport_token", @@ -42,8 +41,8 @@ "app/modules/outbox/delivery.py|OutboxDelivery.claim|AsyncWith:3eebeb550e8493c8|0": "uuid4:call:transport_token", "app/modules/outbox/delivery.py|OutboxDelivery._begin_invocation|AsyncWith:0ddbadb4f6489377|0": "uuid4:call:transport_token", "app/modules/outbox/delivery.py|OutboxDelivery._begin_invocation|AsyncWith:e2bb8a01c8a388c3|0": "uuid4:call:transport_token", - "app/modules/outbox/delivery.py|OutboxDelivery._finalize|AsyncWith:ceb28e7cbbeffa3e|0": "uuid4:call:transport_token", - "app/modules/outbox/delivery.py|OutboxDelivery._finalize|AsyncWith:669c031c700fb7fc|0": "uuid4:call:transport_token", + "app/modules/outbox/delivery.py|OutboxDelivery._finalize|AsyncWith:cbbdbac740d6b955|0": "uuid4:call:transport_token", + "app/modules/outbox/delivery.py|OutboxDelivery._finalize|AsyncWith:e0a55fcc39dc3452|0": "uuid4:call:transport_token", "app/modules/projects/api/post_policy.py|post_policy_derive_authorization_selector|Return:d6d5543c040dee68|0": "uuid5:call:deterministic_selector", "app/modules/projects/api/post_policy.py|post_policy_human_authorization_selector|Return:3de6b3c65d2d1c0f|0": "uuid5:call:deterministic_selector", "app/modules/projects/api/post_policy.py|post_policy_task_id|Return:b69ef92b74c1322c|0": "uuid5:call:deterministic_selector", From 1eafd2ce454c79484e52dbe335bfc55601ff1e44 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 20:27:58 +0100 Subject: [PATCH 281/283] docs: record identifier cutover cleanup verification --- .../pilot04-workstream-default-checker.md | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 300949e0a..560200f98 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -1612,3 +1612,23 @@ zero current unresolved/string-UUID references, exact missing-current and stale-key mutation refusals, and unchanged unrelated classification entries. Lead CI/test-delta review checks exact owner/key/category fidelity. No native runtime or full hosted-suite claim is made by this metadata reconciliation. + + +At clean `33c47d683`, all 24 unchanged identifier-inventory tests passed in +34.05 seconds (52.789 seconds including process lifetime), exit zero and identical +clean start/end heads. The independent actual-scanner discriminator copied both +affected owner files byte-for-byte: original metadata reproduced exactly three +unclassified and four stale sites; corrected metadata had no errors; deleting +each of the three current keys or restoring each of the four stale keys produced +its intended error. Those focused copies are qualified separately from the full +repository checks in the existing 24-test module. Independent source/metadata +review passed and confirms untouched scanner, categories, unrelated entries, +tests, production, policy and waivers. + +The complete hosted run at `62b661bd8` (identical tested merge tree `de7cafd43`) +finished nine backend lanes successfully. Schema execution completed in 748.049 +seconds within the unchanged 1200-second cap, with 571 ordinary tests passing and +only this stale UUID-inventory test failing. This is not a full-suite pass. A fresh +required hosted run on the published metadata-repair candidate remains required +for merge readiness. Earlier native/image proofs remain explicitly tied to their +recorded heads; this metadata-only correction requires no new runtime proof. From ed9b4ca8f0967011234944415ecb4cd1211fbedf Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 21:15:34 +0100 Subject: [PATCH 282/283] ci: assign checker completion evidence to delivery lanes --- .../pilot04-workstream-default-checker.md | 38 +++++++++++++++++++ backend/scripts/test_lane_catalogue.py | 4 +- backend/tests/test_ci_lane_catalogue.py | 2 +- 3 files changed, 41 insertions(+), 3 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 560200f98..aced5bf92 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -1632,3 +1632,41 @@ only this stale UUID-inventory test failing. This is not a full-suite pass. A fr required hosted run on the published metadata-repair candidate remains required for merge readiness. Earlier native/image proofs remain explicitly tied to their recorded heads; this metadata-only correction requires no new runtime proof. + +### Owner-aligned completion-evidence lane capacity + +Lead-authorized bounded scope: this existing record, +`backend/scripts/test_lane_catalogue.py`, and only the literal expected-module +sets in `backend/tests/test_ci_lane_catalogue.py`. Move the whole six-node +`tests/checkers/execution/test_completion_evidence.py` module from TASK selection +to the existing four PROJECT partitions in `CHECKER_DELIVERY_MODULES`. Its native +proofs own current CHECKERS result, material, execution/finalization receipts and +successor currentness, without TASK routing or mutation authority. Preserve every +test body, assertion, PostgreSQL marker, execution kind and selection algorithm. +No production, migration, workflow, timeout, lane-count, exclusion, waiver or +required-check change is allowed. Correct only the accompanying outdated +three-way description of the existing four-way checker partition. + +Authenticated hosted run `38297853598`, tested merge +`d5ba919b2488724027bf0326e148a816a3f6ebe1`, completed all six cases: two on TASK-A +and four on TASK-C. TASK-C completed 294 of 295 nodes before its unchanged +1200-second cap; the last ordinary worker permission-denial test did not finish. +PROJECT A/B/C/D elapsed 736.325/892.426/934.605/995.090 seconds, leaving observed +headroom of 463.675/307.574/265.395/204.910 seconds. TASK-B passed in 1127.335 +seconds and receives no additional margin from this move. The captured TASK-A +foreign-owner case took 9.07 seconds; the interrupted TASK-C run has no complete +per-node duration report. Removing native fixture work is a bounded capacity +repair, not a measured whole-module saving or guarantee of future execution time. + +Risk: missing or duplicating nodes during reassignment, or confusing natural +HEAD-seeded UUID parameter changes with catalogue effects. Acceptance requires +real canonical before/after collection of all 8,776 unique nodes across the same +ten lanes without skips or deselections. Apply both catalogues to one identical +real collected node list to prove exactly six lane changes, 8,770 unrelated lane +assignments unchanged, and all six execution kinds still `ordinary_isolated`. +Cross-head comparisons must qualify the collector's existing HEAD-seeded UUID +parameter values. Existing exact catalogue, exhaustive assignment and negative +partition tests remain mandatory. Lead CI-integrity and independent peer +test-delta review inspect the frozen scope and evidence; a fresh complete hosted +run is required for capacity and merge readiness. No new native proof is needed +because test sources and runtime owners are unchanged. diff --git a/backend/scripts/test_lane_catalogue.py b/backend/scripts/test_lane_catalogue.py index 5309f277f..6ecf73da0 100644 --- a/backend/scripts/test_lane_catalogue.py +++ b/backend/scripts/test_lane_catalogue.py @@ -417,7 +417,7 @@ class TestLane: ) # Checker delivery shares project dispatch ownership and the existing -# three-way partition; exclusive placement exceeded the hosted execution cap. +# four-way partition; exclusive placement exceeded the hosted execution cap. CHECKER_DELIVERY_MODULES = ( "tests/checkers/default/test_contract.py", "tests/checkers/default/test_execution.py", @@ -433,6 +433,7 @@ class TestLane: "tests/checkers/external/test_selected_pre_submit_service.py", "tests/checkers/external/test_selected_preparation_command.py", "tests/checkers/execution/test_execution.py", + "tests/checkers/execution/test_completion_evidence.py", "tests/checkers/execution/test_coordination.py", "tests/checkers/execution/test_concurrency.py", "tests/checkers/execution/test_storage.py", @@ -454,7 +455,6 @@ class TestLane: "tests/tasks/test_task_import_contract.py", "tests/test_task_import_sources.py", "tests/test_submission_predecessor_custody.py", - "tests/checkers/execution/test_completion_evidence.py", "tests/checkers/execution/test_completion_contract.py", "tests/tasks/post_submit_routing/test_remediation.py", "tests/tasks/post_submit_routing/test_remediation_storage.py", diff --git a/backend/tests/test_ci_lane_catalogue.py b/backend/tests/test_ci_lane_catalogue.py index 1dcc698a9..bde3515c9 100644 --- a/backend/tests/test_ci_lane_catalogue.py +++ b/backend/tests/test_ci_lane_catalogue.py @@ -58,6 +58,7 @@ def test_checker_delivery_and_routing_preparation_partition_every_node_once() -> "tests/checkers/external/test_selected_pre_submit_service.py", "tests/checkers/external/test_selected_preparation_command.py", "tests/checkers/execution/test_execution.py", + "tests/checkers/execution/test_completion_evidence.py", "tests/checkers/execution/test_coordination.py", "tests/checkers/execution/test_concurrency.py", "tests/checkers/execution/test_storage.py", @@ -289,7 +290,6 @@ def test_measured_hotspots_have_explicit_semantic_owners() -> None: == modules_by_lane["task_lifecycle_b"] == modules_by_lane["task_lifecycle_c"] == { - "tests/checkers/execution/test_completion_evidence.py", "tests/checkers/execution/test_completion_contract.py", "tests/tasks/post_submit_routing/test_remediation.py", "tests/tasks/post_submit_routing/test_remediation_storage.py", From fde1761577fb14a531c21702e387ef825f881441 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Tue, 13 Oct 2026 06:10:05 +0100 Subject: [PATCH 283/283] docs: record checker completion lane verification --- .../pilot04-workstream-default-checker.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index aced5bf92..b4f1a1936 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -1670,3 +1670,19 @@ partition tests remain mandatory. Lead CI-integrity and independent peer test-delta review inspect the frozen scope and evidence; a fresh complete hosted run is required for capacity and merge readiness. No new native proof is needed because test sources and runtime owners are unchanged. + + +At clean `8219b30bb`, the existing catalogue/runner modules passed all 63 tests +in 19.34 seconds, including exact membership, exhaustive/disjoint selection and +negative partition controls. Actual canonical collection at clean `1eafd2ce4` +and `8219b30bb` each retained 8,776 unique nodes in ten lanes with zero skips or +deselections. Applying both catalogues to one identical actual collected list +changes exactly the six completion-evidence lane assignments and leaves 8,770 +rows unchanged; all six remain ordinary isolated execution. The collector seeds +UUID parameter values from HEAD, so this same-list comparison isolates catalogue +effects. Cross-head comparisons separately normalize only those existing UUID +parameter spellings; no collector or selection algorithm changed. Test source +AST comparison confirms only the expected-module literals were relocated. Ruff +and diff checks pass, and lead independent source/test-delta review found no +issue. Fresh complete hosted execution is still required; the measured capacity +qualification above does not guarantee a green run or authorize merging.

    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⁣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�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 iZD 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 gjb(sm*U7) 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%0D9+mgL+7Uh%g_F6AYf}~R)HAYIEPiv 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 None: - """Use signed human authority to activate the retained false-policy branch.""" - administrator = await access.signed.actor("migration-administrator") - operator = await access.signed.actor("migration-operator") - code, result = await run_bootstrap(administrator.id, execute=True) - assert code == 0 and result["result_code"] == "bootstrapped" - await access.signed.grant(administrator, operator) - await transition(await command_for(operator.id, "shadow")) - live = await transition(await command_for(operator.id, "live")) - assert live.generation == 2 - - async def _snapshot(connection) -> dict[str, list[asyncpg.Record]]: """Capture every retained owner touched by routing, excluding only the new column.""" queries = { @@ -94,12 +73,10 @@ async def _routing_validity(connection) -> list[asyncpg.Record]: async def test_routing_upgrade_preserves_success_evidence( - tmp_path, isolated_database_env, migration_lock, - admin_access, ): - """Upgrade real 0031 true/false outcomes without rewriting their evidence.""" + """Upgrade captured 0031 true/false outcomes without rewriting their evidence.""" url = isolated_database_env.replace("+asyncpg", "") with migration_lock(): await db_session.dispose_engine() @@ -109,47 +86,13 @@ async def test_routing_upgrade_preserves_success_evidence( finally: await connection.close() await asyncio.to_thread(command.upgrade, _config(), "0031_task_import_source") - - # Current application construction needs later nullable columns while it - # writes genuine predecessor outcomes. Restore exact 0031 shape before upgrade. - connection = await asyncpg.connect(url) - try: - await connection.execute( - "ALTER TABLE public.task_post_submit_routing_manifests " - "ADD COLUMN routing_recommendation varchar(32) NOT NULL" - ) - cause_originals = await _add_current_cause_seed_columns(connection) - finally: - await connection.close() - - await _activate_acceptance_lifecycle(admin_access) - async with authorized_routing_source( - tmp_path / "human", + await restore_archived_snapshot( isolated_database_env, - human_review_required=True, - ) as human: - async with human.factory() as session, session.begin(): - human_result = await apply_outcome(session, human, None) - async with authorized_routing_source( - tmp_path / "automatic", - isolated_database_env, - human_review_required=False, - storage_settings=human.settings, - provision_services=False, - ) as automatic: - async with automatic.factory() as session, session.begin(): - automatic_result = await apply_outcome(session, automatic, 2) - - assert human_result.final_acceptance_id is None - assert automatic_result.final_acceptance_id is not None + snapshot_name="0031_routing_success_true_false", + ) await db_session.dispose_engine() connection = await asyncpg.connect(url) try: - await _restore_current_cause_seed_columns(connection, cause_originals) - await connection.execute( - "ALTER TABLE public.task_post_submit_routing_manifests " - "DROP COLUMN routing_recommendation" - ) assert await connection.fetchval( "SELECT version_num FROM public.alembic_version" ) == "0031_task_import_source" From 94687d444d22d4c535ecbe7298e2ecb97df080ca Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 18:31:20 +0100 Subject: [PATCH 266/283] Strengthen literal routing branch assertions --- .../pilot04-workstream-default-checker.md | 8 ++++++-- .../test_remediation_migration.py | 17 ++++++++++++++++- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index cd3fc24af..f570fcdef 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -1221,8 +1221,12 @@ The one-time generator passed the original migration control in 173.92 seconds with complete database, role and object-store cleanup. The first current-loader replay passed in 110.52 seconds with the same complete cleanup; its metadata identifies the clean parent because the archive/test repair was not committed -yet, so this is qualified working-tree evidence. A clean frozen-head replay and -independent archive/test review remain required. +yet, so this is qualified working-tree evidence. The first clean-head replay +passed in 227.07 seconds with complete cleanup, then independent review required +stronger non-vacuity assertions for the two policy branches. The final test +therefore requires exactly `[true, false]`, two requests, one Final Acceptance, +one ContributionRecord and exact automatic-manifest-to-acceptance-to-contribution +lineage. A clean successor replay and final independent review remain required. ### Frozen cutover verification before publication diff --git a/backend/tests/tasks/post_submit_routing/test_remediation_migration.py b/backend/tests/tasks/post_submit_routing/test_remediation_migration.py index a16791caf..aa9d22e68 100644 --- a/backend/tests/tasks/post_submit_routing/test_remediation_migration.py +++ b/backend/tests/tasks/post_submit_routing/test_remediation_migration.py @@ -1,6 +1,7 @@ """0032 preserves genuine retained success outcomes and their exact evidence.""" import asyncio +import json import asyncpg import pytest @@ -50,7 +51,7 @@ async def _routing_validity(connection) -> list[asyncpg.Record]: """Return exact receipt hashes and all success-closure predicates.""" return await connection.fetch( """ - SELECT m.id, m.human_review_required, + SELECT m.id, m.human_review_required, m.final_acceptance_id, m.authority_context->'source'->>'routing_recommendation' AS source_recommendation, public.task_routing_resource_digest(m) AS resource_digest, a.after_facts->>'resource_context_digest' AS receipt_digest, @@ -99,6 +100,20 @@ async def test_routing_upgrade_preserves_success_evidence( before = await _snapshot(connection) before_validity = await _routing_validity(connection) assert len(before_validity) == 2 + human, automatic = before_validity + assert [row["human_review_required"] for row in before_validity] == [True, False] + assert human["final_acceptance_id"] is None + assert automatic["final_acceptance_id"] is not None + assert len(before["requests"]) == 2 + assert len(before["acceptances"]) == 1 + assert len(before["contributions"]) == 1 + acceptance = json.loads(before["acceptances"][0]["value"]) + contribution = json.loads(before["contributions"][0]["value"]) + assert acceptance["id"] == str(automatic["final_acceptance_id"]) + assert acceptance["source_routing_manifest_id"] == str(automatic["id"]) + assert contribution["source_final_acceptance_id"] == acceptance["id"] + assert contribution["submission_id"] == acceptance["submission_id"] + assert contribution["task_id"] == acceptance["task_id"] assert all( row["source_recommendation"] == "allow_review" and row["resource_digest"] == row["receipt_digest"] From fbcb3042acff5ae0b8385d1f6d22f002ec4734d8 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 18:41:55 +0100 Subject: [PATCH 267/283] Require selected predecessor rules custody without fallback --- .../pilot04-workstream-default-checker.md | 12 ++++ .../modules/artifacts/submission_admission.py | 11 +++- .../test_selected_predecessor_rules.py | 66 +++++++++++++++++++ 3 files changed, 86 insertions(+), 3 deletions(-) create mode 100644 backend/tests/artifacts/test_selected_predecessor_rules.py diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index f570fcdef..c621dbd21 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -9,6 +9,18 @@ ## Intent +Final predecessor cleanup permits `backend/app/modules/artifacts/submission_admission.py`, +`backend/tests/artifacts/test_selected_predecessor_rules.py` and this record. +Require a consumed predecessor's actual selected PRE lineage and rules commitment; +reject missing selected custody before preparing bytes. Never reinterpret its +retained policy-context hash as a checker-rules hash. Preserve all stored rows, +current unchanged-work rejection and genuine rules-change acceptance. Prohibited: +schema/data changes, legacy resubmission adapters, invented hash sentinels, +skip/cap changes or broader admission rewrites. Risk is L1; focused current and +missing/contradictory-lineage regressions, existing native predecessor controls, +the final real-image drill and full CI verify it. Independent QA reviews custody +and rejection ordering; human review focuses on fail-closed retained inputs. + Issue #491 owns the complete checker cutover. A contributor ZIP must first pass the one Workstream default checker and every required project pre-submit image. Only then may the existing caller-owned transaction create an immutable diff --git a/backend/app/modules/artifacts/submission_admission.py b/backend/app/modules/artifacts/submission_admission.py index 6763f25d1..bdceca6ee 100644 --- a/backend/app/modules/artifacts/submission_admission.py +++ b/backend/app/modules/artifacts/submission_admission.py @@ -866,7 +866,7 @@ async def _load_predecessor_rules( self, task_context: TaskSubmissionContextFacts, ) -> str | None: - """Return exact selected rules, treating retained legacy context as changed.""" + """Require the predecessor's exact selected rules commitment.""" predecessor = task_context.predecessor if predecessor is None: return None @@ -877,11 +877,16 @@ async def _load_predecessor_rules( SubmissionBundleAdmission.status == "consumed", ) ) - if admission is None: + if ( + admission is None + or admission.selected_pre_submit_run_id is None + or admission.pre_submit_evidence_set_id is not None + or admission.selected_rules_sha256 is None + ): raise SubmissionBundlePreparationRejected( "submission_canonical_predecessor_unavailable" ) - return admission.selected_rules_sha256 or admission.locked_policy_context_hash + return admission.selected_rules_sha256 @staticmethod def _result(result: SubmissionBundleDurablePutResult) -> SubmissionBundlePreparationResult: diff --git a/backend/tests/artifacts/test_selected_predecessor_rules.py b/backend/tests/artifacts/test_selected_predecessor_rules.py new file mode 100644 index 000000000..f54ccf404 --- /dev/null +++ b/backend/tests/artifacts/test_selected_predecessor_rules.py @@ -0,0 +1,66 @@ +"""Predecessor rules require selected custody, never a substitute context hash.""" + +from types import SimpleNamespace +from unittest.mock import AsyncMock, Mock + +import pytest + +from app.core.identifiers import new_record_id +from app.modules.artifacts.api import SubmissionBundlePreparationRejected +from app.modules.artifacts.submission_admission import PreparedSubmissionBundlePreparationCommand + + +def _command(admission): + return PreparedSubmissionBundlePreparationCommand( + session=SimpleNamespace(scalar=AsyncMock(return_value=admission)), + authority=SimpleNamespace(), + task_contexts=SimpleNamespace(), + project_contexts=SimpleNamespace(), + runtime_factory=Mock(), + ) + + +def _task(): + return SimpleNamespace(predecessor=SimpleNamespace(submission_id=new_record_id())) + + +@pytest.mark.asyncio +async def test_predecessor_uses_only_its_selected_rules_commitment(): + admission = SimpleNamespace( + selected_pre_submit_run_id=new_record_id(), + pre_submit_evidence_set_id=None, + selected_rules_sha256="sha256:" + "1" * 64, + locked_policy_context_hash="sha256:" + "2" * 64, + ) + command = _command(admission) + assert await command._load_predecessor_rules(_task()) == admission.selected_rules_sha256 + + +@pytest.mark.asyncio +@pytest.mark.parametrize("missing", ("admission", "run", "rules", "contradictory_evidence")) +async def test_missing_selected_predecessor_custody_rejects(missing): + admission = SimpleNamespace( + selected_pre_submit_run_id=new_record_id(), + pre_submit_evidence_set_id=None, + selected_rules_sha256="sha256:" + "1" * 64, + locked_policy_context_hash="sha256:" + "2" * 64, + ) + if missing == "admission": + admission = None + elif missing == "run": + admission.selected_pre_submit_run_id = None + elif missing == "rules": + admission.selected_rules_sha256 = None + else: + admission.pre_submit_evidence_set_id = new_record_id() + command = _command(admission) + with pytest.raises(SubmissionBundlePreparationRejected) as rejected: + await command._load_predecessor_rules(_task()) + assert str(rejected.value) == "submission_canonical_predecessor_unavailable" + + +@pytest.mark.asyncio +async def test_initial_submission_needs_no_predecessor_rules(): + command = _command(None) + assert await command._load_predecessor_rules(SimpleNamespace(predecessor=None)) is None + command._session.scalar.assert_not_called() From 847be4b4f95ee9db164b181deac16ab097ed7959 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 18:42:29 +0100 Subject: [PATCH 268/283] Register selected predecessor regressions in canonical CI lanes --- .commitrail/changes/pilot04-workstream-default-checker.md | 3 ++- backend/scripts/test_lane_catalogue.py | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index c621dbd21..167e0eec2 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -10,7 +10,8 @@ ## Intent Final predecessor cleanup permits `backend/app/modules/artifacts/submission_admission.py`, -`backend/tests/artifacts/test_selected_predecessor_rules.py` and this record. +`backend/tests/artifacts/test_selected_predecessor_rules.py`, its explicit module +registration in `backend/scripts/test_lane_catalogue.py`, and this record. Require a consumed predecessor's actual selected PRE lineage and rules commitment; reject missing selected custody before preparing bytes. Never reinterpret its retained policy-context hash as a checker-rules hash. Preserve all stored rows, diff --git a/backend/scripts/test_lane_catalogue.py b/backend/scripts/test_lane_catalogue.py index 99a0a9ce9..5309f277f 100644 --- a/backend/scripts/test_lane_catalogue.py +++ b/backend/scripts/test_lane_catalogue.py @@ -28,6 +28,7 @@ class TestLane: "tests/reviews/lifecycle/test_transitions.py", "tests/reviews/lifecycle/test_authority_binding.py", "tests/artifacts/test_review_packet_contract.py", + "tests/artifacts/test_selected_predecessor_rules.py", "tests/authorization/post_submit/test_atomicity.py", "tests/authorization/post_submit/test_concurrency.py", "tests/authorization/post_submit/test_live_authority.py", From 3352d773420d1b65e756e8311be7b5fa0cd8b055 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 18:45:45 +0100 Subject: [PATCH 269/283] Remove trailing archive fixture whitespace --- backend/tests/archive_fixtures.py | 1 - 1 file changed, 1 deletion(-) diff --git a/backend/tests/archive_fixtures.py b/backend/tests/archive_fixtures.py index 85c82fc41..56bc49bdb 100644 --- a/backend/tests/archive_fixtures.py +++ b/backend/tests/archive_fixtures.py @@ -28,4 +28,3 @@ def write(name: str, value: bytes) -> None: if path != evidence_path: write(evidence_path, b"verified\n") return output.getvalue() - From 1a3f3b8ab592900d5b8cf4d6cf3ef9bd7e0e4e86 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 18:47:16 +0100 Subject: [PATCH 270/283] test: shrink auth structure with immutable action inventory --- .ci/auth-boundaries/TEST_STRUCTURE_DEBT.json | 14 +- .../pilot04-workstream-default-checker.md | 32 +++ .../setup_finalization/test_catalogue.py | 229 +++++++++--------- backend/tests/test_projects.py | 6 - 4 files changed, 155 insertions(+), 126 deletions(-) diff --git a/.ci/auth-boundaries/TEST_STRUCTURE_DEBT.json b/.ci/auth-boundaries/TEST_STRUCTURE_DEBT.json index a3f327d78..82bb44725 100644 --- a/.ci/auth-boundaries/TEST_STRUCTURE_DEBT.json +++ b/.ci/auth-boundaries/TEST_STRUCTURE_DEBT.json @@ -122,11 +122,11 @@ }, { "capability": "oversized_authorization_structure", - "content_sha256": "f3098d904831d566b1fef38c6d8bda4d17765958ed899f8c6b219afa12cc6c0c", - "end_line": 5821, + "content_sha256": "5d706a12456adbef037616d73215b361450d24ce5f49cd68dcebb4cb66dbbb23", + "end_line": 5820, "hard_limit": 1200, "kind": "test_file", - "observed_lines": 5821, + "observed_lines": 5820, "path": "backend/tests/test_projects.py", "qualified_symbol": null, "removal_chunk": "WS-AUTH-003-CLOSE", @@ -399,26 +399,26 @@ { "capability": "oversized_authorization_structure", "content_sha256": "e723bd10cd20ba716fb75edda2a5b0c21a78dfce771efd55154834063c08b4b4", - "end_line": 2211, + "end_line": 2212, "hard_limit": 120, "kind": "test_function", "observed_lines": 128, "path": "backend/tests/test_projects.py", "qualified_symbol": "test_guide_mutation_service_executes_all_three_authorized_happy_paths", "removal_chunk": "WS-AUTH-003-CLOSE", - "start_line": 2084 + "start_line": 2085 }, { "capability": "oversized_authorization_structure", "content_sha256": "a801cae6e9f200073a42b7a2cb94edd614480899288fbe78783ea78fffe859c7", - "end_line": 1035, + "end_line": 1036, "hard_limit": 120, "kind": "test_function", "observed_lines": 137, "path": "backend/tests/test_projects.py", "qualified_symbol": "test_project_role_grant_repository_filters_and_uses_strict_keyset", "removal_chunk": "WS-AUTH-003-CLOSE", - "start_line": 899 + "start_line": 900 }, { "capability": "oversized_authorization_structure", diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 167e0eec2..5828ed453 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -1384,3 +1384,35 @@ it makes no database, native lifecycle or exhaustive hosted-suite claim. Raw before/after and mutant evidence remains available to the lead. Independent QA source review covered the complete discovery and custody extraction; composition addendum review remains necessary for the final union. Ruff and diff checks pass. + +### Protected AUTH structure shrink after reviewed fixture updates + +Lead-authorized scope: `backend/tests/test_projects.py`, +`backend/tests/authorization/setup_finalization/test_catalogue.py`, +`.ci/auth-boundaries/TEST_STRUCTURE_DEBT.json`, and this existing record only. +At clean `94687d444`, canonical observed debt differs from the existing ledger: +the exact active-action comparison reaches 121 lines against its 120-line hard +limit, and the already oversized PROJECT test file grows from 5821 to 5826 lines. +Protected main is `51c7e2eed53b4fd45b3ae201ef3b30445c233a09`. Updating the ledger +would improperly admit new debt and growth, independently refused by the trusted +transition validator. The two obsolete PRE debt deletions already in the ledger +are legitimate and remain unchanged. + +Extract the exact expected action literals into one module-level immutable +frozenset; retain actual ACTIVE enumeration and equality in the existing test. +Confirm exact before/after member identity and rejection of missing and extra +actions. In the PROJECT fixture, strict stored-policy validation already enforces +the code-owned default behavior digest, so remove the duplicate comparison and +unused import. Remove only the two redundant None checks: retained compiled-row +attribute assertions still require the row, and equality with the strict validated +SHA string requires the stored bundle hash. Preserve compiler/version, current +policy hash, empty entries and every DB lineage assertion. The file must shrink +below its protected-main size without formatting or whitespace manipulation. + +Risk: loss of exact action/compiled-policy proof. Lead and CI/test-delta review +must verify unchanged inventory and negative discriminators plus strict default +validation reachability. Prohibited: production, policy/limits, test skips, new +debt, ledger exceptions, suppressed guards or any unrelated test/assertion edit. +Acceptance requires exact canonical observed-ledger parity, protected-base +shrink-only transition and retained new-debt/growth refusal controls. No native +lifecycle proof or full hosted-suite claim is added by this metadata repair. diff --git a/backend/tests/authorization/setup_finalization/test_catalogue.py b/backend/tests/authorization/setup_finalization/test_catalogue.py index 49ee8ff9f..97d7ed9fa 100644 --- a/backend/tests/authorization/setup_finalization/test_catalogue.py +++ b/backend/tests/authorization/setup_finalization/test_catalogue.py @@ -28,6 +28,121 @@ from .test_prepared import legacy_resource +EXPECTED_ACTIVE_ACTIONS = frozenset({ + ActionId.CONTRIBUTION_READ_SELF, ActionId.CONTRIBUTION_READ_PROJECT, + ActionId.CHECKER_PRE_SUBMIT_EXECUTE, ActionId.CHECKER_PRE_SUBMIT_FINALIZE, + ActionId.CHECKER_POST_SUBMIT_EXECUTE, ActionId.CHECKER_POST_SUBMIT_FINALIZE, + ActionId.OPERATIONS_CHECKER_RETRY, + ActionId.CHECKER_REGISTRY_REGISTER, + ActionId.ARTIFACT_POST_SUBMIT_CHECKER_INPUT_MATERIALIZE, + ActionId.TASK_SUBMISSION_LIST, ActionId.TASK_GUIDE_READ, + ActionId.SUBMISSION_READ, + ActionId.SUBMISSION_CHECKER_RUN_LIST, + ActionId.CHECKER_RUN_READ, + ActionId.PROJECT_TASK_SUBMISSION_LIST, + ActionId.PROJECT_SUBMISSION_READ, + ActionId.PROJECT_SUBMISSION_CHECKER_RUN_LIST, + ActionId.PROJECT_CHECKER_RUN_READ, + ActionId.TASK_ASSIGNMENT_AUTHORITY_RECONCILE, + ActionId.OUTBOX_DISPATCH, + ActionId.TASK_POST_SUBMIT_ROUTE, + ActionId.PROJECT_GUIDE_ACTIVATE, + ActionId.ACTOR_PROFILE_READ_SELF, ActionId.ACTOR_PROFILE_UPDATE_SELF, + ActionId.AUTHORIZATION_PERMISSION_CATALOGUE_READ, + ActionId.AUTHORIZATION_ADMIN_ROLE_DEFINITIONS_READ, + ActionId.ADMIN_ROLE_GRANT_LIST, + ActionId.ACTOR_ADMIN_ROLE_GRANT_HISTORY_READ, + ActionId.ADMIN_ROLE_GRANT_ISSUE, + ActionId.ADMIN_ROLE_GRANT_REVOKE, + ActionId.ADMIN_ROLE_GRANT_BOOTSTRAP, + ActionId.ACTOR_PROFILE_READ, + ActionId.ACTOR_IDENTITY_LINK_READ, + ActionId.ACTOR_SERVICE_PROVISION, + ActionId.ACTOR_PROFILE_SUSPEND, + ActionId.REVIEW_LIFECYCLE_ACTIVATION_MANAGE, + ActionId.ACTOR_PROFILE_REACTIVATE, + ActionId.ACTOR_PROFILE_DEACTIVATE, + ActionId.ACTOR_IDENTITY_LINK_REVOKE, + ActionId.ACTOR_IDENTITY_LINK_REACTIVATE, + ActionId.PROJECT_CONTRIBUTOR_CANDIDATE_LIST, + ActionId.PROJECT_ROLE_GRANT_LIST, + ActionId.PROJECT_ROLE_GRANT_READ, + ActionId.PROJECT_ROLE_GRANT_ISSUE, + ActionId.PROJECT_ROLE_GRANT_REVOKE, + ActionId.PROJECT_CREATE, + ActionId.PROJECT_GUIDE_CREATE, + ActionId.PROJECT_GUIDE_UPDATE, + ActionId.PROJECT_GUIDE_SOURCE_SNAPSHOT_CREATE, + ActionId.PROJECT_GUIDE_COMPILATION_REQUEST, + ActionId.PROJECT_GUIDE_COMPILATION_REQUEST_AUTOMATIC, + ActionId.PROJECT_GUIDE_COMPILATION_EXECUTE, + ActionId.PROJECT_SETUP_RUN_UPDATE, + ActionId.PROJECT_REVIEW_POLICY_UPDATE, + ActionId.PROJECT_REVISION_POLICY_UPDATE, + ActionId.PROJECT_GUIDE_SUFFICIENCY_REPORT_CREATE, + ActionId.PROJECT_GUIDE_SUFFICIENCY_RUN, + ActionId.PROJECT_GUIDE_SUFFICIENCY_WARNINGS_ACKNOWLEDGE, + ActionId.PROJECT_SUBMISSION_ARTIFACT_POLICY_CREATE, + ActionId.PROJECT_SUBMISSION_ARTIFACT_POLICY_DERIVE, + ActionId.PROJECT_SUBMISSION_ARTIFACT_POLICY_UPDATE, + ActionId.PROJECT_GUIDE_COMPILATION_REVIEW_PACKAGE_READ, + ActionId.PROJECT_GUIDE_COMPILATION_CORRECTION_REQUEST, + ActionId.PROJECT_SUBMISSION_ARTIFACT_POLICY_APPROVE, + ActionId.PROJECT_POST_SUBMIT_CHECKER_POLICY_DERIVE, + ActionId.PROJECT_POST_SUBMIT_CHECKER_POLICY_APPROVE, + ActionId.PROJECT_POST_SUBMIT_CHECKER_POLICY_CORRECTION_REQUEST, + ActionId.PROJECT_READ, + ActionId.ACTOR_AUTHORIZATION_CONTEXT_READ, + ActionId.PROJECT_SETUP_RUN_READ, + ActionId.PROJECT_GUIDE_SUFFICIENCY_REPORT_LIST, + ActionId.PROJECT_GUIDE_SUFFICIENCY_REPORT_READ, + ActionId.PROJECT_SUBMISSION_ARTIFACT_POLICY_LIST, + ActionId.PROJECT_SUBMISSION_ARTIFACT_POLICY_READ, + ActionId.PROJECT_EFFECTIVE_SUBMISSION_ARTIFACT_POLICY_READ, + ActionId.PROJECT_PRE_SUBMIT_CHECKER_POLICY_READ, + ActionId.PROJECT_ACTIVE_GUIDE_READ, + ActionId.ARTIFACT_GUIDE_SOURCE_INGEST, + ActionId.ARTIFACT_TASK_IMPORT_SOURCE_DECLARE, + ActionId.ARTIFACT_TASK_IMPORT_SOURCE_UPLOAD, + ActionId.ARTIFACT_TASK_IMPORT_SOURCE_READ, + ActionId.ARTIFACT_GUIDE_SOURCE_READ, + ActionId.ARTIFACT_VERIFICATION_EXECUTE, + ActionId.ARTIFACT_PENDING_WORK_SCAN, + ActionId.ARTIFACT_PUT_ATTEMPT_RESOLVE, + ActionId.ARTIFACT_PRE_SUBMIT_CHECKER_INPUT_MATERIALIZE, + ActionId.ARTIFACT_SUBMISSION_BUNDLE_PREPARE, + ActionId.SUBMISSION_CREATE, + ActionId.TASK_CLAIM, ActionId.TASK_START, + ActionId.TASK_WORK_CONTEXT_READ, + ActionId.PROJECT_TASK_WORK_CONTEXT_READ, + ActionId.TASK_READ, + ActionId.TASK_SUBMISSION_REQUIREMENTS_READ, + ActionId.PROJECT_TASK_READ, + ActionId.PROJECT_TASK_SUBMISSION_REQUIREMENTS_READ, + ActionId.PROJECT_TASK_LOCKED_CONTEXT_READ, + ActionId.OPERATIONS_TASK_LOCKED_CONTEXT_READ, + ActionId.AUDIT_TASK_LOCKED_CONTEXT_READ, + ActionId.AUDIT_TASK_EVIDENCE_READ, + ActionId.TASK_QUEUE_READ, + ActionId.PROJECT_TASK_QUEUE_READ, + ActionId.OPERATIONS_TASK_QUEUE_READ, + ActionId.PROJECT_TASK_CREATE, + ActionId.PROJECT_TASK_SCREEN, + ActionId.PROJECT_TASK_RELEASE, + ActionId.OPERATIONS_TASK_START_OVERRIDE, + ActionId.ARTIFACT_SUBMISSION_BINDING_CREATE, + ActionId.COMPENSATION_ADAPTER_BINDING_READ, + ActionId.COMPENSATION_ADAPTER_BINDING_CREATE, + ActionId.COMPENSATION_ADAPTER_BINDING_SUSPEND, + ActionId.COMPENSATION_ADAPTER_BINDING_RESUME, + ActionId.CONTRIBUTION_POLICY_READ, + ActionId.CONTRIBUTION_POLICY_CREATE_DRAFT, + ActionId.CONTRIBUTION_POLICY_UPDATE_DRAFT, + ActionId.CONTRIBUTION_POLICY_PUBLISH, + ActionId.CONTRIBUTION_POLICY_RETIRE, +}) + + @pytest.mark.parametrize("identity", list(ServiceIdentity)) async def test_finalization_action_service_matrix(monkeypatch, identity): case = Case(monkeypatch, identity=identity) @@ -128,116 +243,4 @@ def test_exact_active_action_inventory(): definition.action_id for definition in ACTION_DEFINITIONS if definition.availability is ActionAvailability.ACTIVE - } == { - ActionId.CONTRIBUTION_READ_SELF, ActionId.CONTRIBUTION_READ_PROJECT, - ActionId.CHECKER_PRE_SUBMIT_EXECUTE, ActionId.CHECKER_PRE_SUBMIT_FINALIZE, - ActionId.CHECKER_POST_SUBMIT_EXECUTE, ActionId.CHECKER_POST_SUBMIT_FINALIZE, - ActionId.OPERATIONS_CHECKER_RETRY, - ActionId.CHECKER_REGISTRY_REGISTER, - ActionId.ARTIFACT_POST_SUBMIT_CHECKER_INPUT_MATERIALIZE, - ActionId.TASK_SUBMISSION_LIST, ActionId.TASK_GUIDE_READ, - ActionId.SUBMISSION_READ, - ActionId.SUBMISSION_CHECKER_RUN_LIST, - ActionId.CHECKER_RUN_READ, - ActionId.PROJECT_TASK_SUBMISSION_LIST, - ActionId.PROJECT_SUBMISSION_READ, - ActionId.PROJECT_SUBMISSION_CHECKER_RUN_LIST, - ActionId.PROJECT_CHECKER_RUN_READ, - ActionId.TASK_ASSIGNMENT_AUTHORITY_RECONCILE, - ActionId.OUTBOX_DISPATCH, - ActionId.TASK_POST_SUBMIT_ROUTE, - ActionId.PROJECT_GUIDE_ACTIVATE, - ActionId.ACTOR_PROFILE_READ_SELF, ActionId.ACTOR_PROFILE_UPDATE_SELF, - ActionId.AUTHORIZATION_PERMISSION_CATALOGUE_READ, - ActionId.AUTHORIZATION_ADMIN_ROLE_DEFINITIONS_READ, - ActionId.ADMIN_ROLE_GRANT_LIST, - ActionId.ACTOR_ADMIN_ROLE_GRANT_HISTORY_READ, - ActionId.ADMIN_ROLE_GRANT_ISSUE, - ActionId.ADMIN_ROLE_GRANT_REVOKE, - ActionId.ADMIN_ROLE_GRANT_BOOTSTRAP, - ActionId.ACTOR_PROFILE_READ, - ActionId.ACTOR_IDENTITY_LINK_READ, - ActionId.ACTOR_SERVICE_PROVISION, - ActionId.ACTOR_PROFILE_SUSPEND, - ActionId.REVIEW_LIFECYCLE_ACTIVATION_MANAGE, - ActionId.ACTOR_PROFILE_REACTIVATE, - ActionId.ACTOR_PROFILE_DEACTIVATE, - ActionId.ACTOR_IDENTITY_LINK_REVOKE, - ActionId.ACTOR_IDENTITY_LINK_REACTIVATE, - ActionId.PROJECT_CONTRIBUTOR_CANDIDATE_LIST, - ActionId.PROJECT_ROLE_GRANT_LIST, - ActionId.PROJECT_ROLE_GRANT_READ, - ActionId.PROJECT_ROLE_GRANT_ISSUE, - ActionId.PROJECT_ROLE_GRANT_REVOKE, - ActionId.PROJECT_CREATE, - ActionId.PROJECT_GUIDE_CREATE, - ActionId.PROJECT_GUIDE_UPDATE, - ActionId.PROJECT_GUIDE_SOURCE_SNAPSHOT_CREATE, - ActionId.PROJECT_GUIDE_COMPILATION_REQUEST, - ActionId.PROJECT_GUIDE_COMPILATION_REQUEST_AUTOMATIC, - ActionId.PROJECT_GUIDE_COMPILATION_EXECUTE, - ActionId.PROJECT_SETUP_RUN_UPDATE, - ActionId.PROJECT_REVIEW_POLICY_UPDATE, - ActionId.PROJECT_REVISION_POLICY_UPDATE, - ActionId.PROJECT_GUIDE_SUFFICIENCY_REPORT_CREATE, - ActionId.PROJECT_GUIDE_SUFFICIENCY_RUN, - ActionId.PROJECT_GUIDE_SUFFICIENCY_WARNINGS_ACKNOWLEDGE, - ActionId.PROJECT_SUBMISSION_ARTIFACT_POLICY_CREATE, - ActionId.PROJECT_SUBMISSION_ARTIFACT_POLICY_DERIVE, - ActionId.PROJECT_SUBMISSION_ARTIFACT_POLICY_UPDATE, - ActionId.PROJECT_GUIDE_COMPILATION_REVIEW_PACKAGE_READ, - ActionId.PROJECT_GUIDE_COMPILATION_CORRECTION_REQUEST, - ActionId.PROJECT_SUBMISSION_ARTIFACT_POLICY_APPROVE, - ActionId.PROJECT_POST_SUBMIT_CHECKER_POLICY_DERIVE, - ActionId.PROJECT_POST_SUBMIT_CHECKER_POLICY_APPROVE, - ActionId.PROJECT_POST_SUBMIT_CHECKER_POLICY_CORRECTION_REQUEST, - ActionId.PROJECT_READ, - ActionId.ACTOR_AUTHORIZATION_CONTEXT_READ, - ActionId.PROJECT_SETUP_RUN_READ, - ActionId.PROJECT_GUIDE_SUFFICIENCY_REPORT_LIST, - ActionId.PROJECT_GUIDE_SUFFICIENCY_REPORT_READ, - ActionId.PROJECT_SUBMISSION_ARTIFACT_POLICY_LIST, - ActionId.PROJECT_SUBMISSION_ARTIFACT_POLICY_READ, - ActionId.PROJECT_EFFECTIVE_SUBMISSION_ARTIFACT_POLICY_READ, - ActionId.PROJECT_PRE_SUBMIT_CHECKER_POLICY_READ, - ActionId.PROJECT_ACTIVE_GUIDE_READ, - ActionId.ARTIFACT_GUIDE_SOURCE_INGEST, - ActionId.ARTIFACT_TASK_IMPORT_SOURCE_DECLARE, - ActionId.ARTIFACT_TASK_IMPORT_SOURCE_UPLOAD, - ActionId.ARTIFACT_TASK_IMPORT_SOURCE_READ, - ActionId.ARTIFACT_GUIDE_SOURCE_READ, - ActionId.ARTIFACT_VERIFICATION_EXECUTE, - ActionId.ARTIFACT_PENDING_WORK_SCAN, - ActionId.ARTIFACT_PUT_ATTEMPT_RESOLVE, - ActionId.ARTIFACT_PRE_SUBMIT_CHECKER_INPUT_MATERIALIZE, - ActionId.ARTIFACT_SUBMISSION_BUNDLE_PREPARE, - ActionId.SUBMISSION_CREATE, - ActionId.TASK_CLAIM, ActionId.TASK_START, - ActionId.TASK_WORK_CONTEXT_READ, - ActionId.PROJECT_TASK_WORK_CONTEXT_READ, - ActionId.TASK_READ, - ActionId.TASK_SUBMISSION_REQUIREMENTS_READ, - ActionId.PROJECT_TASK_READ, - ActionId.PROJECT_TASK_SUBMISSION_REQUIREMENTS_READ, - ActionId.PROJECT_TASK_LOCKED_CONTEXT_READ, - ActionId.OPERATIONS_TASK_LOCKED_CONTEXT_READ, - ActionId.AUDIT_TASK_LOCKED_CONTEXT_READ, - ActionId.AUDIT_TASK_EVIDENCE_READ, - ActionId.TASK_QUEUE_READ, - ActionId.PROJECT_TASK_QUEUE_READ, - ActionId.OPERATIONS_TASK_QUEUE_READ, - ActionId.PROJECT_TASK_CREATE, - ActionId.PROJECT_TASK_SCREEN, - ActionId.PROJECT_TASK_RELEASE, - ActionId.OPERATIONS_TASK_START_OVERRIDE, - ActionId.ARTIFACT_SUBMISSION_BINDING_CREATE, - ActionId.COMPENSATION_ADAPTER_BINDING_READ, - ActionId.COMPENSATION_ADAPTER_BINDING_CREATE, - ActionId.COMPENSATION_ADAPTER_BINDING_SUSPEND, - ActionId.COMPENSATION_ADAPTER_BINDING_RESUME, - ActionId.CONTRIBUTION_POLICY_READ, - ActionId.CONTRIBUTION_POLICY_CREATE_DRAFT, - ActionId.CONTRIBUTION_POLICY_UPDATE_DRAFT, - ActionId.CONTRIBUTION_POLICY_PUBLISH, - ActionId.CONTRIBUTION_POLICY_RETIRE, - } + } == EXPECTED_ACTIVE_ACTIONS diff --git a/backend/tests/test_projects.py b/backend/tests/test_projects.py index 0be4facc0..9f03053b8 100644 --- a/backend/tests/test_projects.py +++ b/backend/tests/test_projects.py @@ -33,7 +33,6 @@ from app.core.config import get_settings from app.core.hashing import canonical_json_hash from app.core.identifiers import new_record_id -from app.modules.checkers.api.default_checker import WORKSTREAM_DEFAULT_BEHAVIOR_SHA256 from app.modules.checkers.api.external_policy import validate_stored_external_pre_policy from app.db import session as db_session from app.db.base import Base @@ -4003,18 +4002,13 @@ async def test_submission_artifact_policy_approval_persists_effective_policy_has ref.startswith("guide-document:") and "#sha256:" in ref for ref in persisted_policy.source_material_refs ) - assert pre_submit_checker_policy is not None assert pre_submit_checker_policy.lifecycle_status == "compiled" assert pre_submit_checker_policy.effective_policy_hash == effective["effective_policy_hash"] assert pre_submit_checker_policy.compiler_version == "external_checker_policy.v1" - assert pre_submit_checker_policy.compiled_bundle_hash is not None locked_pre_policy = validate_stored_external_pre_policy( pre_submit_checker_policy.compiled_bundle ) assert locked_pre_policy.policy_sha256 == pre_submit_checker_policy.compiled_bundle_hash - assert locked_pre_policy.workstream_default.behavior_sha256 == ( - WORKSTREAM_DEFAULT_BEHAVIOR_SHA256 - ) assert locked_pre_policy.entries == () From c78964585d5b331dc2c92ee5bdb4b0d55938bd25 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 18:56:49 +0100 Subject: [PATCH 271/283] Expose bounded missing checker capabilities on activation refusal --- .../pilot04-workstream-default-checker.md | 16 ++++ backend/app/api/deps/guide_proposal_http.py | 9 +++ backend/app/core/api_controls.py | 2 + backend/app/main.py | 1 + .../modules/projects/api/guide_proposals.py | 20 +++++ .../projects/guide_activation/service.py | 14 +++- .../guide_activation/test_contracts.py | 79 +++++++++++++++++++ .../guide_activation/test_postgresql.py | 8 +- docs/architecture_checker_framework.md | 7 ++ docs/roadmap_status.md | 5 +- 10 files changed, 157 insertions(+), 4 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 5828ed453..c0e8cf5f2 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -9,6 +9,22 @@ ## Intent +Required activation feedback repair permits PROJECTS +`api/guide_proposals.py`, `guide_activation/service.py`, the shared +`api/deps/guide_proposal_http.py`, canonical error primitives in +`core/api_controls.py` and `main.py`, current activation contract/PostgreSQL +tests, `tests/test_api_controls.py`, the checker architecture/roadmap and this +record. Expose only bounded requirement ID, stage and title from the exact +approved compilation when missing capabilities block activation. Populate the +existing canonical `error.details`, after current PM authority and custody +checks; preserve concealed failures and refusal before activation writes. +No new route, approval/activation behavior, legacy error decoder, provider +coordinates, rationale/evidence exposure, DDL, skips or cap changes. Risk L1: +pure envelope/bounds/concealment regressions and the real PostgreSQL +gap-to-corrected-binding journey, including refusal rollback, precede full CI +and independent authority review. Human review focuses on exact approved +generation and absence of cross-project disclosure. + Final predecessor cleanup permits `backend/app/modules/artifacts/submission_admission.py`, `backend/tests/artifacts/test_selected_predecessor_rules.py`, its explicit module registration in `backend/scripts/test_lane_catalogue.py`, and this record. diff --git a/backend/app/api/deps/guide_proposal_http.py b/backend/app/api/deps/guide_proposal_http.py index 0b5eaa91d..95b1ba5d0 100644 --- a/backend/app/api/deps/guide_proposal_http.py +++ b/backend/app/api/deps/guide_proposal_http.py @@ -28,8 +28,17 @@ def proposal_http_error(exc: GuideProposalError) -> StructuredHTTPException: code, status, message = exc.code, 503, "Guide proposal storage unavailable" else: code, status, message = exc.code, 409, "Guide proposal conflicts with current state" + details = None + if exc.code == "approval_blocked" and exc.missing_capabilities: + message = "Guide requires unavailable checker capabilities" + details = { + "missing_capabilities": [ + item.model_dump(mode="json") for item in exc.missing_capabilities + ] + } return StructuredHTTPException( status_code=status, detail=code, error_code=code, error_message=message, + error_details=details, retryable=status == 503, ) diff --git a/backend/app/core/api_controls.py b/backend/app/core/api_controls.py index d68c63673..06152c5f4 100644 --- a/backend/app/core/api_controls.py +++ b/backend/app/core/api_controls.py @@ -56,12 +56,14 @@ def __init__( detail: Any, error_code: str, error_message: str, + error_details: dict[str, Any] | None = None, retryable: bool = False, headers: Mapping[str, str] | None = None, ) -> None: super().__init__(status_code=status_code, detail=detail, headers=headers) self.error_code = error_code self.error_message = error_message + self.error_details = error_details self.retryable = retryable diff --git a/backend/app/main.py b/backend/app/main.py index afccb57e5..a5c509dac 100644 --- a/backend/app/main.py +++ b/backend/app/main.py @@ -242,6 +242,7 @@ async def http_exception_handler(request: Request, exc: StarletteHTTPException) code=code, message=message, retryable=retryable, + details=exc.error_details if isinstance(exc, StructuredHTTPException) else None, compatibility={"detail": exc.detail}, headers=exc.headers, ) diff --git a/backend/app/modules/projects/api/guide_proposals.py b/backend/app/modules/projects/api/guide_proposals.py index 8b9c5d115..d5266ec0b 100644 --- a/backend/app/modules/projects/api/guide_proposals.py +++ b/backend/app/modules/projects/api/guide_proposals.py @@ -183,6 +183,15 @@ def require_record_ids(self): return self +class MissingCheckerCapability(BaseModel): + """Bounded manager feedback from the approved compilation's missing checks.""" + + model_config = ConfigDict(extra="forbid", frozen=True, revalidate_instances="always") + requirement_id: str = Field(pattern=r"^[a-z][a-z0-9_.-]{0,99}$", strict=True) + stage: Literal["pre_submit", "post_submit"] + title: str = Field(min_length=1, max_length=1000, strict=True) + + class GuideProposalError(RuntimeError): """Bounded failure; the caller must roll back its root transaction.""" @@ -196,7 +205,18 @@ def __init__( "operation_conflict", "storage_unavailable", ], + *, + missing_capabilities: tuple[MissingCheckerCapability, ...] = (), ) -> None: + if ( + type(missing_capabilities) is not tuple + or len(missing_capabilities) > 200 + or (missing_capabilities and code != "approval_blocked") + ): + raise ValueError("invalid missing capability refusal") + self.missing_capabilities = tuple( + MissingCheckerCapability.model_validate(item) for item in missing_capabilities + ) self.code = code super().__init__(code) diff --git a/backend/app/modules/projects/guide_activation/service.py b/backend/app/modules/projects/guide_activation/service.py index 5a0a3548d..a4b56f1d5 100644 --- a/backend/app/modules/projects/guide_activation/service.py +++ b/backend/app/modules/projects/guide_activation/service.py @@ -18,7 +18,7 @@ GuideContributionPolicyFacts, PreparedGuideActivation, ) -from app.modules.projects.api.guide_proposals import GuideProposalError +from app.modules.projects.api.guide_proposals import GuideProposalError, MissingCheckerCapability from app.modules.projects.api.post_policy import PostPolicySelection from app.modules.projects.guide_compilation.proposal_service import GuideProposalService from app.modules.projects.guide_mutation_repository import GuideMutationRepository @@ -242,7 +242,17 @@ async def _readiness(self, command, locked, policy, post, review, revision): if current != binding.registry: raise GuideProposalError("approval_blocked") if locked.result.capability_suggestions: - raise GuideProposalError("approval_blocked") + raise GuideProposalError( + "approval_blocked", + missing_capabilities=tuple( + MissingCheckerCapability( + requirement_id=item.requirement_id, + stage=item.stage, + title=item.title, + ) + for item in locked.result.capability_suggestions + ), + ) ProjectService(self.session).validate_activation_ready( locked.view.guide, locked.view.snapshot, diff --git a/backend/tests/projects/guide_activation/test_contracts.py b/backend/tests/projects/guide_activation/test_contracts.py index 4c51467a7..17bf4daf5 100644 --- a/backend/tests/projects/guide_activation/test_contracts.py +++ b/backend/tests/projects/guide_activation/test_contracts.py @@ -20,11 +20,90 @@ from app.modules.projects.api.guide_proposals import ( GuideProposalTarget, GuideProposalApprovalReceipt, + GuideProposalError, + MissingCheckerCapability, ) from app.modules.projects.api.post_policy import PostPolicyTarget from tests.projects.guide_compilation.proposals.contract_support import HASH, target_values +@pytest.mark.parametrize("field,value", [ + ("requirement_id", "../private"), + ("stage", "review"), + ("title", ""), + ("title", "x" * 1001), + ("provider_coordinates", "private"), +]) +def test_missing_capability_feedback_is_closed_and_bounded(field, value): + values = dict(requirement_id="required.tests", stage="pre_submit", title="Required tests") + values[field] = value + with pytest.raises(ValidationError): + MissingCheckerCapability(**values) + + +def test_missing_capabilities_cannot_be_attached_to_concealed_errors_or_exceed_bound(): + item = MissingCheckerCapability( + requirement_id="required.tests", stage="pre_submit", title="Required tests" + ) + for code, capabilities in ( + ("proposal_unavailable", (item,)), + ("authority_unavailable", (item,)), + ("approval_blocked", (item,) * 201), + ): + with pytest.raises(ValueError, match="invalid missing capability refusal"): + GuideProposalError(code, missing_capabilities=capabilities) + + +@pytest.mark.asyncio +@pytest.mark.parametrize("failure", ( + "approval_blocked", "authority_unavailable", "proposal_unavailable", "foreign_project", +)) +async def test_public_activation_refusal_projects_only_authorized_missing_capabilities(failure): + from httpx import ASGITransport, AsyncClient + from app.api.deps.authorization import enforce_human_authorization_read + from app.api.deps.guide_activation import ActivationRequest, get_activation_request + from app.main import create_app + from app.modules.authorization.api import ActorIdentityFacts, ActorKind + + items = tuple(MissingCheckerCapability( + requirement_id=f"required.{stage}", stage=stage, title=f"Required {stage} checker", + ) for stage in ("pre_submit", "post_submit")) + error = GuideProposalError( + "proposal_unavailable" if failure == "foreign_project" else failure, + missing_capabilities=items if failure == "approval_blocked" else (), + ) + session = SimpleNamespace(commit=AsyncMock()) + service = SimpleNamespace(activate=AsyncMock(side_effect=error)) + actor = ActorIdentityFacts( + actor_profile_id=uuid4(), identity_link_id=uuid4(), actor_kind=ActorKind.HUMAN, + ) + async def dependency(): + return ActivationRequest(session, service, actor, uuid4()) + + app = create_app() + app.dependency_overrides[enforce_human_authorization_read] = lambda: None + app.dependency_overrides[get_activation_request] = dependency + command = GuideActivationCommand(**command_values()) + target = command.target.proposal + project_id = uuid4() if failure == "foreign_project" else target.project_id + path = f"/api/v1/projects/{project_id}/guides/{target.guide_id}/activate" + async with AsyncClient(transport=ASGITransport(app=app), base_url="http://test") as client: + response = await client.post( + path, json=command.model_dump(mode="json", exclude={"idempotency_key"}), + headers={"Idempotency-Key": str(command.idempotency_key)}, + ) + expected_details = { + "missing_capabilities": [item.model_dump(mode="json") for item in items] + } if failure == "approval_blocked" else {} + assert response.status_code == (409 if failure == "approval_blocked" else 404) + assert response.json()["error"]["details"] == expected_details + session.commit.assert_not_awaited() + if failure == "foreign_project": + service.activate.assert_not_awaited() + else: + service.activate.assert_awaited_once() + + def command_values(): proposal = GuideProposalTarget(**target_values()) upstream = GuideProposalApprovalReceipt( diff --git a/backend/tests/projects/guide_activation/test_postgresql.py b/backend/tests/projects/guide_activation/test_postgresql.py index 6b5fe4e7e..f0df5133c 100644 --- a/backend/tests/projects/guide_activation/test_postgresql.py +++ b/backend/tests/projects/guide_activation/test_postgresql.py @@ -234,10 +234,16 @@ async def test_checker_registration_requires_corrected_approval_before_activatio await seed_selected_review_revision_inputs(factory, initial, actor) stale = await _activation_inputs(factory, initial, first, actor, grant, values, policy) async with factory() as session, session.begin(): - with pytest.raises(GuideProposalError, match="approval_blocked"): + with pytest.raises(GuideProposalError, match="approval_blocked") as refusal: await activation_service(session, actor, stale, grant).activate( stale, actor=actor, request_id=uuid4() ) + assert [item.model_dump(mode="json") for item in refusal.value.missing_capabilities] == [ + dict(requirement_id=item.requirement_id, stage=item.stage, title=item.title) + for item in gap.capability_suggestions + ] + guide = await session.get(ProjectGuide, str(stale.target.proposal.guide_id)) + assert guide.status == "draft" and guide.activation_operation_id is None correction = await correct( factory, diff --git a/docs/architecture_checker_framework.md b/docs/architecture_checker_framework.md index f87040d38..1eea4e904 100644 --- a/docs/architecture_checker_framework.md +++ b/docs/architecture_checker_framework.md @@ -204,6 +204,13 @@ External image execution never occurs inside that database transaction. A valid locked policy with no project pre-submit bindings is distinct from an unavailable required image and may proceed after the default checker passes. +Guide activation refuses an approved compilation with unresolved required +checker capabilities. After current manager authority and policy custody checks, +the canonical HTTP `error.details.missing_capabilities` lists only each +requirement ID, pre-submit or post-submit stage, and title. It contains no +rationale, evidence paths or provider coordinates. Registration alone cannot +clear a gap: a corrected compilation and approved binding are required. + The target launcher and checker integration use the agreed Rust service and SDK. Registered OCI images are not thereby required to be written in Rust; their execution identity is the approved digest, schemas and resource limits. diff --git a/docs/roadmap_status.md b/docs/roadmap_status.md index b16fef083..4482fa034 100644 --- a/docs/roadmap_status.md +++ b/docs/roadmap_status.md @@ -1041,7 +1041,10 @@ with a typed Unix-socket adapter and request-bound ART grant, and one versioned Workstream default checker with exactly four blocking outcomes. Both executable catalogues are removed. Verified ZIP/default checks precede approved external PRE images; only a complete pass permits immutable Submission creation and durable -POST dispatch. Production completion routes true-policy success to review_pending +POST dispatch. Unresolved required capabilities block guide activation with bounded, +manager-authorized requirement IDs, stages and titles; registration alone does +not clear an approved compilation's gap. Corrected compilation and approval +must bind the registered image. Production completion routes true-policy success to review_pending and false-policy success through shared atomic acceptance. Default failures prevent Submission creation; infrastructure failures retain recoverable outcomes. Local Rust/MinIO integration evidence uses runc/docker-dev, not gVisor, and the contributor From 0c91bb0e22650b94e318bb5ad4a7b56f91a36b59 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 18:56:31 +0100 Subject: [PATCH 272/283] docs: retain protected structure shrink verification --- .../changes/pilot04-workstream-default-checker.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index c0e8cf5f2..2f7572c30 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -1432,3 +1432,17 @@ debt, ledger exceptions, suppressed guards or any unrelated test/assertion edit. Acceptance requires exact canonical observed-ledger parity, protected-base shrink-only transition and retained new-debt/growth refusal controls. No native lifecycle proof or full hosted-suite claim is added by this metadata repair. + +At clean `25742a230207880315db3dd66daa1ec501db267c`, eight focused pure tests +passed in 414.37 seconds (447.322 seconds including process lifetime), exit zero +and identical clean start/end heads. They exercise actual active inventory, +complete structural-ledger parity, protected-main transition/assertion maps, and +retained new/grown/unshrunk debt, stale-hash and policy-limit refusals. A separate +actual-source discriminator proves the exact 117 action literals are unchanged: +removing either PRE action or activating an extra planned action fails equality. +It also confirms only the three approved duplicate assertion nodes were removed; +all other PROJECT test-body AST is identical. The retained postconditions reject +missing compiled rows, null stored hashes and substituted default behavior even +with a recomputed valid outer policy digest. Independent QA reviewed that frozen +source and ledger with no required finding. This is pure structural/test evidence; +PROJECT native custody and the complete hosted suite remain separate obligations. From e334f6a8bcb8192ff48c6464cbe9d7adb40c2cd9 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 18:59:41 +0100 Subject: [PATCH 273/283] Prove missing capability refusal preserves all activation effects --- .../projects/guide_activation/test_postgresql.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/backend/tests/projects/guide_activation/test_postgresql.py b/backend/tests/projects/guide_activation/test_postgresql.py index f0df5133c..f6a88fdcb 100644 --- a/backend/tests/projects/guide_activation/test_postgresql.py +++ b/backend/tests/projects/guide_activation/test_postgresql.py @@ -11,6 +11,19 @@ from .pg_support import activation_case, activation_service +async def _activation_effects(session): + """Capture lifecycle, activation replay, release and dispatch facts exactly.""" + return { + table: tuple(await session.scalars(text( + f"SELECT to_jsonb(r)::text FROM public.{table} r ORDER BY to_jsonb(r)::text" + ))) + for table in ( + "projects", "project_guides", "guide_mutation_idempotency_records", + "workstream_tasks", "submissions", "outbox_events", + ) + } + + def _capability_outcome(*, supported): """Return the same requirement before and after exact capability coverage.""" from app.interfaces.project_agents import ( @@ -234,6 +247,7 @@ async def test_checker_registration_requires_corrected_approval_before_activatio await seed_selected_review_revision_inputs(factory, initial, actor) stale = await _activation_inputs(factory, initial, first, actor, grant, values, policy) async with factory() as session, session.begin(): + before = await _activation_effects(session) with pytest.raises(GuideProposalError, match="approval_blocked") as refusal: await activation_service(session, actor, stale, grant).activate( stale, actor=actor, request_id=uuid4() @@ -244,6 +258,7 @@ async def test_checker_registration_requires_corrected_approval_before_activatio ] guide = await session.get(ProjectGuide, str(stale.target.proposal.guide_id)) assert guide.status == "draft" and guide.activation_operation_id is None + assert await _activation_effects(session) == before correction = await correct( factory, From cedf84e8459377cd5f0c3b83a76b896e221431a3 Mon Sep 17 00:00:00 2001 From: Commitrail Probe Date: Mon, 12 Oct 2026 19:02:57 +0100 Subject: [PATCH 274/283] test: replace review policy predecessor compatibility fixture --- .../pilot04-workstream-default-checker.md | 34 +++- .../fixtures/pilot04_predecessor_rows.json.gz | Bin 862803 -> 886493 bytes .../tests/historical_submission_fixtures.py | 2 +- backend/tests/migration_fixtures.py | 86 --------- .../guide_activation/source_fixtures.py | 22 ++- .../projects/review_policy/test_migration.py | 163 ++++-------------- 6 files changed, 80 insertions(+), 227 deletions(-) diff --git a/.commitrail/changes/pilot04-workstream-default-checker.md b/.commitrail/changes/pilot04-workstream-default-checker.md index 2f7572c30..e67c933cf 100644 --- a/.commitrail/changes/pilot04-workstream-default-checker.md +++ b/.commitrail/changes/pilot04-workstream-default-checker.md @@ -1221,8 +1221,9 @@ in the named `0034_checker_retry_source` snapshot; provenance therefore describe these snapshots as composite captures rather than claiming every row came from one fresh database. No retry run, audit, grant, receipt or project-bound row is copied. A decoded old/new comparison proves exactly 30 supplemental rows and -identical seeds, revisions, tables and values everywhere else. The archive is -checksum-bound at `25560b75796f84cff46bb506abdcd4b9cc2b7535411096fdbbec921d245d95e9`. +identical seeds, revisions, tables and values everywhere else. Those rows remain +unchanged in the additive archive, now checksum-bound at +`e24ab79e764452f92d41bf93ecb00c6a9e08fae427145c51a3e55160108ed054`. This supplies a retained predecessor identity prerequisite; canonical migration and receipt proof remains required. @@ -1255,7 +1256,34 @@ passed in 227.07 seconds with complete cleanup, then independent review required stronger non-vacuity assertions for the two policy branches. The final test therefore requires exactly `[true, false]`, two requests, one Final Acceptance, one ContributionRecord and exact automatic-manifest-to-acceptance-to-contribution -lineage. A clean successor replay and final independent review remain required. +lineage. At clean `48bc8d741a0796292aaed6d19d99f1ca1f59c859`, that final +control passed in 228.89 seconds with database, role and object-store cleanup +complete. Independent review verified the exact archive provenance, both branch +counts and links, unchanged retained rows and installed 0032 validity predicate. + +### Literal second-review predecessor fixtures + +The two 0023-to-0024 ReviewPolicy controls must preserve the retained-true +refusal and valid-false upgrade without running the removed policy/checker +owners against a predecessor schema. At exact source commit +`3e2d59ba426a950e64b8e1632f4587c3265b0ea7`, the unchanged original nodes +passed together in 394.45 seconds with complete database, role and object-store +cleanup. A one-time follow-up capture then emitted separate exact 0023 databases +after the genuine true and false policy writes and after every temporary +current-only seed column was removed. Each snapshot contains 240 rows across 33 +nonempty public tables and exactly one ReviewPolicy with the named boolean. + +Allowed scope is limited to the checksum-bound predecessor archive and loader, +`tests/projects/review_policy/test_migration.py`, +`tests/projects/guide_activation/source_fixtures.py`, +`tests/migration_fixtures.py`, and this record. The committed migration tests +restore literal true/false snapshots and retain the original exact refusal, +unchanged policy/selector/hash checks, current-head upgrade and installed CHECK +constraint assertion. Current guide compilation now calls its current writer +directly. The unused predecessor-shape wrapper and its cause-column add/restore +helpers are deleted after repository search found no callers. No old policy +model construction, private mutation service, temporary column, compatibility +alias, guard bypass or archived writer remains in the committed tests. ### Frozen cutover verification before publication diff --git a/backend/tests/fixtures/pilot04_predecessor_rows.json.gz b/backend/tests/fixtures/pilot04_predecessor_rows.json.gz index 71374c80e33375afae54385e831864cb9f8c3e45..997369793fdde8c659151c2cd693b533cbbad770 100644 GIT binary patch delta 860705 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 }>(B36Ze7Zw82r*# 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%0ABhqB^4e>^&GQqc{GQLPT>4XdyrgyH-ENFK!)+ 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≦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

  • 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 ?S`t6_7LM2xH_(iL=RdInht6hMyr4+6O-D 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

    >zv5et&h-bSR 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≈o z=^>_45xlk?6WWqLZR?hK*6JT|$@0W1J(*lVCL&~3c;q~nq`e8U$m%SNeM?=MEw`Qp zL6;^QeT;uja$|sZ1Sg?5=&rarR0BE>+&3O9*90aQ1g!M2t%Xnii_?oW-qMj=Hd!{& zXVG9}+CvDlQ0m~GZ7o2FxivW+U9egw+)UNeLo`A0gm2JQF(U&06|CR|xyn+6mLWpO zYeBDANSSV6H;Sd%=$=KC*V;S-7}l(!1A2BUXhwg17|4fQne_!zt0Ff(xZp7^d;sj< zA}vh0z*6=_jNUSkr?+XxuqMi%Kzcr;I)6EtzMe*Ek=FICew1qcyM_3!77yUSK$TVi zudK7MhYVvnD`|6BitiOE@ECG@{-%}k`KvG5Lzj^Gi@Hf&eZJt*xhgV5u&J0tNF^^T zgFt`I08^||{I~TrgXn9fsBf~57zBco5bzszH~ZGR<8}rXV*zbx<2^7N1GAPA1jL?# zfT1v&l%n^=`rv(n_?I4Y=?vHkHmhixArD(9&nsjsL+V5fF3KpB$NiXP<|P)FWu3GR z6jNs*D})Zp84iPwak3ka>0Uo7FS&ainmy{ z{9PFa)o*C5mYTYr*hX_KijzbE;@&NMTf8vWW5O(c*(zqG)=ps{wyGStaxwcHlYxIu zgFNC`2JMKEB(w|&N=g=?M0E;4`^IKh2Tj$NFKLG?p-Q0gR6}X=jRuu8QSb;21t$;R=?G+zL>_QhVRm zGPw)VT5oZ`}*`yf?&qK(SATV&8lGcaIKb2PpMSpw!!e7mBLWo|LXU?Oh-9^O6uc z*m67s3YR6FU*-k&TI+Dw-O{$e-mX7wO#<-3u*Na`C4kr^G?Ry#>pE6~54OW4<|klF z$nLe)lUuHL6RU(2d~y8>1;BrZfS63WiIzw``3wP&3dn9FN)igFPSwyb=T)PO&yB;H zHlA}1!4-jE>HMYw9HPFH~b;Ug<{36t6;Nkj8?{5Y!pz@=zl;OYia zD}%?f)FR*8EZYpUtPU(lk)i;GB;;uT&r*SiW4O~vk->?<$RctQz+8XDrXZ{0lv|oy z$r$urg~s$CKK$jghD{In2t`P_js|}!KvP-CTA|>BNVP(V zN5LRvmlAvm8d{h9kU~<(#wUf5CdCww3~!7bnOec-`a-ey@fdM@YU1C>S+pSYR${FD;9By z{b|nH|17T<21WH3>HeZ++wwoQP0|0bsW<(&q5U5=v~7QHyN`D*Tz`H$Z*qNpMvOxu zliv8BqgA_OEKG~=H5!09or58BQd{Uu3DlGTA+yYiKp&)SDZqfXWQj|%6)sXBT@qX6 z-m1@;sanBk(lP@qq@;rR&8n!1WnC>GoKC=RI)d|L&cRo$U>PczveL;CsSU||{P5~w zKo(=F^3s1Q4rK`)h~dM~EKgUW@y&P<5V zz#>Kvxe=xo$zZdJfS2&3JuB4*fd8swwlD;-_`(sM-n7quU%S1pCA>0B2Of|SWb3)~ zzCeG2fMXRTc(j&*8X?eOerqh51+qyQWMEIXL5nJmUj$g^LRMm3us>9pd+En8WB?D8Z-ba zuV<(oo~Z@Dt+}RF?pzp^D^qTx(n?{rAxnR9teh1`_`47li=Y(P(ppS&rraMu0||J} zv;j>A=Yw8<(Ylh_JjUaJOq%Pld0FZ4^VVEmBnIx|s~g|9Wj^-ctsB4Rwm}(-J35^` ze#nM7xVssHdq^i;9IAu)H6j$CYUzECtO3ZU0#Lh**1Sp z5EJMS;TMcR*^rmNZs#11>xFW1cmr*GttdhzF&+TBWR1!Wibn@4Ovy?VZ%V8X_gJR{ z^+@4=m2)VqTsUZ0Q0Ngo_Zp_pY3ZQI>+9a0{LfHBc5|{7Tah}QUZ!hm<$ivClF$Ej zMyZPDXXFWJQ;+9odx?4V246$P8{2;liRq+-GbjNX#yJe9#jS0L9=vAmNm$%Q(1PhITA%||H(7b!2A6BC5Ildp03--! ztpw<>6dh$#421{jlyl7KsD$89&oCcrhD-+)L=!E!rhBxvuvq3u&sbRLkap`=%;pjL z{qJwiTOodhA)mdqcFagSi;Wtk&bvHb1o9L&8oBrT1j+ONY4uP!0xA2kPzQhr z@OxhC@hP})dT}!C8|Jnr+c-xWeK`pOD&zh6|07SvWgpJc{f5t3y zKIEWPVhg;s;(6+R#0XZAk7c^CMw-UQAR7tX1LHJ7du;Naj>ozW-|0hKyF+Jbk5d-t zWw4dEH)mNM}q}QQ8`!&rf!X%+YROB;kI4B3J_mv zo4~*_Ti+RUtrOVcN%dol|gSU)1g6be!&Vtd4D4opfy5 zKCyLzj&0jKv7L@>+qQM{|Gv6)>%Qz-HETcYhh2N^HOCy|r@e38U|$^@<YH5Vz);6ld$3-aQaE$*-?(*zUv`Fu#Y)O^0VIEc zDTZhwN}Ga>mhy_WmphLOM{LmiQJSZCP^LEj;qm)(0%7WKM;@O!s@twog3K^ZSkI2O zq!r3Zx(-9{t*S+hN0t5#P)l@KexoG;iPn#_UYwuNA&PU#>;e9kk}Sez2|Z@zr>%j| z`oWg4K=Tv|{apaU`~O{{^ac6^;1f|qv9@X>?1v)D3Jkg zs5d<_tL=5r>bUN*Z6%2={;(V$+(?5w0N7y~vLPjkjbFg8sMk@v1D7A+=9{VnHs4}2 z&{}UNn)Z(ZFX+x(4lY-;+?Z|O8DcBTlkg`0lNgU`>CTc zJVHgDY6{6zz0|bQH};>uDt^I@L1`BjHo+|N%M`rYc(=<(f1Oal1lTznEO{=3Tx}eQ zz92p5yrW3J+-<^$#4!S5qqa_-@6ox$78ZIu3W-1BArh3SpP0=<)KkUh@O&ljf1jN8 z7&Kb~OEdG{U~HhQwH+eL_Tv{}0#a#kR;XwsO_&0~L4QaN)1UkFZ)zAboT|E2;~9h( zUd3;y{_c=>t-Xysk#J<-Y+Tbncr%RlKku)TTLB=qWUF@ntiGRTdD>ER>ulY^LUJEG z>MA(BQ5TCLjg|?+wi!B#_d`%E{QN~y8w(x|G?a9PI~z&ei#s!6bm_iQEa*U3#_(AF zE7-`RN&f5p7_`ro7mMS>r0{A!v{CSzS1rzIIt@a#64757ejt&oU6B)b1<-^l>-Y`qR6}ZxE!L6!@$*oh9pfl zeC=!ZaRjXN@l&R#^zR|I2$T{3VxXcR0u8cmR9RyK$shTQTYG6O4+^EA=T;%|0Op2l z(GDcl&G%C5g3+snpvW!b=x^3Y+iN(%9ae~Q(_7%%c&HP)s1s>wrZsfp&pLG)sjmiA zRl**#?>@p7vFV&?w~aHJUwm74NbBw9+-|Pz%TP-UBX_ik8wss9L`Qr!<-~AqAUm_# zNO$20RBGAniS_StMS}XuwigxT7s7l?eS`9#ZJ6)o`3(&vO{Sw4gO+@&`=CQry7<$q zaZ|_eR9g``Ve%2)c_?&1ex6K^kr#b)he9}5bD^@ErG$F|iBP!lnP6DQAo5RTe3F z1xf$85P$+iBgjTxnwb(KS1iwZ*nEC(qK?uTPmn*02oxe>9jRZ9KrN2@VnPYgo|*uJ zNTF#GA||1+u-ao1T~(DQGN6C5=k!*v(pO6-NJFC)Aa?4r8<zQn+aOo zsHK^a{L#0Xn7x4Twf~JP4kA?Mvo1g*hu1jQt-27_xT%n+;OwKj==u#0{9vgN9)cah z!(>nB*SS-M(Az2h;Oj^cG+dkef}JWWS`XGo7Z1;Byq*u%w8M4vG9M8G=|!51BrSd} znr$zFE#yds2IRGlHbkI{u4pWB-+E9soehEoP)6ChY@Ie| zvBgiu&%QJkU<<;rt={S%ldx<3$A2h`W_R7}OJ|Q{QXzvTp^gOMo?YMnS6g}PAZ7q0=l@CILZSe{@LeOn z-O@f4>xC{~^8#-Sq*;kC{+Q%PLT;ilG@Jv&qeg8@6L^2?omeQ37s*K{0xa{Ve4EB8C({}i+qsN!v&QAOI z(QLL|eOh)H3+c}E;ms@~K(@;SV0?yU*c8~cR!=eO<{+FLd>%H0+i(;+eou%O?N|VM z*Nv_05{PbEe@5|DPvn4I&~JQ?9^+}!DmN?i?o2~@7TM0D-wx*Ae?o-9kS+S`WPn^Z zZ6HieZ1frHT(Y?GKi0T}+}M(GQ#M_BNQCA0@ZfKy?P}zSjBk|f!OodVw|jW$!K-%< zB@A?L1($=_-N3BV&ZZ-5?Gd@c;;sDxs$`+Ndd(o8veRpMeS)%gN0vWCJ?>6+vN zgV>PKAhG!I6;89@%f>Za_sTRo;k-d8(%=?q$jRZXx&eDRrj=JgR7ccSG5Z08Y%wvb zJ37p_?>rZ~7rGkA@g0p5s+wRZI<`S{U}-y#<~oq$Cy4Nt(`KSIoBddLz}naXcOzXe zr^@a3&;cD>V|F%4-)OtCo9$b(pZD&Y{{jB5$`YyA!Vqw_)ADXFp=N*VW->OoYrBHB z8A0gLPWe#3yaOaX&`3%FdL-3=zgFLfz$6HCdAUR|U(yMHpBD%R=3JX78?>AUI};{2 zL+%2$b-iaI2mHiJWg2cCyYywt>5WBv5%9Mb=TPEX}sk`YiBRf!>ZH!W+Qtl z5mdE;al1wlx7KZbyOGd0^nB5o3AZ*mbD?2u&?YUz!cs_n^*_4KkT(1r|11+jqLPY& zJx;tRT#Fr*s4S4$IJPnmFHU9Ry*9JZUH6@0-Mq8SW)Y|Z`2o=UxPQ`Z&legV>15lL z-tbq;XO|=`SHhUTJ!|+rZE>JoHcfSIqSC7YcV3c-B&w#95g(-quk_%t)Ki{sm=^B< zgA|v=kv%cktO$F@DQO7lDA7(AbAZ!v5>VRl6zy8IBQhota@5B0Bu9~tW3}F33qb^$XP}pS$?3Cwo+#NVw@BiUo zE(z542WAzt%csgLD4L&&j>W=SARQ3(=OjQ4OwIGan3SrUfWOoQ#jWN+Yhfk)dMen@ z+sx)j00b}1`?>vARfbiyR20@TIuA>V-^QI7p0QMxiY#b@=0#zS~7QswV8yLXQ9R!@J3D)qOd%Vu=g#j z5vRjC20PR#QD&eL6oJpQmo6NoRW=K`A-moe#-V?z{oL<*={JAT!x?y@OJNf=SLmyJ z07keUSW6D5S(Q~pIO1#2kA!vy7KBNm|LTH~1|(*2H*6)HkFB5>JA~Ec_$B+f&^AqRMLw|AeA zWai*v?;*ix=y3hoU;kcC<1_E%%7DVJiHDCOhyPeiU-VA5u6IiqjVbV;Mt(BBU;`f= zZ3+<0-Q`6H7vMknptiU+dNuoW#L#pU;7-YIJp*-}Rq^u_!$2QCx6V@O*XaRkzTJYO zMDc495Jby91Ppp;CzbE()tOv3n$lY?0-w$0w*lvQyFH?SzUhz6Xd5E)4(hZ}2zb|i z3`@zF0wwmNZaT9u2wb6Pi6mO*1vHhiz3}U~+&a$kGZ&$@n8bCly}G2j+wpB3TMb~zU_L3B`cE*W-C23%!-yd7-Nr^&;Q!b`0M>q&HNpslm83lIW3lTHWGw6F} zPf`$n!rA5f^plL%2q=+W_B_}xrP>n=&-noqcw))zEd!ov8{#zF3?ouT)}HG#QQA_r zIt-g1ZXHPTk-a_UyOFWesb~7?Vz6vx@Q#wuDn>H|7-(#V)2(9Yc?v*LkC0GJ&Wl^B z3smG&CPD^?kabj}1_q+-jlvi=F$Fa~BH{1Q1G&k+r~6-iIJ3_yTfXTJ;S(rt_k5F$ z6#6SWw?%C{?qAEBwDXK$&$%(zb}sf6VZI>VaO;3PQwVP`qVC*YO`14A7Q9umKzLSS zTp=-LY!FYw6!ed_t!EH8jchTKWaqXpwt}9j9`VG4Jx|ykQ<+DJjlm;*nO2{-a-s-3 z;GnPT=bXu&B+*wgVjTwYpalO*=9~$ZC?RDHVRsTg6U}y`XBGl2R%c2yrGz=Y28%*? zhS<(FkA^^;mntSWOdF1J)mYtxcjc%dZdJpHvkbGZuun+9reqZ8r_`p8DZ4*i39XRW zO~WRmA10Y@b`dXM%V?uK9@{t<=%^6}r86p;q`$kc;mP$1eOpw?7pdTDcr+kQ_eHmB z%SZ~Gd^(E$we3KHq9%lX;9h8hRLUlkBGceDUN8n>sYW%*8#pdL%mTtDM^^H;8g@em zL>^@Fe)Y89^W=fowHjwe4p&5)m4UrsEQxq$%mD8NU3)WHMvx5Gs&+~RnXm=eeNtRv zz_w~&0$fn4vPL8M`Q%0RAnXNy)wWeBYA zUr*3$@tEnUF#PrdyF02R9^1+&L}PhOIbw|)ts;bWuK@UnUJS#`lbV&-DEA6npa}xi zyF@X2CdH3)-z0P^H+m#zG%70Jg#9_Dvq8z1K|x*<2i&6yN%Pi|KWBMhAt9u> z281lmjp{d$!S%ynq}PRMs#*%Cw)^Absnlrv}~2iAk3#Ts6vS(j+XKiDC2I{ zKeSZUr~@wt0)=JR%dTj@05FlmuTDMg13Ic3Hk30yMh5pyJk--5MKfdt&o2fj?=MRk zD)T-+?Yi8WWJ%fFEu&h|Mauel+8F#oN0%h7m6)zibmVYdm>2gDYkNM+0)mg=)o$$$E zFhHv@BRXA_Z8$WBXRN)|JhSsHI+xup2c8%2E5}l z*NWe0_)i$$Cs9$9hGK^>DTmMqPl)wpQ3GSK=?huVVagdAzmdmtM02u)Q!rq;1quxQ z+-aVxz7-9f!38+{B{IUQPp#`ABLjdB2Pw-;!|jch_C%xY(K^D{qZ6*+nA%?k5uCbO z>Nj6YL@&%;^&oL!65ka;ul#|X2$X=7^^tKDLON61fW)a{BPXY0nNVP0N7iZzD+8)8 z6x5XN>P6zzk(hkR1m;YXf~noM!;LdXUM};aVb^^$ru~?Z^j9;~RUN}I+z=I5?%gTi zUoV&M&#eV0=+uJ02G~~`^YYEF>d2AV=N;X~l)E7)b+EvnSl}uFwei$Hq)f{v0IQ^7 z3Bg50<1`G_`dlY79L8C?NsYq`cfg31AF;1iq5}c3`3h;A;P4p=a%-9@|G!ocM`iYg zi3s&AS>rxD%h&8s&BXbJ?O$*dfi<{f=#<{bA3Hws->5FW&G6u$tM9yN4xtM2Jd#va zsB?52jn8@E?6+zmF6$(>;0EovDIMN zwYS!R5z0ESeBiRhjG_Emgng{XTmNqNj`5xGC9G4&wmlfsmX?(yG&mr7I?2;yh{vvY zK}!bVVc;QV@vs{eGdk;C*ZR!R)}|B=CyhFqd|v9vMfHBaj<)b3RQ1Mt_OO&m-K8Ta zHNLP}`Z08HX*~5D?ph@+L5E!=EBOl{7B_~F5&;Z|Zc1B~*+!3fdo^_aOHL{)$mpi; zp71NYaT&UWITu9pf9kL-2hDuq zFcZN)m2I~tZsMHYi#rHl)r@Z@vQ9c2#wP~YMLLX2XKqPA?E12^s%#}MT&$Yd7}Ztz z31B9W=l-y%o_>q})18aq{r(oC2qn*B`{MU)fLga9X+SC~^T#Auz}D}*sgFNRTky8% zEC=-3*Q9*TgaaC=zNmFvd*sUB)3(@3>A^h%>A0-2zTYWJi&hHB9e4_VI>%C7m?H$! z{Se0En&2g?2ESj%;YI8r{RSl#pZ9kdud;>;$O7gjx;@HhN6obW-UePDZ8KTKiW!+J zPYt)1TA>IBkBkD|ijLSk2!;vJpPhD4Ts0y|LshZ#rSW^Efv$I7Bw&Pz za6}CV+@9Ik)=d9gsObExs&7ihY_f9j!VDGm`PVo##{X{wY2>bP3)P@^3**{RLc7MA#)TGw6+opNL!M^nS`TPk?91Xf#&ZRwu$|%y!n?v)pQTU^8 z;nacn*LYzU+AE*v<83grIcqoK52-9^&!MR+@9w8V9x&B;Z7OS~&& z=}cY0aU_p)C6zh!c3!9Il?2ZGG)5?Yzct!sUWherT1 zI>V{Pnub6-Rha2X^0I@7gzk3?b5H>t{CC9-@){XImz7|rIJR9Z8S5^Ijb=4p=VFhy){emF5xb^`VlB1rSlIw$DbY&94*oL3YN0bEh>@Y{|SJPl%i7&9M|U9 zWDV!D+7)2sK;7jah*TVSLw~{YgsS?rer+kHq2yd$p+7-yuOt`FQN06y(pyCs*_7e> zzTIf_au9CP{A})Uw6UEeWTb?tJ&J6sMd$CfYU8l%LOp``={gp}{8S1kftp~B?~5F|!|19G7;@^0n)$k6`Yt7Ts*BRG(? z4^zg=(H}z@-6L+MmR*eT}t%ZbK}NR_6)? zWw-&qPrI7jE*Cj4roVyX{d%lR3Z+G|L>1ba2mG0;5%_d@i?1hs*clR*AS_MFOf|E< zwsw|rN$Y~K%;<~x69+uOZO2N9$CVPJm=)UC8F zA`_usU#A+5UK2*-e+im>$Ym4CSPRuGIT?`SM5DiA#C2-0U04_-IblTA5w?l!@s}VB zoi-yDbP-yqNL`sD9Vb|)!thjXf?x7IvM+8k)+9NSP5)A z_bxdITtCd(in4nt%q?fz7~Sd*4F?ykXqH3>lfUaRiI(8L;l~H$$3JwtlWIwsU_ND>e=W~K+U_H=0xNmt@s?$#t^tzRh7fQZs4$;>!} z2xG(I+MX}j0gDaIA+ex-Hp*idyE1{eSTXKK@@2#_{cgSStj7k6girf*U}qql>u^*{{s=*1CNH)T0HfG`NTYO=Noe7= z1|hFn<&Ci^9Q;qgogqCEH{x;G47|b zdT(-!4yg1xnJjFYX+=LE6M(D-s3?zgPL^MR!~wq6 z)F3B_kYvZ)C(`7Zi zO53ZmZa>jmU!a?@gSwm{ykR5P0JT-K1dGv?%(=K$Ia^t3&|pES@D76L%YUV4jDh{v zxEh%|Lpt=#$4DUhX9T`zaJ0%yW5lf{&S+!FJ5k0(Ly|@1$I1Mp=l!kjdwVjw04xSj zP2dvu;Z}EK&PqxyQ?J5QOH$UXJR{By62IARc>pfTiv$oj6WcMr)@j;{1bY~*D8&$K z=SXUmq4$v^M>4!`-zpGp48m>>p!Oz9g`XaAGL`OjVXVf>0hcV69B3Ul(_a?;L$lU* z=6kKhf&d{|Iw{Ywsoyz{fO&!g@8X=CsD^+K^ptDr@y+T(wO4Tz*QB0@&P4D1Xx zlY}Ivaulm>8hs?W_J<&}c#OYP>|2skdey{;Q}v*avi_8YANS==!kfN2AtR(Uaanju z3ni+5h9`{5Qa3kbIo1JIh06BvJ}IeqAUOrX-ARGA%QeozBii44Iy{0yp8E|+67CYt5{S1@ElFn?dvP>?1@BkO zYh9!Fs;IYelFyT&uH+be7%U(I)+tBXR7b=zk9HCd84MM?Pw-FYxocq$%NMQRt2a#u zZ*4SkdS*_T`XAV0gI9c}>o~gE$=}}Kw4PC0mw_I64JQm6*cBAdP&gpv(UIN0`(RB{ zM!EhICG#BLYVu&q4&N8Ze0x9)WJ5nT)g8K+s+}f>A`BURxct!0S4wOM;(}F0eXZY2 zmcdhxVq$67&`GMp-lx70W~H}_5Ea4ckX{+?QEzD}UJwK;e3tQ|&HL(EQ=;a5ABUEj z-EG{uUsj(=pX}r2#EMup{vdziV5R6Crecz9%)x`J4^^cwq=$#knv~g!REsrkYxB0~ z-$v#UDay(>zrw#hUP{0ZuulP*L+DXmPjEMQK3-ngHdhO^jQW;o!NX&2l<)zZchd&N zS1sSrHL6Ukv**swoko%oO#*|8DZ_{8uOa2XQLoti#mhz??YuLj{;R@7mgMUrEqec>KhAhcswAL^B$#*VNFe}zx&Di zHz^OtoZIxGuU#qMV#ID*Dt)0M(lIm$g~3MM(IsGtveNJJ&)G3_I{t~X0Me`HP>OIf3zfL zMLp1XT1_U^^RZdSX|vKkU+q1sbIY#lk-KjVz-#X6L#B8S(AtQ97oV_>r+*EEj7S`S zp(Oo|A!g)cPsRc!%e&?h*%GQE4BrWz{@~wMDIu@rya1e^`@YfxW7?Z+xCp~l0EJ!+ z>y$-KY2!DdT|&x2%gBav_^X0NXi9^*hs9Q#j3XV6G31$Xgr2AabuheK6>9TM4(vi_ z_0%VepcrNM%YKPfdfEJD8~)(?TcK%E4+g*G9oc~($=d0MN2y|tb3}IlGPei_Juguq zz3kqiG6NVgGa%DdB(mGPy1IOcW%8>*RSKRe5jO7Sv2gD>52T8KSjm5NYVlrY@Db2s z`4_9H(;%$8qB)pq3|UG+peBySo4JqxwR}+NL>GV0Tyh=cdzL?!s0tYUxV3WfL>{rF zcrToQ#m*XrRV#U?qnge~`>D-o)slA$WsTOamkqq^eV?+Z>O!yc^zfp`?fCoHn9+s+ zTyruOh;TtL=@_%sC%WJ4X8$GOpP8}2x4DkU0-AN;!6H~)o$F97?x3UST4&KEPI#TL zV#N`SU!Ty&k6UQvUGq1A;yLj#zj}O5#<4jx>3KPCUEe$0sF~9Vzu%SzB|TNwr}+$W zPXK-NbSaQ@I2f9omqG~yFi_GktzTwY$8Ar}uB-NsZFg>;UK7omS8wWPtZX~0+>x3a z&Q6=6wD$t^C`|y4s~CL?Ij5}u!ld;{no*p}Kxr9e4-uFp(ZR1C2<+F24xhQ;R&znu z!NLnn-lLBXexwx|?cKX)Eo7edKRmQ^3W59OIe&uVEAx%`-yJry0tEOslVa0Bo&aBM z7>R^*&{X>M%ScBA&=p4pL6yL3V|B=)X_&3bjw_-%yOOPCB5`yIug=!@hPmYofZd=! zfW=@}SbTC7k%xmT@QMj?Eyz%i*ak=bFt zG$Z$z{!tGDel*3`&MV^nioDWd59drBzA>f7-B?H(vg0iep%vTZFr&Vvs9>#;f~# zoHGjvZ!D-wtG@WgZIOT1{$>AkHp5HR`Nb_b{F>Cf+#dekN5a1YxLp0sQiBjDP1wrn z@8DgcG}_sc5zQ2Lkk+R=|GOFZBOgF_+TrcVY+?nNq{jRAPOD8eKm5*4;gO^w^Lhl? z)k)Irb>TCEe<~cgtD|^)Jjn5{UJ~cdu+|8^m?Ia5n7ud!c80>mC(aHY zpg{9>S?w^tiF+%4QnS|F>l@h@r4#(aylhTpdyzgw*=n2~2(QXQcx8S%TStm&7#YsR zRufW?tA)8g+Mo4ts`V&tYbD*K1u1YuwO6eMZRWB^h4HhX5DO8G2vwli?QxD?+Yj&in?0_h91$Y$FGTwX@GFD*mb?WtDYX2ZM&fP{K61O;hP= z>XeS$WRm4$FHrjlEly4aOO9h&+&1 zqZOVX=!(vYMVh-Q(8pyQuc4i8B^9YIrLpLG{p%6`3--@H=9T7Al=%h!O%;;(o5%rv zc7>}YsBPsfh#|e*g|@|QF>E3L6cU(#!?$TW1>lwK9L^m$R=^%*Lbw8rTJKK~S<;f* zc)0|ILmN*y(LX#wtSab~hzUoSEPx2sVS2qSyadENCnlXsgI&B}mRJFOtEKx?E8w`t zMcS8`@9x*ukEJN^1IeB0v1G`4**VxNxuqozxWAAa?BJ|x#zqD}>K{dh!71v2;j*e{ z!9Y9Ck+ms2ct33r5oA}bsr`O8eZ2({=j5GTM?tU@E`P(|sc}14 zbj0szyTNe(wB){w@5D^4&!YA{fbDJto%CLjVKL?6<2Nf7PLQ zWUWzY#fxuefnb{VxeCk4K{xt1l6aC%V?blAnGW^Y45R#Rxy`{_ulZG$N=Ma|(+ruB znPDhVnxAMn5j^O1NZ_w}IS`f=y3SaNrj3W$!#Czm)sXaEn% z^zkV*uU|MHHarwGG7G5*!dipCX7Q-o%6ZxFMj)rUL%Mqd%T?PsvA0#0Fa1MhKq*(? zFh0JTs!0)^GBT}2JL>K+R0oILOR(^p<<(G{Y-OcN?Atd-#C)J@K z6^#@%2zZg==Z9Uvxy&6rp8n-o9{wa#)6f1CJ(Ly@0}9)r^v+M#lflh2BYSs_^Nr%n zUUVABN=*1uKK1R%h2iFlTfOBqzM7N1ZOsCy(ENkIvDaeyAqWfO_g@y02A0s?8b9^<1ot8$YcZtAADM&sZ#!)Sx~k-JRO-nboEX#aL|G%w!!&lMBv zPb|3@*)@1kV1d>R845D42fBHkldvmf1j1yK9KOTcaq=N}!{>eGgf~^{jzvEjr?j^u z5$A7qgY(B}ge~CYF`URoBe3IFqqNJoJG=!)G3q1-?`~k-A>VjnhM^vTgk;zDGCi`v zFn@a2eky(R+2)(_YH%a9ra8Ff&!nrQVsD<;4yjph&ENc0|6togOFvu7$40q=x7z~8 zTieObU#sOi-M-iMMe`Q&FK8{w!fHvBsso$i8g(77-+U|O zxX7psS-YRW3?D}$K&@`wH&KTfKiv7C$Sa|^A2;~~WI2#0f-0_(Y+VOw)-oIrJFsq# zlwM6Dj=LVWr=I`oYgnM>hhr%TgXFgPfoU7XtA`PKFdh1}ID#Gb#?5R~lM%l;57q6z zGYHPYfFhw67_vXRfO6hvYsIh2#WmKi2{y$~cT^&WAFsu~2ba$uZ@YkLd^;nsVXfzL zS8^i%ri+igTF7TTD+oH(>3ct)>Itg82JZKe_)d%7{J>XcNb-X>^joN0_iK0~>5pdO zge{HaV8U}17aVb&B*ND)2+cXHgM#Cm+Fz|m>|*{-t}Gx90=*K1nhdjClh61a9neZ6 zlcZ)e*Q#+8y>dSKp?Oh)zn!#`WU@b+TM?WS7uqWvZ67E`rJz{=YqIy+;Q=@*o+X{H zXN{5O83F%B-u?O_Aq^DD+t&#X@iQ7Ev8ufm(ap17B1Xk=+(Jq<`Ng8$2+A;g7oRQ+Lz9^AN#H<-(|g%ypbqaFTvm z8vlLKM+!!zQ%HsaCu2jI!tAz_b<0H;Cu;UC#=OJwZ+Z(;x*8?$y*j#}4G`&>l~L=h8f1N00EgEHZ{FsAc-!8a&evY^|F$_SuFU??la>&jjw0{fId? z3>j0(U*X}I_#b*U7e$Yg`B#Uch3RaEw^VWPjS%QEA=^~m_()8|l~TS#^EEG>_~mLw z`<4~jz!h~a9$=fZ1_P8R2u?wTdTT5BgSEvhB>3v^oOTaAyyWw^X0E~ZMY%xKzOyiM zj+!EYaORYKJ+VWF$=g!t`r}gQ_xCrq_gkxsXNvEu6Ylom|TB^`2(U9P9`ih%gdwol`1k&lF)v_Zj$-C^;sI5~rr` zV*(9D04fms4`qUPik%uoWM)=yIB!{`c=bK(KaxqgkMlgJ>SbP~tMx=p?fr!BNKItB zsi|D+{pE3bS%U_7Kz2kbbit_5sNl!%?W)l?9yuWQA4=EU>Ep@5-<|Ns3-r6Rc2`}3ZM zF_?)S!+6#rN&W>>#R<6V0!|jIfL#ehBJ*-kTQuWu#N_|%{rG5s37J{*@dB%z{qy)Z z>CI2p`SJ0%k1FD(&U3M#-#K*zq*gR)2-cxBv1mrofBFHiewDTvrOo%GJ|ci|f|O*H zIbi%*P!yE?n;cgqw9zERAf}Ntvau$#w*@BWq@)+|jOo+eeX@1`hx%C9K5ap4gIl%{ z%rNFaNoJ{G3Y;nj<#=-sN^b8j4B3J_Fny+j6}Ii=l3AhIo`c@7B$>M^R8}&DPi@H` zXSi_$W$uR6BaD(xO_a_aoh14 zH?ehiBSJU*?>fKVYxu^-7Uig%%Wqn^o_ap~GdGt1YQTY8EKGx)-$VbK^vDTAu`;r( zQQDA(&kb3}W7+f!pSL)Vrfy5W3g1oPUFS6$2egXB>#gbhvGA-rADa zvlrUv;uQe6f>EV+j->HHS;~{B>6A1cXvwN{$XQap%H>+P_-8QH#B1O8$6cfMYjXNS z5c>z9+4|q$xqbgpvR}5R);?lP%0^SidSm6rO>6oCb(#B3%Ig6e?nGs0HB%-N#3SJ< zw}ac;w{DCdZ45BK3pZbpu)^dURF`(DZ>vCf9TjxIjya>O5gjcr&60hP6zxU!lv*|c z(p1Mqo>POvO4>eXlsa-Xh!FAlf&;AYrns}gL!ipgXSd0H@uv8*YCdUp@#@==Rlh%Y z`F2(?2r!y{4MC~tcNu?bA)V9_+zwgjeR1D-Ht159p#kqq|2(7YXR*X44N$9QXI5`$w%< zCF?gu6)z7CAP02`{ptpF5H|xt8r2#<)UEl*r%0ggz87~8?j)SB7u-0zNSz4=$I|ry zwolsPiYHxHpFF;0zA8kVS4F({c&*}+dL)c(#A&?LOjI_~b$iCF`QQdTDm(38aSQ>s z@t?9Lx2(=23||-d?0GQ7JH6~j_8)$aUfR;Dws|2mP2x9I?aM^?V3!?LOe}u`;94Qs zdc{YMz1CcSaJp1-BNTKN~3AS%H$nkgi0@)DX@}-~}k6DjvXz z$1V1Pw%EgBQjI*99()Asd7Z1TBRFHNG*q?LWRwq3h-6m(?U@nNm0Yx}8vm!B5BgXQ zFGfF~py=hrPF9!tLrOy{zQ7p(q*?6ja_kI5!`Rg0H8a<%MKz^SwxH!_&*A|tQ>J3M zivF|yv);1EzO2u$Vv^P2vQUDWddr46UI9RRWiw|^#=|?*osCdp0#_%2JY8jb*sYQc zw1~w$RnA#(D9vT>CkGd(IT~HKS)6;dI(cWi|48!y%5-!UZRjaoa@@LjD@pLwwhQN_ zTjK6kqV@>6pRKTFBzXWQNML|6K04+Hqz!P~!e-y{)Ca8XB+VofgB#HiBj6cwy&S$g z7Ph6CYC^Sn&31*8TWcJzGDdl9?+dhElB}HN1B+KyG$@!Mi>k!uGtp`dq(d)1@b5IS z5M)(BIf&5xrHKwQI3B#o*rPp(^U}(g;SO$U0|1w`9e&=LatH2i6&4_GonMb=%N9}6 zDqq(lu`O#4^c5i8JKI4Gh%$5^ttpAQRCM>GkSAX398n7tW)5sdA`dwu~T_! zEV^*8JP(X77RX{Z&9yRM`gT&Cs=r62PARHnWz}Pp$NgL=yjeM~g_Oy0OQ~ z!$R>eE_~cz!OOoXcL3D;T;Zx$3CuQiZNi=P6{6B7wx{J@k|)j1=~X3^_LqUG?8L#E znDRh>+6ax|qMtOLElf*MvD{>ZA{j{)Jz4f(+W-x`&bxg+M?NNIsbb#IA)gA@cHCDm zI3Jk2iztc_u0r)p0@D*-ZJR;wpL@3F6mkA{pTWXr;qTCQ0>Bsdn?h$IxeLMzg3vm0 z6d=F!s+?0jQ#Qx?`l!H1+wAz&Y@bte;p-gGz3$1O*A9VW6l`|1ePMfcgR@ob;s zwFt0$w)k+L2IjXNYsmt9ZkzViIB+r7Bj`QS-WM9NEk8e-CcC1X(yyz4fF>`hJ=H4Q z%(+S=xypxXi#e6>CGQT<0*I%+(WP-!rChIza4NnD&qJrg zeYN4w$_9Z&@;LRT;z#rNa*^yYd>)PHs-2ngO!cT2u=loWmhQTd$M1|=+zBDTwKa2t zA<Kl5QHuCxv`Z5Ur(5Mt+WlNNrGh!+b?o3Ehn>7dN=cO58Yjq`n-WL)SjRl3C~T z@p5;^__Z4#vTp!;{e?mOFde))su)hGZ z38#DnMh7CvY8tAaYjb?Cf3#c!%-n;XYcpv7J)Si+5VhJ4G`Vh8Y_v2`;L%OhQVdmp zO;oPVqS)Q8-es|uk)7vm4qf0+VzhnJ%D-mr7yC_k9X(EzJpNVU_LXU{PdXICWw31M z`E3%tbWJ{CD%V|fWw)~-g|fPvfAMZOokjv|Izy!Pbs0nmc7Zj5gw%LZMto#^sMpT- zf6(OJP+RzmCq*JvOLlygqP_hZ3kq)^h}M}}JV<(UPJOf~%M_eV_Ij;)pulOdsBALW z-gx1UjxKw_5WKy)d#i2<=8by~=h0ttzIO~uACBaK4*CQU%pus-9enuj_HtlCF< zRGfWAiubo&zkLXocqWNqb8F`(2O4@^ zRi#Kfx6s`gMir|rT-`4SwbxXMVp=qcffwk3gqO@r4t0)lDAd~Pjc~=yn^ksvjEn6w zf*V}}W+z%$Kk*m>h?ICC!Qv8lwMjn;O z@y3?qwRf#dBV#l)DTTnsngPJw97+Uu89H6T0JLh?!tbGrrvvAk&3sl~9|Q9PMMJo- zEep-R;;9wCfyR>}Sr8X{eudAu5SVB|?H92+#d zGA^Cw@zl59V-nkGvzvGw2HR}4n~cyKwI8plYnyS^5TT#Vx;Do~DgFPb&?zCWk$o5O zeJ5@RQ&1x`mZ&+3Yw-nQ$Kpq%VPzyrC{MI(tG^y4>Sp2S`Wzwc;I!4KDOb`D`%MH@ zugkIBc#* zQ885d9EcIXijETP#TJ__!vN zm9R?pR)|@)a|WT#U;vk*Npd?bPH1-U)<&gfhJ#$+7=DTc^RB7QaMpWc7DhM&U(&&2 z-ubU-67g0>Mu7^$7;E z#`_03#x)5FI{l8hEP4d+eTAPz=K@AvyFTw*-kY&Jfgx4zf1MHaMs|xgC|~MBY70pP zTTQan6ynL6epPMXJROc7ESo$s?@BG0w!D`;XWte(1jiOVTD%BW`u*X#l6pL4*yRGX zg^5^H$TeQ?HOH=L{V5GW1!g}I{<`oAye4bYGk9$w(OFRoOP_38EoQanE#*tkN2|6c z@Q}kf2R?c)I6RJMNt{#h`cTPn91b=|zdqs1Ff#IXPP_k!5j}#_)o1ijM9jg9^f!w&BT37BwrH>id zW`IQzpB|inv+LoAjN8%|-DnD%VOVJJNw5@J{=)kc&NH^1{4KxI`-S-`bp*duV|9GDg_~}L}F}( z2AZ&>Y$dIXHi9mb@HUSZ_2suDa2ug)E4-;ihLx69bsCF5LPfuU=jFbbs}2ZOzf(v1 z&d(;>s+M+X<_ri%^clYG-V*(R*A;f8-evMuVNL?I7jMGAQIo(8!rptutltkZ?2&%<_5lN73S4?q|g*9V+-Hv&7vGmF^W5 ztJuz5-Q97==sA@5o4cBC`Y&bIWG&E{UlKSA&h)`G>GuEAwn+X}G5v|>3gP#p7A-Dd zm9shXy$H(@*?Xh*l-_Cic1_j(38%HO!1+x3c(jTh54C?om$et10j;J1xqhn|<7z~} zSW}9|H|#jnkoML{MFR79mtod%GkesPy&F5|n9Ft!{>yr=DTL6D^odelBL`J=)Uw-T zEt^=0_&1aoj6Pl)48eInCi=pQ{(d{54S>I~{>1;@b7`>pAY&mQyxR7nu-#gZI_M9E z3FpgS-#c|!-y1C%oEX$RsNad4%G7p%F)~Q{C`b~tc$RO-aZCKX;18jf7(octmip+y z*e_Iq`jV0-q~Fn~Tq{f{b5Ko{N5bjt-3@d_B`wNMFQ<9~zFnkBMu^Dl(?Ryoeot^& z*3Xbj zzO^(hZXU4ARus8Z7J+5T3D1E{AJ<<;rQmaJo}*Lbdu z>bT^#VRm^1&cfofJSkZz3ovP4X=!^~EJiA}+gfVJ65PR>MErwvb>V;*XPW@>O~WR>!&@-BC~0FVPYar;OQxSF6QbBK}BXL>iZlxAVx z6TPQ>#tN!Yw990sk=iv%u5{T(R}728j!WUWQq+UNxVaIOUvDtwT?^#zI%n8oScMll+ce=>OAHoWAtsd~D^h zM0$z56j=L}Bww#6b-nDl(+fLD4IQW(i1lLm0>R`-Yv=LJPh=;ma3RL6HOqB#;+{0{ zZSR0%+M_-I1*4o9ulSlp9WQ;r7_3C)=THNf8>M9>R(-@~axw4?k!Do(SiAnr7`)uQ zm*aZ_EuvACY_uVaqseXuUPUiNtk|>m_iL_ob!f`z1@Uu`q?1}5e)sMp+F9n(#YH#I zf#L~!fzx;gZrXB}N_e-ku}|j&aPsG#hgczV8HH@!$S?F|#V?9z1OFyr0`xY7c%I2o z!lHu^+=cGw4Fez@2ss>5tjBtKe`Q^KY{VsAgC33eJ5ld<*TMp$b3(V#6nqhO*>z5g z@8@_cw(#ahYj;Z2MFa55=9xxUaNG61<|R8Vl^6RlIFl1|h8kT>kV5De36msAM0Vo+ zC{WiAAk(Wvd8tf0)Rj3XDog$?Szg@4t2UL#TdV8R2mwU0(uu1u8{`K>`}{SQ%xLlr zocSg};eX%y!eqG3|J^iX2vgFmedeHH2~?a7DVsbJ;s2;(yGd z{o%NOX~N_F>`s>pYO) z)^?+Szswl%+w^ofZNG^8@b8|wmU|k~XXrT&4+dWA0$F?pdYZnp5*vRh+`6#nhGgpQ zU=Jv#`niewyT4yWhvV5jW%V)Sib2*PyxK|RZ1Gk=pp#+Fl_P(R@Jb3DLs8n1de|1{24v9rU9Dm_xH(#IW;o;Hbl~t{>`nrH+-u=;{kk|-X)VF?WY8{^=H+?*-v$OR2QxHxG znsx$1LS*6kkYJKd)!_fU2+v|BVk`SM#W<6t5!G_3(?_{&&tN%9 z{)5Eg7=bPq!^}l&lAqOE>^G#LSMa@ar|685unj()5{RG(eerkc)qucK&=9~KT?c|f zQBM^KsoO-t36Q-AM$d|CljA|bUyE&~L5aMJIF&8)+yD4OfNHtGBok$=4z`nrtj+~k zq#C@ZC4(Kv2&G(-}!=LkYaCv$R7O>kI6XNzAkOsUg0s;-Z^9pLE%_ft+U zz#>s7S{LQ&--EQ4Vgt=pe@JmPo&tI=JOA;aLSPi)rp&OU*UBjX+jJRqZ%Pc?Tq4j6 zi?uj*wz7Pkah(xgt7-?LqIwYIBtBC;2CpimwKP9S?wDq*-Gd7$tvO+aL?%lh#VEE@ zW1my@(*E#a$LQTH?CJINC1sjGFKM5Qf|bCGltW$A+B6Uxe^w9`nul z8IW3da6zV>m+~}PKo9-`gmaf~B+o~2Avc<>%`Z*hr@kR{B_|{OOO|=wzl#0q@v&(g z^fu*EdE1;ajZ=Tg$p1s~@I2zp2a$S0+1uZDT}N(|AYf*ePvlX+ny0JxHG?7^2OC4Z ztZ17fCp@>fw`yiWfLW(OHKsg)D?n(8+XzA*+IE|cPN{W@FX(Iyz#Ys6r_2}*vhGk~ ztvhb5^OA{wW8ScTANzUq@6X!|N+r-;?=yzXH{!?MRwdD6#ydM_8>;qmW$HU3H zLJjN-SKrplyUI&930GW}L%Q`=g?7e8@W7i+=HglVnFU!;B+V60m$_=Bq!Cna*a><@hu zwcybolZDz)*F&0&UGjL{k9EUy2z;(`c;1pQ!V}+L=iYvJwVTZlq)3%jhUt2}&so84 zOR80R15({#?eX3Yb$z6<^GM5;){YBKdG%7P6z5f@+$46qrc<>4Ih9!ALn?IEDLR7U%t87(bjwBe8 zwe1;L{Z%#oC_i7U79`rFwlGK$$*!s_GBOir(LMCFp5S_xYb@3O!E>|q!NYpfCqwJq zk-tW5MEWZz)#Wb)4UmtG=+epiH=tUKbB4l0G^_y!bEtKmYLAC&T8}>X5m~H7+$YER z7m@P>fX2Vo4RHxE_2M!GX^D(c=c?`pqs`R%7M}aBtj7m|lsInjt@XOyEt!9bS575= zePr+U?d7|5f0mIV=p>{l%#aLMiQ33CwlaVMJ`>SQgQY+47?`vXcdBQ!=>LIpqxOp+ zQoo4>oHgxV45b_drMIo~%}8+{t3y8z$`?>3Ts6a9i3li;xt#cz()slJdge>HNTjwe zR_SItgb=#w7(6>R<5R|60GyF6wJMqc)XcH9+FnnsVkr-Wptrrl`0Wx6)us>=jp#NH0TEc>7z}2a%03P=EI{2tRDehQLg{9ckzZE6FaBLD$bO<1`s=PrM6F{?;dZqE9x|gwUWAQsZWQ~${v&ogvX3l25tN` zF;`4&Kw`neVMx@zHm#kQUDjl6o?$@;-P3l|pROd@#C%t`j?YZs?EM+6{Y8&OSc)l= zXO~(@;YwLM+dqZ6CD2ngl-JxT>TP#LJ0;EhDLCNb9s5!82Wc)DIrLok6oy9KHY_Y) z3g`=~gLb<5>XAk`vg_a)iPTesNc(y{fpvBaP*3zu|4#*6$^^+D3* zJDlR7#e$fs$5{R8qQ?Ha9S(ZNC1p<{5cqFB^R`!I@%o7!2&#frY3m4RI2E`Mr15z8 z$=I#ORG^F{tc3WrFR#VIVMk^CsfN!DXHRS~&>Kcr17qcoXmBmm%I?Br8C9Kqe%Skv z2A;3j;OVeNrT3rm7BmE`_7Hjg^eVT4)I)Xu(JzaP&;$;bOe}8CXEaK1C@*mV1i-G2 za$_61RoTJ+5|6kgg=u}L?gQJJz<|I;gC zdX??rX}l<>WNHZS{D_zc65k9&`V)a{+ZmX5e8V^uET()mwX^_6hkGxe-h+H&3V!QS z=7$B54R%Ex4@KaFsjj)QZ?OB@~^E)h4f+o*6ZgfMJoNn z1CttEyyM9e<1)yIU*Zf%n~a%7arj$h)xnIVv2Dxv9(m=1=0Ee0EPVFDa8^;eFOhqW zqKmr_+-6-Tmz$uKi^asOQ2Ah>0*7#l9;x`ljH1#>P(wBpd%`$blY=;q(8ijIjz6yN z2iMdLZL!VGSM`_CmWvh)B80D&ASHFQR;LB5QxS&DKJ8e^>T68ED%!auJX!LB7@9tV zl2;`IEKi;0BxfjY*K_6but!>=Fo8%D%bOAp{;sTweZ1WuEwSB}^Bq4?{_KyNv|w*o zC=1D}rew{k`DBH4`G8D$z{ew8zw~f?{sAleh`UJJzG{UI&1OrkFJ{k?CY6Jms?Ha` zXn%pQZinNGNuDhL(=|i2qr8|BK8q+?8)}->$<|*=naW=GP#cz(Ra3>Bh1pC*y~#YK z;_g82dvk+!*__{@@;BtF5b0dzWhI(+WqLfl(Kuy6>kkB9qT`e=neYpopbLZzAu3lP z{-L##&+_p5xi0>f&sw~yObxd}IfZ6kb6DY5DQ1U*9$ht%R>_aubs*@?ASd6~XxFyI zZr%JkSho9!U&;X4R1OzkTUz(4dUaUNtjRx#`{Ir6s#j4*)8P&q1VGH|BaeQP?m9Da z`=lv`qP8PksvBHnhtf@;Rf|W-IF-td#pKhvan#@_l6(A!cqJzKx~szrv5Lj^Ta{Q! zU=$W==R*M-<&m$7oj(g#SOTgl1;~pPwFd}fpdU>*>qeBs%!9Am+TwziK2yaWch?V5 z-@Y=aBJYgfJY+gU(pIV{5$})#;)t;t=GFDO?1~-=au{M_{gF;FN71yismc|7!e;Kw zY$dSm9$ubO3K>1Iar2ZDmv5*rG{YWVx;OfHOo zFo;z-cw9Dm=}lKp2nLa{0G4O}e_CN=Chv0#zy*X<$W ze`$aMwWC}lrL}KR6GL8j9WBO3Y2em|i9zh2Jty~G2Veq+yCZ8c;a!#?BnL5E!fix= z^z7cfOBb4t>{`yUoxuPi-te{j6s}o(2645mMKyo3{e+8t4u{%Q{ zomvo0mt;WlzuysTRCVaM@>-W#@y*{<=4}?`cRx;lyH*&!VXZF5tboFun@$-@x_9^EW#g~IT7BNqK97g z`H#nd?=(-Y5P`(QzZ%QsPk*}PaUQ+IHEV_9LSbQf^jRpY-He)ow~u?LsttH6vi)!n zK7fYOt%M8vhRDUzq-5Nl(-H;4;RvKcdcfb-6~ma~d0EkQKLl6pD^)eCu6a-VwMnM` z)L*lW2p~So3%W2xgW01QP>h%^w1wbxB#*KVF_U*xBZ#U}o~4hhRxqQyN%BcIprypV zX7zR_+jR5xPz$+Eeey50{fIxcsYvu1v|$g~c#%rr_SM*Q*k8b<$I%rSrGe>_q9tL^ zV{3T{wU!NmjDOKWV%XSth0Ni9C1T=R=*Y}veCDh;;$#l|O+BK|ljfip98bpt%^_tsFypbz@7!lS_H*x5mS&nbp|7GwRTF3u)%AUmWag|7?xOb_5N(C3v>`T~ zkCm#h-9EIq4+l*ceA>klN&TVhLG(X+R?}uLay{!&ZTicGDJ=iq|gf}(++K)3|WQRUf z&imuasw~5AOTyN=zlxkDgP&yXevP4?BkDNcv|j;kb9xVc$OuQKG#^yKuQ{7S{6f8W zFivu17k4BjX|REcsB!6r=~Rb^;qwvKH7EO7jaPu{J)jbg;F=eQff_0&t3T+#RF-7j7rk7CGBGb zI}@ApX$hDIzKm0_hrr<_)tU#TkQV(o`z(94q|pP#$3^LC=Iv9Lg8n^Rzr>9+aL3ZP zmr?_&Zgq8>yOj8%iJxWxy;rwpJ|9cSd?kLD515@kp=S?pE9MZvnPqH~EafiKv~KqK zqs)Kv7wYj04#K7Smb*VMUZ!giWJh@2!uL}ME94puM^ofz;ac}NlNrFcR_&5%;YK7S zZ}Ksof_IrUwL0mbqL5JnygzT4by}tA?{;9&Dw{AX*p(iS;-5rWPwQveSkbD5(BNFW zZSrMyAOaoGaIh+kpKS`6Cluo;8+(zNihuypx~w>4GBrG zgScS`1x$3aHW7o76wqieV-%9Pm|rMx1(kroxS*K-uBv_Ff=25Z0s9#+189wo3$Wi;VI=+ z%%KG%TEOlHUhY~G4g@ek@@%+2k-`y{6ur!it%Zp|Av%=QU=K_^v`>oqj5@Q~w`kwT z>8+!EoZUO2kMcbSn*O=+D_mYZc}vak`ugnmmogUn&(QoJy?>Vf)AQ5PTt+qW(vVQx zWmxlO#U09<|Dmf&>{Qx0~3Ir&}#VF%MTMGU2e zJk@;8(eT3icEi6>OI9t!>vWf-;Vv{ z#*~@VQ-YVj3MN^8*JHjNMs(e7e}|SSb$}-$w}ob1=Cslch3;?(X>M(;^Tqv@;b;9) zvG7%REr(Cx2-=urHf)$hNbKPxVqA`~ew7u&szT1lZ&b z!kqPiyi@qHa3`3Zr+zKuq>~?Pov4b)f(+VlnYgWY?0RxZ1YLQ_XI$<^+>K#VN5DBB zS2^``tBE(HyF%Z|=k5LGrwY!CG6l3ck%b+4Sw{A1*nFG+m70gf%h*-NTh&u(w@Lsw z96L=+_yi5sKu@@*Di>e)N^DzF^<0uVrKT03#kWcsQn$TKb7oGH@p%d^vyItFtTlGW zKc2tCWLxdJw}iF^ikPnGzfo<MDqu~dvEQug>dgU&#&=;pEX+{2) z@uGxmDq9nbh27AsXsy=FhAUZVBbhTY?|)&&(2iaoroVt1^1g(px{+p z#QNlI4>dhZ3g!G}%iQH-N;8=qRkb2_1{AKO9bugdk6B*^Ey+WI0cC3}b^w>Yl{zM= z(mWL*#LaVv-65|?EZGfP&8oHw7Wqe>^E~?3oea%n_R3++kSj(l81LrAASvteCWZmG zqNgnO?r9iC>C5_rt*oWNQRNtzZk+ z`*6raSmrin151TiF58HDEx>%6umdavlw!fGIygC&BDLMoPyLORNemO#71JnUf?3Ib zr?|To^S=gV8YW>z0_A<}f?U#~6KiJ;(^(8QF$gmY#Je$!F7gZgS3B$Olxew_+mm_9 z=A)vk5+gnJ{>WNOtayA|;=lqaw;f1rj>?sEY_0Sx6J!r5zuv^E90KkMzdQ(P1q8QH za9&CywkGrl!LFa4-oMJ;LOYq8WquVTE4ul<2IA*h$#+mD`PE=&hPec1(y<3V_?^3k zR`&GnwL;(1X?|m=WA(m?1g8igMgjgCMd2UBmu(r|OFKZ1=Yd~!{6dm6Hj8-_#Vs7g z_kj~#chjXoA(BK$vP&jovw5%0mM!^KPhZ4;_aiA?33Xvb|QNl$k0P^7_|=@$xG$E9_Jo0~iXRL*U8Mq3;|Q z0p-cN8LcyCi3wk~OT>5hnCRfJjDOROYNMb(g%B>#QRQ8-c}k#oJM?+$kW01NM*nJJ zZj{0x=Mv&vH(g*$2-#v3+chG!7iBtPC{r>7<(p)%SEm1Og?_UJ(3b?qRmqxJEd10(lH$%=!W$9`0_%VCJWT@;r`Ufn6onBJp__k%Ai z-4{QK0xNW}Re;BF5y)2f&@!A6{1jZT4(;Xe*nDW||1c`4`p3~G$;3z-_h@D0WEWFU zuz6hE={XCn1`3`fi$3evk-~bw*6u&N{bYrh-XnEaGWI_dee6!)#S9VJT^ji?f#jml zD%2`CQoX!01^HtlNgeb~s#zbe?AVZInHOg;%nloifZtUA3A2?XHG~2UB-rrsEe%)$ zjiUV_nm;Mv_YXY7zFq&GGSCBI*S@2b=q}m6zJ3;IqI&i&G9DF3ytOKXq#ho)BvN)? zi1Ke93M5zT)|{k)Sd_jdu=O(P5Dm;4Sh3UhLekSI-chZ8gSspZQy%VLkEYG+*2Y#h zQdI$fsVJda%wm;7fO#V0_CR-5!_8|;|CW+C6!+iHuE@HL4yn1fKKn?nV~RF!QUKy| zuYyN9o$K7&3p#a9=jyOyROzrNR^8x2?cJsWze32t#q7?=mt1I&G0{6buYKuVH~lvs z!wmWP6vN^^_*BmWsnX82TO`(*gJo;8WbX=qGUQUvz2y$G{YyZWIF&$?Ryt|ZGO<8* zmiaR1fBuv-1RfeHr5SoVu^OkMX8gQGtuZe-AYLqyC-L&T0kq<5k%5g$X-+hwuxZ84}!-0RK zQ!(@z8yj*t_wyl6n3t{08Fe7O8eBue5_RdRXmgWqpUqBIT2%E^S}`M>Onldh9UE@* z^Mo~c+lt}(35v)~Yf~#}@DXCb(Y5qYUG>*V$D5Eg^lVC6=^St+_XuqQa5f!RRGAua zDV7!IkH!Yg*+`9ND4&V^j7B1l)c~aJurs+bdK&aZ8r8UQ8wL|OMhGr8L92Dku_JQp zTqVZl!Fve6%Ne0G4>MJ5)tZKYjiojxDRL~qw+h1(JWY{|hS{pD{LH?xj`Ww)T>qKB zzBlXpQd(DY5kXA(3;k%RAM(RDO&_O+v7?Vv&A)S8T~z0}-M8P*PIq8d$N}LG0}Gh2 zLoM$v9n(A%z^=~@dfj`@@SlsxH%Jz0;Q`hg6%WmucpJK?8+LlKI8u_ZKPiB#5M&~? zeEP3)(CzQ}l<1Z@4f23gnqk|tJ|UB>M;G7B;zW{BjegfuM<0ZpObWKKxm!r|mDS)% zS|L_&Wm-@V`6ZM*_VExxgeXN)v(H!rmeO?B=d zb?RefP#i$WS@jOc$v*NNEGeluQ2B_=X|p3bQa0xXE+*#TvTJA(Txa=&^3kE zR>9q)_08|`!6~dxxJ~d&T4ebORw8YFB&!T#dQPFV92jI|LZUfS4Rk$3`QJWvBm@f4 zuL_^px(4e0iaXut*b48MZ%o5YOhvc0a&3!X45u79)SrY4eDz$6aC^8|XaN1vi8|NDH&aX_( zOR`?A&pCaNpd)E2%iBWNCY_8c%T=>f(l^i4)T%DY6Zme; zrlc@*=Vs*>W8&ubC_6dbzq|1Hhp>T~aVe(km|QwJT;#L|O0Bf*j5+JT0f|qH*4q-( zyZ8pA|J%zg0{H%YXG}>QIEZ$l7W+hmfBgJJgs;m7ibnJImH&qb<4jBc4-w9!(QmkF zs-pDJU)*@eDu3!;r7mm|T&}?EJCPoyU_ZRCR(6#8zff_Mba|&G_8yqsCo;Cuy8f!E z{9BN}>PclVU&fVE_RHhj(puT%)ez)nG77*(ZRB~+-+dyjv+nxB?jM*}{<2A!f^(D} z?yeWSdsHrrpr>WLeTOJxP!n_gD(dIOnXZF>=6Mr@ ze;B>cHC)=F5o;!;2XC!733o_$lme~94JiVfM#f6F!yJKwyh?N?M{HhU(Pe7I8UZj3 zCD$fX<+S38UuB+rqm-hoSfu!~U8S1BW6tA&e~1~OfSJOPv9uV}3(>f$#9CAP#cL1g zy-N2b*16kF4>C5h*hGm6#->CSX;)x{bsX+ji+ZIhJ<20#lj8w2;tz3>N@r38P1f@2 zqs4nG1ZeLeiGTn|I7!1Vl>=#ZYZpKs9jrp4FX$#s#{$$GbPpNYrL;V8<}|nTv@4y2 z2bM%&ucPR7E|Qg+xley7@H&b&!nJ5IQ^tj&+LutroZ}JOm?abnV-ZyH8)9h$O+Zx& z-X1$47{|+yl7%{5*4jQlHWYzQEqg>IU@662DbMGWzKY!Vt`)x3xSSOVJ`7N3I#rB* zF@GrZo#sq>+Cir63pQ;;;)ONoh)$nZijXS$q6=gGZChu5nc6lB8f!bjHWU&MZVr@U zfJ2re1e~1zbhBG#Rij%J)i%$JnkKm#j4lsk`A+IeTcuK|8CzL2&huEV2AXD7R_E0c z3@|ZhcXPY?>vlDehS0e}+XIA;j2Jy{e?j3M2D7gDxda9WUy)O28Ufv*J|MSHy%?%T zyyg=)pg5@JfIsi{U8=VN3}mVd-J@x@u!3cjtS~8RSU;GJXsa39R%=%1d8E-zwc&W* z;si5^v@LD53kB1$JMTeI5AE=^L6tdBSB*wV>hM_>0Q-G!UmvPF*t%Wq5L>Qed~IF(?GKixWgSwjEET#&f%myQp zB>B|gdnDSId5uS?EvB#HfAP8d2Jv-+>j<%hcml@f~VNl zAm%;xYjMGuL9ol~Mp9V)eHX1{#<$*hFr96+JaI6(=&;8oF-$V>Guot7FzPFgd1?+r zaaPp2v2_TM#l|W&Vh9H=+5^5UV>kB26|wG(DgSPUCq#EBDV0(M? zZ3GU+)eh%+O%$LB?jGo7)FZ8^{;lxqpEz}GW@uW7_T#_&Txz1a1>aN=O5|ih05)$0qIwr5X&7)rU7hdM=H!EiVXbQ!B$5 z*I%V$jkDUe_K0AIP(>(OE~V&3Z)qUkrx5bOUdd%{S{R2|U9@gjdBRLqXg|Oysp7=W z714$CB=t$Hnbw=-gvmh{LQ%OoDiX^kv7fG?O~z}h`xM)!b1xw5GJN2C9ka{>5zogaO$XLSDfw`s;KDczC@QpqlZnT>6BG{T-z>96vcH7Jn^}; z7C0y+u}(YCJJx>3ohM>860OAemZ?VufPX6sMn(e!WTzpjh}0#S$AwcJlHW;p*t585&E6{~wP}M!Fe87DNmf9zOeeJ;u0rex(ei?GnoxJszKWIYp2rZ6?kv zTDD5U2O1~+dN0%$p&f)P6Aub7FA5;w!%nswN)XWks)sXj(VPd%u5+48bovWC4OR=WGDsTsl)Tq;k`X}>-axtn6LRgL+32O04&hHwY^EwC zIeLfqB1&a5Sk}!%)$v8o3o@<#U(^!w_A~7g)SR1o7bE}8j?}7e3*@`k*O$OJcMxqw zdajE#x2@^1x7{I8-K{}pTN8gaFBNcJz;VYD|FgZtV`BLk{M_q3NVd;Ldzpjb>_`Do zXEg9v^IaYPI0^3Pb>G~yckqZ-`*4-R>BS~EF-ckRrKZQ;Xl)GQA_pyXGiRNp(R*0o z$f#LizEw#`Cv-t0~!ER7h|PK2+q?Cs2ES-AKt)xX1x2D=>&9$_P0`x&_7t* zFWtB*clzLOVqf6m-8CnMjh=@_M@&&@teskXivCA43Sa$fAa#wDn1Po^wWq?ej+@iS z|AUrTV3@P4Q5zRp13CE~W~Sld{!FJ2bigH#rry!Be~q2bHZ(g7B-l#v@=^Bx>a&(= z!b}UUS)s2s2%Mx-@DIxymC(mK!CX%(Bhty(vy`l1%g7<6>$NigV(_iwxqbTfaz3t6{Xh#B zN5Grg&22>urBHV^=lj}GV$PO7*V9vf57!>-r+Df#4 z-C>$*pSyfF;w1!Lot+=zw&aU1;*2POk~;N9vbuiIAuzt5oScl@zI zSJwOM(0)7cTYkg9KhyC+BS#_ZYQgnK_w!gGp@AQt*Mi2DT=84QNqATG&Gr(I#tytc zk43P*c(>&m00JiqOF-7$(&nKsS^{!DhrFBkcs;#468-M?R&&yzLi4ISoH9HI^+umd=;(&+T~GGZo$P z8yhsT9)!_6t01u-a>!DJpUZ0A~SSC_7#Qa4Gb)}#C3=LoM1)BB84pKJ!FdAh| z>SxByKZVYMT!VFm(&*7F-Pcz?D>=RFJWX6xW0cpq1i4+6)_SMpm6dr;ZXV{0Y4gqdmHmj2OEYfBgaJu zjVhcGXtcw$Qqt92GDPUhnUl%Az#0wJ#p3n;+;W&k{ANL_Nz`^4m-soW8EM`0AIFXo zC|vafs=bfTw?1(D8qSZUCv#dI+7FtYf|vHtU@qe4;nCWA7_;{ant{Nm2$Ti_^3{O zW{wL(j>cS_W3j2Wo>|en<^LT|PTgEPA{B)tdg03#xnjCx*7!7Ct}26MB-H3(fBR}# zx7upl;mXcGF^##;Dz+C#fzQqC_6 zN%tP3XPohO?elbpKV2p}S~~Te#&2iP`(aP9jrjj?%m<&=pYc*fnP{IhD%C)NpI}$n z*Hf1%tw+GH%5jR%_C|gqGhN<0#?G@g2~LWMOW0#7(PSSX(7!C!*c@^y6gYx5r-8Lx z5?!+e0+mug1Vs(K66y^etYRX0$($p(qJPBbg05f?`n+sr?d}lf2B>ma3+AX6s1TR8 z1qN#vLfgZ7eqRyL8MP$Wo9-p4*B{eYG11oRd4~oS;?}MF$<>>f#2&c$yEuNe$3T~V zru#)13K8DX%YP%1{(6$;RNr*gipDjkJh)2`uzB0U;^*;<#N7*u9N8Xreub%syQXRO z*m<_bXyy~$Y@V8gk+?;RRRAd)G>7Mn;(rr7SC^G;oy}q>Dgp>;a~Si9*Ao5p>WZ5F zDO$K{QMpp@vtxz*B}599dtuFus!tlLPe^bhw0s$NE-scn>sBNyL_rPrfM1{W#@Q7@>cJL%0h%9ujKam50* z>}IwUmLgGVmPAP1(hp6&H<@)it=c;QdPxEM?w?bZ;1`7{OVhe+2n&Tn)2N1~@!ALkV`B%}3Tx3w3$K`grsypq0uPqp8Ux7rw5O^|jUKlH=h zk$pf)l*Z*T7nf#Vpxs>AMR8LOr;)6m+}d?En+5c7yo<53K7%bHPLSu~aoQYE(zSa& zc0S2XXn!oc7<{Hj@o-1A-?TpGqz=8OTWc9+^!nj*;%q`u2V>yC>o)}6AD0Qu%|J2x1OgNt!dZduxI?T%(EIcNi@GB zk&Ci)Y^@^ph@Gw-D&PFISmzj6236bom>2O?5WF#NtW>o&-&^*Z5b|+=BQ>8a&A~vQ z3R{*j#I{%0$o5m7xny{?z}r{;GZpEaX3(=jpI~^d^?K7dEwO(ZMnGzth`$UCX`1SX zFtt0~p~Y)os9z^Fsru&%zu9!>xU$Wuw+1V{CYUi-Ur$H82~O(3Rh9wtZ1dL0g@Jr6 zLAB?cvqU1(J_#RT&sCi=o(DS3Kk5?&?`AAB`j@#pp?DoV=NHs<0;6Aqqx%k5$xoi~U$aBR zscCx;wZ0%16~W%WGs^&?m(|T36ZpIg9sJfDtLR0#WGbmAj$jditO{`8iz{fs3e%L~ zoT2DF`~SB2mb2<+Nwn-k^s^T5X z6mPV^FezoY3Uu>2pt|YmO5E9S+cug!y{K}HiTLiL@MLENo=(kjgS|Jcc(viWS0~GD zn{Urem>v7zHTVPWc>|&<_vn||etl-%kk*3Ma>09Er3XDf+IfD8NL=L4+O{y&>T0Z8q{g(SvxX^m6M@_!W5K2)kd_EhU&~I&! zsk4V)ud5S`rStK6YOCY;WP1+xwz=e&_;nCc@)IK3PSg_seHP|;W4wHw=A7;+pIN*~ zT7v9EcDpC}75yOK#omx>MKNDx`45RZ#=+zcrNn~zci%;A8_ch=TGE14DYNZb*7YxK z4%ylruPtuJ6DYE7m?|{PY9KkqJoe(WLiQH0=wB z|NHc05FlV6xE$UoPE*s;u_^M&mjy|VII(Hi<%ZCxoS+VCT~o_)*tQZQ_vQ`3-nWta zD3J|f5gb|Dmj4?NhqOsvvKZ5EE{LEh_>DT8cij@L?jMTnflWqv8r`(7VE!R^wJgVP zJ|adXYJ~QVu#Z zw-{Rso7dIxdhUoBjS3nJuKs{iNpXhtvEh=Ln4@5URs5bCK^@zjd7=j zEcbIUS3yaFE*nGV?Na8Zy!%{5*T38#=FxW8Y2_$>ebSx_Z6xX7750zwoaKhV)rNDe z1fchQcjlO0f^flOyEThng2GVNIv=jJO#X>J4b&>AwzWebC(mR1a-Er+wU0_evd8k< z8tZ$mR^^D%3s{dXhm{-QC+ePOXw^=Ts`M7OS`yn> zx6XIw_s$t)6rc2{Q}l1qdg~ILHZs&WVdDJVok$Q0l+$ciYm>3S`a|3Q+ zm3idk6wFl>&g!*&kTQ7kS1Cq)$xD-Jxt5a&^PtkRGUhKHuF3}o1(xmpJcC7IFZD1w zsHOs~41WXls7BCYpNZgM)i)-}L3R4lwdE>uP~rGik)m7KY!&w7Y4v>--ncd8!U4I4 zMx~O?DVtZNB9p}g6KN%L`m|u~bpTo+XK!JABP)*!v&TpgKbwB?Wu`{Sr>ip4SfGZ- zO}TjtgCOS*?9Jm+v%739llAb)3Ul0=wp=x-UTPJn)UMi0Eu3Q?7R8JaPv$CC-4U|J zF?hrititSN9 zAWbSgryATxsAxK4#CQjK%4(4`BS%!c6(=yl%$#Pdmw$?B;S=4_`IsY>Z^hL~cQpi) zbP{JE9M8aw>y$BOOsZ2sPa^E_G@NMjc4OnXwQDBTPY~h~u_aX%e4B{*hZME1`LoY( zylXYhwYHK~`r0NzI#$9$0BBYdGMT)s6>N`nvp98}%t)BZNKjq(W5j7&`XdSHq|Hd8e289{)@)%wTn3ZCmP zn~CbnBqw#au1NodbTf_H_Vfl(Il-w+D4AO2FXf2+5Rue>E{D?@O#nIc+CZ+hAwpI| zB->@sgZ6!Vi z^eJoQbb_-PNRfqbm|4745VHCODiQ0$DLMFNHQg3jrS`&UrtJ0qFm;YWnnYWdF56vJ z7rJcQUAAr8##^?!^p;N@=%g9({nVY2(CY3~e3mjftV6 zbTVzx!62;)h!N1R0S=ajou5O@SN={iN@X1y!H37pHO6$FL(f$5O%*daIi3r!YA9)B zuA!vV$f8wvNFrjc71Kn;BtaJ}0SC^~e~Q4O8cIa%{%3hkET~K!hyB|5K=p3)u8q&0 z-k33rQx`6Zml1Gk2lW)=szSz@zM5OWeWnA(^2Eh*s!QrTG(B3Fi#@3X_19X7UbM)l zw^B&8rn52~XDmi3QZ>kJ86sH)W;>R1~3iFuS*1|P{wL2_1GoTN8Kn3;rmyh#|xb_)fNTVjg z%8hr*#sRKnGQ0rs%(^3X=+X~kEKv?MOP=g{!|AFn_#~2$Q>DTpv`nZ5v{3uhM!9{E z`uXN#ICfEupm337;WSLI;}Y51I;Dn*v;gS+2jYnLiLuKkTBWDP>f)z@U-vt7L++{o zkR^-qFNJVO&w;MRr0yI^Cho5m5-38E_!oVxF+gR{TOJ=e%9+5T?D_e-v*RXIkfuTk zMnwY#TZ9E|1(l{mY;<=Jb>ILpTrAbE3dvoQcpn`BCN7nuEH&;~Hu6q_#_)&zrz=bg~bOghd;ZtBOXoS2Q8W!0M}lNwMfpog%iMM1?v0zZPa(HS=k z_5gvf!liY;($Jz13afScGtn&r9N`mlY^;o+5c28;xY^!O5D#pu>vS59vCmy%{ z#XTcr7SdLKcg7az&&~p?LPfL@v@aP9#-?huo0*^@4a|bs#Uk^$RcPWBd?-c};sHq3 zLa$tEc)H2zUFH>zN)aE3vPqN&HY1@4vWl&d7hB+6BM^b4>`-|9P&Ku_Xx|FXTTfD? z`#2}+4+>cP6huU*UOT&6^VBAME}}~geE)sW#2Rxyi>;yHqd<8yLe1D7n9%7%h507rqkA%FBb3<{jkz}&iEMHF+f_;n7z{&c|H?4nK3RLE=--F zybXW=^XVzP7ozB{bze!EA3=1}xb{Q5*IT3$8vT7*;SxIT-?d`rB}h>=Owya}VQ7AI z6Gf4;9h;c*qFv{F+YHsC)jH-NtsJ?}Tn z?K)C35V={sNab0AnJi7SLaME(iwiBG!W4A^0}Mo$ZCM>gmoAq)(R4Nq^bKeaA*pBz zUO>v$?Eqbv@mKUJn9mm=ufy57;t&=&Gup;+#lIk6FrFqznPc82m+5!99x}ZEBHrh?AQ- zmYOT&&BWBt`ydBrfa9MDRK~qZ@f3E-y1b^Q4wZEfNRA?alpaDg({CrUbQvlX-}e6! zk$ulId(11gU2oKC^0pFPDh62;0JkTcnWnE+@51WCuIZB#%#a#H1Gu0NlmDb~KvY41 z>EbjD8Ie6rPGwHX6ReOlGezW*8^(r~KeJ$$IFSp1!}lbkz^4+n}{LIf6l0QuDx8wXW1{@X4;07vIsuD9M&$Zfkxk zhtP*LhamcmUPkwAXcJ40)Ms#$JtotQL7y#mSz;$2wt;d6YYn_E-IrNT5X~J?2%Kbe zC{#ed$FxeGhWukywIOy zwXV@6ODtRE3TRt4LQUt~3_X(gr`?PlCW;vIIBTIf`_a&>^H!2kzAP`j1!&L9_0|S< z(pcv+86CLs$eN_)2PdXJNVKwn-{Of8X>Gs4vvz9W}_f_&|art>hRQJhs}9 z$dcSt;8{l(1&ay}bVIV~{g0%;Jc|)x0Gv#URmF5MOa<>4@o_ZL9K3`-zN;Yv#UxaS z*iZ=-Yp;1xHw%k@rIdQOXfX!q0W79vFQrL}V8@VZazZ)3S*|ZFN-ce~X{s8#yIwIW zP4(M5C{T_H919>X_<@6nKv1wNX_#PzA_jcET>NNX)=Y0YwK+QCEkwu&Aj9_kQ&=2; z){F#29%5yRXjuN^v35XaxwP^}wTV9fR=Ph`*uiUo|DW&FGjYqU7pN_KrJ3P5l%PX& z#-Huk(_mM25YhpDL{aV;qf#&vw6Rlq5Y=6<3;PySC?i0zQ$cSfDp5xSCOdMpT6ESe zx$U&RUWu$DzRIyD`%Xa1A?gWO@d}tdT@Lodv86j_3TWi~3AqV~Ap^MWJI{I)4z^X8 zu~nbFb#_@Y1s3~}%Xn5y670}Bm}Y|UQDyJfT{{X!lpref>?)`kwF5mtN%9iqca6?% z(9iDTs0)y^y*{{;Ab;|zlxN}d-ANyb8tnDeaa}lRo*W^}bX~aFWT!N~`(4sd!m!2& z?apC*i*Qyrao|cL*GCV;HYP2ijX4IXoMmkfcnV{}gs#IGv2P7E>ga@PXt2%fjY~4u z35TSZ%^RJ_X=y;>LE9DKv6Fw-TNqLVy%$PA2m|nG)zVLE!)O(-{qmXnHJwLA?M@~b z>m}Gn+4QTT|G^3;q)}II;E{`t0NvA&DO%#8f~D}%X< z!QDqRKIj$f;ny`0Q_Z#kYtm?4RYt0u6lV}xu3hGUgBI^P`9+_(mw5mFHyZ6B2M&j- z77ws7diTJR?nNu|`eXz}=gQ5~VV4IV(%Y0<(o^Ttlm|VMZ+lt1$~j2j20om|;Z8D=5M>k{K%ngYOD?-FqUFWhn~d z3OVQNTSV!%YybH>yLX_vSm0}fg02U;Dv|b^ZCawNu)wHl>AXJ?vO1IvX$uJQTQ?jI{-@I{ zbseOh_8qS))?AS4A-FSEs7W+RPZGc%Oo~|e@2|2gsFSnCnsfV3el0jUvbA<3mck#5h#;?C2r10RPf75rx`3Jftowy^|jXug$OOY!M( zs8q-)Rap%q)x0ldP*M1l1KIb*RBuFt^W0~u*la5L{NSwNK(Dr`1u6NX-z6qi2THp! zYD&%}f~9K$vkU9%%hq4ZFg#c?y)Mio=F*`FVUh|zX!9=f;7;uagoBSx^YEP9Lc~+$ z8OaI$nmq<|E9d@0cP0g;z?}r(aVPs&A}AXO)#hOy$O(lGICbNn$&P*ssuPOHZAx@@ zl~h{$dTn*+6kD@dIwSYhCXRWhZ0AV7{_)JrIJ7ht{QkJA=e9+1rK8s4HyC+ z)GSf)sjT7pz{!J}vB577%lfI!>8ThfKO*PTQ(-2Euoy@vjFaVLERO+++#a*YgpWbc zpSwZ=|8skAo4aEm7EWrQQns?sNkYK7ZOCy4=5r`xXVjSTMIHLSpO~@$j0d+{&gRxO zXo}crgx9n@aev&MX>jOV_zp-{=!LNc;fCwA`48n)BV!@oSDFTiK(wA$Cfx zU7Lk6>8;-Jx5xB$g&?}+=|l~&&HGw{zSNBIdN}FU2_x%DF=)PmfnlO`A|(Q007^I1 zr2lvS^}XmYIYo|5KJTLB_GM3^c%bz}%7`dOM@}b@7jH%x4K1IY8&)UZ=}~E47=}w3 zUKy=dm>eeK6h?Snq-0dVGecpIAh_*jc?AB6lRp-8b409#eXvtN#og|K$mxdaQ8j~H z!HQNHI|&Dy1xmQ$WJUcDOH&t!#|TahILc7x5pnEg#*#=+zzZN#)x_tF6IbAl-_4g{V(9f~i`;tZ6F@O@S8(;|cGJ~@ zyi0%kS^!G$*`SV&+cRFq{ks3F%m5kIQYYXxn0r~FBXYs>V6yI#pBeNDh)xj)==g(> zDfO)HYMTv|g)!;KIf5zVe{bUzWmRf)%;%m;jRZNIqb^H5>=%Td&m(~sHKbXDnYP`8I;Lif<&kbl*R~C^1qxu3lb&eNldT_B71j0tm;QoJhdT_kSY7c zl$Io^X|d*UI-6wexc#uvi)Nt#=sT3H{Y_>-1RJHWx3vEImV>1U#`IJI-GkTaIJc}z zW}H$%c@nKM#RkP-^xnj9j9g~^tgq@jOEoUeWNu7xB+6(^LqejCKn`XK0YbruS_5Y2 zlz6AmK+K=*2Q+m0Z#BlCNM=;)v^LgcB&V~%zDhTm%<$~-xe1y4evWUv=D>Z@uZ{ff zjora>s_~f7{pFu){(N@u-R${^e8RPC;m+1X&)q@_;z7{i&iUZK3x+gc}{E){$-bXgYp2JlS;k z9gC|J+Mls`Fn3JRS#=|}Q6kl^kg?N)L-K&4qk@WP%6XGw5fM{Sar_1Wvj~<20nX;i z4&`QnifaS#oYvYfx|yjdbB2u!=R_`W|K$JB?8sdQ2j0Z#45AiE0}Rf6=O&)%-ds@^ zhc1;GcOc8A9h{X2;$k%*A= zYm`8EOW8Fq&*|@V0lmuvHY}i`$TqzmK_O&lA<2rIze>ZAnL^w$emsXOa^tj6QEl@n zEypMc(q&o(xFa=o;Kt zg`}4bTrr|c&NhNQR%ELUC3e85bc2YZhYFd=I=UPUA^2*icz*7)9z6#KHIV~ zfL{<;-B%>Y`Y|l*01Fp^SsaP;sSgiAt2X#Ed;JZ7xM`%N`O6^kiuq$d`}XBk0@>g} z{opVvLF;~*gJ{hwVJ{XQ=3hlkhkH8HaL>DgoF31)xQqWP zE7{&cvFq1Kgo?+snVs0l!#uY$iMu(5WXB_)u;XD&bHS}YlVjN3eB?V9Qy97Fdy19r z0ocA}?gduth*t-Dsgl0sC8NwyNNDZ`2*^iiPe*<#!)u$Le2&xiN4^_m52x+}ym(>m zyV)fJd;{$CT=~^CgyXz;Dc*q128UJG*N4%N&eMPVX=bSjmO1RH9|dtYIgaeKlRtJd zX5Rh$>NEn8GZmo(j^;=VFS<3&u3Y2t0rt&t#>kZ{OfTgZla9zRRdAv7f0~i2S>V-NE9f#kK{!w{smQ1rztq z9Sa_d#nhbO=w3gj^#oFb*ct8$80A;?3KV-@hG@S98=&1S3NKXLrA92p5P^OpVCxMH z|5g#3Hxku_JBXLL0F$Ar+w{M)APHIbs4DV zgN(KEZa%EInH&1No%eD*qv%zb(BwHk2jJ7)vl+>~$F=Fz3sA=<4NAv?2{PbTqy#|Mf# zFM}8d(d<`E&EvOF$i1X>V$!g5%NONr^5TE{n8%d2)-r(&ua)q?0)o#1j)oO`OzWg^ zUmO#xnX5SI_Co0q8ejhGSW9^y7T>cwlAQ&!sDFP_&C^WJC5NFd2gZ>BI0|1M_hU>_ z`nq2*jfrqYfy1MeBTm{V7yOhLP{SMjWV*=}2Sao)sq75>=NJW;sJXjx2r!?4l z+S6W7|4NM0uHY9kriGvbq?RO|Yzt}z~0Lia!#z1R} zH;Y;Vej@M^xZ*RUshi`*0F%@oD#&E8fA+Usu^fLYJA= zxyr%+PuA(5mn0j8SJvZEPmY`gQ(DPqUId5VoZA}$GF@c8tMW*HuDvm|Z~J&}RsU;; z`gpJWxc{ry2`s2g7O@>}>x8TkvrUpvE1@kfDacH)BLLI}sZ+eN#*O2!N_egNtiL#t zVVoM@mwM#zwoAP86j#3V7rJ1|4DR!msCa344HO`8WmvHqXUlz+`)eA2#!o{e3eS%# zI9{Sj(I0s-p1liJP53}=ZA({tLW^8VvK;LGO?CTZN>e0Et&_FDX$&;s7)S3bVxR>d zk023YQULzt{I0-dSj{*+Wy=D#GwH>??!};*K$>S06XeRx5}VN1y-=NPCh$QXim^+# zS)k`{V}&%Sp?-mWY7&=Ju21Je^u=k>d%ZX2*=!8aV+@kk=X2K@Wz2>2k>9JFZjt2_ zKC)w;p%>ss=GUSpzKDuWB`6K;=P%X9Mb$I+4kuim)$Suqxt%%Lj>6X`_|TY zj6(4S2*_%`L*#@spa(C?2FKl|fBjo;P)c3g8#$Eya$6M8e$P`H?P7%|)2?w5gVs^FyD$a4(P{jHU+b~m6vn9T zRNa;)ON`dp09mFpQ7OyKoD}-io`l1on3y1&57x3sMHsS2z=IAAvCK^k>tv9*e)Bd3@`|@}{ zLJ_4ua-cmjP!+XyEAgTZxbtvyv`8!E)$X9;{baLuh9fxf)cClQd{LK-in_`fIHGMl z_Pa0Waph|4xzx(ZQvMV8;InmxUb{A<5!^jcpr1nvAe6U5${O*~NvSx}e=z-O1{7m8 zU8wWpka=obyYN~qrr;BNeI8;4E?4BIQRX|S+vN2_z~0V55wsSaYxIiEF^-|dC%)uM zCHpXCTe)DGCvVYPVAa=eg!{}pHSgeWH}y3!+*$3Ec=*nE_eVv`2eRx5@@INtb*@ma zlxvo1nyV)r&Zp68{OP;J_BfJE2kgU}K0*{hy=L~#<)bZfrXFF(L32a-I`Q4m{9q{3 z=#bxl4UdP+sVXi#HKUJ)Na*8 zHAzL;3wL{N$fW2?SY@q3jH_B0mRcHe&_@67n0>F7@ZpZue-)8Q?Hvv68pjtdf&$&O zNd^^*1~nCOPZTF6SW?0DzBLUf&-=YGav}!qitlYXm@6@x`W^OZPl$BOBgmi%60uSW z>r+!u7=I@9HYxcX4HB8zI*|>>W7E!U@y9kxi`&A5QA}0pCPawF{Y+H+?1NuRm!5A& z2mx`>)uf|eJ>Ordv{F0OP30eTZ7aM zj-Y12iE-}WY>auw@g6PWSV5J?M zV2Tqt-EKm}Chi)O_N3%RDqT6uqp7i2dry0G`i$^_FqN)3DvU{S(6G*MdeMx;Dh3*v zcfq2{=F5i8O$VQIH!&mFesw!7)tkM(IAQ4Ffn}Sp}ir0eqlN8$z zQ&8rYjsPk#E1Kn7H>dFSH2L8jr{-@HyzI|x43rPyavWzhgsN$s`}P8MoSk(%%DukVf{^l^(D}%3g)c zRl?dN>(p)!C?Xm=#5E zBI#UNZH*=gIq7aqhc-$9eNzH(qPHRW1!I3Bb~mE z>?fFwD{hLFSfzxt9{L$^YnUB6=%{!^K5$x$_*{8Nb;yWl|)y!H5+=cJGzWzCnZrgp#ViZb+kjEn>@iVX)Ob2GcYZT}a*7%Aj*q`|BA9W#CPkB*>>MW%3xj zsL&~_OsmU`wBVttcM46)T&%t=FTX^S0gmzQwC|QS{S0<$2k zI5BKkDy)p>{crh`4HNSzYw1~vnj}tus#6j(|MMhrIRh=G>%2)C8TdVu6p-NWEo?k~~{pzwi+ z6CNL={HD#sv%wTZ#a?;NiI%RrAo#1 zeAR9w+NMf_&DU5=E9(v;12ER?GiIodCix%j8J<=oCP{EeZDdcy*9`C4n~ zm*&d9U7gS=J8)<3hXt_YJ6r5&h@g3S0i^B`X!m8|=oy}QvG z9^=xe6;j``{{Hwbu7!N-@ZrhDAoAWFdKMI}*UIzfVm1u>;KH}q^D7i(PDo``oX%DuuAx9X^84rQ4H1o>Pvh71Dj=Wo5I z4JWE8QIV600MsB>Of|DAArT_bo`L?r;S)!2pq!er5hC#{uT8KRIj9wcO}H)odTQKA zl6G04JsTnchAjxdo6f;Crn+&d&wlFcy++d8+tIOuWW*hn@=(-fVe(R>d^1>e^Vp>Csr>e1m2V;3B1q?>LqQ zaCb8ODW&U3GJ=K&tg_7vSFl;*?p=>lC>ueGV#;>R^)V%OXjGlMJ;bgUm-^gJev`xL z!7A!L9y$l`x*7|(-wa6=__tk06ojbXoWAAD*Mys$02_Z_jjCy+W7RgYU?crz{8UAF z8KR(jX_j2!d!I#Y|Dua)=5qh}2dlbfJF}(fFJ?wh1>Zv-#X8K?E~6b4M&LN_Uwr1b zGY!}|Zi==%x(#ZRqAT3fevLeCRtf9ZWWO*{;Nmi1jFVoV#+X?TUzEIXo%4+JS1OUZ zO&^F#N0Gam9~2?iS^lb;PfMd>sUZ^9DU!yR5cGH>n5>mZU8Ptx90K{CBg?Fx$1s*O zxj;iQn+e(<*!k!CE2bjA8Fz8vV=p|e6rpk{sRN0v7TenWWU#?@3#`sCUcpw`7=LkX zT=hF3VRbjkv|vWxJ<#E^Ex9XgAojv=1L_N6g#}EHFSJ1S zvR`*-z_o8)Ui_0JMh7}saCLNTDg8{}(aS>$?uj}pn=B*&QZk-Er0wb^6G||r{+EzQ zn7Zk%mk%+j5r@i{m9BV5WMFvzw_^)nR(JxV0Y1ZHT-HyBPB%d%E*6P8}e zki@|nJ5eZmQ=^-{!M{YoP+vJzAUsk+8cj01o&#n;GI4MkfDh#H)aw!M<^yPR&m?3o zI%dQ!;Ur~bP_0*+nHa5YXwJZNJeTE|eHyW=q!>pbZcuLL`dT9_Kw@&1DXoP@Xz}~k z*S|Drn(Yt{4#SMB_|K!X_QaKkg#5p?3Cy{!QzqQWALEO=B>TWA zl;ZV;h*!E9fW6!29-oFXsn3DMejzY3!{B$-hZsTWCTbEdrF9-e*t2_Dn5oTean0xq zw!r?Z%DVj>#^rKId`E4xy*(Ys0h3erB6)wQrIX4Z#nMu{wnE>HvnN%7(St0r!)e8u zE~=bqBHx+2^cA4tRvoR<@0N92bw=V^bc3n|T(!w_z=U6R$iaKqGlTvTE(%`dnH<#% zuktcsThILJV>TN`eXGDS{C; zKWROP#C^Ib_cUbn;P*s8%S0jbx+}zK2GAmJsRx9epvi#|pfBO6RcCzdE6(@iMPI4A zAGm=&diR4vl52tGXK@63XUUDc?|~cdiycf zl*F%5C=VMLPLeI=*WPkea>Mk&{@?WV5LFSF<+qZIN^E~wg}0VUf9L;4l4CvP+wXO*BQqr-HFu#^H|1M-efUFKjf#U$f9ry{0{ z8wn4+r?3Z!Oly7(>+$n*tv18I?O*Nci0CDh8-pJ-sEuSbR2joC_;bQign=`M8G$oH zyI=L`dUFyv|Id1`K^l$MT$)?mi~sswiF}0uC}(%ZrgML7#mPak=8!FZLs`rZ3$2c} zf>#$&vnepi_2YuH_lJYz*NuZ!Z@)Ou$O0A;d4aRCH2l|eC2J~ovZ zO8HEk1A|t%vx&JnpP57vMnXIm8l%&>6;L>7*yxiupqy~2qa>!7$C~z19nGt+UeMfE z5zf2dieqrYoPEEFTh0ojCasN8xQ+AqX6FfQ^9si@W{RRwpK~Wd^F^YvM&EBncUHioI|P(A_~=U)qi!B~am_}>pjRL6 z1y1As96E7r_(qzP;IxKN`vz-@j0WK;a7SCsK+Zze650qUbeRl?W-3($N@3uEYDox^ z@k*M>R?6RYPJvULqrka2pyKNQ!7HIqfj7u-umEQPJ8;dsqPkw6Q<~e#dz7DRLRV)A znt2$*B&zUYkfTegTpxSb;8ud>(OV9i-z_R;yvsUw3~ZMg!7TGOX+L9)pT{snX!8;G zIYO%bRYieCv9NNm=5Xp2iW<&{NtvWmq`pDEhuTrx4`7@gJ6U^OdcOsO%7z-?WK8 zT}cgjhd=QEYxH0+fVXcD@PHlT${k9P7iP2X2I?jn-|!;2jICO+p{B-}|C=!R_%+x+ zxrwC=XD>LTFI=$^2ZAm;#2TP9><5^%Cu;k4PiubLIi9^dZ*?puEut;3&&&5c3j>WP z2Q&~b*A7M?&4|=L`&Pg~f}Vz9Em=Er`-eYoZ@fob5XuqZENs2}BVZ_cxS=Q)bT*|W zA(X>kQ6+$$S@A~O@bsUNFjlf}bA*!5@_xe{E2x>UF^n*79|*HbMWi49Kg)!2zt(z3 zsFe&G#Jc8^`5 zV0O<55z4BM$TA3iegJ(>;J+HPhd|4kF0f8`J{_Iu_PRzEISaeT{CC5wC{f)QzdEg| zPiOy#%>cR1%eTrNhxshE>LavaI9aoQXNo~Zr<^<^J7*uvJvw%lXnnRsbvb4f6c4(5 zt52WTcQaal8jBcg2|}6b=nd56(-TWis)l4^)eYtpu_}F9xB-y0bD)+6^XwYCiw>(+ zz4(%CY6r6VF8|W0GPWDkSWGP*XVckeZq~&6!k||w+T1;-+!fX+b@iK*{rixyeh_$f zMuu+q_RZq?h$tR;s?XSHV}1TPLJ^$!KFRLU;5$5?E@_(-f*UiyhtS!D3uB_+XSFvY3QB3t78{p^hvILG3L;AYm&{%BgpjWO8 zP=noCLf9GWhLR~>pZ_vP9EXl$+^!O<(^}Y1AxGCV*d5e;3F7&9jNrh0{o6?S8YDX| z6_7Og`}si8=6=)nQc(9U#;d4oZPI2;{`t;6Ma;M4fB{IU1pfFO;ZU_TI4|sXcAY#- z25$NXz(J?(<2YaI+E~Rj=785_jySotsFZB02qh#6gIZ}{Z-;z``*I`LuN4`M>+jeU9=o%lla^`ldBCCf9jpq&?8eL6E>*FYEaf1M-#|T&xi!YhlRIyu zv!1Dmzw!H2nYx`1sygt8g zuPi^?dODUHs2L$xLbm4tRbhBAUKRhu(10qGs7+{CxL7#IJ8@N$gK98#j%gpEZfG&w zX?Y(OadFajkJ%QhGod)CMTBjjZ)rBb>Wk#YD}V3$sQmWCYS#Mk*pIxnyVJPZG6`%l zH3O26r8Ca3CJ+8UKdjW_z42Y%Hv>t3YW|}&TR*#*_p`x+tD8R}gojE!QP}%Ib(d|l z%2csObxf4-FC@7&%|6d-EePd)ux}TyxE`jw=&XeXfGwZgu6Bmih_xG*? zp-B@&5#KJg09$PGqrny1tAZ z=q|EqeUff|zZI{##%y-Cj;Uiw_bwS;?c0wsco~9sbK;CkyHv(vRIY_72z*kgf@zD2 z_o9VdoUyQGp#NaZwR{BBw19ZS*-SJ5>V7ra4-4U1&s3k*)y0)OSu|chrzFLR558+m zH*V2aA(jw8+3AJK4L^J|Kdrv(+9IVR*S!13BDK!7!PHY7-yeC5xlt>7qu zH+^?%8Y|C3tsY(3kzH49XMmP1b?L`uyrO}A1 zpOjEYXPBP$RwybXLnS^C6JT%8x#w23Zf%!@XT1*J*oV`cxA-^1Q&LBDA;R$Uo;Cw+ z>c#nbI4bn!j-Px*QoT+nOCk0lXNz`zUH%egxg_;zP9oJ4n(k1Wl3oV_RlwN+8Qp}z z&|dQ85$i@O=;vi1&0S62?{5_)*9qGyKtCRco;eEJF$&vMyjM7Jh#m2Fl*ZHnDBN$a-GIqByi8)!_H6i#?c6T0n_R6|aTVM-VcR0F6m=pr1BRw2iG zVa`91_vC}C+(}q68-!juB8ZHD6~WP5JW4h}0|Lb5@qRPw15fee`EyQi1Dp}CIm=0? zL8wnu)ynQDPyuj|t@GTY4+(hERZ0{?4}YR{r!Vz(EqIVvslUZoWf8;?D~sC2%=@1 zm~Sy=ltR~PaY$9Fm;P#r@Ac9+0{ zxygyp<>o)BsIeimlgTmiHIaDAG%TX;5!AtC#PGPmXPSwlA6(Z<2n-5(4XLy$V-+QhWqrqWU6!0m zTqhQ>pqqcprg!(UQ>VI-Cu0yT4#8`2oJ0PlsI0p)ZC)+o;CQL;sK@Vb&1%kCYv5_>b)PHV+#>FI?B551~ z+Ti4VQk55a5BnsqUNT{7ro^f=aDjCnr3Pf3)daU`R5(Ak(`nL44Wh6*8&SMuG z!3R`BEhXBUGu?$V{SiHm+?J-&1)d*|Lq~(~b0`c_hW2c!io*&CmiQRXtpRjmsW z!%coKRXScKk?SyG(S=r5@H#X+X7uetd@MQ~p?0V|5N_EU-vNllXVxIe@ z5t`vIukz*eNLbq5!8vlhe|bjmQ<|lrhw*qNV{_#li|yrXP`6O=-&c$|?ek6X)@xIT z!_c8>pHpN+v}Ti;a?v)1F*yrt#&+tG^X*>>X! zZNh~B3V+;_AtT}8!p+iN%@Uj_4LpshQgEGLK0OgN{d>T>dY?Cptcaj+IDLyY zatOESAOD;Kxt(!s@28Pp*FwSL?%3xIY0gjv#Gm}QzUyCm$b6HMt6KpU7UekDV`bEu z#B___WS@f3SE!T4qlLi0vc_pGNJAMt1GZ6r^X zcauH(HYja-qt#~!cmh96IC^a1)il>dMBYc3yP5%agee;T>c{dTRcS1ZGrDq6R{wr; zbnv6Fy9_!(>wFmx)V$*~w(qk#g7uICBoif0zSf_PY-|r~I5D=bTW#aiIlCv=ANR9b zwwv^!(){K|L{6~O?Z=~pV(0^9B)z&|%wLBtX|r?&EGZzuM>mo z0-Y#qWh@UBl{a5@!hV`S-X_aGOTWs+FSmVvy`r^CM3s|Vgwy>(4Ll+_FEp+-!rK8YP8XyBucvow(HF+2H(Ruj-LU5L|O; z_QuFWc|AIo&`JM%3*-Klhgf&_*cR~IoJ z?eX`1fD@&bWHsce_DEJ3x765v)Q~1H`p4Mi>L7{+5Jm@_91!cXN_gr96+Q=^=6+~M z91&{oi;P%{@;4|Gz!dh8xzbYQXF+^1mpV~1ebcHZV8`cLo3V&_;+;~-8BwQeQQur} z#n}Fi3dZfW_0y;WcreN$Wd<_Xb1S3_HNVj8{&5XlSN9>I`xf z{R}X%=}>FZjnssfkQ&zL3-*jC#`RstQEByjH;q)>4QWbiOdRtXY9H%s=j1w!C3ABEc2jZ|Qz}zM3#C((Q$*J=Yaqc1Wq9JnTGAwi#V(iw_g7DF(*3z=x%+>_Z;(&_YbbC zy=dXB=RhB-(zF%y(9C> z1t6PX^6~QwyoB4^g6~_sfLsJ%qQ|%0X9$I0x!c{CR^KLx!9cvo^oMPI47euO52wIG zQt^S%AX5)=li9BDTBoK8#LEp6I_1=e=d`85-x)}$dt~W)N=jCxZe~I9{o#l4K4vg| zR?=>j8uX&Wxk1k=e1zmuM*&s=Vb9Z34oo{ zLclfl8SX@5KRSdc#c}F*^Z@sMi(%%I~>%Egh&Mw*6KT2UK_EW|oJ$7q!{v5ivDZs8E(It~Q@7iUZv>C1g0!&z6D znDon|?5V|?Q&5H1q4b&W0gWA;RKoMK$GJ=1wN4U?Qdk4=PpRxFDr6o0*dy7$p3CIb zIVqvEJt>PNw-1JQbl<*W_n$*Qpwfw);Zib0@DUqEB-TZA`WJgSNE(gM={e=iSrR8n>{L|YIzG^GOoel72O{XPi-%kektzUtOpn*7}(`jkF9ZexP zhw#x%x$UD6$#4`Kxu+OD4BPVYX%U>XXu~Oimc^AKXPafdxywX)B_Ruh#wLo68S< z|ITaj%SBP00P(6=WeB3I6(w5qEf#xKG6c-)7CL0HErWCtUz!= z!nQmEb8;FDW8TEAT%V$6Opp{VI-VZM9GZb&Zs>P(M8k)ejYMZDJ`^l9(BRUqsppfi zZ1J(Vo>oKG&`|;=qJ7L3gbwi#^ZllD3IH+9|Dx+0gDdHxa2-#qNhZd`*2K1L+qRQ4 z@l0&nwr$(ViJb{fY}|YoRk!Nat?FO9x_5W2A8Yqs>)G$Sp#PY3w4Q)Xd$(k;`C6BM zas1bKpp?HxZkj{BbR8SDLNR{s`RQZq8Ae`Hcl$LhPcJNlsUi?Qa6C3$@^CwFfg}J} zRclRcRP4tBZmTC67dm8(Kft2WRgvls#=fy?>+g|5h zUww@QZ)~I&AUkBfhp4b=p!AkB{@O~z_WX8(Swq2d#v?F{ zz2a)=`E*R1!`U?u9>Z`xOM~PY3RdSj3o2vO#=t06Jy##P79=`~KlN+PwT!|%X?+Q) z?~n5|X_74;HVE)-|J|??@HG5dShz&!7ctNoYwy5!CNtSN36M0rtLGzrx=AQ-e)yGb z^U3#8_#V+n{O+S<=}_k&_&Iw~uu_Had~&{b7ylsiznM%+8xwwq_L39?g0kqNW+;?o+h48(WNnSs3+g?2!Xw6?D8Cq6@h<-z}rWQz1=WgnkS zZ?v{%z9WimczE8OB^=J|k4@#>>eZEfA(<%==$mo|PS)?^loK)|Hc`k7oC zPyd^nC0Jmj#=Bg{febl^6~}s6NmliANMl##vMU_>k3|x4@34673-g82QoxV8S8J^* z4IM=tAaH8--;x8z&H++}zEAn4J5^kBgXp@yLXv|dU?Y1iIVvhJps3Og1I)PZ)2i=W zM%rf4K6$Fc8A9(A2A6->m4!!#Ok_)68zPiQFsugR>W@vJ1Xy9;2=SdZTNwNs@}a8d zz8Z4WwX&dyk4jcy^X)U+1)!nZ*Tv0^`SaYP=Zw0ttiga<^5CSrVcXEpU@q4vz+q~q z@EOfw{g0ToDeh$T@+6Mn$kLG=`r$`IZ66$YsMT)!_0p63g|&rO=rcinR*B8-RJq;%PXA&}FY z7bF`?!*3;2hI;LP#4M00gktNLBy1{qOXCW>oj(vRG!)laYMs1YeApk*bBgJfpb9 zHJ53|N3>kwnnV72=nO?2$@Z55n(JSaE1YXWj>?2j5T@`-3he^jhq+cSz~XEWqMB7- zxH>3~ewXla=|?dx4M}KPh755V>r%VvTs}x_>Ff@L4Q_H&&366Bl6@XN0*hu_=9nGd z(NYPiH?y0YQwPKj#IkKsuXqyC#0DtJ+Wk1a2r0O+Ar88Fh()ZRj}AT*&j41sujoph zX47l5$SiF*%U!ljh6WhWJCI;CDGft`3LLu;{^;37%w#C1D>hi`-mF>ANQYZ@P7aPw zEsJ%bxin1-vtijbz{_Jzvdu`7fwK2~gsLBkcDQ~bbpaOHl+Ub5z?@u-7y6~vRmHwx zf0q-MIU=K?>=@|3&~GJh@%;=5(w1LJu-Jr1tt0Vkq-d|T+BL+(LDoUEPSj-*ccG^~ zeK6W}XWWS9>i+Ei+A3h@l%G&A55&9AdtGqQ<0CGOlPF>zW+%?IX;-?Y6aBD%?7v9e zw?lZeZUR_eoSxr1wiiXrlyDC4ubWF|Z4ug1SqP*g+(y*@q0&l**~b&U>*&}7QrZN1 z9liM+@$X;$qKHY2^FL+Rc1ycG93JSGlHS^Hw${mctM{nvfuXSXKgt20a5*yWAkT(i zLi(j{PH3XEWdZsw*5v5WsWF^^xRftfJ~@(ZdIPBM+_)N}H!-kjG5f*Z*wLCQd#N4q zllt?SapaaId{0SjBGD+70!_s5uT+)s;?g%bMJLX}?HIjI7c^1gZY+%fB~PMd3H@jzN)4@xzb7SsJSgbe7wP zFHJ<337d%+x0R!_oOQiDBe(Zt=>y2ZD824&NV|0#7nW5{PBai1l%33dO|KjKD1JV(5CxCXv!MoyQiex7l8ET%k|Lgos1dFe2crSFFAv$<;M{2jUlskodhiH)&7 zqH?`Eq16p`U!obs=oW^IZ@nZcW2R%pV$sRBY_qVSs`fhXE}MOQ`;~NZ6A;TWzb@D6 zuVF6_BD&&d_~*ei)O+)^TR#(Cmtssdkg{lm;bK|yIJcO$Sex*Vy&Z-$h!t_1U8!N- zREa!AC`1(?wTF9BVo)-YU!j-b&T~p*@Nt%Ja!gL$rNwRa5TED)1G5_@tjyKFssg^p zYyl)o$Ti?{aPc|1r%qVh1yFN~i>`1uI+O!XGXR3+36zRjgQH0AnPt&$tK_|$bgJ`> z%M@Pr%4JJOWCmrI(P7Ah;s4q>UCy2@TkgG72xj1m1+UBD=Eo?0-3Vm8sue!!7#cWj$BCaA}yJ1bSOKJ@U*1%~#o-%3%L;6~p& zEfRvGo)=_?^dAn(K2ONFW3 z*)>`_99C)bDEmk5Cre`O<(u`tzpJr_&IaktLox%QbAbFB1mjeE#?FxQ5L234BP9uf z6Jv(?+T-kT+r=I@p*w`;OIXy)--b>UMw|{>*c4=uHYURR39(TKL(*tTGgUs};nyJ{ zi(T#9XFjhP6}mv#_?2V3CvE<$VP01)SB3Txb+i0tW@hm<=d74)^y?RRFRHxe7gXsl zW{)&vUWsB^vBH(%kE+cS@`={3?Rm+EU1&fr#HZA~HJGLs9s3tFE!vT_j0?3nK%)nvfzPuuT zhR%pWC&e(?blwoCsmnGiAVL~7x5kyxTaA}O3oPRtQg||@L#Ge&`BxrJ(I>Q~^mQAy( z(&_<$B0&c&bxkaV#|e@TTqMQI36d5O%8Y2Hzo){M@AnHwO05$lhJ+YU0((c#s)O`Y zCES24$-Z*buIRS9rHA^41C)d6M~gsJ#vD?2L_srx3$rxlZ77xKVF+$kSP&R#`11#` zJzpuuuV}5qjuZrENM->4z~z=e*F^RFCfzXeZ8u=V{gV6bOVs$#_Ct)PdE%?j8g2Kp zpT1b5wYAeSt^g>iU*Fc;JRQk)3rt7-;F5e9mPDopg$m;+{+hu1RM1wRy*TWNI` zkRx;@UoQ+beQs$jaZ51wa&=YChhTBi7+F+KvFHQii_25n(2_(5T$X{oNx{9li>*EmXbEj_`RhG1*!razV8xD4%NiW{r9_x^=sQbjLPnJ>JkI* zlP#()z5c!LG=Oyacg8T>c!hCxZ!n1oD(zwov*aXX|4kYpRgjs~dqwx06?yRPpAqk@ zpl;rl8X|W~3VK41J?dBco5`h`IbmvVGa%D30~HKnc75utbfU=zG^BEUdtPH*>9k>OVh@x*-N7!>u2 z=O@TB)e|Om@6U1UmHUF$sn4U-6&2?+2}bzP`_ebZLtES3JoQ?N+5=pBD#SNI`JsMy zf(o$YoRt4rOU-T{fdPA(gO&0Lq2KMZU0aq->`iHktifTobCj zc2j?L1ptJS3p08iu8rL6_z7xz?vXLe3zq{`bD)&UDS-{QcSR=>9z^$k=K=`_^|=o0LH7KQ zZoJw;dxJ`aCo-z*%kX32B%RtTeKQ5+3)#fw(bGi@M=(0bWz5Y1Oe{=Qw*p4%v)4=`I>1|1NUEgqpB~&^L&F3B4R=F# zJ6Y+;wj%k>XH#>W{jA^CT|X32M^aV8W`|B}nzuz9T2q=k5j`nzGdXw8%))LCP|H!2 zaL|@Vmn(qy&BkXk1K%{JNMAoCFQ!Z3fNpYH;TUVz`eT6n+{SzM<)HAd7Qo~^JwB0z|^71zcMZ3aYpmz>W<^g0llfJwS~?4;sdc-OD_0#?4U0yAwaR}dpfg9Ymk)2)*kaoa8L zC%1;s?WKOaX;MfmP{!Pq^z+nj`}e3pzXDw*Z)50-=!3VtS_2X%Gro{KkZh)F+Wf`+ z{WP6&{Iyc{F)hTE(&jbWrGbK9<7gyPQF5Ts7IL3#kVXMQa-#M?AWc;G5V&cSLtt|y zT0eJIJ^h?~;K7Qz0_zWJ707c$O}+`PbL2GRRa7kj*Os$SmT9m1!4FGlbwEz#mUG|b z0UvJHvdGR2;{4QMu=XpUGsK2=7J2|AzMIA6OGpq>P*r%=4u$vwYt+_GC=vNqKTGQWt0V?>3O0qw-?C^VFpLzza)Lw}jf zGh0AR7|}>37h9m{1%{M>%eb@ znz63;RS&VVLZnIP71gj|%)|1igR^QWYz0p>Jqidcg75gW$eqj3N5K|^+zrU}f;Q#MqK`&FO%tZy!iS6SGy2uS z)x}i`{h1BBY+&>O*qS&nwz-Sb?SX{rFiPrHh_y@?h-t z)WNc=1@m?c_%?KlmShD!H)6WqC@*)=&N-#`a0E7`lQZieyFoAmc}|*v$v+Cks)!df zKTPrcT&C|f>(>?CRp<8eM$mFD+V7^@$KPk<9Rl#W+n8RUe#x)_w;q=_TR-xars?@e zs>g$uhdnPrHj{Nxi(GBWvPi69(c&(;NLTa=QVX#gK)ML>Y*WCT+G=lv`ShH5si)?W z4y;XL8LsQ7XhFiV97Zv#5N-uI1A#)AU{j#c?$Tx+H}yIML;iLAtGF5=X=}esjsd(X zC^G;BzP!pYIgRoZA`h%0wbI`6_h#;xd(7l0#p{V4gs*D}pe4^G9~? zmJLgtXq;ZK+oA0!+j?%N`xB`d7XIy#(Y>`&T8I)*vf8s??BEtx6t7JtRHQ1b-UC*X zhv%<9FLotx>Kk0hyw+4kCDLyiM><1KYQruU01Q8IEjwi-PuXLbXQH-@&Xl3ygT%0% zUeSXX`_l5p348CC*K`mH6{854$qPYi7ACg}PEn|7IkjS65bDNC`vhD)!D%+f@01K6 zEj%yZX+C|I=uoA!20caS9xtLwe7!Y4ef%4}Nl$AKFR1VUV_>;hUL zK`d+4v)}dnZ1RC_EC|$4>SlCrLn$-9kSzQGyWE0Y%k|W3v9BtF!xrjzN}R6u`OFSR z0=mHOeM5f60Iajql$lV45xFP~bn|a5*{{#75SYpDxFt1+*n88FuZMU1 zRAlZ{e=LivA=Jf5gG~}df-^pdwD1_o!uxm}utQfev|8z^wo~V6>z}G-M=?UTc}(|4 z2-|z)Ck8>kEWR(T`v4$=B!${wwyBa`_N$Ph=%*|C3z(@vcN!w97N@vGR4tK(g|&Uj zi`hb5VLdNz4@YT)ww>*nkE8`;7kVszELt~5AhGz%>sj(_a!DJQC%mCJ_7~NpIeT-U}J-&I4 zKib>T$uZSR1t~YHMgZ%&F@A4zK@!EjuIEsRk3r^e`&!WbZosXA`=f8h5>%%Rqz{dc zM1(efaDNKr7v-914Eobhvd6A#Zlh*FtnH^kV_ zG%ZgzAj4Ee6ZaZdPw@aik^*`OUDSe)$yrIfxao1qg#VaCDN^g41|5-KF!B$|r*b_0 zg*XTi*;T@k{b^zwe89yN|Ap0*9`ac1q-7-^R4L?nEdXbeEIuM7Ygv3I<7knyO=V` zx|LO}6)BcqyoYcghr`tam^lO2P93PCGm<#b2|GlZupD|$cjstdVM5_e5S5s%mZYhw zTfC?1$lVLGbfYEMayLKPK@@qAw5R7a8HMsx-cLt8p&4s;7=;DC`SrOWLL8iG@VD@r zL=>(Do5KxjZ(+v)>j0rt_}6mn)#2LoEOg9eGdE59hK*Cl5e}9m`F*{owT|+6FIa)=9bfb3H9rn}K8CN)5H*!BKf4}} z9Di4_6s_zGAEbxQSFQ9|99l1r7^lISa+zn)1S=e)7)P}01VG8^{)v?Q5CZQg&Bv^% zj8hsF-;YSFX$vH7QrEVj^<6_*eGAr6tm)w~l(|WKk$#pEvkS(YXSqaV(1$nt%7-cY zPxfV_@F%nizvOI+ZcwQ^DAb3jZVfDTC+mzTD3dBo=bs7cf|DTQd9f!l2JvcSuLA}7 zTe~P-yc>Oz0U0T(D(9xicT`w9jc1!`r-TCGipRb2L4;Kp2;&-8c?rwKI~7K{$`r04 z-)yE>n3G+oaxZtvRCPyDbk_{ItSHKc|FMJd3RxJkNE{Yi>tB4caU!W&dAa0A+s&KS z(S!H=4H0NOpNjv@ox#QgUjVG~@Gp~Y+55ncCE@K~+sZ|Z+88HXqk4{ULGTDhw#$y!^H^iuADy#pEGKg9m#gD6CNoPGGXcPLIqN_+75@s093QlCH4Irr&Abf7 z>K2O;a#$Nt!yEty6Fxi;)avSGnqz5VAfzRlFfC1G7S)bcsy?l%=|tH>&mb(-dHMg^ z?=a#XU{)_d{9Y-uvF}xOIM;4ke%%!ooh&;itSvj)mHEk-6Q$^l_jLK;%N>>FGQ_x8 zfKIsCQ);nN%sy2`dX737<+}F>9ZRMKW0q}C2IT@S0uIylpyQM%xoD*-bv5AAq^l;m zOoC8M9X+nT*G-y_5!6iD6HT9gnRW_lP>XUOyh*YPq6Rd4_b(lvdUQ7wd9s-ZhfKvL z<{u8UV=OcN>%AwwC((V8IqAq@x>SD;0fq>$wGfG(tpCfy_jgw%SeLlUUs-~RF`J*h zRKHV7;ah+{4c>bSP*kV^HjUydA(xHmXGP8e^*qDwa-JQy!KN{XxPXo;2{t=B+1X|$f6~yS)7Wxv|t^5VFG^`DI zi&>6WTd~@7s#IU|#~RULsL%?BMpm4rgBK`AW<%QdO{K}4-g5Eu0Q}oq~!cTq+H+ zH&%6VH+s9_%g7J}C8wFL%6|Zsq3IK7#e&goe+ZG~B_=k4n*`=NX_}Fw%-KEeT&lCE zt4%cvKCT+3mrPU?&30sbeEGg(Qg@_=v2)99rS~->}N{T*R!!)Aay-t$Xl~BPrbsA3*pqOpRHZBoBsCtxE=!)r2g8^Wu!q<%_|}l zwO$?PH}W3Xk=QiOue@(Yvr|dYbA_excY!vJ*3jKUWaTwm6o$q-t!Ana(gUK*v$>gZ zy6yR0FS+kVYuuy#WO;zr>-k2^H-JI7fbH?uN(V^gMhkQqFnBkr`KZ+ZtU|sH zZ0XQ+y$tC8pOFfI^ChC?e|7Qya)tW6Doj-{&E(jYFb;{PiH;g-mCDX--Pb(Fqo-LT zCe5k+b|_bw%?>8AJ)hIU zQD>{|Ooav$bZ4Jb(~|DRz z=;7U=0+xg!kxbpkXY;vZGaX164X({pKu8)YmRDiNSf}}@-S}0eWMiqZWHbrn_H>o(R-p z3y9*d%T2JLTRE}4ennf%T3sgav_Mn~{IN_$!!jy5z`|eZqS)S@_-6OD#HL+9$xuiI z)pR-~S&MsakemfX=QT1DcBc3|Fc7QzP9bXr#}?lKx#R zxH6opt2j7>I&V@gE;JB%SQfdOYU9pJ1N2Cns$obi>NcIcU8`6}3OP9fpovQ7o19w< z-;jorjjuC)=#yt#l9sU?^V(aekp&6vE2oV7t&XG9EWM%Tm@_^~r4G@F%S84SD1Q0w zz*OJiz)35ngES_1bvv2?VO_PQK`!D&o!agK!;jyU*zi3R90++gKb6@%kmYS*34p4@ z6Eq26DdfAV`x6^^#ZvzUA5}B!DQXF|CS!C?MY_{BTWYkZ8G4^jd?#KsC^ov4e5LGL z`4x?zK=IR%+6PSB804tj8Lg}$hIfT$52+Roo?0|@@l!z^H5~drH-v;f$Lr-Up6!?@*L%@uy%vrQVja8G4W#%qThmThTb>NWT_;02*}kn0f}QAn375f z*U06!GTuZF4OWyRdIX;hKnOb*sQv@uD@)$jjhV+ugcQvh= z-w1yE+6Zo#@Mw9rOlB@EV9_ENzBlCq@c5td>gF2U8FnxgJbB?^?##c&2aeV`tK%m^ z>8ai;8H!;P>?NdIAo=0a$w2p|71KraJ?Byyr0oNbjaYqjUSNJYWA2?t&K5}kkwqos z+^9IUVcqAwlfifZiaFI19?33qvybWa5*;|%=LfI%y*m+6m+lQ&48sJS@U2o`jvv-n z6T}3TRI}!}ubCo>OO8Iv{4QQf79jgDQUtO)rv|=}sN&^ze$w7T$Gci*04vzrG5c2) zq=7xtRm8#v9yhU<7BhT5p>p?g znx**R)T8O$(&vi25lpOl=sACIIpKnx?(f2<2hgoeKvJx}XT>dNG!oDw*1JUsYZz9m z#b+Urd?7+$?K`+1Ji;a6nbW2Ze|q8VbcKf0JL;q+S*oT_rf%F!eYdO>p^9)(c<;&k zq_qCX#m58a8B#nZSCDUt^w(WlEom9%e%+h)?KDjA$$DXK9;4tWZs^_(=o7uLf2Y-5 z@G2OyZK0T1&jW>MH@0NPVi+eL7$wxz))-6Lv?OE{R&WQlfLwOo7>dAtdvcW2O6eR= za9?{<>XmBGU9+rErGmLy25`7yC(|0_&VS$53w8nA?7msKqvhguY9*q!8l22e*?P-c zKZTgr8?1)x&f@YraMWy2$)s4{>XdF^B-14!$h)V=PI9hQ}7wDEXch%rV}0Q;@sov^-$sJ@c2#5d0l@_vg+qkj%9BHZ5SI2qj8krXM|?sj?XbnTp7Qq<;ST?#|nM! ztW}`bqpT^CgfuU|(oQ)PJ%=zj%6emAjF=T%A)!*S3Q`1E#R@f_(mrVH8={xDZHfax z->i`oQnpYC`j#7WWdjRkp?yRykO@_bZH7@W^z^E(o7EMBmVUpn>nI^IYtFba{oU=! z;L6u5=z$|p3MsoIBy$T)hhtwYy~KnBvCBK$5&q#!~jSpbItYi!#v(U>{_5VL;d5vtIl8E8s8n{@*!D(s8|ld zZbJ_II$lP1Km>sz;u%yW9EUHRz$3zo#!O+D;DsBIt2H}RI=nzE0cn;cqtcH7LTlYk}^Ff#NJ!_IK+%l8;$$GYL>A0TI*`Ju7Lq ze>f#eFH~fXI9zLt*xcNmWbyJDQ#vqwuBnUjOY=OQ&pz7i0gf0L+?NcwP(HJ>wzCJ| zB?V&V8exB4ym3^t95;N@)>=9&=U86sU)xQuf70jVrYp(NRCXlv@?iByK7 zWi_MZxT2}q6|lmQ@;E%9L;Hm+*LuAI8faO3LU|Ufp1e-GJ-?J1cg2A&np-CH3nbmv z)=mHQI2$Se8A^NmQNK3Lpo#qLLd9{1xwZ36xa_o#5;7)k8OJxNY0o@NzAQ%Mu2sRq_wXmIma-$p z&tH5jU|N%#a7tOnCkVC!YwgHK4W%GN4p)DdiaDDBaF1%;59%^2%y_ty9nU)10r%H8 zM^phZMezb+7VFG>Oj8NBhxiK`Zob?4w`2q%68C@j|I}^rN-eyP+J{q~kbB?r`-5$b zd~-=;Ran2j0b?jB*_rZ+t(r8ktLpC2cuu)CmvwM(HoH^uB^4NEPwsa{EO;6LI zpM$(0nL%1UAe`x)iHY0VF=D|uXE1O3CDPYL5dFy2|J)e!NuZhXJ>g3Ns?SVXOTD;G zi+kLF0GF|;jCwUbf8EE}$-kXBWjOY#sG#B&nDO($B@>NGPycx6xxR_B>|x1F8pIyo z5mT;h8uz?CcRe@~^`JOAL)2Gy56dSdJ_+6#bNvVtmthm}5kYS>xT((2MvW7d2 zom7#ZA4LJ*Q-J;?FFGuvk%DzQpKuKrzUw+IoTF-*AqiVY*$srUVZ8KzeK0XD;}EzZ zC_#SVcnt2oWQ^t`xdUC|V5c)KTs-f={&Q?XZV7}9gHKuXziI*=wIE)X|Kz1JdWNS~))k1Ci$NCVpJ$$Csz98|; zD(wN+;_)-nXKd2h#YarEIZ#Y@eK>t5169*n@(QCf&Nn09o%-Yx)11SV#kb8^AjTeL zq>LRtzM0PA*(2BSu-6LX0xb#U zZa7M27rWd9sHLbRLDEn^m?Gfa_KJ4AwB_6_oB_wKUybH}7+X|99EkE)tKaw&-YBzl z?=F7&r4%PYl7CS-lSyB2j%do$*TVq48|M`BE(%5t3R$kemz;jgqy#?MbEKIqu}i++ z_stGB<{XD_xsXKreVbyakZnTb^w?&TQaX6g59L!f>wfR9u^m2UW(s(IA3&i4ItSbM z=SPmUbroR{GbIm3NYHUGk)1pR_n43D_^Jcz6%c-%UdsBD6C^5yB1_k}^9VS(u6FZ3 zDcZm;tJmU7E!Xk9;FpgqlV0K~vNA;}w|?g(Y4bsT;J1L%Xl&#;8~*msiL#5mS;B>< zGsMT*0p#Xs?-G3$MY$4O80sq~Lfilo+R+%vGY+#H~)$z zw+;5l>o8hOud-@ZJD2na5+uN&<9C2eLf-1ZqzoK!CaM-)HxfbXaal)BOZm~KRYC0f zfgy@KtcQkhbRKhy1EyNzUJ@INFxN`z?C_x|p+#@#@;bc1<;2tqdD7a_RJec{UAw47 zKUCoMCvVmP;%9firq!>YX#|66Q8(aavy(Aj9bIr#P1uXqHp z{#PnqDLfn9_)48d7QO*cE8d_igpjsw%AC=4)zth3i>Ll|>PDuiiF|_hHQE_)E)9df zDhENg+SZr+PZpZs+AXq`3q|7ZM9} zXN3ri#uf;Yo#UTaylyvr&L;NfOVf928W=C)MjRfmC#9HTZ>*f zS(%3&uVInNzYCHAaM@Jkl&E3mC#<7@+Ut`!YBI5D!A*Kmra!Gy$oIE|Y$+%s0^aqo zA(h}M`k3a#RcJ7Va#J76=rcFSH@8+N6l597LVvZy--Gn@V{e2e6pvo9 zN?{EO=9pexm;l2QrBVb**!2tvLtQ<@73H|cG2Yo{p!&6lU zoJBW5sXj$kD!doQ-*v)bfyUshS7T|TnR7qAC0Vlb1nbNSJ&!edh&Qipypbrt*5|0? zGJAh(#O^+Y!()d`D)&J-s}+f!9=I6dA|zg;U`zfdAsZy~dIwQ&<95@OAS_YdqFzQ} zBB((s1Q5ee6oH&Gfqe>&*_lg}i43F+kqWdna-G{;wysJf+c%C1WD(6(LkkpCNoewh zo8FZd!N;M}?1YVX%q3DRgA{>|DuY@KU-R|lMN8xjl7^zas50xOXa+KqLaJ0Nj2?8+-wHXZH$W(x z9py$cNkbCI$R=s^idEA%??XQ47Fhg!%N5gBM4tpA+H1W|hYm2C-P+zcATkq}J>qYS z0Jh~u6xF%V>cgc~g^)1P{G||2$^-Y5TuLjIG)*)^r70kCWq-vLQbDJl8h_!{Or~PM z_7ahuQ}LoV*$z#DC^z>x0Y-*TH}xAHZjAY3UqYypPv1{}n$ho!7cBe=jj_KqEOw36 z2FDLLu^b5MP4RFDyQAN1scg9|SFfn+eP@M}F3IFq zWX8=Zk7Ni9*Ghvwl8}T2#E4$`(U+>FjAcO5L)b5*JY_(#l1DW}$VM_v@L};{&h);= zFYAe5B!%p|p2GiRDsr5EU|Oq}9B5Bb%7mmfMoP2P2qa=JUid|9Y1RYm6BhQSA{Bz! z(LIU^)H2HBbUE%P@i^G)++mg8J-EQ@K{;v4R_51|5_7=D?_IfC;c&au^863zdvDkM!fxP~ zQPVx8v3>OaA0B#QM-gytc7v1Fkl|!^_$Bco(-hDbJbHXGni-%x^hFHU|@|x;xgyy721` z<9_9U@9;J@*``y$JLJ0v^H4M#-*n4|_X+pp^tctAJxG=C>8Mg5-Fju9*~cZ8>ip}& z>VVHA#oc<}fq7bc@8`}Vy784*N&rwEmwd0eVQHE=dW8fdcvyrge(0(th;Qx|Q2_Z{ z{=!CDb2Go4P$6%r~?m;MLjrIp%Z|L;?EvC^$VNqVW58&-vu+(rtTf`FhzxM~-~^_3O+hbK9G- z_hW!pkWM^|JhkMKgXA?>kW9&kt17jnE(P%Y`mXJB>eQ{)|*uj zNORp^sG*Sad$~7V7s&EIX`n{&e+U~J$noP9YM3cTcv-VZ(D!?IE}Y4cD|>IKq0oI; zOZ+YHdUki?u#o)u@qFhDp_ub-@^XnGCXj=CbsO_v$cGMYBE~!fKAq=pj#Wb6_Zr4F z83ocEPf`GxzJQa77)pA;^YPe$FPB~)qd->oYYbe;+oMFn7iwaBbETo;`|%GbRnz?f z3>NLlX1~8z9rS&FJ^hMp`}I8$CF#q{{%OYoxc~bp6noEyaleFt0`ha0FWctA^*3ctA^19+cX?x#NLz!^< zNKN$qULYXHD3Gl$&;9(k?Z?{nwt08+xG-@V=HKJY^**aA`}Q7TRnwi>{dzdQc?#B( z{qPLP7}I@!2cDvS@N4w}-kj#6K*hHAn-&RdFVT(NAgsKGM`^YVXekt{_Kw782O?Iu ze7;>>OLG*tKuh^Z!*Ip~iY-ck3Df;7rP79|YNyGP(7hqyUds4wUsp1`zoD*H`42@( z%Z=Cl#n=7ARCZBxL~L-AoUZr|T+kWwX|sUXpZHPk(~bVy{!2O5wy#bxwW6o-<0Mcs z6^0Znskh787HU!Bs_G%`#Ng`{YRo2JBx5_K^SV|ejeIAt2p3tBpgGmCBG?+Yhfpu^ z5)>8*l%U9bisF#CwP&)(`~p_-L)6Hv)W1$t73`}gdT6a*6)>+_M(MHJg&{OB?;gNr z&(nut@ss_jp7tUbCqc;G-r+>^o}NyhUBN&JZT#|nuQhpaN9Ci})1xD9k;6r0uvc16 zVCSm=Ow8wbK4Z-6y{}Tv&Z`9Fna|uwVc;>))%`Cf<@O5;qPP6v2?OKJsUvJrXoDBd zbfN2amvjf8W>9vKaY}T!CUUB;o;9G&UgORnwR8eNpOX-posrVOE$gOW8G$l|pnh+j zeB`$zqkXZQ)b!+s|2EJ4V_V)CSYzJUqhj0=P)MXvO$F`F$BEO$hn7jg6HTchibrxv zFUbEzhP+RvE^65()4Hk-TV)`KElI|ZIJb@OHl{%7M!vaafQ1=}}-wI6Z1gs{$^IxiLURP)$nii)}319ugG$@`HgQV-v zBn8Zcw0kvdG6=;y6ogForyk%EAc;zc`em2i971<}lIX_Ba$1Pdt}rCDt=IVB0H1}= zI~3t0G-&E*%JmLj5pzxL;p+JAkKV*HxY+`lhLN~MjZ`R7-foh}8;3^Cai^t7(mkC{ z9-kLL2~ohRi@xCMsa{roy;C%I)uM1M-Dh14`A3BPFa1GH5KE0ZMGZhsc?eem4Nhr> zT9WiF1(R693@ZhiLc)xoq=>)7OcYD(C|PVzTx@GtY@I@Exmaxe$Ixx^5J){-Nlpf? zdhs$tonE)%du!#l_Dbeq{!xeO+5!P)7B9l-*5yF++LUp*b81-S85HUz6-~O;g%( z-%q?uNNS-B9JoDa5s=y6VJkuf^1)gAL$8CMx2EWb&gEkoi_t=GDPv8)Rz?f>qte-z z>VLeKs3hvU*IRDr!U)tjHy~ztVkB^F5aH8ruF|zOKUntL;PJ32VI!R^&#S{N30YFn z$+suCY)}A~g|K!xp~3Num7(QhD?;N=0D(JprPaEHv$mRBVL#8p za6h?g0&~lhO@a}ffp(=$dlc(1^)cTlAo9GlMb>dsDZ;ucMf76XFlls##|xI_v(f9x%pYR*epdtA&Om;DsE)KggaBf zICp|Y8RXO!rk7%pJd_(Jy=aSqDFitx-%QB#d8Ef~U#9!zH9$Ykd6 ztW32`z+YhGX)o+xvf~~1>eT4S!Rd4$&4NOa`?hLEVqIp}MIOIc5aXg+!(I2CSR6pe zzuaLC`s~;UT0%N`Fj@1px%$SJV1LAsat@?Lm#_c!L$ru;qXlw~%soS5I!KD^;T_+_ zaEH5z($kA=YHllR=j@>PH+6%$mW`KU=o_eK6MYBv>J?h#1^m+$w8wW`2(3L2ayRi4 zsg$a0G83~oC6fjcS;cuZkk%wYRmgXz!@~9%hDC$x785ntxr3r||5-ubuQ)Fr8w0L& zR6Jz+EGGHYYgdIFsl}%`Rf4h(U9aOQ4qn_(_ZiO$M{(lUAqYv&cqo4}o-xis93RYA zu2P-SJ>)Zs{J7-t`a}t^1Z{!-Fl9MTp9Kb`f1igD%V5Y!-fVps{<$nhh(PnL&N4{hJQ!-lk}AyJgAGN}f&m1I#4R_m6HSeeXNZ$Y_O34!Fb~=4Lq7X9N=}$PZ)5@eu$4uaMk%}O(lLs> z7{BS=Wok_RCKNs9I#!k~oJikkY4Tu^w$o{ea0<>NCy89rD#N${9f%v&l=Ym-Y<#8N zgp276u{l%17$5XmLggIn$b4h;e(X06nYY;=BK!zPd{Iju3H*~d8wuArW<2kFSbfh@ zLBo6h2F@ZJQtIjHt1AC*+Az~UR^|Ec4T6C{p(yhC^_&LzTCZrB@gAaDy0RSG2J>hp z?3q?M@EUDc&9vAb445N?`ej%DS|sAtQYlpk`EFE=-;~ks1nzYd#WKbg7G`J@6$1My z%4N&xf71oEG}IGmWEn8#V;Js(kp3Ew&61Nj(7;6`TB5qF0iWRnBh87UDHqvG8x>8V z#ufGi9qab)6nPr{poZ8)IO64`vjE;M??jS$NA*o#%ax-X6X;MFhF1HvDh^rXjJeft z`(~@PG1imV;Ft6X|+!afmqb-G?hx|u1tlA8{NbxE6X zl88$y3{~Zw7GNb4X~Pn+q4wQcmK(x6VJy16CkLmxOyWq5TibiC5XZx8CJTXD(URdKs7bSl>kE07#Iu*cFQ5d9ZRK727;Vd-z%(uu4ja&^!L)hXs;u}({DK$jEmiowbEVn8eCr388<^tI2pM#4&hEyV*n`u);(AKi8gyT2BvGfWfw^pi)L5iiog&d|P^y1?D z4W?D(PUW3vmM(`g&&5tH^eEKKuJbgHv?j6(bQ)n}J*#rbP_D*r%MdXG#~hE!uPYN9 zJ{Fl+YO$!iyjYJ$w=GUVsRE}5{BWe&NQ94))ZFXK`d&%cYgNGqIV3Iw3u*?kS<1J_ zm?f^V;2if!`c$XYhWZk&m!OXFM`N>*tnGsz^1!cMWg8}>SuT3oXlGWk{LF1ni8jL; zM)thtie`KdmNqxa@?L~bqqJJYH{yN_(33AR3yO#D#B0Qf(@1JkHetg+ z&_Pf+H$F`SYN#dRX8zRvS(Jxpp=4KezAr#QesDJ1>XNzglB9%eq&mL>Qu_~FO-+?t zZ3KqG=XnN4?ZP+(yc(PiU_j4l7%6x!11B1)XsV^ICzoU_H>6cd)h9K*H3}sQ%QBMc zpu9k=0L#ll4L_PtL7_Ltj0lS@ddiz2fP%$Sgta5(hjKM7D1-97mD}ywNiKA1nNAbB#7(1d6DOxC+Zurf+ykht3Z@nh!U2nf zgs|`p2P#L|He=2DbYi)}(wRW3i1CI}rWm3v?;rM?@wZ<3_Lyqj%|H5L5R+6YU}z-K_lA(&^u+mbR_wQaIF4N=L9=X7vA|bTlS~9!E&#VoaLI_rmux z(<0EbokbO3BP8Gg0ZH^Y32TW{`E?QHdiQ0u`q$)|2e@BUN`c7W+N=%7R~TX))ohy- zwW#!$fC8`78C`Xpna)o`#1cWJ6IjC7Htt18Zi zT5kVnEP_g@9B8*-T9t{nkrltE1?oj3_w>-XW_@_H#o7z790|ud@J+>R2@BjYeB)^+ zfMK>?RBJt=A#b2Z`N3{+?m$D_qpe%MpPUwec=E{^ct5axu*WR*(AJoH5&HIgDSmyv zNTiL49u=%T6ARsO&990H;V&5#Af;irL*n1@IVWxYzKBea=O_7@XRoZWj!eR(9N#ih zJ(hQ4+(0k*IW}cp zOxB{3_%G?Z?k^DPaJ8aH4s|T3&Gdgl&FQWNCKge^EtTkW%T57@2VbkTS|2UX1)V|% zSVv&r1{P$%4?9-wn55ozHp|T=e{9$Yx{Zc%@<9xY^*`D!u~gsRv{=QHo=K7j09=D)nQnGeqRzJN-9dFW@MWt ze#LGCZq=w7@Ig$ZaEt;V_O(^iQ2TJ9u5!^-^1V*SV_c4AGk4@cS>PfcLrlp-V3`nT zAy5-5Ty?_D-_O}x%ycnEg;dlyW530U>>-cv-U{gw=yfR9T` zbE#8raj;DdbFzbn!0;_bWV0{Q)iy(O_apw+7xfSn zXza^75o3Bx$;}f`Q1dWa$V%Zo{cQ=hpT+9Ei+eT8x}`z)Fx#+#tpC|Aab2gO_AjhN zSs-RZF|qcc!iCD_a&6*KM)-IkdA|0Kqu$(stNyXR%^-5S#@g-*k2D|DOwD~_K-^Ec z5zQ6^eq-r&?c|+60x_!Ruq1WPR`nz&;PiF^XJ={mIce($GTg}A*B`?+HklkN5+&`V zI3295jfZLNC{7Icr70R6Cz>>*9c()Ox?OkHA{jVDT~aV3e<;+AG6*|g12$K!af-FF z4xg3nmVA0dVoaLFyx>omsPSZQcix69M~8ab`ah8P=rgRc} za<6YD_(;+u6PU2tRI)8&Y>L9od7@;yYxayT^p>8~V2#wa!h!X$_9+_7_uoZ>+U|n| z5*Pj-B66>J=688Tz71A`){jf!6>^}~p9mA4-0dxGdaee?iC~eSe>+f~B-E>P`y6IR z6YU0ewJp(5;By-W(gp=oODV4)fHI}?-m(K|?(Z#&BJ0_A_D>A$U4X3K=X>1|QRiu2 zb@SbeHDwiFx39!_SjO$ttAPcUr`vTEL*L3dX2Y!$ShTeaZ{!%;(nYP$7vUhWt<{TJ zqJp_GKtM(|n`ntK(Dy4gd8!~0zD)JazSfSJ;l%vMFZI6||E!HuDGW%M0KOCDE@7Hv zT47&=osP_gI22g&B@hqS*v-Lf*p4%-q}k!T@Job_iaA_hK+JN{Z$MoC;8LCl?U&6LxDCa+QuMCKRsEPAk4E zgERaMY5(4JbGEOLusKgK#L zA0p5w(e#9X70@8Y;XJ!ZAI=YzFV{FC1`&aX|2&rqc_-B+R$xsTZ3d_RUZq196i3xZ zjSP;5Sw0)P3Adk1~={o4yjTLMem#D z{{HCj%>V3idyUogNScWXR2%jvOGly!c*6$C!jRYuNm4x4{5kl|=_`Oxwjnbt*ET8_ zw3syFF{-$SkR->04zMR(hFoeI&z1CgF!lqSeKXi0ofNZFz2I@Jwv= zPmnlsf2kEnN>D~Q4#5!BAjKmhH1@MJ?liM4FN|ft=R0v9Frp@@kG+D?j>c7pQX1-G z{V_&O1k=&RW1Z$kM}$;YrpJ+!ilXd})Bl`li(T6oo<}9WcdD3X;j?p?JP>1aBr*Ut z@4nK)pAZh4cRZouX0%(!rVkBqh|Z4gEKrxRvTgi&&AX~!T@#KF`=Pcj2(`Wcm{2dURW3Eo0sA9ith^esoSU5@C~<(0VZ92+6!ud z>@4rXQeJfdpg6s~VG>4BMp|I?U=YABbJE^a+E`9{^;LEAj;`QyXMJwH{mpYj#SaTw z(srrUGTk`dEWKhK>RUfg&t!&AS0M>Z28I!gnQWnpOQcxOTX1oaQvCI?u#<`)cuCNI zLu9nYgXMN@gg!;?WVBn{ovm*cBs7qk%R|uy`ZF6Q1Y=*`2#U&4eZ;!DdmcdCqJDbf zK%4PpabvF!MTbX;Y=8#k>lBE690b7CY;~NxU66IR26aiSYwEeG`#{j@ZQTw2*lv(M z%21#GrR`ofw*{4BQz=NOpGyV+3z;MeSQUK@z%*?!5n4=%?rh zV~lUx)Aw%L=*`V>j`I=;czDar%fcE@k$6utvK1I}Y>IvES+%79g`$KSJLursT6yQc zqP5r8Pl{l~<6>o3Bqj);RYfBfe(kKdzr)w%Z0F8EOmbPzuq*g}-vwj_qb6Pd{rHTh z+4K5sapKqSsGgHzI~qeU?W)IXXXhR({6X=2w&eYMi^;FQSlXaaQM0QiD?j$5?5DUi zSr+k++O{jxJk5w7#BY@3eZeI)S0vDt-*hN#X{w4ZB<>8=5}jc)mLZTcQpf};8x;H< zZfG4GbE;snzjG>V4>tom56MX3W5T{T4svMz$RStsul3(+gH!B3k=Rs5mHeclR`bhP z>o`{!8nBF-hNjP#4qp7%s{$Z@Gc>vy8Kze{ATrz8n0V641)YPestU2iJI7A=<@`&( z0(&#orW~?pSgt7p+tLWu$J$mD69l7YRhHZ=F&5tI_<3xkBy0uf*;aZt4KqG>)oPED z|NhM}IuRHKDks^sd1zCp^*#7I?)uZ2&v%j z$N}YNK|;XZ ziJ68@bx`dVhp?jxOvBfk@3vqP!<8+MZO9v9Vi}HX;6i z`B_NyxBI#;b;%PX4#5*F91L7a-+2V|6f)rt93H1=f-`y`#Q*`K>~FLl71SD#76;V> zCiA1tyUJFLDL9B-W+){Q@S`2A3bRtg#Gy6LxDNSfeZgRCfs2?Df(C92Vo- zkBasKtf5ZrWnmpO7VE!hU z<cD|~23e(Ws?)u?gT^V3SiZsN@V<=W z%o&&PA?MZe!&KK!ES`PT_7fSqU-kIn!Tlz= zjUD)oeAOQG`uq7>XEWLk{lD7?CGHn@2TESQB$YhTx-zE_%SKY=LoxHLO8=R@PP#@> z9S;;*ZR}AYL6AfQYNu66ZpHm|U4{(S*z@RQwAh!k;T!Zu)Gy3opOn6|2gO{g2f&{c z11~X#q`^dKiZESVkF{w4E$i$jf`vIu<#1mRH>}EUC*_#3-ZHgg&N3Y6=?^W7I+K;H zlcVDbaj;aQGXhKgws;$-dkq!-+o7XrMh-+3YD~eHl;}?~XNf@MrHYI+OvCZxg;DP$gOnHc16a$gZwC|g3|tDqeLK5gEQ0y=CWQ9iNix|2vev{CNm`xK%XhJ`2yU!NP*&SkWVMavpiuLMjC zLbRxzMJs$_F+;(P{0)0I-~K68;v}8l!!!Rzh13o{NvkRd@5CzmCk|T0Gbx>~k4Ffz>JJ;#PBcI_x>y=50O%WiT4&%LQLYQ|fR~!?#kdIAXk5zT|mP zeQ@$h?2(n1;HQPv#(RJ1&x@|9TeJ#R{l<5L-nGP=frm`kpFm@YK2I6$dH_7!VF&DW z8DcA6jmVrdY5!xAjEzhwdMG-4tiDnJ4_HtdC}^7Xdi}tzT2vYN4%E&f*o9eGZwG5l z2#M1gxnTL=&!h9Cp5)ZU?jm?#b%A?uTL?m)jLk_7Q63(UP#_8$U#3szm>y(Bh`ip+GtkI+N>RN22^||a%Auh znn!q#`^^3Jwl!n}`{4$vG%C(*b3z^5SBlwfYY}&z4S?I>w@#f@ekus8kJVtp5B{pP zxBA(4K?~wihWc@>k^`!OZeIt3M5<(HZ&E*xjy&ilP>XF$S`z(aGWMzC2@Ho|8n4Mm zgszpEUWPH;uW?+Z!&rts{7+hlLjfbE%WkE(RE5u1;A6PhPak+?eRU%^anBi1T0b~J zHIwgO1d5fsJ6JwDU_Wr&jNMj`6!~Mql7GL7ty=E&C=AHh;pLCtXi$^I%%*q|sMT9p z6NQ>2d#QGcC8r_Bwtzc(&`(!5JVr229sbSv?Tm?hd8x-3<416~%Gt^C*gHzI}_7<1|CYpCB zEE0PaxYDrf_}IoP_%6imCLcUA{awY?9Nn*@J&d-vY^%2tzxoUDmZ45_5sQnd62Sm)-N;JnH!KY>Dy+98rQC~}1q4yt3 z$`HYZ2tK-L7bM%wV=QGxy&twj`ZcbE!;VvMzLg!;-IMh>LW_>0lDy&9ik zB-tS;OFXjOpds27YXzsE%xPG*J=wYk!0OM52Im}wVMRLqKa5jyh{+1QU*86aY^Lny zDXwb(dGpyB&bu4y6yTEog3`f6y<2A(8@k?Z<%Jt~X3;#)B=NaFKD(kYfUy_Pe%{zL ze+7ly179mH153Ab%FWI&eN}80-|SV#MZ-~Vg+(tx@shwWKW%X6oj6vDP#19o$Pbh0 zEf$U^F&WTLpNRU@zs-z$_7+cKe!??N|Cw0Gh(zQJP9kE?eLH{8FiGs{e}ia9fWrtJ znkX4_T1P*{PHYUlZgP}bKKbYLfdL__gZ(MT@jNHx{YQvsp3-$S+RxFe z05RlO#G(&)rr`_NDSlRn_G8pB?B8JP168fwMU`64z69Ds`ANf;LuJp8?jsa(amDAO(qwS>onk~W$ISiMB?bu0`_%AF|`=A}T zjY_0S)t*9GW1Z}&T#MS$Y}|#N6`B|{c?6C1dBw7=@e+eE`?H>#+e~KfDCAMUunwrkv#bL~OX?Wmuv}xw$iAB(EDixbq~+4) zsy$6*$99aVg+wp6pc6h|7TQWQX0kdP)&RzVEmjt!=$M1N?jI~;EG$is$fl;`IEQIy zY^r)p?Sga#!HMcG6%Axl4QXN*WvFcA1Yq@2X2U`am!c*i<<~u^J zO-P+csX+@llxVW1Qh5uuYjVwZeV~gw_3YGgb6SHl=~!qKNz_w8B^-fk-)IrUOiSEV zy`-vzbHrVzn;6)E2GlK?mM>I55y&K|E-cnIp)6sV6F@Py4mIcgdi>?sUQ6#q(?NWj z&XK2iS@O6)iF^x-lhPZLxo(YtP=;Hws~63MGYM+h89TT?k(sQdtrlPCrcS?0F?f?W zxo)&g5E_Q%zTar~ivF=Y$dKT4i^0+ODeq?`pj62A@>qqE0o-xS2;AN8-zGL$I61rf zD)85gZZ@}Dy_S{(i!R;zZ`b2*)#KM1Dg7Gm^M5Hei$8V`-gX@={(RV;=Uv?x)HfB( zm}Lh)hZ?jgkWDf)5rvLxSx&ys5xr|X_P;-FZgMm)6zs4IxN$?;K44_bAbZ>`Geih5 zq;%m!#k{vL0LT#v^U) zK6Y6Cwz@G)@ErK~bF$?Lc57hJAfWw~bK7vvGe!a>1y+{Pi5>E#8%xq#q5l}~^8L#9 zq$&ByI8NqANQwCJ@8{AZxxQrWLuL~il1#IY=YY4ymL$&_)?p!2)4TnNXjNfzRnFzr zqZdtCXCG+$UR2zyk%n>ftXer@lT2yuNbz2&u}PKKDX!XYaf}lZa%x*e2Ok|q=L|>9 zm}d_xLBLiaam?tuvMIfg$mTq$tWRMmtDJ)u7sIniO+K^Xd zEu&T2=dib&S{iYRvyyYZCWo2rcex!=+v7kEPaDOBK<|8jl{I2+1f!A}RG4`tj8sHV zXIPa7@ijz7{fsgk<+`b+8SmP0WBj_73vZcwf8m}`w{6LIn#%f;wiJ3&QZ>1?T4z&_ zyT~8QeBOj9^rK(}aVBnoShe|y{KzF~s?N&Xad%h!84h~_%SbSE5e{=}o0r#_lZFZ3 zA*}9SLF4*_A=vZW*JH8;-%~0lz)4ZEczHXY->MX^{}`RgI9+k2Y)^pW0K$0=*mv|3 ztXIq+gshRX6Du$Mc~^K5s~6AqsNlQ<_A073r%c;6A=WvOB!H#m8eYUsc0!31|5aa> ze~$)8>sKiFIY~~@)0t}I3W;>68kwPqrb;cDt}<_WyxnAfK(&Hq>c-YdWmo+GRBIp@ zSY6_qJ^X*l=U1uieF~of3=9x3af~2{Jo_z?x)NS?Qpjs+1%;WuSMR+3Uj8wIoQGc)8VLJHPaap=JU~%wKETgs&$#z5NRU?`% zGHp$3t~D7UI*`8t@?J8D&0^6T3JvWJjB-3sDOd6r-XivL1ElPSHV{gtqn|iX(7Pui z->MGvf=(DeVA1@`y z_btS%r=g4_-XK|IeEMq&h$)452Ao(Faa^f6`+949&TTb)OHqT=38*|KHTPhZMx$Uv zT3Rcu*w!bnW3^?2)lDUN zxq^D#3{M%LRkv!)5qJ!042h*l89pa$uO2gSpHZ&AcQ4!4{FEiGU>S81Tmh7r^qrXk>Y)Y@C7z5{? znoz4HLI&&P@bAYrX-Zhgr%E+t5|aY|TAVd{oWdZ$v9kI0uahi?$oB4+7R1;!H?O;l zoaUt&Vuc0I-ky0NARa~C{^}jzut&;1H*1YH_F;WFe+kTa`G?*e4YnaXKGMnNh~4$^ zh3yY-T9K8Epu~n|Eray*qQ{I`I16Tou_;YaRcH61SASjav`8}>6M`SOy%9wogv6Bu zR5bvk$^Eln^`OcE)?JwZ>dQU-Jbp9d%G<&k_{Sh=Arw+?x#~oZbIqTKVO856oAQJZ znsiOdp2!WbdY+X)55Nlb<(ICs&8(&7s8$U=Nq{O?ia8WDoV+5gg}D=W3jKLezr8rP z^6!dYZRoubw*Ij6$tk8Q-zi>ek z24fxbLv&@c7-~LMEP^~+M3hutzE&qV*N%D;PX;#3tg`Jcetz9&`p>dLzrXmN_%t#- z!?YF@2}h`wIFdlAXCPZd~ESH5uAXi;My4AE-qJq(kjJ;O56p~ zA{<6ZD2lGayGf<@xPFv9bFbi8JKt&|s_)_RP6&;Cp$a{5TSdtRzSMOVxza0FPAylcI_Mi|2^ySpOoD!Oq~ZldqdpxSQ^MdU1>X3lbR&!;QPsw8an5{N!naE=X2z*xqbW{ z7XS+0o5|1lZ2|WH$9H#tCY0sq`|@qvsRXx^T=V0jne62+QPM=m@84>IlMM%VD*bau zm|=Bvv1;m})ze@H3NU@54fW4hA4Nm!6u6+b2=GRXXagE?VU9QaPef;u%c4gJt~ES} zRMSJzACe=)B@G0hk~FsdWIGAq)6rX9xRI(}#q|Zo@Cf3AQXew|D2z&4(10pfulO;O zB+;rRvCfXpbh>16HKrKc9s?$*vQBZ)$@}ceki`+66v_JO$p`BLrQ1srhuU;wCNV6-2u8!(6U?3EZD8# zj9J`|nvP6?O`!{5w>cRSXTE;-H@GK0<0W|J$o>96= zjpfO6CrZW7busu8{(EA?hh0|wrthox4C(NSEs}R<5NTf{_#yGp+AL1_cR~6eLn) zRO)YZV2ejAcaneGL^IHKS5rOj=;`D5xvNwOS=*ZlTqHV8vzVPz4AVr(O>3!;++GfQ z3E|`EF1+lvL9mlTGVT&RKTKz|rhpCU{9!9pk35+Em9V5bH`J~knTNoO>v(0 zfwltwowJAi$}WHpF-TJw0yAlh8QSKXc;nZAwB?gy?L8mOF7k$`>Jc6Vaema`Ws+%{ zMfb~ZU{#XyEPd{&D@l+S)72QqP0_VT*s^EJQ2h6RkvaOYAPqtmL!d~KV+A>}d1@jV z7lGPex8>jJ1Bobkwal^Ipug!j>6B;u&*|P1)O|8hn-qNi?3|$n_^98+=hUB>qKeqL3?dHaIwU`Zn~9 z@l;oyUJJxzb2+`eT)w20o>%z~pG*Lsknk-;X)yFN)IdsJdxJAQ6IP{1w6{rf(JdOH zAkeqrV;3XcqRl4ADO&<2sqK6n^=+n`pHY*<#To{sI6-B4Yyp?|fPi;3i7=rihnSET z>ZyEG*o?U%P0`EyU-I2z4?oj?rrHPUU0h(nkd{0r!oi51H1LbPZfxKZ6qfE=g%9@ZtVz0;C&R@#;8yWQYeRG8-1#!6aR zND&JYF>7mBlFaYVBP4AEpw3eC6x=?P%1f$=OgpUM4L8G8*!#p7H9v;*-+ZW=?XVsO z=X*IPPKMM-gqHMwtlX{^@k^oa{?N^GHl5;Pwg^36HS(T{<2oA2{BPlsTmlF=D~leQ z@_aesedow17C<>Ukiq!64*A$1ca#V+ju}#@yQmLTY$zZnKOKzTERRUI5lfVMcEELQ z`%4l{`zQ*X;LAcJkl9ye53g2-xYso;@J?+_vg|7AqgZ0HSEVU=aL1XHkqko0Jfx6JCFAZCx0A@CZ=02kziEvg*pQ>_hy7S7L=$sO>#Ps8b zF$81N0vc`e-`4+e1is1~U(b_Dm({bm zyEG?@5;LdNJ*E5PVDPzllgY7H#1}sE1!1mGPRGeMTEehu7AK_8?2$~P_Qr|stbVj^ zD7ah1ow0&9D;6pxpRMc&o%gKN+y!8OY%HM{!9nfh`Eh3FHH1KbPMh1YAq<|Wgw%Kk zKC@5jmN-+ctcn4SZm5}h5EfXyt78A_c*(a(ZrUULCh-EX+kZt&`lE-N90Qctuv4%w zLp8iIzV!@$0LhXCg(~B0F~lX~D|2$G8P=y^JT4K;a`%+(;;4v$q;^8;Q4Nyqg)WC| zng(<7F8_rnZ3RD0k;ZDGYW>Cemj{?E_^1VAUgY$@YkO%de4`KP~wOy z-ijiJfv*ck0I5i3Ln_s(|vk# zb&%`_$@B@6Z_*O2)Eu%rC=3Slsc!|_-{lZmR=#93YY=LnDd^B(_Ika)ziR)0fG0+Z zg=%6B8V`0__&b@t7`zPg0_0QABJz*R}ll3GZDQCqap6mCEw&T zOE#u2t4Im?s41s0x@dD7Xg7J!F^-zZd5DxZ9nWqVyr{kys9(pG1AT0R1~(C?5R8<2 zG?Kv#fA4nKYq7c&?|+bUpVY~?!#}XK#cwI^mmmKLf}o7}WKv+sUYbI%2D%rm`|am3 z)NimQ!H~)XL+?cof5%<4LxhSA#6Bxzgn$z>UkraC-2@z+|8$W8Nj^@ zd^G}jaZK@g!cpAQrF`;VB1`^oy?^oq89i?#cS=2D>-SqmckMCq3&)RiL~y~$U;ka1 zvosz?X}582!|g&3bhNd-qbcA>Rt8Iv6go**e-aad7qW==4W&1u1l^SWDOWd%fxlq1@rh43kiSD7 z2Y#F0529K4Ojf)*hJobRYSNu;1!F(iWr$h+Yi`N5{E40qc((wwHsM|t)2*jh%VrV} z{qt4+OXFwX$dv)eA<)uqXZv?A*Dp@ko>|G|y*Dcx#TSLz=XRVg=UdnKl^f0a`Nc|{ ztBZ6KA_0{V^K_}=j0N@~NB~y%q9YrP^OD2zIkUh+cHxD71+sf2-F|YSk_EhGtqsDFSm(h8Lof&FqSU zno}H_U-a18MN=h$4yv9)qGlg>mldH@?e7o`D86A~SNh8oO*c|bHvf;AZ#E0Ruhq9-_5$``Vu9^Gf+-=9V5r{Em@VY^sU|R_|`*yubNv^GFG_E5zE9Y-eMz1!3AF zgvIO`_0%shZ~Atrz?Ck`1zzB(gvo`1H+#oM>;2>>VaBye_CYlcU&-ScA`QYAT#nA? z)?1MU5MI1EwemUJS-P)q|MBoLzlTVx`c}J;em_sSWl?7^aT*5RWA0N8SXfX#7attyIXrZ)q;@;Ue9_axOl1v9^=+ zz;5wG<->8fZCrb~f{_^%^hB zLnR#9+@@O-Y3;V({weVOc3>oKU(VgxJv8Zoc4eIjw!rhAouiO-KMUL8sQMSpJtX@z@eI%iVMyaznLS%NyR=tm z`$7DOq6`_ia#;NT;=F^bRjr>tqBpPr>rWqud1CKWGj5<_S+&iey+^~F57T;)B}b3u ziwtW%{OsYS?lA$<#QGq5FV21Pq^$i)eGc$U#I*Z9htUBBC$#mr$(-U}EiFtz+-s@W z`I0tA`NcI@2EI%2VtXQ#LWc!W=+YUQB9(JW#yXW4Wx9;VaYBT4UhU`}?FGMqQ$<;o zIwcefQ-_0u&iBXWi^Q#k3_l)-?b9STH1Tn6CyeOh&X`A%FJg&c=D>Fw^_>_=DqILm zAf5qsy#DDA))~A5Lb80nAUFf01Jy=ifF&9u6vAC*02Y+?w$i^O4K}L7+HDfelXxa6 zhQX+2s~DSHp%YrXnE~FRIg<|5kp1cqNf*Ra2Y2^j1%IB{GM;#knK9< z72eKtC6e|Og*eV6mLl*0E^HZbZ-8Sx0ww~v4T)zsR6}Z0C9YGuhZ?~cxmnUgfDx&B zfo1n^R7(_ke?AIcBI%y4sVI;0Qrx2W2MgN>_3}*M4P>9N)v9O)t++i9#G+}vNl0J| zolM6ED_v(8<*sRQDPkrBGl+hwOhv_ASo};rPfeb0Ek2ohqX5`JOsXnyf2#5Yy^CE^9z~A&w z!_A}Slw*r=yL+z^;C29hP`dawcZF(d;?dZ`L$dV|BUBE*3}H6SU)q1~T}Ki|3~m)S zDdIWowcfjwxMYO7tRZLPmxejtk!x5}?vpDIZO&41ARXyNt^Lhmzm4%V;$d_jao0rR z3F?eVN}19ZPorgX%JJc)wjualM(SDG1*ee)mS^QNgKn0P^v4zeBL`<`GtI$4FvClu zonjm%fb@0`W&6Q2ED=IOLY@zv^~++NcxaXTJg}AaP8sdn0{wsr^;0$Ggxj^+*G^74 znMLHLYiCX2K@z|D+SGU4u9YA2C#N0$f-R=qsR#SXH2$QT6%81 zTAh7Hj@rr`->!Z@A&!Z{XguG;#O$N(Lsc6@c&XYkA-%Y8 z?PG1?#K1jOrG>WrA7aXN|M=#)jd-jyLtVb{2J?U-?SMnv5$N(!S0Lxr8Ms+sO_F^P!$SV;!C&MsTF*GAIHfwmw>`PEo# zJvbgw`?wSdg!j{i^}ZG*A5$$Yb1=T=#UxU)wTu{bWVYB2*4LxzC%((4uHFUU5E<_9 zr9n?qeuwqV2_ zZhf(`^L)@{7gSxf#ZO*d-NSujXAF_gt~s|acYh93g?Pnq@29s@O@De(oKH3L1=A!G zHfU2-xElsLRL1;V-0N;=$zwhsK>Py)a4@-`~ zVdztez#*~;E8mYMfPWs-10H$RHiOtO*cIO?wB3wCJl}uti08hZ_cT`WiG98&E&YZ^ zJ3oRY`)u}>N4hw$fAd3aU)n;n&z&{^(~?A{Yv@dRmk?g@+k$%_CIY4R$16X!~HL1dToE>5tdm0u%(oWRV!)ZJtxl( z*!Y&GBt?IW9xy(C*gl!@T_=xM-twNO1YQqeNlS6g{k6yY>Dsy3kQUxnx!E4BaQT!| z==n1bKD1winEs=WhR&ZJzLZac8l8ujlJxo%Zt|z;O}cu__-4QbljZp7jR(W6fqrBl z!ZD|c^KbzgHh68UuztJvpP%~3xlcE@pT@fFQ@Vee;?t)L%>B1diB7ZI>$AUoy1mDp zcNBEn!SGK*ywRuWY_TTO8>}8KEEeJa{InXZH(7e+CB5si{DlX!wMRxTy~J`;?#g|6 z7~RmNC56<6o(vX4rL^ZZL9(u+KSqm`J=o){0nLLv?C`cJ5Uxx^m?{ihiO=&XN! zYZXL`StnyQf4F_(e*Nz)NeBCAZJyq<;Kij7+qo)h2ii`f`#wTK$8PvTX!l|sc}mp` z0Qu)mXsSVa-Hs0bmdoqu&EqKed0y&f#rgacO$A$lswTwnkiLu_F(R!~2$8d6^?f^5 z&&JBxSUI(^a&-Q7>$09JiXI73St@_X!O#6^a?cQV;oH@1$V(Pc|J8k|D_8nNqrI{BXB5(^FVedCGW(}CCDcEGD1JN^)S<)l>3 zyez)TAQ;O6g`q$cXjO~jAR4HmJ@_h1kf^|_daGnp6-DZpYKrnd5MOxG)-$Nar+!gnkjje`@-`L+SYJft`?Z-RF zclzl5cF|{5;_~;uEgmrhiM7w&7}A#-skH9Pi)UkD{443C&ypu9{j+~5zYM?8%r(}t z*!T!;X5Op7EHm2BF0Yj)+LUL8hfqxnD}8BTpqj>1=B2U9$>J{-zge|kGGkF%2fj@@ zS6C=KYEz8om_br5CLfLBUNfmG&#)aq#067K$_QIx*VksfSO*QKz_jJkbY<4L@;O=; z1dQo}3ZF>WtR7N?YioZh#sS{cNn2G|&PHfUg-!(4O-k*Ggt-M%Jru}YA;D!TEXQH4 zt+$2Qt!?8pm@L9TGdw4zbY1@0sAJTa49ayR1Mw;5P}`zppfLIy+u1$i_uUYI=<~5_ z7Fj;uwy~Wzw>RbK;DHvsHInHO)0=ubX6b%lPqvxf^|Uq_RzH8ogqEzYcRi(b6YX73 zXM-L0uIIDI*n8J=JHR4*C-eJ#en@dVa@m<8zYoIfOp)IQT~4gVUlMT~1BLp?m3C(~ zr&Oedb4A6hvuj-OqLCp>Q9092$&-P~!F5anIm%nUp!XgcEu7T*(9z<~4G!y(N2T|W zuQ)5HRNA-8W!HZT4d<@hkUE?WWl{2UM%Cc*Wh`I9*J)e5ez`?t`KzSvY--+MHW#YX zObz4!S2uI+Qpb;uGt2nSK}yhU`zA1#?GM^0xZ$=DAGe1Vqi+U&?roJLgv9iwZSl5g z^%nPCws%qGll$Dauvv3)^~H_pq!DuezAYw)*N+6)Tw{OtC4s2?d%pogDXP{An;&^z z_tm2p^`#d$=Am4-1*nBue7lgv{TuoU)T0M<)18;ERt_w^_;yjMans`mbH4iyf?@Gh z-(kIfu3~=eyII%xr@z*s<@6=oL-e(3!GP89o4YS<A*)rS)uD&jL`gpyGuZPgN*J5mUX6z5<+g>Bl zgLHrPhWyfxb#Aq30p5e=_L~^Ir=l~5zd;V~gzxbTzQUfQwtwFdw{wCN%x5QFZcexS z{^nw}%hz!A*m3Jh_QdF$p_b0dm|e1swIVhi?{A!tnFr&2thyCjcUX)?g&*RqAKXeP zHB1^q-I+}j9aBxUS|ygL4>Q}=W4_(^jl%@hks3LdVetbbe_46>%1DjRjr9&Al}a?Z z3YKJ%-lVwlyS2=(EvtK?K118q6{NtJXfV~7P;vn*HsQ@qRYm&&K=DZ@e#cwmPA2aab49?X72hfteRo5DARl zw+Vt5zf8)_SNyL1ck)a7iL@a7dspaevA==-p|2;OTNm===I;8QAjstI+ugMNL`NI5 ze_7N0dhy3E^S>^~UtJDg-A#v|bf5Z*m-CCmor^Y3%YV(p`|j?WTL`%8+x*y>8+Z59uRz58fJcA*viS3I>C0j8UC*h-r`g54 zQ+Lxho?5^1%i_}I+D(_En;vfeXqyeSfB*h+@%sqdjCcJ@yX6Zdw{+j=q@GT?Iv3LR zu3F1mu(7WeDbXi%)@l!%M!mI&-B-J7{k{dYwWHk(t$zQ$2Pbbh^g2-sw{xeoot@H7 zn^nG{2y&aV-QyQmAeEhq3JB7eT;l~5H);>dW?fT(u7LwhA9K2z-porPZ*MSBe}L?u za2#tKfK9^{4>FYCbqH%c9g3yQe&zx}sn7sEIs+gH?9BT0Pu{K^XkYno1M4AVAXE*_O_OC|6Um31QWw@ z1H19n_-*ZKXL^R&qN*(P_w64me~;*{jDOx;S^nk5)^M~!i`F2+S~UmmPyc|+Kc+Xd zQ!Q-|ZAW%&xs#0*E;T*}{27V_z5=c?Zo`&iw=LJaaZ2WfJ5Sbp&W5Q2w!DeAw+|3b z;qHl>?=;iuqwf8D(V7Fd>^Ld_l51=!sfn4FM*FCPSAfMytW$w6zJXz8e;W@w2Fnk- zf;%p<)nh6cIlIVheBVWVt#5f>o_Xi4iiuL7JGF6F`y-9qwC3BeaBqE|$7fZ2C!kq* zc)VNR!5$y&-@|~Nvr3X~h`dSOSS@NOCT$Sjfmgu!$gqbYHL$q3_SuQd^CnIn)X1b> z-Tq1E6;!qiT%5if%Ee*=fBQ_V^X2y2xs;pt8?y)830LoBrw`nqqxiNm4ka7{Bytt5 zQQW4a0#n7U?>X)@WbyhY8mSsxmClhV82#>L_FPSv*2?Jv_Z+t?uC#r(qWi#IIbx$z z!(0s1A0akAu+)g^MHNX$p5@9$xA#T}=p-6%qG{*^JI0{2QRM|Te_CU+Cej$C`5_zK z-L5ej^D}Yxz8yMh(>a4avmEOeVuHY+B2uho&9zzEbWXh9G~1KmXBlqf1!q0Sq(d*gPj@$nm%U`TU^ zhhjl09Y2;_T;gfd#^uIlNY)7X+CZ>+=DDlBJ&8GQ+>VXgf3e2LZycm=P~akCELE$I z-sWI=shc(qDp3XOnJNssS6pSu#j4YJ<92V{jy2x4alfzjuDzaq9StVt#>%f*IQZkhYqeOp#x!+m#mON+a9$55L8_Rq^%8Ab7^s%6T7yCh-&f@J{d zG3x4rEGZVSE*BvxI>6>JI4hH=oO8pm_R%Z7I5|B1f1}rkYwXHif?8do1Dy|Hx2IQ! zwclI!8ZNcp>zOxiWZt}ydGmJW&C}W4Rrq#!6RykVUU<8`yse0u6*>TY81;GR&XFl< zdYC%nrC{6I<~r|UyojPI`$8zm#$&U<*=>en_iM=cDl)5os?EK z`=nxK)#JTHM;n}CuSY>Uz1C-mvu`U;N+oMP@*k><2r63I=MOg$<`UX6-&9BRBzD(cTW&J^@o6tv@X<$Y4n za9;8j2#Agf^7Ztlt<81$`98D_djIR+7wyOSvxh+2PguwBx!iy1?V?ZffLlrkq@U~z ze@%9lu?3PI?vLLt*AFqf*^F;l8Rq7@X5VHHM-`E zv8uvG=bSg96z!4(gsNSixa}v2TcG9>ZuZppkVmz0exx*;t&{6NBsY9t@ zC)I5}jiB;fhUq3+9-6F`@G>VYy!e5{HPBDLPp?H+yAJJk(pA3w^QL3x1u1=6xM}u~ z6wE;@r4T<0Nd+CK!=z|pq&x%dcoo1{D#tfYQiqr57!h6nfTO8yr*r-VsZLEef0NAm zpM>fvQxUY5c;iDdP4&`hk9F0OovH4LSqCpgb*)=eNza-3DX1P^+Hfh?4+ytVy_*NpSCV z7FGl;n2pRpIbi*2@k;YjQgYzhkYvu9s^nPasmf1W3*r?3gpFk}V~Yc8e}u6C>V{Px z`x0sSF}0<->*0Gg|5Z;QOS|84z!eB|g$4R*MqAgG3Co=w#hVfZwsQeDw$&F_$TF9^ ztJ`naUG2vgD9b!l#h%l}#XesOW}zGxa^#EquvABNf(n#OX!C8DG`P(OsoxFNEj|9X zL(`X5<VHw?eP1O-)ofl*jo{85yy^tpG13CQz}2T+L+{I zJiq50XlXEA$DSWG!DEQ%9n9{eh~gd0_YmCvq-l(KvOh8%Co(<7f9wno5BJm9^>pgT zMd#z~we~3Os2(vp*N^jwVN&~r&v&iHnIq4AYX?Z|sjs zp2f$T45NFfu6AVMYYK&-!gSYn%MOPP)hzdwW1IhII2f9bbxsOPX@rkZwNON5Hf-u> z09|ZF8qU^JnU2P{e?$=dhOHa>!tD(UmlI{(*e|-Waz(+K@mW*qxg_tluTcmP7~M-< z_rhGu-rZgG!~OLx*S2Kj{dF6smM@os8@h72lkTon9jK`^F0q!<;w>4&2VPN<7FIYjr|op?zk` z`jV^4F!!JAzA{^;4S2XgMJ%p0$b^NnSpU~Qypf=~<$e`b>joq!_(#z2OScXR7W zL$In%D8e?uGVYl&9;-cS1CXbm+xqZ}BHkh6?ba%9fPjJu+!P*+N|oxylmON!Rms9w zg>E#mR#>vqDru7|s&*k@rzPzYgyG3S2AEnK7(cpk)`tcYs+N1HbX&{erAeFWe+bri z6{!fde~(;J!EI;PNxKS)5#zFnJbL;RL8GOxypy!OQN?Q~Eo5x+DZ+ls$w`-;)7%$G z)}n(>IxuG-Cvz0s3eZQ%O4*v!`ylO#C4}y-jRTW5PAZ}urA1&bP1?l>xiB}n^pCjAqY>jA{S>Fi138I8>r z01mRd(Mn)ZVI(=Oc9Hf8=J!<6?kM__0u>3D|d3G<=^*Kh^pW}zc^aXUBwfF2yHlcBxU?$oWGXy*aBzSP5Mj$;aD;4Mmzb)gM@f62LUB^tj`~Brp4v(HZyQ{tXqK{raDazl4WLp>T zW%=uF3T!d1*R(;_4~>hv#x(7;$Z@pa0EV46y9<~~g&rvP6kIV9i5@~d0P5x&>d-nGQ!;XH{QE|WYE!iC4`9H2{*~0a5s0sO|tfCiiv5ewjdJwZ{X7INb z{!mMo1^KT!MVFf$3|SoOtql4GWJ5QD{?E4iJVn85qcs2|vj~)*-`_V8@B7cM+aG%} z@KfB%$L|Hl*jI~^=<%4hKL1i$sdc>UUvzYo{gCi+id z(l3dA@uNil`bp?!!Ox#9_&51~b{l{%E7tp?ocAHtPvG&|Db`z;9=EW$^d7N(aHP(P zSYJEieMJ$!&(Zj%oMJB)LiFk){?G`Rol0O+6xbFufZ3!wtb%k2m!4whYr@f_y_r#=diq=N|m;f-KaQ>GS>O8MSo? zz*x68i3(VbB-zW0&l8;>4Nn<_OTU}VS8)gjJPk~&1bPhX*`FPB{?NmSs=wF@!{f>7 znUOyG0x5P$$#tsw8m^{!e+x}*3^NiEtiRAoKZ@c`d6@HZ#MrJF7f|DSh;b-uzbyFH z-n~r(M#$RImSh>O>@S=Q8j@m}iWZYv%r=)B~L9`Nd+8!ZqHEe$2+uMf?=t@baJ+-Y1476qhpcYG9IB8T8C1$6z54E@&0lESdf3}8=ou#3KSL1Ek zv!~x*m1;K)V7$jm`3}(XOtVeG~=w19_8$5sP*(;&#oAvcx3P^l9?wljJIS20tP-{YT3xFCu@@Yb5 zJAp05sO=3YU6EW{f2m_-!6f;a7_}q!TmT8!YO*2wh`@bkZ1usxOZNTzn->7wi^ze| zqHZLG!$`Va;m16ExGZ1ifuWSRI)r`<1+lv|zWCdQFyeh4x$YMbqC>f@ReP+z;kIkJ zKqIQ4q)XcMuFde()$N}o3?A+u%P4fV1tov2+e%3Z7)G3Ye^)x^lqwb$gA2YUYoZGt zCY`kSPb}F9hvjg|G0lXBfK<_tWTgb|-q$dQyrpFISnBP48OGQa-w;c~vf$RZ4C6(IMky&9XQ&)R#zmv?kG2<2Zx{gOL%pff*oD&d;#jMu6Uh~s z8!x4As>qCsf5cTtB;Wd<40dxj-+y(Z&m~R!_~e#WF7xemnBFYzYuBaw>Mne{x(&Ho zg6>lP%>PB@wrDK2B$_B z0u1B<2|=YOpy8Azxg>MnCIC;3DJb;dY5y``UzSJJ7|!@0P+l>-4<36s|UV z2I-q>sRGcpR&E5N^AC%mMa3%+uuo8XMQD~XKyWQAnk*yqY_=~dg>9|XxlkMLglJSS zz9Fh?w3W$cBU6n2;(&e%)+k}0E`$>p)_M@Je^Z7ufp^I#R$(1{6d}BG1>Tzw-dRp; zpAeQ4#<<)of;$1w)h#*Nhy6rR4U3Qm@MixjR!lopT^6_$q}ElZOm=8sT7xW%G!^hE6i~)b ze=Vs6jOI*WF<9P6UwCB@SzM(LBdK?-z(^lP|9Q1326 z`1*pHiBv@iMFm+hjHn10U34})XMwBL22iw5HfNu0aaMl<}$YRDMxuFtMyag_3O-+m!`M z^2wC5kZV&j7b%EnIjcLoA#0PqTul1i3-r#pzZH4!Y*qRCo@x((ZA?^_O9)=ge_1xl zuxhHe7;gx{>*AElER~|U^g1iWtkFgl#p}!ZNJdmfi>4&BAgBv$h9O(%87>bH=z2o2 z0Z$j_;EM(?0qzgcH>o)8w9kqa^-;w6&J}nU;=Dif+#{^bgu$9{N66|0ufK|{eyZ4g z3KtzNtNSzKck3v5taX~EM7Wdtf5)5mA*U6LL~D~uQv2#sF$BB0V5VwWtaUkLV*-yM zid-a}tcMy?jx1T{(+hh@1l~j5n8r%$8(o8Kysa5vq6%4gfgmya<+Pbd$+bKJcn4J) z%cyCd;ju|p1n-!3!G0J?y>kVADoJg$mv7Wr&7upMq8wZSh}IH<*@;vdf5s>$34luY z9p{R`*|o7k=O$YGDKQW)LaM5!z0!Fk(uP9f@A8as6nnkMV86YZLQ>~)-_WkP>8Fs!$!mjM zH6cJ1+X?|K900ABp#bW7n8YtCuVJEzqy=wSF|{EVOyih=-0*EIXvrcR-~_P~!7-g9 z+#uO|N_bDi*) z%*OM~fu2k75n?WRX=@_r!0*?kHbG%szVpt~v^l6F-9K8Cp7wE`bXT)PQpO6WH&t(5^}CiI-W@QsSn zHQuq>l<18U*~;MkhnLnnoYCQqvXbA6U0TCRR?aXVEAtSQA;M$tan! z_BuMb(_d{HTVP%}?{foVyZQoQkd!`u&R>1~`0!3s8t-mr{miH`dshYG9UeE9#I4pP zDjS@ZvUp`()qvi~CF20iEk3!Rd<|5Tt7e{@&VpsfIK_;-sDRHEkfPWEEN*q9c}h)C zfaW2mqA&!_+OofU1iYU}%e8sBd^aE*8_6z}F*H?)42WZei|(Vy_nj;76M3(H{lsyl z-n{VE#)gtZgvh2W85c|wgW!#*yh4gcsjI%&+R_cXiNSb>A4w&eTm|r3k=~@ZLwIkO zb3do>epm3^q>_qLi8~&HQB`Q*b4SfPfLfAK!B8ZT2s}&Uy_H2fn}n9uG0mfVS$G~K z;Dq+R5jwj@R~H*6Jdj7>mMZOkR%^l`(%W-@7V&iP?U*4H2SrQZH0cO+k+|&2yL|}p zy>kUV4m{T&oC&wwinlJ{ONx;(>{S#H(<)L1WTrYJ(g@26?AdD10)B^ppLckr0Q-Im z`|>II9>R8`SSL;ays=Tl#s@|v%)F=q{KDH}=dT~I%@UQOWU_LtQYt|o2pw$2Dizq+ z*5NbHK_cx87v zWN_s$_meTiE;%#~V60Kpi9!a=a&kLFy3gccGZ{c%D+qULjR5f^>!uXRvGnU@`1=;! zf88PHdlKCxX-G#ejDo3PMFxjjP;|t9t4WpOLOg_ec8(Y4WZ^+lSwBl@7dqwlA-cVy zHpovG-H8LZapfAK{Ki%+2A0SA4-%QOZv{S-=;jl_wUKAZ{c}q0yT^Dnoqc&9LOTRt zXKQ6roFY|HwX$aIG|z>zRIKuvt0=9Ce_TWvN-VY{mj#1t*RJ|^Ahh{J3eUZLy3o!H z)ax{C(wwO&xQmHWhD(tjMQHC_fe$9Mm2ynFv($e7QhPZdpT7C}ZUPET6Z?$uw)XGA7;rMT#4V}$E$>l~nFR^toe>GHp zkouTrjO7r4ZG<=K>GHY;qL=FEd>LAT=O|spJ6ZZD@_OeAd?>fKpn7D+`Zt-C19|Lx zVwjYxtWh=BhDxwC+5li_V`FH`fNu*VjLKqRqHLnG0c=*J2&H&Y)ZVO|Uf8|Mqf2Te zHkmoFH#`aVusRnCK!b$4tp`(QboU_cz0EZ|1FTi+& z{&h}5sJ}*)C~C%*6ID=9*f&v{B$6~LI2o$lFRR5wd&$_-!8KQs5fP`xDOH;4gemk& zAJqpD*1K2Woq=o4fvc@F&^%tnMkGgvcA*MW4-nRJBAgY1?-kaq2zcf4eJ7g;KnbUlk;j>@D?8{}>zX@$)?QkJVSwtANwHM^}@XxK&|Mw^SJ!-oKQ8%*&K zx7J&qnK*I~Ycb*dE=R{yQ>|8sW$MGt7SG>Ub$(?w)>fym2~G#eq+s3$#gs6ZP7&Cx zm=vaDJT^smO(hm!*m)VPmVyc|?0efPoHQDHL+!GxRSmYC1E2chf7sfC=IZd`D_?xK zBaC8sUZAX)STRC)r94DXDk^XgpTWGWOQBMaVk&448!~byB1KCTNLgq}=gdK`d`e)* z{-M;TlvQ;9;6b#cP zV!%7!xQzzejD68ye+g@&V2%qTVJ5H<4KC$St@cvec+c{*N|q)oP@m&U*a~vVP=-eE zoQbazh_-570?Zf-?Z_OnoMXBwXdzP@`nK^cD-ri4^Tyi3sQno}rBWhix*EopA27-d z-7%T*UCYyPENU=nu%$Xvz4tsC1|o&hQjmub5+KkV4Yo)Lf5&R_8WbD~#7k6#+wG%S z&Gw6s50*+WP&Wh-F`trR@{TsTLpApca6hs;#&*in6fNY|=NpXd;dZV;+e_D^JLd9x zsjuSbhH=up&(CeUJwxazR<353rQlP_AEeiX=W0!p|4Oq zhKn&0{QE!u^HbkI_|x1X4RA+QVI^D3bPVEV^#qIe}wtE-GRFsWUNBXwk!A8V49`d zyM@ww8h*s1=6xu;h=uR;#@=d~t%H-nhI^7xc=Xr~U#IV@X5xS1_y4PkOyyjvt!n6rI~<9!Nk_8m-b9z%N-H3&3qn65`qW2y6!B8>ErOc?Sp;fNe!}@~8HPS#s*a z9Klvu4$+jT){^!?f0V+fdiY|g4qlZxE zDwL2ogeO*+MXsQ1Dulj*GTZ78!^QmV)IKm7Vlk|!gnfac1(7kAlYlG~+D03c6+Q*V zf7>D)GG|kbqA+QJi3G*toA-f@jrXJcU^`8rALR%8XXk5p6MnF!m(rY2xe zJCa)eNCPHw+T<2rynaDv7j=;Z2wa&UARN#-BMBaA)ioQ*91Lp@sm>~$zB}O*vqeKE zNL?%QFPB>u1Q~z(onm^TF){x1Iz$3W3cSosO3)!*&t3|gJqdtODZ1)QMEOm%L zBZh*$<&JpWIqUD@_t)`&9mW*fAWEY4kkZP=<;WXqj%$JPVAk4=9ovBej<@g&2f}v;w-X%R*^k& z^>+R|65=q+-oknF>zoC%!W&z$=}~gmc#%amKJkOjg5AUz`}8tDBLDyFeP?qd$C375 z+1QT?HLkqjH;U3xI*}4z8W~xvyHOTO}%ICz46c`Tb>T1^-!{Ai@>njbJe+ zUW;P&*OJO%{|tOQsFY{~e8AN0sB}B0?{TNzUo?UVDU(8OoP)?M_*XU6yBgC`G#*9c zVMTwVa$MZsUYE=&$OVw7=gv01SWQ)kd}8`nA{qD3z(*w+DIP{2CF9{GBj|Hp=c!Bn zQ+_V#=6a84Ok~_Rh(_j`%4OCi7ngYY5TcRul4~?MD-wEA%2E>$mJ7KUr8CpkxyozM zMhoVH7OLiqwKBm`P)K|~qEYe$)2YbVL|=bHLv@y{7UTkscM**qV%*(7Oi>Do-*8l; z+!~Kh2bs{0jpf(k%iKQ$AC+wM-i~X|?v#x?SpAT~5!4Plx>EKeX@J@Zid3bXOztQg zkHYbw!jYeFF#!d47LHPYG*z}u@R~Qk*2#KpnW^U2A{_V5z(*t;DPb+sTpxww!-aq2 z55HYecNb`SaS9pr@7M9-;(Bp?6)q`&^76D?ujJF}*4F%J)*Fyt<=sA`C`G#@r3uw- zWqZg|&c9{u6OMo6iL#1|RXR&*8$8mb9p71!hM#!GgkD8ytoVyYI0?m`w?Y^~w=F9K z{<^sALy#pONLHwE8h{d<_H*a76aPM+!!{hOnyO+URFT-;9gB=@RxX-DL z?%czD^3iQQDRHku2}3~WDmZXhNfIsH7~)0#g*5y<)-qg&(~CDZ{b*JZsH1-pS)GXM zse18x{L)!CN5AO7c40=*^EN82l=meCkz)m@#0&QD3W^uo52p`)fcAvjtHa1K2IsRQ(MHM+B!i-x|} zbi3Kj@MNdnuLk~JZgRJo4e5Vk+`-F$o3!T)OoLwrFLm;v-TgPyA4=Cpn0;=In^ z+zba6Nay2bdx{%PZFGH3@{)ql!`l7P0Pvribd4rY+hEcyo$V=Tz<`&~7v=m}_qhB> zrwCGcQGKNV@HaiSd$zqL$T24*L z+it^OPYh|6zxMeMktv9%ZwB%8m@%r#jO39uE^9<`m&W=6a>1 zcf(@iQv>v+8($-9BnwVd17I9dZydFfYKcx-hsTp2qq6f(0OBe z`*qK0(_5Bj%O~zL*@wy}F!7tU8Kh=CwGHR$`o^c;uJ+FGz5QkRXqSK&NGgcNMih#9 zbIkc{?^MaoNyXL5yR=4AIYO2v$srK6Zj_ZE0Rs|KtXeO#DKhJpcIH^7fg{G#G#r!L zcK`h5EUsLE50Zc6#Cxgtw*sl-ot}vef9X)Bt}Tm@(yLXrPd5leM?d&cRk& zUogohAtR7luq=j>szSrkD?m8Gt=9p#Dq8NGQi%uYjbxEF9u?DyB?hQ+B>80_DzL6wl$_iInV@AGl!U- zlQ;A0Lo{=Kd3Kc!(a_~Dm-BsF_-c;KR1II6!OjJj;u4u!eqfn3hU9Sf|>i4%ID+w&VVwjUA|KSBILftHaFJ zIcy6uFmAd)mB%)BdDYhIK9Il}wf39CH8(qG=ME)&I=pwdmKFzT>FURM0`~48=iyuY z&EcAy9lVpX19tNI;$MGlW#ogj^S}=M&?au~B4gJLmb38l{OsloRzP}7M$udCoUOrT=aBFFCZ4I&-Ml@?5KIvkr+D2&- zMt0utB?|irtzq-}|K^uu_6&EX)9`NPzj!uAmn$MCWqaw9F^h7iXuVh_1c^Ka6@X1kpaG14A2q2TnsQr|ta( z$b7N&`0)Gk02|ceFpZSd+JS z2Hw4o1P4!(qhNnA%e^@Y9_(;@$RW<>eE{%|^-CR>8nRTBD811pN13Ey-qG0rmz1=n zXuMrbL9cA#j#ukMWjs2ixsCh3wN{2OCQDWNRO7tQP3Eln5|T(t-+E?oG25C=W61c@ z(bd__^$>sjIZg?bF0S(OgxN-%RQu{GrFR?3-A7d|)5!eK=z!wrfmS%I-+X9f*~Qt} z{CZCioIH`58^0M_yW@FrVvQ1Zl6Pj*nZzxnR8mcdDmM6CX%#Thg1z2WbWv7km~gRi zA^S!Z78++lYOK)=qCu-@?cSn`x5cupB6rs+X>NZ%wc83B*H~s#Rs$gfL3iQ zj8m$m3aLTtXqd%PFhFl2<D>`T2KQJydU!Y#$EmjJk+v#l`8iNH^y(x8Wpw%E z_1A4^^sDfyO$PYtW`S?Kx_(<;^+SBsE$cAnJsO0R8&1j7bWT37jRmtSv#XoQ`TJqg zmRe_{0OUkHt{3ut8R}9v!T6!nCGmo)6`jeUF`Tk)1b{eOUW~dVSZzyfs337;Y78Mm zt5n4gtS*%STJ#P|DP4Gqu-$H(y!mxGyVH4(@!;;GhatE@C9N#Vn3J|L^38u`o7S}Z z`fO0Ux2npXHv06pgT`6i*rxIyZm_k7gdQ;`dvL;?=Y$_@P9~7#5tB0Z8V&rmChb-v zb^AE)MM+OgEVSSc=<&XFe(I&%8mF=y9Zb;{UVDfOV~VIcmo$y+Ns-pO5y?Gpun##R zxCYYh4UO*z<4$@ob_;O3dkcRL1aFTzI=4N=_4adXHPED2M+sm9fKQInRUi_U9tFPE zvocSo2m}<~l)Io96S)Z@OBsW~S5q{+q+~gZItrthm8tNk730dWoK%o1Bus}3u-;gk zo$R4!?%wT0=KpSEklN&6PfiH;2O)<*%v~mJ<+E`C{fZzG?I_K4im87gz^Hj4+?pQB z%~vIr`Q`PRJ7ui8L}$SS62Jd`KDilwzQkB*D}#;;U)(HaU1Ez_w@%{$3>n?`zOXVl z*Zi~VT71KPijORSQ}0Lt%dk3MVAW)h$ZRIYb7@B`c`7mW-ZeSRtJYuswmjiD9<-Ue?w4A#PqZA!WCae-Rule9hCg@OD6Qaal zsemn+u7>sDq(62Q1Mb*OOsGyQ2iTR)RPV|C$&3(*Lu!>OgB5=UmY=D-D41n6c`XEp zH#r?u;dW;?Yb0wGs|C^M8xhgV0`~N-EfLnGf~QVCS#Hd&T(~!V_9X?rQP9oB)uyZS z(P=2r04Oz_wnF8pw{#w}kF$FBwjsAI87kQd1PG34U^FN0rH{FFN^EUuJAbm6Wkr*W zg(4;G7E=8X&1HXJ)^RS9fQXBjl%Pwp5c$b-N*-3#)&kDwcJ%5dtK|3apVe<}3#) zfLE;Nw#Ff&-36$~-q=&DlfKkW{s1=K=DkVxMp99lapp1XOK%zqO zS3h{PXXnse>yrmZrTj5_I(v5!s~V3(!CoKCvK z%*@Q(Nq3l;nVGS|=`g3l%*@Qp%*@Qp*?cn^?T?)wE4{L=EURR@RAu>|d!93%Ye4uk z4vJ4yzv{r1nA-)7xdGbkTCW0gm6fIzA37ti;0RS#@lvys`<-`1I#7XPu%6X4$vQjfW&Tc>p4AY1 z?NGgnj>z$)eivy^6C=IR3D}hOCPV(e={>#v`J>~Y5sVVxh!+{ub;uYk)XTj19!tPu ztYi!Y84Vc3Wh1Qh+M5izKZc`^E5}=y#N4BwTyFom(thNW1L>$Cr~#ufZ1oRDV8 z;_iRa)bJvmU1qu_8GN|uUJ&tMPaOG?;O@HsZnzNchXvY$MWIR9*SDGn$J;GK_5cU(^Z4jQIl(LN$@6A2dSryiS+9h>u?BMfrA%CtFayXfdfjg*Mmh--+= z!rX~mZGDj5BL#pNCVpRC?F=TZ35MS9{H18S4P1{iOB8EkXiNyc>ev;GnjL_h??f z$8D(#ZV;vP0Hu+3d*WxPUS;4qn2+aMOWVWfL#maVNsj??TC%EM|LHd{wZf|##z+R6 zQPmuUhLN2KPp!Q-Cfa{tTy^y{)9>P&%2eHPgjKP>AJl83*Loy|A|`?S#R#6Y6>*8s zzLmX;=F@y+4%D8zw-mUk_0-{CRbB&sLME$x724dT6m zv>a#1_#zkg%1-H)?^!fE(G#zs?ns(Gc6_xE#jv&Q0@5KSlc>hx_$onpzc8>mI1!dU z)FFXiYVfTfgft@&0^W~WP0GD(4EGO5U8jRvh z*rslQZjdsrQhhqgOQ6{`)rBu5_(Wo7>APpRbGk+vvGA!0Xh=L4ADJ+t~eWRactMr?tb&gHe0eo5|~C z(;WZTN7=}MK#^-#R{PsZ(cIXU?Cbjq!53qPR@>Xt$N|P&n=U}A^=3u)ldI+Z?EX@> zD^1JiV`cxg?W7No_IUax5X}Ji(v7!y|D2j@o4fk-;l=?xdpSHI>B<&fB5lbm9wTje z^L4&YeWkKKWC1c+A6~8sfq-P%<0C+N%=adhpSK`=>Wdj``)KR4>-%IVkiKrF=El0D zI^TwDDf+(vLs#T|$Hj+g1I&dkjZlUlehHoO_YhqK4aLZH&; zd&r3E*Za%;ZFD@+$II9V^5^?P;P0>Zhx^;B_^VHMZfC%!Pw$4V7dKWf#vJ6w?o_;u z*UdwI2}5U!)EmYek~h~u4+B8J{dsJPV)lIO#NP+-a*(g8`)NFT#85Q~U#3;FWHmldqvJ({FIkgm+pqwg>4{`9O% z_AlT*&0KLyN_m_kOZxl%&PLjPGGfheWXW!2{J2hIAUC*6>ymjsPNN#|xtsVtiLjSL zTa=gg34tOcfB@09?H4E3XVVwk%Vm?U4CUimiN?E&ME8~tUo66w50AIo=;W4+LA35V$4HfJLEj(01bb#V*PWNRz1Rk{)_%x+1rFc(MiN z2*aWPy55{TUfNC$Oy|ZshQXXH{MzlWm+D?!^ znbdm#pZc?rS4CD2AHaCF*G#!Bq_N=@=mM-ugZvQG4Q>9RCD~NanM^m^74)pZ$s_$% zSR&w*04dKHD`8u2p|M*}i4wNFWF@sEM&dHS!{PVe3X5N*Gl^|tkbP-#qGoQ3;}mG= zRv#D8lAtV6xETAfKdW9P;tg)J%vdvP(Udn2ASBWK>Zoynagcc}GR<)-Zkb$;?GOYh@*|P} zO+`A1XVMBraYu}ApqVva#4Jz=$LhWkL`&izj(7Q}V1K~M9n5#r_KCr#nMKj7>z1DG z?rTacw%P3^x58yf#dhuV`UEcj!9lMBuGf3xm9j53!N$PkrO@>4 zQk~lAq}ca>FuqEHPW2+}GcdIE+591$^?p4!eNn&EQ&`i-Ouo8w>8}2mMrYQ-H7C07 zYHu01So7==x8%c@_R%rhib(pw{}9I0V>`Rrc8ccO8>qO5D^oQOQ#zu~t|JMwWq}~U z!0u2WffDsVK%v9#v9vGvtBlx{rSpOeEMbA519b&1u|O~au#%+_Ruj*(6ln$4Q?NR_ z_8Pl4A&Et+6F^ikI4XvJU1ikb|0d5!5`HRSJWjh?{F0814=8fuqAyNHh@!1)QuB_G zZ3%#1A|MxP6Iu3tyY#YSMXGsLB7gWMN|vUJ?9SN?1dQ@TDMdHfu1jm&2|gV1AGlFs>DyZ#sYJVk46XLTih!b;)qb1;N(s9Ep}Q*4f9cOtl>$4p*=(xtmbq4g zCvg{css!wby?r>wa&DHYa8d~2wL2kO-+dXt^x4OV2G+q2oc?g;i|2%lnm2M zk?oRFi7PIru7cA0?o9$y=i`rpBv&qxA~xV3*+`e)RI$VJ#@x7q2HE3^!oJS@{o5$@ zBRLbg5RC3D&p#fE%IYaJBUUl(Vv6#I2NYfv>p~P*Ez8;8ob2y{l zeWiLU70-ev$YFIfD5#y1nN0PJi24%geUZ^r5b-~dXCyqn{l`=K_jpWs-5bY%!8}D_3|G#u{=iX0?jfo(k|FVbsg!0JE&FhoRl+Ux;! z^fN1cS|FG@UO#1ZJ5Eowo2t;e(nYZcXqc7Is{{k9(1F!By(eY*Lx!W~yJYsMuXgF| z{h_obvBJcoKc6m4IYzGe5oYA-Z6hSGzN+A??q?eo*@cs96THM}3!ducjh-H+c^j;} z7P;>a{}i@Hmbe)fG(?I3s<2B~@8T#hm_1LV8WMjMY8B}GQoTVMQ4XkzOPA(Y`mbYu z8yen9&kM8j4yXmdkH0-jrC6lI?YUI03d1TE&Jx7d?TRN`EIaUE`HPtTd2FTd6o+GD zmyX%w=rO{(RzF)4;bVyJxD-QC6k{QX71=Y#s(44Bx#a#WwFuy{9?6>gx*9fYx=FSu zFRp~84hi;@WFrr}S#9^iUlaYI_*hF2i?JuZY{~g-H;eDcRYccp_jx$1*2I)#Q=XIm zBHk7priUhdu;lMu6VVWYTu6Hm^|)c!@FUw-5R~WGi|du?a#*FXW<8+7!68zm zAfGs&#(ICVP9ISA{<|rc(xk0Upb0dpRj2{9!WTO|I_a9aOg~Sg^*!l zps+o%-K00=#3SLb*NhUFJiiT^xyUpU`WR#t*)Thtm3u}qvB-5*Vfib~mMIwN8nt5sCkw@8pn zUj(p=npzmFw=?P}e}CMG*@ZaJbbC1a4Xd7Y(QFAqu#KGM%)%cVcERTy!QzRzc!cUS z%tm43KDjK0`)@&{qt+j+o~Ec8)cA;=g>oZ$`ZM3ya0St{*cURU;!nmw>X*qVk9!*{ z31d%18{vOBGZK(Uj#A7xI?QP{`FEOz@_?o#cE~Sxnu5tN4BKpa5&dmBmB8-yYGOl^ z8cKo)nQ?gaIC@dlydZkD8H~Z)!@lZc!FdYrq(YLkOJhaqtA^;hZvC2<%rP=!; zzsggk;w#{o*HT}`R0^L$$A5YetO3Y%C0GmNcrXZ?Vbsb??5OKWAk}ZjL8FUL4Wwn% z1@+#C;Nw9D7bL$$$&B1DY4kn5fvs!U~*3l=zYqs@sz@OmmPt?85Gj%36d2oSIESdyZ z5A+eG*FNadzo$~QDiRdLFIV4h3D|%?`5|Zk9jr8ofb8ddW9kbMs7{&{NTP{>y688V=g;p!nt>erJgTy?~@qOB6{LB0qJ>D6zKlIOmjK<`h+u^y`PC z`7r5StO1GP6j4(b?v7{yT>U2sYWuN5Pb|ge<&Kr1@?pU^iuopDuphY%C*CBE1DnGD z(n___#cMrLxLM^}Dq}K(0}bGC0*K=vdjsQAs47*yE44Z;O!VO3{VP?kCsKa}kAn`w z=tJ%KQ`GNgSgBOW05W#ek-@b72DWc*&e}MVH+FVou_Peu0j1*Lbda0Rcrdqqk{Re! z38{$HKo!h9`I@gK#gFZaJ&|9^>j((|*$bcLrXsNlwGLWV-WX`8bQo=@to?7$Ux3&* z=uaMk`-O3mp2IEN5&>z7V@7p!UN;v--525hI753t2+w0O4298u8enRS&?q=hlPr;1 zG+c~ZFHMVS_x~CL{jERW!xIIL7jvi@0zrub9QId9>FF8Y!QH<1e{z1 zVKL6*D*+$kOKvEz>I{jN_unDOaO z#dL!c+60)>)qTE({E!pO|B~Yk8K`t6V=CSIZI6gi@`axE zOv-TW_4*?60W#&aTmz?RDw3B5Zm7CFKe8vJ%|0sN2O$8 zklpGK)hBCEk*eW9_0L+(N$zS=7A#z1LGolN@K~A~tgOImu6f*m`Q`y$)KsZn=oorQ z@fFmzK4_7!s)IkP^rqKvPJkTq>VKUx#3$tYN;rO1i3n|7qss$0jkt7hn3US z1#v_1)a3hCfx*mCQf7zwq&ZNj!N@R>>G1yydsw3@R%#wEJ)VBZD;QP8+|*)|DhsVa zz;=+^L3+E=myTykITWnqms(kCH?1)$r7@QV>Eiu%V~z2^EcWYR69A-T=++lWd5 zAPTW{8pKExulLg`?d6MuNvi+q3V2+k&=4G}9NiRHW^F;5@1>ZeXQ;f%&|TGt-lMuE z-XVF88(QU{a)7L@P6mCToOn@#y$dY1GxJcN_*n9t)+I;P!FDz!o8lo(g}IeU<8y@Y zV(j<)U2}yv;B)_c1qv7#i;_D{5iD^f;XpMm=cCgeU43J}>kC8XUS`Gt4=RiMR@Z-d zTB8b_>zJ1rUQsWk z9HPn}26;xc{)nP?Ohnovq@tUct^36_H^c_`;?T7~AJSBYDgch4F0kklsaC@~;!?;3 z1CEp7^Rb0VXhI2MBj~&g1}gOwH2KV}Hf7SlT{S2|N3wb2@~uS4gi~vw(~Q^rRNxpR z{3H+ptfFS*yk#tjqO>QwHHDckLDbdQW-Vc6$IJcQbyzw3!f|zEL+dq6JHY4Ci+g5P*GV{|OB>`xd%ADl z>Mx``hsXv`+W+YFGp>s#rJT?jGB+v6D?%eQoc4ykl_~z|0yAnv^WB8r2!HI%aG?=Ww68 ztX6hb$S4Zac$YYU)w3nn-b<5&&bP|N^&Qi(fTv9D40*PjlCVtFw!+@oG|_K%$CH@1 zNA(&rzGs8!;^QUl`}!g`0d0Th?UEqQSrb)Z2^#}PrrIF+kN+O!F~G%OjAJu z4oPG1QGQJ`LGCciY51RpF=B>E%_h;_{B7**IfQ5n&2X^oXr))IhWQnbK8wxx_gi=j zKvku+gt>*I;aMyu;gmhZ^;+;v79L4Rl({(ZWlE97sRChTbVVeyX$lj$HeF`u?U_CR z^@dWqr+%i))gK{E$~OxAexDxGxB$%4CpRKmhmFV$DkF7V2Av2JlA*!HCiP-Skr+bW z2dP8YEm1p`X`_`7%&oD%5?C}LjRbMX1t8)N!WXim7wU6RMB9S{dj0hl^s&=(0eX{W z;~;^6I4r>HdCTN0J&%4(2>^i*trm9tAG&@Q^(?J{^>|#=PBj4H&SLw*Tb2*@C zJQO*TtF2$NjAO9Yy@KakQ&#EwkEZooM+c#cq(3 z7~)WfS2#*F6$++BMqSvB7;tADxz~UMu%<4#@J^33Qm7hw z<(->*WY^Lmg~H!0OY8iWG=FSYr1>0G%43ajaA)vY8;#+vZ$s{x&dR-uZlz9!0B@9#50a7qGsC_xtccGa^`l zt1%H}&K&k=8f-oiUQK39b-^I4UMMl=i^kUSm5bclZ@=hK-kBAqcY zWvg*6EM!M_dSY9i%6`AA))nRb`=2#6ZD$oP z2wH8OhXGREhU`1#a3_#6nZ?z$UB`+Gc0o{yZjD~<`O#oF?N|d!UcHG7LzzEh5FtJ; zKbmy|7~&(z0UEXJP|Z!O>K?_Ww5C6HZSF!v2?_BB)GS6B$Ev;Q+gg-G}&e=U*Y@i9M45^3NR6xv8 z%hjpk3739}-tvHg*J^0H)q*S%!%}uZke&)FsXfPlU&zveuBD!py#3@;19qjL4R0Zk zaC5C00oNrU-~iaq{JwYhOr0AwO->-xlF!VWspO#in7wc3Q&Ig%I<0Fi#jrqoC*;}= zzkC-&CN~AYl39F{b#wt&oTM{wn>ILf!p`}{AV2fQPPTu+&AzAOx$HR-OMzer3cIHIi-?~?i-!pj�#sw0E=(#f*RB^T{-{k(yGQ14!-LBNH?;t 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