diff --git a/.agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/AUTH_HANDOFF.md b/.agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/AUTH_HANDOFF.md
index db923bac7..04c916a38 100644
--- a/.agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/AUTH_HANDOFF.md
+++ b/.agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/AUTH_HANDOFF.md
@@ -20,7 +20,7 @@ activation order below.
The remaining AUTH order requires one correction before submission work can go
live: split XINT-06 into `06A` (pre-submit materializer only, after hidden
-ART-04B and before XINT-05A) and `06B` (post-submit materializer plus checker
+ART-04B1-04B3 and before XINT-05A) and `06B` (post-submit materializer plus checker
output write/binding, after ART-06A/06B). This prevents contributor preparation
from activating while its mandatory fixed materializer still denies.
@@ -99,7 +99,8 @@ immutable historical records and the deterministic deletion proof. They are
not an active design, grant, route, compatibility alias, or permission to
implement a second intake path.
-ART-04A1 through 04C2 then implement one hidden continuous surface and publish
+ART-04A1 through 04C2, with 04B split into 04B1-04B3, implement one hidden
+continuous surface and publish
its exact route/resource/guard manifest. After 04C, a separate reviewed AUTH
activation contract may integrate the evaluator and change only
`artifact.submission_bundle.prepare` to active. ART-05 cannot start until that
diff --git a/.agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/CHUNK_MAP.md b/.agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/CHUNK_MAP.md
index 8b309166e..1a0526fcd 100644
--- a/.agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/CHUNK_MAP.md
+++ b/.agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/CHUNK_MAP.md
@@ -22,12 +22,16 @@ they cross multiple L1 boundaries.
| Chunk | Goal | Risk | Entry gate/status |
|---|---|---:|---|
-| `WS-ART-001-PLAN3` | Reconcile the complete remaining v0.1 custody chain and AUTH/REV/CON handoffs. | L1 | Planning only; proposed |
+| `WS-ART-001-PLAN3` | Reconcile the complete remaining v0.1 custody chain and AUTH/REV/CON handoffs. | L1 | Merged planning |
+| `WS-ART-001-PLAN4` | Define the central default pre-submission checker catalogue, disable semantics, and split execution contract. | L1 | Planning complete; internal review passed; PR pending |
| `WS-ART-001-03C` | Clean-cut legacy guide identity/excerpts and make the verified same-generation pipeline live. | L1 | Merged PR #249 |
| `WS-ART-001-04A1` | Remove legacy multi-step contributor intake reachability and schema without adding the replacement route. | L1 | Merged PR #264 |
-| `WS-ART-001-04A2` | Add bounded one-outer-ZIP intake and archive-safety inspection in private scratch. | L1 | Implemented; internal review passed; external PR gates pending |
-| `WS-ART-001-04A3` | Add canonical semantic manifest, executable normalization, and unchanged-work gate. | L1 | Proposed after 04A2 |
-| `WS-ART-001-04B` | Run non-bypassable platform and locked-guide prechecks against that exact scratch tree and persist bounded evidence. | L1 | Proposed after 04A3 |
+| `WS-ART-001-04A2` | Add bounded one-outer-ZIP intake and archive-safety inspection in private scratch. | L1 | Merged PR #266 |
+| `WS-ART-001-04A3` | Add canonical semantic manifest, executable normalization, and unchanged-work gate. | L1 | Merged PR #268 |
+| `WS-ART-001-04A4` | Remove the legacy independently invocable caller-owned submission-precheck route and contract. | L1 | Proposed after PLAN4 |
+| `WS-ART-001-04B1` | Add the single versioned checker catalogue and compile one effective execution plan from platform defaults plus locked project policy. | L1 | Proposed after 04A4 |
+| `WS-ART-001-04B2` | Materialize the sealed manifest tree once and execute the mandatory platform/default catalogue phases. | L1 | Proposed after 04B1 |
+| `WS-ART-001-04B3` | Execute locked project-policy rules through the same plan and persist one bounded immutable evidence set. | L1 | Proposed after 04B2 |
| `WS-ART-001-04C1` | Reauthorize and atomically persist capacity plus durable put intent, then write the checked ZIP once. | L1 | Proposed after XINT-06A |
| `WS-ART-001-04C2` | Reuse verification/recovery to publish one capacity-charged ready admission and compose the hidden continuous endpoint. | L1 | Proposed after 04C1 |
| `WS-ART-001-05A` | Atomically consume ready admission into one immutable Submission and binding under fresh human/service authority. | L1 | Proposed after XINT-05A |
@@ -45,7 +49,7 @@ they cross multiple L1 boundaries.
```text
AUTH-04B implementation [merged PR #245]
-> ART-03C
--> ART-04A1 -> 04A2 -> 04A3 -> 04B
+-> ART-04A1 -> 04A2 -> 04A3 -> PLAN4 -> 04A4 -> 04B1 -> 04B2 -> 04B3
-> XINT-06A pre-submit materializer activation
-> ART-04C1 -> 04C2
-> XINT-05A contributor preparation activation
diff --git a/.agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/DECISIONS.md b/.agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/DECISIONS.md
index 97382d3e7..5adc85abe 100644
--- a/.agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/DECISIONS.md
+++ b/.agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/DECISIONS.md
@@ -506,7 +506,7 @@ new snapshot. None creates a sufficiency decision.
The continuous submission-bundle request cannot become live while its fixed
pre-submit materializer is unavailable. AUTH therefore splits checker
-activation: pre-submit materialization activates after hidden ART-04B evidence
+activation: pre-submit materialization activates after hidden ART-04B1-04B3 evidence
and before XINT-05A activates contributor preparation. Post-submit
materialization and checker output/binding activate later after ART-06A/06B.
@@ -538,3 +538,49 @@ v0.1 Workstream lifecycle and requires a future reviewed initiative.
Local/MinIO product lifecycle proof, AWS deployment activation proof, and final
cross-domain conformance are separate PRs. AWS readiness cannot bury product
behavior, and product API proof cannot claim AWS production eligibility.
+
+## D52 - One Versioned Pre-Submission Checker Catalogue
+
+All Workstream platform defaults and constrained project-policy primitives are
+registered in one code-owned, versioned catalogue. Each entry has a stable ID,
+version, owner, phase/order, dependencies, classification, input capability,
+default operational state, disabled behavior, limits, bounded result contract,
+and policy trace. The effective execution plan combines non-bypassable artifact
+custody, Workstream defaults, and the task-locked Project Guide policy. It runs
+through one internal API and returns one ordered result envelope. A second
+registry, project-specific execution API, or scattered string dispatch is
+forbidden.
+
+## D53 - Disabling A Mandatory Default Fails Closed
+
+Every catalogue entry exposes `enabled|disabled`, but availability is not a
+policy bypass. Only startup-validated, versioned deployment configuration may
+disable an entry in v0.1. Contributors, Project Managers, project policy, and
+task parameters cannot toggle it. Disabling a mandatory security, integrity,
+or accountability entry makes submission-bundle preparation unavailable and
+causes no durable or provider effect. Disabling an advisory entry permits the
+remaining plan to run and records the disabled entry in bounded evidence. A
+locked project-required rule cannot be disabled at runtime; changing it
+requires a new approved policy lineage.
+
+## D54 - Generic Defaults Avoid Project Semantics
+
+Workstream defaults cover universal custody and submission-contract facts:
+outer-ZIP structure, archive/path/resource safety, exact archive identity,
+semantic manifest identity, executable normalization, unchanged-work rejection,
+sealed scratch integrity, high-confidence sensitive-file exclusions, required
+packet fields, and contributor accountability. Task-specific filenames,
+directory layouts, languages, tests, evidence meaning, and quality criteria
+come only from the locked Project Guide policy. Ambiguous name heuristics such
+as broad `token*`, `secret*`, `credential*`, or dependency-directory matches
+must not silently remain universal blocking rules; the implementing chunk must
+classify them as narrowly high-confidence blocking checks, advisory checks, or
+project-specific policy and prove the migration.
+
+## D55 - Legacy Standalone Precheck Is Removed Before Catalogue Execution
+
+The existing caller-owned `/submission-precheck` request cannot prove the exact
+uploaded ZIP or sealed server manifest and would create a second execution API.
+04A4 removes its route, schemas, service entry point, and OpenAPI surface before
+04B1 installs the authoritative catalogue. Pre-production accepts this clean-cut
+gap; there is no compatibility alias, redirect, or caller-manifest adapter.
diff --git a/.agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/DISCOVERY.md b/.agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/DISCOVERY.md
index 5a5481c50..9153caa8a 100644
--- a/.agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/DISCOVERY.md
+++ b/.agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/DISCOVERY.md
@@ -243,3 +243,38 @@ Plan-review resolution:
ledger tables completely; it does not retain detached compatibility fields.
- Downgrade recreates only the exact empty legacy schema proven by the upgrade
precondition. It never fabricates a session/item lineage from newer facts.
+
+## 2026-08-04 Default Pre-Submission Checker Catalogue Discovery
+
+Merged ART-04A2/04A3 already own outer-ZIP safety, resource bounds, archive
+identity, canonical semantic manifests, executable normalization, and the
+unchanged-work gate. These trusted capabilities must be registered into
+pre-submission execution, not reimplemented as another checker stack.
+
+Projects already merge `WorkstreamDefaultSubmissionArtifactPolicy` with the
+approved `SubmissionArtifactPolicy`, and the trusted compiler emits a locked
+`PreSubmitCheckerPolicy`. The remaining defects are execution shape and
+catalogue ownership:
+
+- checker names/defaults are spread across policy constants, compiler
+ primitives, legacy registry code, templates, and historical docs;
+- the legacy `/tasks/{task_id}/submission-precheck` accepts caller-owned packet
+ and manifest facts and cannot be the authoritative one-ZIP execution path;
+- combined 04B crosses catalogue, sealed materialization, platform execution,
+ project execution, persistence, and API-result boundaries;
+- broad forbidden-name patterns can false-positive legitimate generic projects;
+- `disabled` has no safe canonical meaning for non-bypassable defaults.
+
+PLAN4 splits 04B into catalogue/effective-plan composition, sealed default
+execution, and locked-project execution/evidence. v0.1 catalogue state is
+startup-validated deployment configuration. Disabling mandatory custody,
+integrity, or accountability fails preparation closed; only advisory entries
+may be disabled while remaining execution continues. Project policy and
+task/runtime input cannot toggle catalogue availability.
+
+The catalogue snapshot is immutable. Its version, canonical manifest digest,
+ordered entry ID/version/configuration hashes, and enabled/disabled state are
+embedded in the compiled `PreSubmitCheckerPolicy`. The existing task-locked
+compiled-bundle hash therefore commits to the exact default snapshot without a
+second task-lock field; runtime derives and records the effective-plan hash from
+that same snapshot plus the locked project rules.
diff --git a/.agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/PLAN.md b/.agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/PLAN.md
index 2934fb81c..6a7958513 100644
--- a/.agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/PLAN.md
+++ b/.agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/PLAN.md
@@ -307,10 +307,36 @@ separate cumulative safety proof.
Both identities are compared with the immediate prior immutable `Submission`.
Exact archive equality or semantic equality rejects before checker and provider
-I/O. Mandatory Workstream gates and the task's locked Project Guide checker then
-consume the same read-only scratch tree. A project may narrow platform limits
-but cannot disable gates or raise limits. Checker failure creates findings only
-and destroys scratch without durable artifact, Submission, or review state.
+I/O. One ordered pre-submission execution then consumes the same read-only
+scratch tree. It is assembled from a central, versioned Workstream checker
+catalogue:
+
+```text
+non-bypassable artifact-custody gates
++ Workstream default submission-policy checks
++ task-locked Project Guide checks
+= one effective pre-submission execution plan and one result envelope
+```
+
+The catalogue is the sole registry for stable checker identifiers, versions,
+phase/order, dependencies, owner, input capability, severity class, default
+availability, disabled behavior, resource limits, stable outcomes, and policy
+trace. Runtime services may dispatch through typed adapters, but may not grow a
+second checker registry or scattered name-based conditionals.
+
+Every catalogue entry has explicit `enabled|disabled` operational state. A
+disabled mandatory security, integrity, or contributor-accountability entry
+makes preparation fail closed as platform infrastructure unavailable; it is
+never recorded as skipped-and-passing. A disabled advisory entry is omitted
+from execution only through startup-validated, versioned deployment
+configuration and is recorded in the bounded result manifest. Contributors,
+Project Managers, task parameters, and project policy cannot toggle catalogue
+availability or weaken a mandatory default. Project policy may narrow platform
+limits but cannot raise them. Only a completed checker result may create bounded
+structured contributor findings. Infrastructure failure, disabled mandatory
+checks, resource exhaustion, cancellation, and authorization failure produce a
+stable retryable infrastructure outcome with no contributor finding, durable
+artifact, Submission, or review state; scratch is destroyed.
A passing result stays bound to the same process-local scratch generation and is
consumed immediately by the normal durable admission path. It is never a
@@ -565,8 +591,10 @@ them; no runtime plugin discovery or parser fallback is permitted.
identity/continuation clean cut.
2. Contributor intake accepts one outer ZIP, inspects and manifests its complete
tree in bounded private scratch, and rejects exact or semantic unchanged work.
-3. Mandatory platform gates and locked Project Guide pre-submit checks execute
- against that same scratch tree. Failure produces no durable bytes.
+3. The central Workstream checker catalogue composes mandatory platform gates,
+ Workstream default submission-policy checks, and locked Project Guide checks
+ into one ordered effective execution against that same scratch tree. Failure
+ produces no durable bytes.
4. Passing bytes enter the existing immutable store once. Complete read-back
verification publishes one bindable admission; ambiguity uses existing ART
recovery.
@@ -686,7 +714,10 @@ AUTH-04B implementation/activation [merged PR #245]
-> ART-04A1 legacy contributor-intake removal
-> ART-04A2 bounded outer-ZIP safety/intake
-> ART-04A3 semantic manifest + unchanged-work gate
--> ART-04B scratch-bound platform/project prechecks
+-> ART-04A4 legacy standalone precheck clean cut
+-> ART-04B1 default-checker catalogue and effective-plan contract
+-> ART-04B2 sealed scratch materialization and platform-default execution
+-> ART-04B3 locked-project execution and immutable bounded evidence
-> XINT-06A pre-submit materializer activation
-> ART-04C1 durable intent + one provider write
-> ART-04C2 verified ready-admission publication
@@ -705,7 +736,8 @@ AUTH-04B implementation/activation [merged PR #245]
-> XINT-08 + ART-08C final v0.1 conformance
```
-04A1-04C2 remain hidden internal pieces of one continuous contributor request.
+04A1-04C2, including split 04B1-04B3, remain hidden internal pieces of one
+continuous contributor request.
No intermediate HTTP route, durable upload session, scratch handle, local path,
or prepared authorization crosses those PR boundaries. 04C2 alone composes the
hidden endpoint after every internal dependency exists.
diff --git a/.agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/REVIEW_LOG.md b/.agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/REVIEW_LOG.md
index a0aaf6781..6c7b4c450 100644
--- a/.agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/REVIEW_LOG.md
+++ b/.agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/REVIEW_LOG.md
@@ -299,3 +299,38 @@
semantic-lane inventory, stale scans, links, and diff checks pass.
- Architecture, security, QA, product/ops, senior engineering, CI integrity,
docs, reuse/dedup, and test-delta final reviews pass.
+
+## WS-ART-001-PLAN4
+
+- Replaced combined 04B with a bounded sequence: 04A4 removes the legacy
+ caller-owned standalone precheck, 04B1 installs the sole versioned catalogue,
+ 04B2 executes mandatory platform/default checks on one sealed tree, and 04B3
+ executes locked project rules and persists one bounded evidence set.
+- Initial review found conflicting standalone-precheck docs, duplicated registry
+ risk, stale caller package/hash/manifest authority, missing route-removal
+ ownership, weakened coverage commands, and lost executable/crossed-state test
+ obligations. All were repaired in the plan and canonical docs.
+- The v0.1 catalogue gives every entry a stable ID/version, classification,
+ phase/order/dependencies, typed inputs, bounded result, policy trace, and
+ explicit operational state. Mandatory disabled entries fail preparation
+ closed; only advisory entries may be disabled while execution continues.
+- Broad sensitive-name heuristics are no longer silently universal blockers.
+ High-confidence exclusions remain blocking; ambiguous patterns must be
+ advisory or locked project-specific.
+- Canonical flows now distinguish contributor ZIP/summary/attestation input from
+ server-derived archive identity, semantic manifest, pre-submit evidence,
+ verified admission, ArtifactBinding, and post-submit materialization.
+- Architecture, security, QA, product/ops, senior engineering, CI integrity,
+ reuse/dedup, and test-delta reviews pass after repair. Docs review identified
+ and repaired final route-prefix and AUTH owner-table drift; final confirmation
+ is recorded before publication.
+- CodeRabbit then found seven valid specification gaps: namespace mapping,
+ typed result provenance, infrastructure/finding separation, audit redaction,
+ immutable catalogue snapshot locking, stale historical response wording, and
+ residual client-shaped evidence fields. All are repaired after rebasing onto
+ current main; the external response and complete PR trust bundle record the
+ disposition.
+- Focused architecture, security, QA, and docs re-review pass the external
+ repair. Architecture additionally required authority-neutral shared result
+ identity and complete platform/default dispatch mapping; both were repaired
+ before final publication.
diff --git a/.agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/RISKS.md b/.agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/RISKS.md
index 49f339066..3a7a2632d 100644
--- a/.agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/RISKS.md
+++ b/.agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/RISKS.md
@@ -62,8 +62,13 @@
| Stale Celery delivery processes replaced guide content | Critical | Payloads contain identifiers plus setup generation only; executors reload current lineage, binding, extraction, run, and generation before invocation and persistence. |
| Unsupported image/audio/video content is passed raw to an agent | High | PNG/JPEG/WebP expose bounded structural metadata only; OCR and audio/video are unsupported, and image-only required text stops setup internally. |
| Extracted guide text performs prompt injection | Critical | Delimit and label extracted material as untrusted data, expose no tools/secrets/provider authority, enforce typed output, and test adversarial embedded instructions. |
-| Contributor preparation activates before its fixed pre-submit materializer | Critical | Split XINT checker activation: activate pre-submit materialization after hidden 04B and before XINT-05A; keep post-submit/output actions planned until ART-06 evidence. |
+| Contributor preparation activates before its fixed pre-submit materializer | Critical | Split XINT checker activation: activate pre-submit materialization after hidden 04B1-04B3 and before XINT-05A; keep post-submit/output actions planned until ART-06 evidence. |
| Review packet ownership is confused with review lifecycle ownership | Critical | ART owns exact binding materialization and integrity; REV owns packet manifest, lease, assignment, decision, and notes/findings through a typed joint contract. |
| Reviewer evidence actions create an unapproved upload path | High | Keep review-evidence binding planned and unavailable unless a separate approved REV requirement adds exact slots and guards; reviewer revision remains note/findings only. |
| Contribution or delivery silently changes accepted bytes | Critical | ContributionRecord stores accepted Submission/binding/content identity without provider I/O; future delivery requires a separate authorized full-read capability and rehash. |
| Final live-proof PR hides product or cloud implementation | High | Split Local/MinIO API proof, AWS deployment activation, and final conformance into separate reviewable chunks. |
+| Default pre-submit checks become scattered registries or duplicate APIs | Critical | Use one code-owned, versioned catalogue and one effective execution/result contract; typed adapters register capabilities without creating alternate dispatch paths. |
+| A disabled mandatory checker is treated as a pass | Critical | Mandatory security, integrity, and accountability entries fail preparation closed when disabled; only advisory entries may be disabled while execution continues, with explicit evidence. |
+| Broad filename heuristics block legitimate generic projects | High | Keep only narrowly high-confidence universal exclusions blocking; classify ambiguous patterns as advisory or project-specific and test false-positive boundaries. |
+| Project policy or task parameters toggle platform availability | Critical | Catalogue availability is startup-validated deployment state; project policy can add or narrow rules but never disable or downgrade Workstream defaults. |
+| Legacy caller-owned precheck remains beside the new catalogue | Critical | 04A4 removes the route/schema/service/OpenAPI surface before 04B1; no alias or adapter may preserve independent execution. |
diff --git a/.agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/STATUS.md b/.agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/STATUS.md
index 3f9fb56e6..84402929a 100644
--- a/.agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/STATUS.md
+++ b/.agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/STATUS.md
@@ -112,10 +112,17 @@ remain pending.
AUTH `WS-XINT-002-04B` activated only fixed-service binding and guide read.
ART-03C removed the legacy identity/excerpt path and made the verified pipeline
-authoritative. ART-04A2 merged through PR #266. ART-04A3 is implemented on its
-bounded branch with canonical server-derived semantic manifests, executable
-normalization, and fail-closed unchanged-work comparison. Internal L1 reviews
-and focused evidence pass; hosted PR gates and human merge remain pending.
+authoritative. ART-04A2 merged through PR #266. ART-04A3 merged through PR #268
+and provides canonical server-derived semantic manifests, executable
+normalization, and fail-closed unchanged-work comparison.
+
+`WS-ART-001-PLAN4` is the planning-only correction, implemented with all
+required internal L1 review tracks passing. It replaces the
+oversized 04B contract with 04A4 legacy standalone-precheck removal, 04B1
+catalogue/effective-plan composition, 04B2 sealed materialization plus mandatory
+platform/default execution, and 04B3 locked-project execution plus immutable
+bounded evidence. No runtime behavior or AUTH availability changes in PLAN4;
+hosted PR gates and human merge remain pending.
## Gate
diff --git a/.agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/chunks/WS-ART-001-04A4-legacy-precheck-removal.md b/.agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/chunks/WS-ART-001-04A4-legacy-precheck-removal.md
new file mode 100644
index 000000000..d2adea2e2
--- /dev/null
+++ b/.agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/chunks/WS-ART-001-04A4-legacy-precheck-removal.md
@@ -0,0 +1,67 @@
+# Chunk Contract: WS-ART-001-04A4 - Legacy Standalone Precheck Removal
+
+Initiative: `WS-ART-001` | Risk: L1 | Status: Proposed after PLAN4 approval
+
+Artifact contract phase: `upload_admission`
+
+## Goal
+
+Remove the independently invocable caller-owned submission-precheck API before
+the authoritative server-derived catalogue path is installed. This is a clean
+cut with no replacement route in this chunk.
+
+## Allowed Files
+
+- checker router/service/schema removal for
+ `/api/v1/tasks/{task_id}/submission-precheck`;
+- removal of pre-submit-only legacy request/response helpers and registry
+ membership after proof that no durable/post-submit caller uses them;
+- OpenAPI, route-negative, import/reachability, docs, and focused tests;
+- CI only to preserve exact existing coverage gates.
+
+## Not Allowed
+
+- new catalogue, checker execution, ZIP/scratch changes, provider I/O, durable
+ evidence/admission/Submission, compatibility alias, redirect, or fallback;
+- removal of compiler primitives or durable/post-submit checker behavior needed
+ by 04B1/04B3 and later ART-06;
+- AUTH availability/grant changes or public replacement endpoints.
+
+## Acceptance Criteria
+
+- route and OpenAPI schema are absent and return the canonical not-found result;
+- caller-owned `artifact_hash_manifest`, package/provider references, and legacy
+ packet shape cannot reach a pre-submit service through HTTP or internal public
+ methods;
+- no alias, redirect, compatibility parser, or second registry survives;
+- constrained compiler primitives and durable post-submit runner behavior remain
+ available for 04B1 reuse;
+- import/reachability tests prove no product composition root exposes the old
+ path;
+- no artifact, task, Submission, checker-run, audit, or AUTH behavior is added;
+- focused subsystem coverage is at least 90 percent and repository coverage
+ remains at least 78 percent.
+
+## Verification
+
+```bash
+(cd backend && .venv/bin/pytest tests/test_submission_precheck_removal.py tests/test_openapi_contract.py tests/test_checker_runner.py -q)
+(metadata_dir="$(mktemp -d)" && trap 'rm -rf "$metadata_dir"' EXIT && (cd backend && WORKSTREAM_TEST_ADMIN_DATABASE_URL=postgresql+asyncpg://workstream:workstream@localhost:5433/postgres .venv/bin/python scripts/run_isolated_tests.py --metadata-json "$metadata_dir/result.json" --timeout-seconds 12600 -- .venv/bin/python -m pytest -q --ignore=tests/test_isolated_database_runner.py --cov=app --cov-report=term-missing --cov-fail-under=78))
+(cd backend && .venv/bin/coverage report --include='app/modules/checkers/*,app/api/router.py' --precision=2 --fail-under=90)
+(cd backend && .venv/bin/ruff check app tests)
+python3 scripts/check_stale_artifact_contracts.py
+python3 scripts/check_stale_workstream_wording.py
+python3 scripts/check_markdown_links.py
+PYTHONPATH=. python3 scripts/test_lightweight_agent_gates.py
+```
+
+## Required Reviewers
+
+Senior engineering, architecture, QA/test, security/auth, product/ops,
+reuse/dedup, CI integrity, test delta, and docs.
+
+## Human Review Focus
+
+- Is the old API truly unreachable rather than hidden behind an alias?
+- Were reusable compiler/post-submit capabilities preserved?
+- Does this chunk introduce no replacement behavior?
diff --git a/.agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/chunks/WS-ART-001-04B-pre-submit-admission.md b/.agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/chunks/WS-ART-001-04B-pre-submit-admission.md
index 8eb486f85..5ab01f817 100644
--- a/.agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/chunks/WS-ART-001-04B-pre-submit-admission.md
+++ b/.agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/chunks/WS-ART-001-04B-pre-submit-admission.md
@@ -1,6 +1,9 @@
-# Chunk Contract: WS-ART-001-04B - Scratch-Bound Pre-Submission Checks
+# Superseded Chunk Contract: WS-ART-001-04B - Scratch-Bound Pre-Submission Checks
-Initiative: `WS-ART-001` | Risk: L1 | Status: Proposed after 04A3
+Initiative: `WS-ART-001` | Risk: L1 | Status: Superseded by PLAN4
+
+This combined contract is retained as historical evidence. It is replaced by
+`04B1`, `04B2`, and `04B3`; no implementation may start from this file.
Artifact contract phase: `upload_admission`
diff --git a/.agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/chunks/WS-ART-001-04B1-default-checker-catalogue.md b/.agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/chunks/WS-ART-001-04B1-default-checker-catalogue.md
new file mode 100644
index 000000000..deef71f95
--- /dev/null
+++ b/.agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/chunks/WS-ART-001-04B1-default-checker-catalogue.md
@@ -0,0 +1,164 @@
+# Chunk Contract: WS-ART-001-04B1 - Default Checker Catalogue
+
+Initiative: `WS-ART-001` | Risk: L1 | Status: Proposed after PLAN4 approval
+
+Artifact contract phase: `upload_admission`
+
+## Goal
+
+Create the single typed, versioned pre-submission checker catalogue and compile
+one effective execution plan from Workstream platform defaults plus the exact
+task-locked Project Guide policy. This chunk defines composition and validation;
+it does not read ZIP bytes, execute checkers, persist evidence, or expose a route.
+
+## Allowed Files
+
+- checker catalogue, typed entry/plan/result contracts, and composition code;
+- reuse/migration of existing compiler primitive definitions and runner adapters
+ into the catalogue, deleting parallel maps/constants without aliases;
+- adapters that register already-merged ART safety/manifest capabilities by
+ stable identity without reimplementing them;
+- project checker compiler integration needed to emit the one effective plan;
+- startup configuration/validation for catalogue availability;
+- focused tests, docs, and chunk evidence;
+- CI only when needed to preserve or add the exact scoped 90 percent gate.
+
+## Not Allowed
+
+- ZIP parsing, scratch materialization, checker execution, or durable evidence;
+- a second registry, project-only execution API, dynamic plugin discovery, or
+ string-dispatch conditionals outside the catalogue;
+- per-user, per-project, per-task, or runtime mutation of catalogue availability;
+- AUTH availability/grant changes, provider I/O, Submission/admission creation,
+ post-submit/review/contribution work, or larger configured limits.
+
+## Catalogue Contract
+
+Each entry declares: stable ID, version, owner, phase/order, dependencies,
+classification (`mandatory_security`, `mandatory_integrity`,
+`mandatory_accountability`, or `advisory`), typed inputs, result schema, stable
+failure code, resource budget, default state, disabled behavior, and policy
+trace source.
+
+The initial platform catalogue names the already-owned capabilities for outer
+ZIP format, archive/path/entry/resource safety, archive digest/size, canonical
+semantic manifest, executable normalization, unchanged-work rejection, sealed
+scratch integrity, high-confidence sensitive-file exclusion, required packet
+fields, required accountability attestations, and warning-only generic quality
+signals. Project-specific required files, evidence, layouts, languages, tests,
+and quality rules enter only through the locked project policy.
+
+Initial stable v0.1 entries:
+
+| Stable ID | Persisted public name | Classification | Phase | Typed dispatch capability |
+|---|---|---|---|---|
+| `artifact.outer_zip.valid` | same as stable ID | `mandatory_security` | custody | 04A2 archive-inspection result |
+| `artifact.archive.paths_safe` | same as stable ID | `mandatory_security` | custody | 04A2 archive-inspection result |
+| `artifact.archive.entries_safe` | same as stable ID | `mandatory_security` | custody | 04A2 archive-inspection result |
+| `artifact.archive.resources_bounded` | same as stable ID | `mandatory_security` | custody | 04A2 archive-inspection result |
+| `artifact.archive.integrity_verified` | same as stable ID | `mandatory_integrity` | custody | 04A2 archive-inspection result |
+| `artifact.archive.identity_computed` | same as stable ID | `mandatory_integrity` | identity | 04A2 archive-commitment result |
+| `artifact.manifest.semantic_identity_computed` | same as stable ID | `mandatory_integrity` | identity | 04A3 manifest result |
+| `artifact.manifest.executable_normalized` | same as stable ID | `mandatory_integrity` | identity | 04A3 manifest result |
+| `artifact.revision.content_changed` | same as stable ID | `mandatory_integrity` | identity | 04A3 change-gate result |
+| `artifact.scratch.sealed_tree_verified` | same as stable ID | `mandatory_integrity` | materialization | 04B2 sealed-tree verifier |
+| `submission.packet.required_fields` | `check_submission_packet` | `mandatory_accountability` | default policy | `validate_submission_packet` |
+| `submission.attestation.required_topics` | `check_confidentiality_attestation` | `mandatory_accountability` | default policy | `require_attestation` |
+| `artifact.sensitive_paths.high_confidence` | `check_forbidden_files` | `mandatory_security` | default policy | `forbid_artifact` |
+| `artifact.quality.placeholder_signal` | `check_low_quality_generated_artifacts` | `advisory` | default policy | `warn_low_quality_generated_artifact` |
+
+04A2/04A3 entries import the exact typed, process-local result from those
+capabilities into the plan; 04B never reruns or independently reinterprets the
+ZIP. Their configuration state is still visible in the catalogue. Because they
+are mandatory, configuring one disabled makes intake unavailable before its
+owning capability is invoked.
+
+The same catalogue maps each constrained project rule type through one closed
+namespace:
+
+| Stable catalogue ID | Persisted public checker name | Dispatch primitive |
+|---|---|---|
+| `policy.submission_packet.validate` | `check_submission_packet` | `validate_submission_packet` |
+| `policy.storage_scheme.enforce` | `check_evidence_integrity` | `enforce_storage_scheme` |
+| `policy.manifest_field.require` | `check_evidence_integrity` | `require_manifest_field` |
+| `policy.hash.verify` | `check_evidence_integrity` | `verify_hash` |
+| `policy.file.require` | `check_required_files` | `require_file` |
+| `policy.evidence.minimum` | `check_evidence_present` | `require_minimum_evidence` |
+| `policy.artifact.forbid` | `check_forbidden_files` | `forbid_artifact` |
+| `policy.attestation.require` | `check_confidentiality_attestation` | `require_attestation` |
+| `policy.file_size.limit` | `check_evidence_integrity` | `limit_file_size` |
+| `policy.package_size.limit` | `check_evidence_integrity` | `limit_package_size` |
+| `policy.packaging.require` | `check_submission_packet` | `require_packaging` |
+| `policy.generated_quality.warn` | `check_low_quality_generated_artifacts` | `warn_low_quality_generated_artifact` |
+
+For platform rows whose public name is “same as stable ID,” no second primitive
+alias exists: dispatch consumes the named typed 04A/04B capability. The
+effective plan and every result persist the public name alongside the stable
+catalogue ID/version. Dispatch uses only the mapped capability or implementation
+primitive. A compiled project rule receives a deterministic rule-instance ID
+derived from catalogue ID/version, locked policy lineage, and canonical
+configuration; it does not register another checker type or alias.
+
+`disabled` is observable configuration state, not success. Mandatory disabled
+entries make preparation unavailable; advisory disabled entries are retained in
+the plan manifest as disabled. Locked project-required rules cannot be disabled
+at runtime. Startup fails for duplicate identities, missing dependencies,
+cycles, invalid phase ordering, unknown primitives, invalid severity, or a
+mandatory entry configured to skip/pass.
+
+## Acceptance Criteria
+
+- one catalogue and one effective-plan compiler are the only dispatch authority;
+- every platform default is named, versioned, classified, ordered, and bounded;
+- platform defaults cannot be omitted, reordered unsafely, weakened, or
+ downgraded by project policy or task parameters;
+- broad `token*`, `secret*`, `credential*`, and dependency-directory heuristics
+ are not silently inherited as generic blocking rules; tests prove the exact
+ high-confidence/advisory/project-specific classification;
+- plan identity commits to catalogue version/state, locked checker bundle hash,
+ effective project submission artifact policy hash, and deterministic ordered
+ entry/config hashes;
+- the legacy precheck path cannot construct an alternate plan;
+- no duplicate primitive map, runner registry membership, or compatibility alias
+ remains for pre-submit dispatch;
+- the hidden contributor surface and fixed materializer action remain unchanged
+ and unavailable; no runtime bytes or durable effects occur;
+- focused subsystem coverage is at least 90 percent and repository coverage
+ remains at least 78 percent.
+
+## Verification
+
+```bash
+(cd backend && .venv/bin/pytest tests/test_checker_catalogue.py tests/test_checker_compiler.py tests/test_project_policy.py -q)
+(metadata_dir="$(mktemp -d)" && trap 'rm -rf "$metadata_dir"' EXIT && (cd backend && WORKSTREAM_TEST_ADMIN_DATABASE_URL=postgresql+asyncpg://workstream:workstream@localhost:5433/postgres .venv/bin/python scripts/run_isolated_tests.py --metadata-json "$metadata_dir/result.json" --timeout-seconds 12600 -- .venv/bin/python -m pytest -q --ignore=tests/test_isolated_database_runner.py --cov=app --cov-report=term-missing --cov-fail-under=78))
+(cd backend && .venv/bin/coverage report --include='app/modules/checkers/*,app/modules/projects/*' --precision=2 --fail-under=90)
+(cd backend && .venv/bin/ruff check app tests)
+python3 scripts/check_stale_artifact_contracts.py
+PYTHONPATH=. python3 scripts/test_lightweight_agent_gates.py
+```
+
+## Exact CI Coverage Gates
+
+The hosted Backend Gates retain every existing ART/checker coverage report.
+This chunk must additionally prove or preserve exactly:
+
+```bash
+coverage report --include='app/modules/checkers/*' --precision=2 --fail-under=90
+coverage report --include='app/modules/projects/*' --precision=2 --fail-under=90
+coverage report --include='app/core/config.py' --precision=2 --fail-under=90
+coverage report --include='app/main.py' --precision=2 --fail-under=90
+```
+
+If implementation does not change one of those surfaces, its existing hosted
+gate remains unchanged; it may not be removed or weakened.
+
+## Required Reviewers
+
+Senior engineering, architecture, QA/test, security/auth, product/ops,
+reuse/dedup, CI integrity, test delta, and docs.
+
+## Human Review Focus
+
+- Is every Workstream default discoverable in one catalogue?
+- Can disabling any mandatory entry ever make a bundle eligible?
+- Is project-specific policy composed without another API or registry?
diff --git a/.agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/chunks/WS-ART-001-04B2-default-checker-execution.md b/.agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/chunks/WS-ART-001-04B2-default-checker-execution.md
new file mode 100644
index 000000000..6e0bd05a6
--- /dev/null
+++ b/.agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/chunks/WS-ART-001-04B2-default-checker-execution.md
@@ -0,0 +1,88 @@
+# Chunk Contract: WS-ART-001-04B2 - Default Checker Execution
+
+Initiative: `WS-ART-001` | Risk: L1 | Status: Proposed after 04B1
+
+Artifact contract phase: `upload_admission`
+
+## Goal
+
+Project the already inspected outer ZIP into one sealed read-only scratch tree
+and execute the mandatory artifact-custody and Workstream-default phases of the
+04B1 plan against exact server-derived facts. Do not execute project-specific
+rules or persist the final evidence set yet.
+
+## Allowed Files
+
+- shared checker-input materialization through `ArtifactScratchManager`;
+- execution adapters for catalogue entries backed by 04A2/04A3 capabilities;
+- platform/default phase orchestration, bounded result types, cleanup and tests;
+- fixed-service materializer resource facts/guards while the action remains
+ planned and unavailable;
+- focused docs, evidence, and CI gate maintenance.
+
+## Not Allowed
+
+- re-parsing through a second ZIP implementation or changing 04A identities;
+- arbitrary execution, network access, direct temp paths, or provider I/O;
+- project-specific rule execution or durable evidence/admission/Submission;
+- passing scratch paths or prepared handles across processes or Celery;
+- AUTH activation/grants, public routes, post-submit/review/contribution work.
+
+## Acceptance Criteria
+
+- one sealed materialization is derived from the 04A manifest and generation;
+- archive and projected file hashes/sizes/types/executable flags agree before a
+ checker can read the tree;
+- fixed canonical read-only/read-execute/read-traverse modes are used and the
+ executable flag never grants execution;
+- mandatory catalogue unavailability, authorization denial, integrity drift,
+ cancellation, timeout, or scratch exhaustion fails before checker access and
+ creates no durable/provider effect;
+- platform/default entries execute in deterministic dependency order and emit
+ bounded path-redacted results carrying entry ID/version and plan identity;
+- disabled advisory entries are explicit; disabled mandatory entries fail
+ closed and cannot appear as passing or skipped-success;
+- cleanup is bounded and idempotent on every terminal path;
+- tests prove pre-submit and post-submit projection parity for Unix executable,
+ non-Unix/invalid mode, symlink/special rejection, and permission-only revision
+ cases; neither projection preserves arbitrary archive modes;
+- the behavior remains hidden and process-local for later 04B3/04C composition;
+- focused subsystem coverage is at least 90 percent and repository coverage
+ remains at least 78 percent.
+
+## Verification
+
+```bash
+(cd backend && .venv/bin/pytest tests/test_checker_materialization.py tests/test_default_pre_submit_execution.py tests/test_artifact_scratch_manager.py tests/test_submission_archive.py tests/test_submission_manifest.py tests/test_submission_change_gate.py -q)
+(metadata_dir="$(mktemp -d)" && trap 'rm -rf "$metadata_dir"' EXIT && (cd backend && WORKSTREAM_TEST_ADMIN_DATABASE_URL=postgresql+asyncpg://workstream:workstream@localhost:5433/postgres .venv/bin/python scripts/run_isolated_tests.py --metadata-json "$metadata_dir/result.json" --timeout-seconds 12600 -- .venv/bin/python -m pytest -q --ignore=tests/test_isolated_database_runner.py --cov=app --cov-report=term-missing --cov-fail-under=78))
+(cd backend && .venv/bin/coverage report --include='app/modules/artifacts/*,app/modules/checkers/*' --precision=2 --fail-under=90)
+(cd backend && .venv/bin/ruff check app tests)
+python3 scripts/check_stale_artifact_contracts.py
+PYTHONPATH=. python3 scripts/test_lightweight_agent_gates.py
+```
+
+## Exact CI Coverage Gates
+
+The hosted Backend Gates retain every existing ART/checker coverage report.
+This chunk must additionally prove or preserve exactly:
+
+```bash
+coverage report --include='app/modules/artifacts/*' --precision=2 --fail-under=90
+coverage report --include='app/modules/checkers/*' --precision=2 --fail-under=90
+coverage report --include='app/core/cancellation.py,app/core/file_locks.py' --precision=2 --fail-under=90
+coverage report --include='app/interfaces/artifact_operations.py,app/interfaces/artifacts.py' --precision=2 --fail-under=90
+```
+
+If implementation does not change one of those surfaces, its existing hosted
+gate remains unchanged; it may not be removed or weakened.
+
+## Required Reviewers
+
+Senior engineering, architecture, QA/test, security/auth, product/ops,
+reuse/dedup, CI integrity, test delta, and docs.
+
+## Human Review Focus
+
+- Is the checked tree exactly the 04A manifest tree?
+- Can any disabled/failed mandatory default be bypassed?
+- Are all scratch and authorization capabilities process-local and bounded?
diff --git a/.agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/chunks/WS-ART-001-04B3-effective-pre-submit-evidence.md b/.agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/chunks/WS-ART-001-04B3-effective-pre-submit-evidence.md
new file mode 100644
index 000000000..fae0615d1
--- /dev/null
+++ b/.agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/chunks/WS-ART-001-04B3-effective-pre-submit-evidence.md
@@ -0,0 +1,104 @@
+# Chunk Contract: WS-ART-001-04B3 - Effective Pre-Submit Evidence
+
+Initiative: `WS-ART-001` | Risk: L1 | Status: Proposed after 04B2
+
+Artifact contract phase: `upload_admission`
+
+## Goal
+
+Execute the exact task-locked Project Guide rules through the same 04B1 plan and
+04B2 sealed workspace, then persist one bounded immutable evidence set for the
+complete platform-plus-project execution. Create no provider object, admission,
+Submission, or separate contributor route.
+
+## Allowed Files
+
+- locked task/guide/effective-policy/checker context assembly;
+- constrained project-rule execution through the central catalogue;
+- pre-submit attempt/result/evidence control-plane models and one migration;
+- bounded same-request contributor response projection and audit metadata;
+- focused tests, docs, evidence, and CI gate maintenance.
+
+## Not Allowed
+
+- project executable code, arbitrary shell/network access, or agent judgment;
+- a second project checker API/registry or caller-selected checker names;
+- provider I/O, verified admission, Submission, Review, contribution, payment,
+ reputation, post-submit routing, or AUTH activation/grant changes;
+- filenames, scratch/provider references, credentials, raw checker output, or
+ unbounded details in durable evidence.
+
+## Acceptance Criteria
+
+- one ordered result contains both platform/default and locked project entries,
+ each with catalogue ID/version, source, status, severity, bounded code/message,
+ and policy trace;
+- the canonical typed result envelope nests identity under `definition`
+ (`dispatch_authority`, authority-neutral definition ID/version, public name,
+ source) and trace
+ under `policy_trace` (effective-plan hash, deterministic rule-instance ID,
+ locked-policy hash); immutable evidence persists each member explicitly and
+ never relies on open-ended `metadata` for required provenance; for this
+ pre-submit authority, definition ID/version are exactly catalogue ID/version;
+- execution binds actor/task/project/assignment, predecessor, archive identity,
+ manifest ID/hash, scratch generation, locked guide/policy/checker hashes, and
+ effective plan identity;
+- project rules consume server-derived manifest/workspace facts and may require
+ project-specific files such as `task.toml` without making them platform defaults;
+- project policy can add/narrow but cannot disable, reorder, downgrade, or raise
+ platform limits;
+- blocking findings create no durable artifact, admission, Submission, review,
+ contribution, compensation, reputation, or provider charge;
+- infrastructure/authorization failure is retryable platform state, never
+ contributor blame or a product review decision;
+- the passing result is short-lived, single-use, and bound to the same scratch
+ generation/predecessor for immediate 04C consumption;
+- crossed-state tests prove stale/replaced predecessor, closed task, changed or
+ revoked assignment/authority, locked-context change, and scratch-generation
+ mismatch invalidate the result at the immediate-consumption boundary and
+ create no artifact, provider write, admission, Submission, or lifecycle effect;
+- no ID-addressed evidence-read route or independently invocable precheck route
+ is introduced; the eventual 04C2 endpoint returns only bounded same-request
+ results;
+- focused subsystem coverage is at least 90 percent and repository coverage
+ remains at least 78 percent.
+
+## Verification
+
+```bash
+docker compose up -d --wait postgres redis
+(cd backend && WORKSTREAM_TEST_DATABASE_URL=postgresql+asyncpg://workstream:workstream@localhost:5433/workstream_test .venv/bin/pytest tests/test_alembic.py tests/test_effective_pre_submit_execution.py tests/test_submission_precheck_scratch.py -q)
+(metadata_dir="$(mktemp -d)" && trap 'rm -rf "$metadata_dir"' EXIT && (cd backend && WORKSTREAM_TEST_ADMIN_DATABASE_URL=postgresql+asyncpg://workstream:workstream@localhost:5433/postgres .venv/bin/python scripts/run_isolated_tests.py --metadata-json "$metadata_dir/result.json" --timeout-seconds 12600 -- .venv/bin/python -m pytest -q --ignore=tests/test_isolated_database_runner.py --cov=app --cov-report=term-missing --cov-fail-under=78))
+(cd backend && .venv/bin/coverage report --include='app/modules/artifacts/*,app/modules/checkers/*,app/modules/tasks/*' --precision=2 --fail-under=90)
+(cd backend && .venv/bin/ruff check app tests)
+python3 scripts/check_stale_artifact_contracts.py
+PYTHONPATH=. python3 scripts/test_lightweight_agent_gates.py
+```
+
+## Exact CI Coverage Gates
+
+The hosted Backend Gates retain every existing ART/checker coverage report.
+This chunk must additionally prove or preserve exactly:
+
+```bash
+coverage report --include='app/modules/artifacts/*' --precision=2 --fail-under=90
+coverage report --include='app/modules/checkers/*' --precision=2 --fail-under=90
+coverage report --include='app/modules/tasks/*' --precision=2 --fail-under=90
+coverage report --include='app/modules/audit/*' --precision=2 --fail-under=90
+coverage report --include='app/api/router.py' --precision=2 --fail-under=90
+coverage report --include='app/main.py' --precision=2 --fail-under=90
+```
+
+If implementation does not change one of those surfaces, its existing hosted
+gate remains unchanged; it may not be removed or weakened.
+
+## Required Reviewers
+
+Senior engineering, architecture, QA/test, security/auth, product/ops,
+reuse/dedup, CI integrity, test delta, and docs.
+
+## Human Review Focus
+
+- Is there exactly one execution and evidence chain?
+- Can locked project rules observe anything other than the exact sealed bundle?
+- Are checker findings kept separate from review decisions and lifecycle state?
diff --git a/.agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/reviews/WS-ART-001-PLAN4-external-review-response.md b/.agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/reviews/WS-ART-001-PLAN4-external-review-response.md
new file mode 100644
index 000000000..f755bf6d7
--- /dev/null
+++ b/.agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/reviews/WS-ART-001-PLAN4-external-review-response.md
@@ -0,0 +1,54 @@
+# External Review Response: WS-ART-001-PLAN4
+
+## Comments addressed
+
+- defined one closed mapping from stable catalogue ID to persisted public
+ checker name to implementation dispatch primitive, including the legacy
+ public-name/primitive differences;
+- added a typed checker-result provenance envelope and explicit persistence
+ fields for dispatch authority, authority-neutral definition ID/version
+ (catalogue identity for pre-submit), public name, source, effective-plan hash,
+ rule-instance ID, and locked-policy hash rather than relying on open-ended
+ metadata;
+- separated completed checker findings from retryable infrastructure outcomes;
+ disabled mandatory entries, exhaustion, cancellation, authorization denial,
+ and infrastructure failure create no contributor finding or product state;
+- replaced full checker-result audit persistence with a closed, bounded,
+ path-redacted projection and enumerated both allowed and forbidden fields;
+- made each task's existing locked compiled-bundle hash transitively commit to
+ the immutable catalogue version, manifest digest, ordered entry/configuration
+ hashes, and enabled/disabled state;
+- removed every obsolete `PreSubmitCheckResponse` reference from the historical
+ Chunk 8 pre-submit section and conditions, replacing it with the canonical
+ same-request `pre_submission_checker_failed` contract;
+- corrected the submission packet and operating checklist so project-required
+ evidence is inside the one outer ZIP and all paths, hashes, evidence facts,
+ IDs, manifests, and bindings are server-derived;
+- clarified that `PreSubmissionCheckerCatalogue` owns pre-submit dispatch while
+ the durable registry owns post-submit dispatch;
+- expanded the PR description to the complete trust-bundle structure.
+
+## Comments deferred
+
+None.
+
+## Human decisions needed
+
+None beyond normal review and explicit human merge approval for PR #271.
+
+## Commands rerun
+
+- `git diff --check`
+- `python3 scripts/check_stale_artifact_contracts.py`
+- `python3 scripts/check_stale_authorization_docs.py`
+- `python3 scripts/check_stale_workstream_wording.py`
+- `python3 scripts/check_markdown_links.py`
+- `PYTHONPATH=. python3 scripts/test_lightweight_agent_gates.py`
+
+## Remaining risks
+
+- hosted GitHub Backend gates and refreshed CodeRabbit review must validate the
+ rebased repair;
+- this is planning-only, so typed result persistence, route removal, and
+ catalogue execution still require their separately approved implementation
+ chunks and tests.
diff --git a/.agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/reviews/WS-ART-001-PLAN4-pr-trust-bundle.md b/.agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/reviews/WS-ART-001-PLAN4-pr-trust-bundle.md
new file mode 100644
index 000000000..a0a9def4b
--- /dev/null
+++ b/.agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/reviews/WS-ART-001-PLAN4-pr-trust-bundle.md
@@ -0,0 +1,143 @@
+# PR Trust Bundle: WS-ART-001-PLAN4
+
+## Chunk
+
+`WS-ART-001-PLAN4` — planning-only correction for default pre-submission checks.
+
+## Goal
+
+Define one discoverable, versioned, disable-aware catalogue and one effective
+pre-submission execution while preserving the exact contributor ZIP custody
+chain and locked Project Guide rules.
+
+## Human-Approved Intent
+
+Every submission is one outer ZIP. Workstream default checks and project-specific
+checks run as one effective pre-submission operation against that exact ZIP in
+bounded private scratch. All platform defaults are named centrally and expose
+enabled/disabled state without allowing a mandatory check to be bypassed.
+
+## What Changed
+
+- added 04A4, 04B1, 04B2, and 04B3 chunk contracts;
+- superseded the oversized combined 04B contract;
+- defined the stable platform catalogue and constrained policy mapping;
+- defined fail-closed mandatory disablement and explicit advisory disablement;
+- aligned canonical architecture, policy, AUTH, workflow, glossary, and template
+ documents with one-ZIP preparation, verified admission, and immutable binding;
+- assigned clean removal of the legacy standalone precheck route to 04A4;
+- incorporated all seven actionable CodeRabbit findings.
+
+## Why It Changed
+
+The former plan left default checks scattered across constants, compiler
+primitives, a legacy registry, and documents; did not safely define `disabled`;
+and could leave a caller-owned standalone precheck beside the authoritative ZIP
+flow. The combined 04B also crossed too many L1 boundaries for one PR.
+
+## Design Chosen
+
+```text
+04A4 legacy precheck clean cut
+-> 04B1 sole catalogue + effective-plan compiler
+-> 04B2 sealed materialization + platform/default execution
+-> 04B3 locked project execution + one bounded evidence set
+-> XINT-06A fixed materializer activation
+-> 04C durable intent and verified admission
+```
+
+The task-locked compiled-bundle hash commits to an immutable catalogue snapshot
+and locked project policy. Results use typed provenance; mandatory unavailable
+checks yield retryable infrastructure failure rather than findings or success.
+
+## Alternatives Rejected
+
+- retaining the standalone caller-owned precheck route;
+- separate platform and project execution APIs or registries;
+- scattered conditionals or runtime plugin discovery;
+- per-project or per-request default-check toggles;
+- treating disabled mandatory checks as skipped/passing;
+- a new task-lock column duplicating the compiled bundle's catalogue commitment.
+
+## Scope Control
+
+Planning and canonical documentation only. No route, runtime code, database
+migration, provider I/O, AUTH activation/grant, Submission lifecycle, checker
+execution, Review, contribution, compensation, or reputation behavior changes.
+
+## Product Behavior
+
+No product behavior changes in this PR. The approved target is one outer ZIP
+plus summary/attestation, server-derived manifest/evidence facts, one effective
+pre-submission result, verified admission, then atomic immutable Submission
+binding under fresh authority.
+
+## Acceptance Criteria Proof
+
+- every default has stable identity/version/classification/order/limits/state;
+- exact stable-ID/public-name/typed-capability-or-primitive mappings are
+ specified for every platform default and constrained project rule;
+- mandatory disabled entries fail closed; advisory disabled entries are explicit;
+- project policy cannot disable or weaken platform defaults;
+- no independent precheck route or second dispatch registry survives 04A4/04B1;
+- audit and contributor results are bounded and path-redacted;
+- exact coverage and crossed-state test obligations are assigned to each chunk.
+
+## Tests And Checks Run
+
+- stale artifact contract scan — pass;
+- stale authorization docs scan — pass;
+- stale Workstream wording scan — pass;
+- Markdown links — pass;
+- lightweight agent gates — pass;
+- `git diff --check` — pass.
+
+## Test Delta
+
+No runtime tests change in this planning PR. The contracts require route/OpenAPI
+removal proof, catalogue compiler tests, sealed materialization/executable parity,
+crossed-state invalidation, full repository 78 percent coverage, and owned
+subsystem 90 percent coverage in their implementation PRs.
+
+## CI Integrity
+
+No workflow, lane, package, lint, or coverage configuration is changed. Existing
+hosted gates remain intact; each implementation contract names the exact full
+and scoped coverage commands it must preserve.
+
+## Reviewer Results
+
+Architecture, security, QA, product/ops, senior engineering, CI integrity,
+documentation, reuse/dedup, and test-delta reviewers pass after all valid
+findings were repaired.
+
+## External Review
+
+CodeRabbit posted seven actionable findings and one description warning. All
+seven are addressed; the PR description is replaced with this trust-bundle
+structure. Detailed disposition is in
+`WS-ART-001-PLAN4-external-review-response.md`.
+
+## Remaining Risks
+
+- implementation must consolidate rather than wrap the old registry/compiler;
+- broad sensitive-name heuristics need false-positive tests;
+- hosted checks must validate the rebased planning head;
+- each implementation chunk still requires separate approval and L1 review.
+
+## Follow-Up Work
+
+After human merge: implement only 04A4. Do not start 04B1 automatically.
+
+## Human Review Focus
+
+- mandatory disablement can never become skip-and-pass;
+- catalogue mapping and typed provenance form one namespace;
+- catalogue snapshot identity is truly task-locked through the bundle hash;
+- audit evidence cannot leak paths, credentials, provider details, or raw output;
+- contributor evidence remains inside the one ZIP, not a second upload contract.
+
+## Human Merge Ownership
+
+Only the human owner may approve and merge PR #271. This planning merge does
+not authorize any implementation chunk.
diff --git a/docs/architecture_checker_framework.md b/docs/architecture_checker_framework.md
index 99dd30267..b90928ffb 100644
--- a/docs/architecture_checker_framework.md
+++ b/docs/architecture_checker_framework.md
@@ -12,9 +12,21 @@ Every checker returns:
```json
{
- "name": "check_submission_packet",
+ "definition": {
+ "dispatch_authority": "pre_submission_catalogue",
+ "definition_id": "policy.submission_packet.validate",
+ "definition_version": 1,
+ "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": [],
@@ -22,6 +34,16 @@ Every checker returns:
}
```
+`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 catalogue ID/version; 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:
- passed
@@ -36,9 +58,16 @@ Severity:
- high
- critical
-## Checker Registry
+## Durable/Post-Submit Checker Registry
-Every checker is registered with a stable definition before projects reference it.
+Every durable/post-submit checker is registered with a stable definition before
+projects reference it. The durable registry owns post-submit dispatch.
+Pre-submit intake is not dispatched by this registry: the single versioned
+`PreSubmissionCheckerCatalogue` is the pre-submit dispatch authority and owns
+artifact-custody defaults plus constrained project-policy primitives. Shared
+implementations may be exposed through typed adapters, but neither the durable
+registry nor the pre-submission catalogue may duplicate IDs, primitive maps, or
+dispatch authority.
Definition fields:
@@ -51,11 +80,10 @@ Definition fields:
- `contributor_visible`
- `description`
-Phase:
+Durable phase:
- project_activation
- task_screening
-- pre_submit_intake
- submission_quality
- pre_review_gate
- lifecycle_transition
@@ -196,26 +224,31 @@ policy.
Workstream default submission artifact rules require:
- summary
-- artifact hash manifest
+- one outer ZIP whose exact identity and semantic manifest are generated by ART
- contributor attestation
- safe relative artifact paths
- production artifact hashes shaped as `sha256:<64 lowercase hex>`
-- pre-cutover only: validated caller-supplied storage references;
- `WS-ART-001-05` removes them and checkers then consume Workstream artifact
- bindings only
+- pre-cutover only: validated caller-supplied storage references and manifest;
+ `WS-ART-001-04A4` removes the standalone caller-owned precheck, and
+ `WS-ART-001-05B` removes the remaining Submission fields so checkers consume
+ Workstream artifact bindings only
- no credentials, signed URLs, query strings, raw local filesystem paths, or token-bearing references
-- no default forbidden artifacts such as `.env`, `.git`, private keys, credentials, secrets, tokens, `.pem`, `.key`, or `node_modules`
+- narrowly high-confidence sensitive-file exclusions such as `.env`, `.git`,
+ exact known credential/private-key files, `.pem`, and `.key`; broad
+ `token*`, `secret*`, `credential*`, and dependency-directory matches are
+ advisory or locked project-specific unless an exact generic custody risk is
+ proven
Project policy adds required artifacts, evidence requirements, stricter forbidden artifacts, stricter packaging rules, and project-specific attestation requirements.
The generated project `PreSubmitCheckerPolicy` is persisted with a compiled
bundle hash and locked to the effective project submission artifact policy before tasks enter the
contributor pipeline. Tasks lock references to the shared project's compiled checker
-bundle hash. It runs before Workstream creates a submission. Preflight failures return
-`PreSubmitCheckResponse` with `status="failed"`,
-`eligible_to_submit=false`, and structured pass/fail/warning details in
-`results`. Blocked submission-create attempts use the user-facing error code
-`pre_submission_checker_failed`; it is not a review decision value.
+bundle hash. It runs inside continuous submission-bundle preparation before
+Workstream creates a submission. Failures return the bounded same-request code
+`pre_submission_checker_failed` with status, eligibility, and structured
+pass/fail/warning details. There is no standalone preflight route, and this is
+not a review decision value.
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`.
@@ -389,12 +422,14 @@ The checker run records:
- submission id
- post-submit checker policy id, version, hash, and internal locked body
stamped from the locked submission context
-- artifact hash manifest
+- exact ArtifactBinding/ArtifactContent and server-generated manifest identity
- blocking failure count
- warning count
- completion timestamp
-This gives reviewers a clear proof that they are reviewing the same packet that passed automated checks.
+After ART-06 cutover, this gives reviewers proof that they are reviewing the
+same immutable binding and manifest that passed automated checks; legacy
+caller-owned manifest fields are not authority.
A separate `ReadinessCertificate` record may be added later if reviewer routing needs a dedicated signed handoff object. v0.1 does not require that extra record.
diff --git a/docs/architecture_data_model.md b/docs/architecture_data_model.md
index 06dcea066..de07fdec7 100644
--- a/docs/architecture_data_model.md
+++ b/docs/architecture_data_model.md
@@ -779,18 +779,19 @@ The generated checker order is deterministic:
8. contributor attestation validation
9. low-quality artifact warnings
-Pre-submit has two API paths:
+The legacy standalone `/tasks/{id}/submission-precheck` path is superseded.
+Pre-submit runs only inside the same process-local preparation request that owns
+the uploaded ZIP and bounded scratch generation:
```text
-POST /tasks/{id}/submission-precheck
-200 PreSubmitCheckResponse(status="failed", eligible_to_submit=false, results=[...])
-```
-
-```text
-POST /tasks/{id}/submissions
+POST /api/v1/tasks/{id}/submission-bundle-preparations
422 DomainError(code="pre_submission_checker_failed", details={status, eligible_to_submit, results})
```
+No independent precheck route or client-owned manifest can reproduce the
+authoritative result. `POST /api/v1/tasks/{id}/submissions` consumes the verified ready
+admission and does not receive scratch paths or rerun the pre-submit plan.
+
Blocking pre-submit failures prevent submission creation, create no submission
row, no submission version, no task transition to `submitted`, and no
submission-created audit event. Workstream still writes a task audit event named
@@ -1269,10 +1270,14 @@ Fields:
- `version`
- `status`
- `summary`
-- `package_uri`
-- `package_hash` (legacy caller input, never canonical artifact lineage)
-- `artifact_hash` (server-derived verified lineage)
-- `artifact_hash_manifest`
+- `submission_bundle_admission_id` (target canonical intake identity after ART-05)
+- `artifact_binding_id` (target canonical byte binding after ART-05)
+- `submission_bundle_manifest_id` (target server-generated manifest identity)
+- `pre_submit_evidence_set_id` (target checker evidence identity)
+- `package_uri` (legacy caller transport removed by ART-05B)
+- `package_hash` (legacy caller input removed by ART-05B; never canonical)
+- `artifact_hash` (legacy transitional field replaced by exact binding/content identity)
+- `artifact_hash_manifest` (legacy caller manifest removed by ART-05B)
- `contributor_attestation`
- `locked_guide_version`
- `locked_guide_id`
@@ -1312,18 +1317,23 @@ and active assignment. That transaction participant establishes current
identity eligibility only; project roles, grants, actions, and resource policy
remain owned by the authorization service.
-The contributor submission packet supplies the task id, summary, outputs,
-artifact hashes, evidence references, and contributor attestation. Workstream assigns the
-submission version, creates evidence ids, and stamps locked guide source,
+The contributor first supplies one outer ZIP, summary, and attestation to
+submission-bundle preparation. Workstream computes the exact archive identity,
+server-generated semantic manifest, required-file/evidence facts, and immutable
+pre-submit evidence set, then stores and verifies the bytes into a ready
+admission. Final Submission creation supplies that admission identity and
+summary/attestation context; Workstream assigns the submission version, creates
+the exact artifact binding, and stamps locked guide source,
submission artifact, effective project policy, pre-submit checker, post-submit
checker, review, and revision policy provenance from trusted
task/project state. The contributor does not provide submission version, evidence
ids, checker results, checker run ids, guide versions, source snapshots,
effective project policy ids/hashes, pre-submit checker ids/bundle hashes,
post-submit checker policy ids/versions/hashes, exact review policy identities,
-or exact revision policy identities. Submitter award eligibility is governed by
-the TaskAssignment-selected `ContributionPolicyVersion` for the exact attempt
-and is not contributor-supplied. Human revision preparation records prior/next
+exact revision policy identities, provider references, package hashes, or
+artifact manifests. Submitter award eligibility is governed by the
+TaskAssignment-selected `ContributionPolicyVersion` for the exact attempt and
+is not contributor-supplied. Human revision preparation records prior/next
policy lineage before it may update that selector; publication alone cannot.
Version 1 has neither revision-source field. Every later version has exactly one:
@@ -1403,9 +1413,11 @@ Fields:
- `locked_revision_policy_id`
- `locked_revision_policy_generation`
- `locked_revision_policy_hash`
-- `package_hash`
-- `artifact_hash_manifest`
-- `artifact_manifest_hash`
+- `artifact_binding_id` (target after ART-06)
+- `submission_bundle_manifest_id` (target after ART-06)
+- `package_hash` (legacy until ART-06 cutover)
+- `artifact_hash_manifest` (legacy until ART-06 cutover)
+- `artifact_manifest_hash` (legacy until ART-06 cutover)
- `summary`
Status:
@@ -1436,6 +1448,13 @@ Fields:
- `id`
- `checker_run_id`
- `checker_name`
+- `dispatch_authority`
+- `definition_id` (catalogue ID for pre-submit; registry checker ID for durable)
+- `definition_version` (catalogue or registry version selected by authority)
+- `result_source`
+- `effective_plan_hash`
+- `rule_instance_id` (nullable only for non-policy/default definitions)
+- `locked_policy_hash` (nullable only when no locked policy produced the result)
- `status`
- `severity`
- `message`
@@ -1448,6 +1467,13 @@ Fields:
- `metadata`
- `created_at`
+These authority-neutral provenance fields are explicitly typed and persisted.
+`dispatch_authority` discriminates the identity namespace. The API/result
+envelope serializes them under `definition` and `policy_trace`; they are never
+hidden only in the open-ended `metadata` field. Pre-submit evidence uses the
+same typed envelope without creating a durable `CheckerRun`; its immutable
+evidence rows store these fields directly under the 04B3 schema.
+
Status:
- passed
@@ -1502,7 +1528,7 @@ Fields:
- `id`
- `submission_id`
- `checker_run_id`
-- `artifact_hash_manifest`
+- `submission_bundle_manifest_id` (target if this deferred record is ever added)
- `blocking_failures_count`
- `warnings_count`
- `ready_for_review`
@@ -1512,7 +1538,9 @@ Fields:
Purpose:
-If added later, the readiness certificate records the exact checker run and artifact hashes that allowed a submission to enter human review.
+If added later, the readiness certificate records the exact checker run and
+server-generated manifest/binding identity that allowed a submission to enter
+human review.
For v0.1, the current `CheckerRun` is the readiness proof. If any submitted artifact changes, a new submission version and checker run are required.
diff --git a/docs/architecture_lockdown.md b/docs/architecture_lockdown.md
index d329255cc..99265240c 100644
--- a/docs/architecture_lockdown.md
+++ b/docs/architecture_lockdown.md
@@ -121,15 +121,19 @@ 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.
-Blocking pre-submit failures prevent submission creation. Preflight failures
-return `PreSubmitCheckResponse(status="failed", eligible_to_submit=false,
-results=[...])`. Blocked submission-create attempts return
-`pre_submission_checker_failed` with structured pass/fail/warning details and
+Blocking pre-submit failures prevent submission creation. The continuous
+submission-bundle preparation request returns `pre_submission_checker_failed`
+with bounded same-request status, eligibility, and pass/fail/warning details and
create no submission row, no submission version, no task transition to
-`submitted`, and no submission-created audit event. Workstream still writes a
-task audit event named `pre_submission_check_failed` with the structured checker
-result for project operators; this is audit evidence, not a product review
-decision.
+`submitted`, and no submission-created audit event. Workstream writes a task
+audit event named `pre_submission_check_failed` containing 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.
+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. No independently invocable
+preflight route exists.
Tasks lock to the active guide version at creation or screening time before entering `READY`. Material guide changes require a new guide version.
diff --git a/docs/current_system_data_flow.html b/docs/current_system_data_flow.html
index 385081762..83e0cf785 100644
--- a/docs/current_system_data_flow.html
+++ b/docs/current_system_data_flow.html
@@ -515,7 +515,7 @@
Contributor claims and starts
6
Pre-submit intake checks run
-
Workstream runs pre-submit checks from the locked project pre-submit checker policy before creating a submission row. Preflight failures return PreSubmitCheckResponse details. Blocked submission-create attempts return pre_submission_checker_failed with pass/fail/warning details.
+
Workstream runs one effective pre-submission plan against the uploaded outer ZIP in bounded scratch before creating a submission. Failed preparation returns bounded same-request pre_submission_checker_failed details; there is no standalone preflight route.
no submission yetno checker run yet
@@ -525,29 +525,30 @@
Pre-submit intake checks run
7
-
Submission packet is created
-
After blocking pre-submit checks pass, Workstream creates the submission with summary, package reference, artifact hashes, evidence references, and attestation.
+
Verified admission is published
+
After blocking pre-submit checks pass, Workstream stores the outer ZIP once, independently reads it back, and publishes a capacity-charged ready admission bound to the server-generated manifest and pre-submit evidence.
The server records finalization against the task's server-owned guide and policy context, finalizes evidence rows, and schedules the checker run.
+
Submission consumes the admission
+
Under fresh human and fixed-service authority, one transaction locks the ready admission and task context, creates the immutable Submission and exact artifact binding, and marks the admission consumed.
diff --git a/docs/decision_0011_submission_artifact_policy_drives_pre_submit.md b/docs/decision_0011_submission_artifact_policy_drives_pre_submit.md
index e14abeb9b..f7dae98e9 100644
--- a/docs/decision_0011_submission_artifact_policy_drives_pre_submit.md
+++ b/docs/decision_0011_submission_artifact_policy_drives_pre_submit.md
@@ -137,6 +137,26 @@ PreSubmitCheckerPolicy =
trusted compiler output from EffectiveProjectSubmissionArtifactPolicy
```
+Runtime execution uses one code-owned, versioned
+`PreSubmissionCheckerCatalogue`. The catalogue contains both Workstream-owned
+artifact-custody/default checks and the constrained primitives referenced by a
+locked project policy. Compilation produces one ordered
+`EffectivePreSubmissionExecutionPlan`; it does not create a project-specific
+checker API or registry.
+
+Every catalogue entry declares a stable checker ID and version, owner, phase,
+order/dependencies, classification, typed input capability, bounded limits and
+result schema, policy trace, and `enabled|disabled` operational state. In v0.1,
+availability is startup-validated, versioned deployment configuration—not a
+contributor, Project Manager, task, or project-policy toggle.
+
+- disabling a mandatory security, integrity, or contributor-accountability
+ entry makes preparation fail closed as infrastructure unavailable;
+- disabling an advisory entry allows the rest of the plan to run but records
+ that disabled entry in the bounded execution manifest;
+- a locked project-required rule cannot be disabled at runtime; changing it
+ requires a new approved policy lineage.
+
`SubmissionArtifactPolicyDerivationAgent` produces the artifact-intake contract
at project setup time. Workstream's trusted checker compiler builds and
validates the constrained checker specification and persists the project-level
@@ -191,6 +211,27 @@ Approved pre-submit checker primitives include:
- `require_packaging`
- `warn_low_quality_generated_artifact`
+The catalogue also registers the non-policy artifact-custody prelude already
+owned by ART: outer-ZIP validation, archive/path/resource safety, exact archive
+identity, semantic-manifest identity, executable normalization,
+unchanged-revision rejection, and sealed scratch-tree integrity. These gates
+produce trusted inputs for policy primitives and cannot be removed or
+downgraded by the compiler.
+
+The stable v0.1 platform IDs are defined by the active ART chunk contract and
+include `artifact.outer_zip.valid`, `artifact.archive.paths_safe`,
+`artifact.archive.entries_safe`, `artifact.archive.resources_bounded`,
+`artifact.archive.integrity_verified`, `artifact.archive.identity_computed`,
+`artifact.manifest.semantic_identity_computed`,
+`artifact.manifest.executable_normalized`,
+`artifact.revision.content_changed`,
+`artifact.scratch.sealed_tree_verified`,
+`submission.packet.required_fields`,
+`submission.attestation.required_topics`,
+`artifact.sensitive_paths.high_confidence`, and
+`artifact.quality.placeholder_signal`. Renaming or removing one requires a new
+catalogue version and migration/replay decision; aliases are not accepted.
+
The trusted compiler must keep `warn_low_quality_generated_artifact`
warning-only; escalating that primitive to blocking is rejected because it would
change contributor-facing intake semantics.
@@ -212,33 +253,26 @@ Blocking pre-submit failures prevent submission creation. When blocking pre-subm
structured checker result for project operators
- the response does not use review decision values: `accept`, `needs_revision`, or `reject`
-Pre-submit has two API contracts:
-
-```text
-POST /tasks/{id}/submission-precheck
-200 PreSubmitCheckResponse
-{
- "status": "failed",
- "eligible_to_submit": false,
- "results": [...]
-}
-```
+The legacy standalone `/tasks/{id}/submission-precheck` contract is superseded.
+Pre-submit checks now run only inside the continuous submission-bundle
+preparation request against the exact uploaded ZIP in bounded scratch:
```text
-POST /tasks/{id}/submissions
+POST /api/v1/tasks/{id}/submission-bundle-preparations
422 DomainError
{
"code": "pre_submission_checker_failed",
- "details": {
- "status": "failed",
- "eligible_to_submit": false,
- "results": [...]
- }
+ "details": {"status": "failed", "eligible_to_submit": false, "results": [...]}
}
```
-`pre_submission_checker_failed` is the submission-creation error code. It is not
-a review decision and is not the response type for the preflight endpoint.
+There is no independently invocable precheck route and no reusable client-owned
+manifest input. The bounded result is returned only to the authorized actor in
+that same request. A passing preparation later returns an admission identity;
+`POST /api/v1/tasks/{id}/submissions` consumes that verified ready admission under its
+separate fresh authority and does not rerun scratch-bound checks.
+
+`pre_submission_checker_failed` is an intake error code, not a review decision.
Pre-submit checks are authoritative for submission intake. They are not authoritative proof for human review readiness. Review readiness still requires post-submit internal checker runs against a finalized submission.
@@ -274,17 +308,18 @@ separation before this ADR can be closed as fully implemented.
## Default Workstream Submission Artifact Rules
-Every submission must include:
+Contributor preparation supplies:
- summary
-- package hash when a package reference is supplied
-- artifact hash manifest
- contributor attestation
+- exactly one outer ZIP containing every required work/evidence file
-Every artifact manifest entry must include:
+Workstream—not the client—computes and binds:
-- artifact name or relative path
-- artifact hash
+- exact outer-ZIP SHA-256 and byte count
+- the canonical semantic manifest and every entry hash/byte count
+- required-file/evidence facts from that manifest and sealed workspace
+- the immutable pre-submit evidence set and verified ready-admission identity
Every artifact path must be safe:
@@ -297,7 +332,7 @@ Uploaded artifacts and storage-backed evidence require `sha256:<64 lowercase hex
Persisted storage references must be Workstream-issued opaque object references or validated object-storage adapter references. Raw signed URLs, credential-bearing URLs, query strings, local filesystem paths, bucket secrets, and token-bearing references are rejected before persistence. Normalization is allowed only for already-approved adapter references that contain no secrets, credentials, or query material.
-Default forbidden artifacts remain blocked even if a project policy accidentally lists them as required. A required artifact that violates the default forbidden policy is a project setup defect.
+Default forbidden artifacts remain blocked even if a project policy accidentally lists them as required. A required artifact that violates the default forbidden policy is a project setup defect. Universal blocking patterns must be narrowly high-confidence. Broad name heuristics such as `token*`, `secret*`, `credential*`, or dependency-directory names require explicit classification as advisory or project-specific unless the exact match proves a generic custody risk.
The effective policy merge is deterministic:
diff --git a/docs/glossary.md b/docs/glossary.md
index 1c6b54918..80dec9224 100644
--- a/docs/glossary.md
+++ b/docs/glossary.md
@@ -225,11 +225,11 @@ The deterministic merge of Workstream's default submission artifact policy and t
## Pre-Submit Checker Policy
-The server-generated project checker matrix produced from the effective project submission artifact policy, persisted with a compiled bundle hash, and locked by tasks before they enter the contributor pipeline. It runs before Workstream creates a submission row or submission version. The preflight endpoint returns `PreSubmitCheckResponse`; a blocked submission-create attempt returns `pre_submission_checker_failed` with structured pass/fail/warning details. Neither path returns review decision values: `accept`, `needs_revision`, or `reject`.
+The server-generated project checker matrix produced from the effective project submission artifact policy and one immutable default-catalogue snapshot. The compiled bundle embeds the catalogue version, canonical manifest digest, ordered entry ID/version/configuration hashes, and enabled/disabled state. Its compiled bundle hash therefore commits transitively to that exact snapshot, and each task locks that hash before entering the contributor pipeline. Runtime uses the same snapshot to derive the effective-plan hash. It runs against the uploaded ZIP in bounded scratch before Workstream creates a submission. A failed preparation returns `pre_submission_checker_failed` with bounded same-request details. There is no standalone preflight route, and results never use review decision values: `accept`, `needs_revision`, or `reject`.
## pre_submission_checker_failed
-The contributor-facing domain error code returned when a submission-create attempt is blocked by pre-submit checks. It includes structured pass/fail/warning details in the error details and is not a review decision. It must not be stored as `accept`, `needs_revision`, or `reject`. The preflight endpoint returns `PreSubmitCheckResponse` instead of this error code.
+The contributor-facing domain error code returned when submission-bundle preparation is blocked by pre-submit checks. It includes bounded structured pass/fail/warning details in the same response and is not a review decision. It must not be stored as `accept`, `needs_revision`, or `reject`.
## Task
@@ -267,7 +267,11 @@ review, compensate, and audit work.
## Submission Packet
-The contributor's submitted output plus summary, artifacts, evidence references, hashes, and metadata. Workstream assigns the submission version server-side after blocking pre-submit checks pass.
+The contributor supplies a summary, accountability attestation, and one outer
+ZIP containing every required output/evidence file. Workstream derives the
+archive hash/size, semantic manifest, evidence facts, verified admission,
+artifact binding, and immutable Submission version server-side. Clients do not
+supply canonical hashes, manifests, provider references, or content IDs.
## Checker
diff --git a/docs/operations_project_operating_manual.md b/docs/operations_project_operating_manual.md
index 41ef74619..0a1f030aa 100644
--- a/docs/operations_project_operating_manual.md
+++ b/docs/operations_project_operating_manual.md
@@ -246,13 +246,14 @@ Before locking a submission packet:
- task is assigned to submitter
- summary exists
-- output package or reference exists
-- evidence exists
+- exactly one outer ZIP is uploaded through submission-bundle preparation
+- every project-required output/evidence file exists inside that ZIP
+- contributor attestation exists
- revision replay exists when task was previously `NEEDS_REVISION`
- effective project submission artifact policy is loaded
- generated project pre-submit checker policy runs
-- preflight failures return `PreSubmitCheckResponse(status="failed", eligible_to_submit=false, results=[...])`
-- blocked submission-create attempts return `pre_submission_checker_failed` with structured pass/fail/warning details
+- failed submission-bundle preparation returns `pre_submission_checker_failed` with bounded same-request status, eligibility, and pass/fail/warning details
+- no standalone preflight endpoint or client-owned manifest can reproduce the authoritative result
- no submission row is created until blocking pre-submit checks pass
- successful submission creation stamps the immutable submission boundary and queues the Celery pre-review gate
- `/finalize` is an Operator repair/requeue endpoint under
diff --git a/docs/product_first_user_flows.md b/docs/product_first_user_flows.md
index fba60f66e..76f332919 100644
--- a/docs/product_first_user_flows.md
+++ b/docs/product_first_user_flows.md
@@ -90,13 +90,14 @@ Acceptance:
## Flow 3: Contributor Submits Work
1. Contributor opens assigned task.
-2. Contributor attaches output files or links.
-3. Contributor attaches evidence.
-4. Contributor writes submission notes.
-5. Workstream executes the task's locked project `PreSubmitCheckerPolicy`.
-6. Preflight failures return `PreSubmitCheckResponse`; blocked submission-create attempts return `pre_submission_checker_failed` with structured pass/fail/warning details and create no submission.
-7. When blocking pre-submit checks pass, Contributor submits packet.
-8. Task enters `SUBMITTED`.
+2. Contributor uploads one outer ZIP containing every required output and evidence file.
+3. Contributor writes the required summary and attestation.
+4. Workstream safely inspects and manifests the ZIP in bounded private scratch.
+5. Workstream executes the single effective pre-submission plan: platform defaults plus the task-locked Project Guide policy.
+6. Failure returns bounded same-request `pre_submission_checker_failed` details and creates no submission or durable artifact.
+7. Passing bytes are stored and independently verified, producing a ready admission.
+8. Contributor creates the immutable Submission by consuming that admission under fresh authority.
+9. Task enters `SUBMITTED`.
Acceptance:
diff --git a/docs/spec_artifact_storage_service.md b/docs/spec_artifact_storage_service.md
index 675ce99cd..754eb76e4 100644
--- a/docs/spec_artifact_storage_service.md
+++ b/docs/spec_artifact_storage_service.md
@@ -1099,7 +1099,33 @@ only the manager-owned directory write bit after no-follow ownership/type
validation, then remove the tree; archive-supplied modes are never applied.
Mandatory platform and locked Project Guide checks consume that same read-only
-scratch tree. Infrastructure exhaustion returns:
+scratch tree as one ordered `EffectivePreSubmissionExecutionPlan` assembled from
+the central versioned `PreSubmissionCheckerCatalogue`:
+
+```text
+artifact custody/safety phase
+-> Workstream default policy phase
+-> locked Project Guide policy phase
+-> one bounded result/evidence envelope
+```
+
+The catalogue is the only name/version/dispatch registry. Each entry declares
+its classification, phase/order/dependencies, typed inputs, resource budget,
+stable result, policy provenance, and explicit `enabled|disabled` state.
+Startup validation rejects missing dependencies, duplicate IDs/versions,
+unknown policy primitives, invalid ordering, and any configuration that would
+treat a disabled mandatory entry as passing. A disabled mandatory security,
+integrity, or accountability entry fails preparation closed before durable or
+provider effects. A disabled advisory entry is recorded and skipped. Project
+policy and task parameters cannot toggle catalogue availability.
+
+ART's already implemented ZIP safety, manifest, executable, and change gates
+are registered capabilities in this plan; 04B does not reimplement them. The
+locked project policy consumes the server-derived manifest and sealed workspace
+through the same execution API. It may require `task.toml` or any other
+project-specific file, but no such filename is a Workstream universal default.
+
+Infrastructure exhaustion or mandatory catalogue unavailability returns:
```text
HTTP 503
@@ -1617,7 +1643,7 @@ bytes in PostgreSQL.
### Remaining v0.1 dependency order
The pre-submit checker materializer is a mandatory part of preparation, so its
-fixed-service AUTH activation must merge after hidden ART-04B and before
+fixed-service AUTH activation must merge after hidden ART-04B1-04B3 and before
contributor preparation is activated. Post-submit materialization and checker
output actions remain a later activation after ART-06A/06B. This ordering
prevents a live contributor route whose mandatory checker read is unavailable.
diff --git a/docs/spec_authorization_service.md b/docs/spec_authorization_service.md
index c9ad7e2dd..486d0e0c7 100644
--- a/docs/spec_authorization_service.md
+++ b/docs/spec_authorization_service.md
@@ -408,8 +408,8 @@ The paired artifact hidden-behavior matrix is closed:
| `WS-ART-001-02D` | Operator binding/replica/receipt/verification-job/recovery-attempt/audit reads; the operations-domain `operations.artifact_storage_admission.read` action mapped to `operations.status.read`; verification retry; `artifact.verification.execute`; `artifact.pending_work.scan`; and `artifact.put_attempt.resolve` |
| `WS-ART-001-03` | Hidden guide behavior for `artifact.guide_source.ingest -> artifact.guide_source.ingest`, `artifact.guide_source.read -> artifact.guide_source.read`, and `artifact.guide_source.binding.create -> artifact.binding.create`; AUTH activation custody is split between WS-XINT-002-04A and 04B below |
| `WS-ART-001-04A` historical baseline | the former multi-step upload authority had no route/command and is deleted from the live catalogue by WS-XINT-002-01 without compatibility aliases |
-| `WS-ART-001-04A1` through `04C2` | one hidden `artifact.submission_bundle.prepare` surface mapped to `submission.create`; 04B depends on 04A3, XINT-002-06A activates its fixed pre-submit materializer before 04C1, and the contributor action remains unavailable until complete 04C2 evidence and WS-XINT-002-05A |
-| `WS-ART-001-04B` | `artifact.pre_submit.checker_input.materialize` mapped to `artifact.checker_input.materialize` |
+| `WS-ART-001-04A1` through `04C2` | one hidden `artifact.submission_bundle.prepare` surface mapped to `submission.create`; 04A4 removes the legacy standalone precheck after 04A3, 04B1-04B3 implement the sole catalogue/materialization/evidence path, XINT-002-06A activates its fixed pre-submit materializer before 04C1, and the contributor action remains unavailable until complete 04C2 evidence and WS-XINT-002-05A |
+| `WS-ART-001-04B2` and `04B3` | hidden `artifact.pre_submit.checker_input.materialize` resource/guard usage mapped to `artifact.checker_input.materialize`; 04B2 owns exact sealed materialization and 04B3 consumes it in the complete effective plan |
| `WS-ART-001-05` | `artifact.submission.binding.create` mapped to `artifact.binding.create` |
| `WS-ART-001-06A` | `artifact.post_submit.checker_input.materialize` mapped to `artifact.checker_input.materialize` |
| `WS-ART-001-06B` | `artifact.checker_output.write` mapped to `artifact.checker_output.write`; `artifact.checker_output.binding.create` mapped to `artifact.binding.create`, both using the checker-run resource |
@@ -417,8 +417,8 @@ The paired artifact hidden-behavior matrix is closed:
WS-XINT-002-01 deletes the former multi-step authority and registers planned
`artifact.submission_bundle.prepare -> submission.create`. No ART implementation
may execute that ActionId while it remains planned. The mandatory order is
-ART-04A1 -> 04A2 -> 04A3 -> 04B -> XINT-002-06A -> ART-04C1 -> 04C2 ->
-XINT-002-05A. This ensures fixed-service pre-submit materialization is active
+ART-04A1 -> 04A2 -> 04A3 -> PLAN4 -> 04A4 -> 04B1 -> 04B2 -> 04B3 ->
+XINT-002-06A -> ART-04C1 -> 04C2 -> XINT-002-05A. This ensures fixed-service pre-submit materialization is active
before contributor preparation can become live.
WS-XINT-002-04A activates only `artifact.guide_source.ingest`. The existing
@@ -508,7 +508,7 @@ remain planned and unavailable, and add no migration.
| `artifact.verification.execute` | `artifact.verification.execute` | fixed verifier service | verification job | `02D` |
| `artifact.pending_work.scan` | `artifact.pending_work.scan` | fixed scheduler service | system pending-work scope | `02D` |
| `artifact.put_attempt.resolve` | `artifact.put_attempt.resolve` | fixed put-resolver service | put attempt | `02D` |
-| `artifact.pre_submit.checker_input.materialize` | `artifact.checker_input.materialize` | fixed materializer service | task plus current process-local prepared-bundle generation; no scratch path/handle is serialized | `04B` |
+| `artifact.pre_submit.checker_input.materialize` | `artifact.checker_input.materialize` | fixed materializer service | task plus current process-local prepared-bundle generation; no scratch path/handle is serialized | `04B2/04B3` |
| `artifact.post_submit.checker_input.materialize` | `artifact.checker_input.materialize` | fixed materializer service | checker run and immutable bindings | `06A` |
| `artifact.checker_output.write` | `artifact.checker_output.write` | fixed checker-output service | checker run | `06B` |
| `artifact.review_packet.materialize` | `artifact.review_packet.materialize` | fixed materializer service | exact active lease and Submission packet | `07A` |
diff --git a/docs/spec_chunk_8_submission_artifact_policy_checkers.md b/docs/spec_chunk_8_submission_artifact_policy_checkers.md
index f9b11d344..2ff26ed8d 100644
--- a/docs/spec_chunk_8_submission_artifact_policy_checkers.md
+++ b/docs/spec_chunk_8_submission_artifact_policy_checkers.md
@@ -3,6 +3,13 @@
> 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.
+
## Purpose
Chunk 8 expands the checker registry from the first structural runner into the first policy-aware submission artifact gate.
@@ -222,13 +229,14 @@ WorkstreamDefaultSubmissionArtifactPolicy
Workstream defaults are non-bypassable. Project policy can add required artifacts, evidence requirements, stricter forbidden patterns, and packaging rules, but it cannot remove hash requirements, allow unsafe storage references, require forbidden files, or downgrade blocking defaults.
-Blocking pre-submit failures prevent submission creation. Preflight failures
-return `PreSubmitCheckResponse(status="failed", eligible_to_submit=false,
-results=[...])`. Blocked submission-create attempts return
-`DomainError(code="pre_submission_checker_failed")` with structured
-pass/fail/warning details, create no submission row, no submission version, no
-task transition to `submitted`, and no submission-created audit event. They do
-not return review decision values: `accept`, `needs_revision`, or `reject`.
+Blocking pre-submit failures prevent submission creation. The continuous
+submission-bundle preparation request returns
+`DomainError(code="pre_submission_checker_failed",
+details={status, eligible_to_submit, results})` with bounded, path-redacted
+same-request details. It creates no submission row, submission version, task
+transition to `submitted`, or submission-created audit event. There is no
+independent precheck route or standalone pre-submit registry. Results do not
+use review decision values: `accept`, `needs_revision`, or `reject`.
Durable post-submit checker runs execute the complete `execution_checkers` list
from the submission-stamped locked `PostSubmitCheckerPolicy` body. That locked
@@ -323,8 +331,9 @@ Safe evidence references mean opaque Workstream evidence ids, sanitized labels,
- canonical Chunk 8 checker names are registered
- stale Chunk 7 temporary checker names are removed from public docs/templates/tests
- pre-submit feedback executes the task's locked project `PreSubmitCheckerPolicy` and runs without durable checker records
-- preflight failures return `PreSubmitCheckResponse(status="failed", eligible_to_submit=false, results=[...])`
-- blocked submission-create attempts return `DomainError(code="pre_submission_checker_failed")`, include structured pass/fail/warning details, create no submission row, no submission version, no task transition to `submitted`, and no submission-created audit event
+- failed continuous preparation returns `DomainError(code="pre_submission_checker_failed", details={status, eligible_to_submit, results})` with bounded path-redacted same-request details
+- no independent precheck route or standalone pre-submit registry remains
+- blocked preparation creates no submission row, submission version, task transition to `submitted`, or submission-created audit event
- Workstream default submission artifact rules cannot be weakened by project policy
- durable checker runs persist Chunk 8 checker results
- missing required evidence blocks review routing
diff --git a/docs/template_checker_policy.md b/docs/template_checker_policy.md
index 34ce1a2a3..5753b3d71 100644
--- a/docs/template_checker_policy.md
+++ b/docs/template_checker_policy.md
@@ -71,10 +71,10 @@ PreSubmitCheckerPolicy =
trusted compiler output from EffectiveProjectSubmissionArtifactPolicy
```
-Preflight failures return `PreSubmitCheckResponse(status="failed",
-eligible_to_submit=false, results=[...])`. Blocked submission-create attempts
-return `DomainError(code="pre_submission_checker_failed")` with structured
-pass/fail/warning details. Pre-submit failures do not create durable
+Failed continuous submission-bundle preparation returns
+`DomainError(code="pre_submission_checker_failed")` with bounded same-request
+status, eligibility, and pass/fail/warning details. There is no standalone
+preflight route. Pre-submit failures do not create durable
`CheckerRun` records and do not return review decision values: `accept`,
`needs_revision`, or `reject`.
diff --git a/docs/template_submission_artifact_policy.md b/docs/template_submission_artifact_policy.md
index 52f799edb..e4f88f0da 100644
--- a/docs/template_submission_artifact_policy.md
+++ b/docs/template_submission_artifact_policy.md
@@ -82,6 +82,13 @@ override Workstream rules, or weaken default checks.
Every project inherits Workstream default submission artifact rules. Project policy can add stricter requirements, but it cannot remove, weaken, downgrade, or bypass these defaults.
+All defaults are named and versioned in the central Workstream pre-submission
+checker catalogue. The locked project policy adds constrained rules to that
+same catalogue execution; it does not create another API or registry. Catalogue
+availability is deployment-owned. A disabled mandatory entry makes submission
+preparation unavailable, while a disabled advisory entry is explicitly recorded
+and does not silently pass. Project configuration cannot disable either class.
+
Default required packet fields:
- summary
@@ -114,17 +121,19 @@ Default storage rules:
query strings, bucket secrets, and token-bearing references are rejected
before persistence
-Default forbidden artifacts:
+Default high-confidence forbidden artifacts:
- `.env`
- `.git`
-- credentials
-- secrets
-- private keys
-- tokens
+- exact known credential files
+- exact known private-key files
- `.pem`
- `.key`
-- `node_modules`
+
+Broad names such as `token`, `secret`, `credential`, or dependency directories
+are not universal blockers solely because a path contains the word. They must
+be a narrowly defined high-confidence match, an advisory catalogue check, or a
+locked project-specific rule.
A project-required artifact that matches a Workstream default forbidden rule remains blocked. That conflict is a project setup defect.
@@ -212,11 +221,13 @@ Generated policy lock:
Tasks lock this project checker compiled bundle hash before entering the contributor pipeline. Tasks
do not derive or compile their own checker by default.
-Blocked submission-create attempts return `pre_submission_checker_failed` with
-structured pass/fail/warning details.
-The preflight endpoint returns `PreSubmitCheckResponse` with `status`,
-`eligible_to_submit`, and `results`. Neither path returns review decision
-values: `accept`, `needs_revision`, or `reject`.
+Failed submission-bundle preparation returns
+`pre_submission_checker_failed` with bounded same-request status, eligibility,
+and pass/fail/warning details. No independently invocable preflight endpoint or
+ID-addressed evidence-read route exists. These results never use review decision
+values: `accept`, `needs_revision`, or `reject`. After verified preparation,
+final Submission creation consumes the ready admission under fresh authority
+and does not rerun scratch-bound checks.
Expected generated checks:
diff --git a/docs/template_submission_packet.md b/docs/template_submission_packet.md
index c95202671..6a207ae4c 100644
--- a/docs/template_submission_packet.md
+++ b/docs/template_submission_packet.md
@@ -51,13 +51,13 @@ ReviewLease reviewer freeze during contribution creation. Only a prior human
`needs_revision` preparation may have rebased the assignment selector; project
publication or submission input cannot change it.
-Workstream runs pre-submit checks from the locked project pre-submit checker policy before creating the submission.
-Preflight failures return `PreSubmitCheckResponse` with structured
-pass/fail/warning details. Blocked submission-create attempts return
-`pre_submission_checker_failed` with the same structured details, create no
+Workstream runs the single effective pre-submission plan against the uploaded
+outer ZIP in bounded scratch before creating the submission. Failed preparation
+returns `pre_submission_checker_failed` with bounded same-request structured
+details, creates no
submission row, no submission version, and no submission-created audit event,
-and do not return review decision values: `accept`, `needs_revision`, or
-`reject`.
+and does not return review decision values: `accept`, `needs_revision`, or
+`reject`. There is no standalone preflight endpoint.
## Submission Bundle Manifest
@@ -69,13 +69,20 @@ archive permission metadata is excluded. Nested archives remain opaque in v0.1.
## Evidence
-| Type | Label | URI Or Reference | Hash | Proves Which Artifact Or Claim |
-| --- | --- | --- | --- | --- |
-| `` | `