Skip to content

ART 04B2: execute default pre-submit checks - #282

Merged
abiorh-claw merged 10 commits into
mainfrom
codex/ws-art-001-04b2-default-checker-execution
Aug 5, 2026
Merged

ART 04B2: execute default pre-submit checks#282
abiorh-claw merged 10 commits into
mainfrom
codex/ws-art-001-04b2-default-checker-execution

Conversation

@Abiorh001

@Abiorh001 Abiorh001 commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator

WS-ART-001-04B2 PR Trust Bundle

Chunk

WS-ART-001-04B2 — default checker execution.

Goal

Materialize one prepared contributor ZIP only after fixed-service authority,
project its exact 04A semantic manifest into bounded private scratch, and run
only the ordered Workstream platform/default pre-submission slice.

Human-approved intent

Workstream owns the generic default pre-submission checks. Project-specific
rules remain a later phase of the same effective plan and do not execute in
this chunk. Production authority remains planned and unavailable.

What changed

  • Added the hidden authorized materialization service and exact AUTH facts.
  • Added quota-charged canonical ZIP projection with fixed executable semantics.
  • Added a callback-scoped capability containing immutable verified bytes and
    manifest facts, revoked before scratch cleanup completes.
  • Added platform/default dispatch with bounded path-redacted results.
  • Shared attestation and quality predicates with the existing checker path.
  • Added scratch workspace byte/entry accounting and crash-cleanup compatibility.
  • Added focused failure/concurrency tests, semantic lane ownership, coverage
    reports, and canonical documentation.

Why it changed

04B1 locked what must run. 04B2 supplies the hidden execution boundary needed
before project-policy execution and durable evidence can be composed safely.

Design chosen

AUTH is consumed before any prepared-byte or workspace access. The canonical
archive inspector alone projects the verified tree. Checker code receives no
path, provider handle, scratch handle, directory fd, or serializable authority.
Cancellation and deadlines abort before checker execution while cleanup still
runs to completion.

Alternatives rejected

  • Public PreparedArtifact processing: bypassed fixed-service authority.
  • Direct ZIP extraction or a second extractor: duplicated the canonical safety
    boundary.
  • Filesystem descriptor capability: allowed callback mutation.
  • Legacy checker registry execution: would preserve the authority being
    replaced and mix project-policy work into 04B2.

Scope control

No public route, project-policy execution, durable evidence, admission,
Submission, review decision, provider I/O, AUTH activation, or legacy removal.

Product behavior

None is publicly active. Results are non-durable internal values:
passed, warning, failed, advisory_disabled, and
dependency_not_run; they are not review decisions.

Acceptance criteria proof

Tests prove authority-before-access, exact plan/catalogue/archive/manifest
identity, closed dispatch, disabled mandatory failure, advisory visibility,
project-policy isolation, semantic drift rejection, scratch capacity, fixed
modes, callback revocation, cancellation/deadline abort, cleanup, and no legacy
runner dependency.

Tests/checks run

  • 29 focused materialization/default tests passed.
  • Contract-focused ART and checker suites passed.
  • Ruff, compilation, semantic-lane collection/validation, stale contract,
    lightweight agent, Markdown-link, stale-wording, and diff checks passed.
  • Full coverage and integration execution is delegated to hosted Backend Gates.

Test delta

Two focused modules were added; existing cleanup/config tests were strengthened.
No test was removed, skipped, xfailed, or weakened.

CI integrity

The repository 78 percent floor remains. Existing checker 90 percent coverage
remains, and ART module, cancellation/lock, and artifact-interface 90 percent
reports are explicit. Both new tests are assigned to semantic lanes.

Reviewer results

Architecture, security, QA, senior engineering, reuse, CI integrity, test
delta, and docs passed. Product/ops passed with one non-blocking observation
that the platform/default slice is derived from the locked full plan.

External review

Pending GitHub Backend Gates and CodeRabbit on the draft PR.

Remaining risks

The production materializer remains unavailable until AUTH activation. This
chunk intentionally creates no durable checker evidence or admission.

Follow-up work

04B3 owns project-policy execution and durable checker evidence. Later AUTH
activation and the 05B admission-backed cutover remain separate ordered work.

Human review focus

  • Confirm no byte/workspace access precedes fixed-service AUTH.
  • Confirm the callback sees exactly the 04A manifest tree and cannot retain
    scratch authority or content after close.
  • Confirm no project-policy or legacy public precheck path executes.

Human merge ownership

Only the repository owner may approve and merge this PR.

Summary by CodeRabbit

  • New Features
    • Added default pre-submission checks for contributor archives, including content, attestations, sensitive paths, and quality warnings.
    • Added clear outcomes for passed, warning, failed, advisory-disabled, and dependency-not-run checks.
  • Bug Fixes
    • Improved archive integrity validation, workspace limits, cleanup, cancellation, and timeout handling.
    • Added safeguards against inconsistent submission data and unauthorized archive access.
  • Documentation
    • Updated guidance on checker behavior, authorization, result handling, and staged rollout boundaries.

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 0db1da17-343f-491f-afb0-ceb35bbe84bf

📥 Commits

Reviewing files that changed from the base of the PR and between 2f6b327 and cf7f742.

📒 Files selected for processing (7)
  • .agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/reviews/WS-ART-001-04B2-external-review-response.md
  • backend/app/modules/artifacts/preparation.py
  • backend/app/modules/checkers/pre_submit_execution.py
  • backend/tests/test_artifact_preparation.py
  • backend/tests/test_checker_materialization.py
  • backend/tests/test_default_pre_submit_execution.py
  • docs/architecture_data_model.md
🚧 Files skipped from review as they are similar to previous changes (5)
  • .agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/reviews/WS-ART-001-04B2-external-review-response.md
  • backend/tests/test_checker_materialization.py
  • docs/architecture_data_model.md
  • backend/app/modules/checkers/pre_submit_execution.py
  • backend/app/modules/artifacts/preparation.py

📝 Walkthrough

Walkthrough

ART-04B2 adds fixed-service authorization, sealed ZIP projection, reservation-aware scratch custody, hidden default checker execution, bounded results, cancellation handling, cleanup, tests, CI coverage gates, and documentation. Project-policy execution and durable evidence remain deferred.

Changes

ART-04B2 default checker execution

Layer / File(s) Summary
Contracts and authorization
.agent-loop/..., backend/app/core/config.py, backend/app/interfaces/..., backend/app/modules/artifacts/sources.py, backend/app/modules/artifacts/submission_materialization.py
Adds plan-bound materialization facts, process-local artifact generations, workspace-entry limits, typed execution results, and deny-by-default authorization.
Scratch custody and sealed projection
backend/app/modules/artifacts/preparation.py, backend/app/modules/artifacts/submission_archive.py, backend/tests/test_checker_materialization.py
Adds reservation-aware workspaces, descriptor-safe ZIP projection, callback-scoped sealed trees, bounded reads, cleanup, and capacity checks.
Default checker execution
backend/app/modules/checkers/*, backend/tests/test_default_pre_submit_execution.py, backend/scripts/run_test_lanes.py
Adds ordered Workstream-default execution, shared policy semantics, dependency and disabled-entry handling, bounded statuses, sensitive-path checks, cancellation, and timeout handling.
Validation and rollout documentation
.github/workflows/backend.yml, .agent-loop/.../reviews/*, docs/*, backend/tests/*
Adds configuration and compatibility tests, coverage gates, CI timing fixes, initiative status updates, review evidence, and documentation for the hidden execution boundary and deferred activation.

Estimated code review effort: 5 (Critical) | ~120 minutes

Sequence Diagram(s)

sequenceDiagram
  participant PreparedBundleMaterializationService
  participant Authorization
  participant ArtifactScratchManager
  participant SubmissionArchiveInspector
  participant DefaultPreSubmissionProcessor
  PreparedBundleMaterializationService->>Authorization: consume fixed materializer capability
  Authorization-->>PreparedBundleMaterializationService: authorize or deny
  PreparedBundleMaterializationService->>ArtifactScratchManager: reserve bounded workspace
  PreparedBundleMaterializationService->>SubmissionArchiveInspector: project validated ZIP
  SubmissionArchiveInspector->>DefaultPreSubmissionProcessor: execute with sealed tree
  DefaultPreSubmissionProcessor-->>PreparedBundleMaterializationService: return bounded results
  SubmissionArchiveInspector->>ArtifactScratchManager: revoke tree and clean workspace
Loading

Possibly related PRs

Suggested reviewers: abiorh-claw

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 51.56% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the main change: executing default pre-submit checks for ART 04B2.
Description check ✅ Passed The description covers the chunk, goal, design, scope, tests, review status, risks, follow-up work, and human review focus.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/ws-art-001-04b2-default-checker-execution

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@Abiorh001

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown
⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@Abiorh001
Abiorh001 force-pushed the codex/ws-art-001-04b2-default-checker-execution branch from 021ed21 to faf40e7 Compare August 5, 2026 06:05
@Abiorh001
Abiorh001 marked this pull request as ready for review August 5, 2026 07:25

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 10

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
.agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/chunks/WS-ART-001-04B2-default-checker-execution.md (1)

141-146: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Align the CI gate list with the local verification commands.

The local verification block at Line 129 covers app/core/cancellation.py,app/core/config.py,app/core/file_locks.py. The CI gate at Line 144 covers only app/core/cancellation.py,app/core/file_locks.py. This chunk changes app/core/config.py (a new scratch setting is consumed). Add app/core/config.py to the CI gate, or state why the config gate stays local only.

📝 Proposed gate alignment
-coverage report --include='app/core/cancellation.py,app/core/file_locks.py' --precision=2 --fail-under=90
+coverage report --include='app/core/cancellation.py,app/core/config.py,app/core/file_locks.py' --precision=2 --fail-under=90
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
@.agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/chunks/WS-ART-001-04B2-default-checker-execution.md
around lines 141 - 146, Update the CI coverage command for core modules in the
default checker execution instructions to include app/core/config.py alongside
app/core/cancellation.py and app/core/file_locks.py, matching the local
verification command. Keep the existing coverage threshold and other gate
entries unchanged.
backend/app/modules/checkers/runner.py (1)

773-779: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Preserve the legacy matched_categories metadata shape.

matched_low_quality_patterns returns a sorted tuple, while the legacy standalone precheck result exposed categories as a list in declaration order. matched_categories must remain a list with the old category order for outcomes before 05B.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/app/modules/checkers/runner.py` around lines 773 - 779, Update the
low-quality artifact check around matched_low_quality_patterns and the _warning
metadata construction so matched_categories remains a list in the legacy
declaration order, rather than exposing the helper’s sorted tuple. Preserve the
existing matched-pattern count and ensure this shape applies to outcomes before
05B.
🧹 Nitpick comments (7)
backend/tests/test_default_pre_submit_execution.py (2)

406-407: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Distinguish the three invalid-state failures.

pytest.raises(PreSubmissionInfrastructureUnavailable) carries no match. All three parameter cases (stale_entry, duplicate, unknown) raise the same exception class with different messages. The test passes if two cases collapse onto one code path. Add match= per case so each parameter proves its own guard.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/tests/test_default_pre_submit_execution.py` around lines 406 - 407,
Update the parameterized test around service.materialize_prepared_bundle to
provide a case-specific match pattern in pytest.raises for stale_entry,
duplicate, and unknown. Use each expected exception message so the test verifies
the distinct guard path rather than only the shared
PreSubmissionInfrastructureUnavailable exception type.

608-610: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Set the deadline through configuration instead of private attributes.

This line mutates preparation._active[...] and reads request.prepared_artifact._binding. Both are private. The same pattern appears at Lines 659-661. A refactor of ArtifactPreparationService breaks these two tests with an opaque KeyError or AttributeError.

_limits() already builds ArtifactPreparationLimits. Add a small total_deadline_seconds to the limits used by these two tests, and drive the timeout through the public configuration path.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/tests/test_default_pre_submit_execution.py` around lines 608 - 610,
Replace the private-state deadline mutations in both affected tests with public
configuration: extend the ArtifactPreparationLimits produced by _limits() with a
small total_deadline_seconds value, then configure ArtifactPreparationService
through that limits path so the timeout is exercised without accessing
preparation._active or request.prepared_artifact._binding.
backend/app/modules/checkers/pre_submit_defaults.py (1)

55-76: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Return a typed structure instead of a heterogeneous dict.

The return type is dict[str, bool | list[str]]. Every caller must narrow the value type by key. runner.py Line 730 assigns missing_attestation_terms and uses it both as a truth value and as metadata. pre_submit_execution.py Line 283 wraps each lookup in bool(...). A frozen dataclass with has_required_length: bool, ..., missing_attestation_terms: tuple[str, ...] removes the narrowing and makes the shared contract explicit.

♻️ Proposed typed contract
+@dataclass(frozen=True, slots=True)
+class AttestationValidationFacts:
+    """Canonical attestation facts shared by both pre-submission paths."""
+
+    has_required_length: bool
+    has_non_generic_text: bool
+    has_confidentiality_term: bool
+    has_credential_term: bool
+    has_source_or_platform_term: bool
+    missing_attestation_terms: tuple[str, ...]
+
+
 def attestation_validation_facts(
     worker_attestation: str,
     *,
     required_terms: Sequence[str] = (),
-) -> dict[str, bool | list[str]]:
+) -> AttestationValidationFacts:
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/app/modules/checkers/pre_submit_defaults.py` around lines 55 - 76,
Replace the heterogeneous return from attestation_validation_facts with a frozen
typed dataclass containing the boolean validation fields and
missing_attestation_terms as a tuple[str, ...]. Update the function to construct
that dataclass and adjust callers such as runner.py and pre_submit_execution.py
to access typed attributes directly, preserving truth-value checks and metadata
handling without bool() conversions or key-based narrowing.
backend/app/modules/artifacts/preparation.py (2)

1213-1218: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

The version-3 fallback is unreachable and weakens fail-closed reads.

No writer in this module produces a version-3 ledger without workspaces. __init__ writes all three keys, and _write_ledger validates the complete key set before writing. This branch therefore only accepts a malformed version-3 document instead of rejecting it.

Restrict the compatibility allowance to version 2 so a truncated version-3 ledger fails closed.

♻️ Proposed narrowing of the compatibility branch
-        if (
-            isinstance(ledger, dict)
-            and ledger.get("version") == _LEDGER_VERSION
-            and set(ledger) == {"version", "reservations"}
-        ):
-            ledger = {**ledger, "workspaces": []}
         if isinstance(ledger, dict) and ledger.get("version") == 2:
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/app/modules/artifacts/preparation.py` around lines 1213 - 1218,
Update the compatibility branch around the ledger shape check to apply only to
version 2 documents, not _LEDGER_VERSION/version 3. Preserve the existing
addition of an empty workspaces list for valid version-2 ledgers, while allowing
malformed version-3 ledgers to fail closed.

1699-1699: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Type the processor as a Protocol instead of Any.

This method requires process(reader, workspace) and abort(). The Any annotation hides that contract, so a processor without abort fails only at the moment of cancellation or deadline expiry, which is the least testable path.

Declare a PreparedSubmissionProcessor Protocol next to the existing PreparedArtifactInspector and PreparedGuideExtractor ports, then annotate the parameter with it.

♻️ Proposed typed port

Add the port beside the other prepared-artifact ports:

class PreparedSubmissionProcessor(Protocol[_InspectionResultCo]):
    """Project one prepared submission inside a scratch workspace."""

    def process(self, reader: BinaryIO, workspace: Path) -> _InspectionResultCo:
        """Return bounded results without retaining either capability."""

    def abort(self) -> None:
        """Deny checker access after cancellation or deadline expiry."""

Then narrow the parameter:

     async def _process_prepared_submission(
         self,
         prepared: PreparedArtifact,
-        processor: Any,
+        processor: PreparedSubmissionProcessor[_InspectionResult],
         *,
         reserved_bytes: int,
         maximum_entries: int,
     ) -> _InspectionResult:
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/app/modules/artifacts/preparation.py` at line 1699, Replace the Any
annotation on the processor parameter in the surrounding preparation method with
a new PreparedSubmissionProcessor Protocol. Define the Protocol beside
PreparedArtifactInspector and PreparedGuideExtractor, including process(reader,
workspace) returning the inspection result type and abort() returning None, then
use that Protocol for the parameter.
backend/app/modules/artifacts/submission_materialization.py (1)

113-118: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider naming the sealed pairing explicitly.

PreparedBundleMaterializationService calls ArtifactPreparationService._process_prepared_submission, a private method of another module. The preparation side documents this as the only authority-gated caller and re-validates handle ownership, so the coupling is deliberate. Keeping the method private also keeps the byte-access surface narrow, so do not make it public.

Add a short comment here that records the intentional friend-class relationship. A future reader will otherwise treat this call as an encapsulation mistake and try to widen the API.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/app/modules/artifacts/submission_materialization.py` around lines 113
- 118, Add a concise comment immediately above the _process_prepared_submission
call in PreparedBundleMaterializationService documenting the intentional
friend-class relationship with ArtifactPreparationService, including that this
is the sole authority-gated caller and that the private API must remain private.
Do not change method visibility or surrounding behavior.
backend/app/modules/artifacts/submission_archive.py (1)

359-374: 🚀 Performance & Scalability | 🔵 Trivial

Track the resident-memory ceiling of sealed projection.

_seal_projected_content snapshots every projected file into memory before the callback runs. The aggregate is bounded by artifact_submission_zip_maximum_expanded_bytes, whose default and ceiling are both 512 MiB, and artifact_scratch_maximum_concurrency defaults to 4. Worst-case resident bytes therefore reach roughly 2 GiB per process.

The design is deliberate: it removes filesystem authority from checker adapters, and the workspace reservation already charges the same expanded bytes against the scratch quota. Before AUTH activation, size the API and worker containers against this ceiling and add a memory alert. If a later checker needs only a few files, consider lazy per-path reads through the retained root descriptor instead of a full snapshot.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/app/modules/artifacts/submission_archive.py` around lines 359 - 374,
Track the resident-memory ceiling created by _seal_projected_content: use
artifact_submission_zip_maximum_expanded_bytes multiplied by
artifact_scratch_maximum_concurrency to size both API and worker containers, and
add a memory alert covering that aggregate bound. Preserve the full snapshot
behavior and document the resulting ceiling before AUTH activation.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/DISCOVERY.md:
- Around line 352-357: The authorization tests should use approved AUTH test
support instead of the locally defined _AllowAuthority in
test_default_pre_submit_execution.py. Replace or document that local double with
an existing AUTH fixture or capability, while keeping
DenyPreSubmitMaterializationAuthorization imported from
app.modules.artifacts.submission_materialization for the denial path.

In
@.agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/reviews/WS-ART-001-04B2-pr-trust-bundle.md:
- Line 102: Update the CodeRabbit review status in the PR trust-bundle record to
state that no CodeRabbit findings are available because the service was
externally rate-limited and the review did not complete, replacing the
implication that the review completed without actionable comments.

In @.github/workflows/backend.yml:
- Around line 148-151: Update the workflow step containing the printf command so
its output redirection remains on the same command, writing the job_start_epoch
value directly to job-start-epoch.txt. Keep the existing lane-specific directory
setup and ensure printf does not emit the epoch only to the job log.

In `@backend/app/modules/checkers/pre_submit_defaults.py`:
- Around line 39-52: Update attestation_term_is_satisfied so a normalized term
with no non-ignored words is not treated as satisfied by all attestations;
require at least one required word before applying the all(...) check,
preserving the legacy rule for terms such as “the exclusion.”

In `@backend/app/modules/checkers/pre_submit_execution.py`:
- Around line 198-206: Update the dependency validation around the unmet
computation in the pre-submit execution flow to distinguish missing statuses for
dependencies outside _EXECUTED_PHASES from dependencies that are merely not yet
run. Reject unknown or out-of-slice dependencies by raising
PreSubmissionInfrastructureUnavailable, while preserving the existing
DEPENDENCY_NOT_RUN behavior for valid dependencies whose execution has not
occurred.
- Around line 207-232: Move the disabled-mandatory check and the duplicate
definition identity check to the beginning of the loop handling each entry,
before evaluating blocked/unmet dependencies or calling _dispatch. Ensure
disabled mandatory entries always raise PreSubmissionInfrastructureUnavailable,
and duplicate entry.definition_id values are rejected before any checker
executes; then retain the existing dependency, disabled-advisory, and dispatch
result handling for valid entries.

In `@backend/tests/test_checker_materialization.py`:
- Around line 190-209: Extend
test_workspace_cleanup_bound_is_separate_from_prepared_file_limit to create a
nested directory chain whose depth reaches the workspace entry limit, placing an
entry at each level and using directory-relative operations as needed. Keep the
existing cleanup assertion and ensure the workspace is fully removed after
context exit, proving recursive cleanup at the maximum nested layout.

In `@backend/tests/test_default_pre_submit_execution.py`:
- Around line 140-149: Expand the assertions in the test using
_AllowAuthority.consume to verify all eleven required materializer facts, plus
the received action ID and service identity, rather than only
prepared_generation_id. Update _handle so it creates PreparedAuthorizationHandle
through its real constructor, or replace it with a typed fake that preserves and
exercises the handle contract instead of bypassing initialization with
object.__new__.

In `@docs/roadmap_status.md`:
- Around line 92-96: Move the 04B2 hidden contributor-ZIP execution entry from
“Implemented On main” to “Integration In Progress” in the roadmap status ledger,
preserving its existing description. Do not mark it implemented until PR `#282`
has merged and the hosted gates and human merge are complete.

In `@docs/spec_artifact_storage_service.md`:
- Line 890: Rewrite the sealed-tree sentence in
docs/spec_artifact_storage_service.md to present the events as a clear sequence:
the tree is destroyed first, then only bounded, path-redacted platform/default
results return. Preserve the existing meaning and terminology.

---

Outside diff comments:
In
@.agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/chunks/WS-ART-001-04B2-default-checker-execution.md:
- Around line 141-146: Update the CI coverage command for core modules in the
default checker execution instructions to include app/core/config.py alongside
app/core/cancellation.py and app/core/file_locks.py, matching the local
verification command. Keep the existing coverage threshold and other gate
entries unchanged.

In `@backend/app/modules/checkers/runner.py`:
- Around line 773-779: Update the low-quality artifact check around
matched_low_quality_patterns and the _warning metadata construction so
matched_categories remains a list in the legacy declaration order, rather than
exposing the helper’s sorted tuple. Preserve the existing matched-pattern count
and ensure this shape applies to outcomes before 05B.

---

Nitpick comments:
In `@backend/app/modules/artifacts/preparation.py`:
- Around line 1213-1218: Update the compatibility branch around the ledger shape
check to apply only to version 2 documents, not _LEDGER_VERSION/version 3.
Preserve the existing addition of an empty workspaces list for valid version-2
ledgers, while allowing malformed version-3 ledgers to fail closed.
- Line 1699: Replace the Any annotation on the processor parameter in the
surrounding preparation method with a new PreparedSubmissionProcessor Protocol.
Define the Protocol beside PreparedArtifactInspector and PreparedGuideExtractor,
including process(reader, workspace) returning the inspection result type and
abort() returning None, then use that Protocol for the parameter.

In `@backend/app/modules/artifacts/submission_archive.py`:
- Around line 359-374: Track the resident-memory ceiling created by
_seal_projected_content: use artifact_submission_zip_maximum_expanded_bytes
multiplied by artifact_scratch_maximum_concurrency to size both API and worker
containers, and add a memory alert covering that aggregate bound. Preserve the
full snapshot behavior and document the resulting ceiling before AUTH
activation.

In `@backend/app/modules/artifacts/submission_materialization.py`:
- Around line 113-118: Add a concise comment immediately above the
_process_prepared_submission call in PreparedBundleMaterializationService
documenting the intentional friend-class relationship with
ArtifactPreparationService, including that this is the sole authority-gated
caller and that the private API must remain private. Do not change method
visibility or surrounding behavior.

In `@backend/app/modules/checkers/pre_submit_defaults.py`:
- Around line 55-76: Replace the heterogeneous return from
attestation_validation_facts with a frozen typed dataclass containing the
boolean validation fields and missing_attestation_terms as a tuple[str, ...].
Update the function to construct that dataclass and adjust callers such as
runner.py and pre_submit_execution.py to access typed attributes directly,
preserving truth-value checks and metadata handling without bool() conversions
or key-based narrowing.

In `@backend/tests/test_default_pre_submit_execution.py`:
- Around line 406-407: Update the parameterized test around
service.materialize_prepared_bundle to provide a case-specific match pattern in
pytest.raises for stale_entry, duplicate, and unknown. Use each expected
exception message so the test verifies the distinct guard path rather than only
the shared PreSubmissionInfrastructureUnavailable exception type.
- Around line 608-610: Replace the private-state deadline mutations in both
affected tests with public configuration: extend the ArtifactPreparationLimits
produced by _limits() with a small total_deadline_seconds value, then configure
ArtifactPreparationService through that limits path so the timeout is exercised
without accessing preparation._active or request.prepared_artifact._binding.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 4dfda595-be5a-4feb-9cfe-df631e940156

📥 Commits

Reviewing files that changed from the base of the PR and between c7270d1 and 65f420c.

📒 Files selected for processing (35)
  • .agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/AUTH_HANDOFF.md
  • .agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/CHUNK_MAP.md
  • .agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/DISCOVERY.md
  • .agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/STATUS.md
  • .agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/chunks/WS-ART-001-04B2-default-checker-execution.md
  • .agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/reviews/WS-ART-001-04B2-external-review-response.md
  • .agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/reviews/WS-ART-001-04B2-internal-review-evidence.md
  • .agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/reviews/WS-ART-001-04B2-pr-trust-bundle.md
  • .github/workflows/backend.yml
  • backend/app/adapters/artifacts/__init__.py
  • backend/app/core/config.py
  • backend/app/interfaces/artifact_operations.py
  • backend/app/modules/artifacts/preparation.py
  • backend/app/modules/artifacts/sources.py
  • backend/app/modules/artifacts/submission_archive.py
  • backend/app/modules/artifacts/submission_materialization.py
  • backend/app/modules/checkers/pre_submit_defaults.py
  • backend/app/modules/checkers/pre_submit_execution.py
  • backend/app/modules/checkers/runner.py
  • backend/scripts/run_test_lanes.py
  • backend/tests/test_artifact_cleanup_wiring.py
  • backend/tests/test_checker_materialization.py
  • backend/tests/test_config.py
  • backend/tests/test_default_pre_submit_execution.py
  • docs/architecture_checker_framework.md
  • docs/architecture_data_model.md
  • docs/architecture_lockdown.md
  • docs/glossary.md
  • docs/operations_authorization_service.md
  • docs/roadmap_status.md
  • docs/spec_artifact_storage_service.md
  • docs/spec_authorization_service.md
  • docs/template_checker_policy.md
  • docs/template_submission_artifact_policy.md
  • docs/template_submission_packet.md

Comment on lines +352 to +357
- Prepared authorization is consumed through the existing opaque handle at the
hidden fixed-service composition seam before any prepared-byte read, ZIP open,
workspace reservation, or checker fact. Until XINT-06A activates the action
owned in the catalogue by `AUTH_ART_04B`, production composition remains fail
closed; tests use existing AUTH fixtures/capabilities, never a production
ART-local fake protocol.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

rg -n -C 6 \
  '(_AllowAuthority|DenyPreSubmitMaterializationAuthorization)' \
  backend/tests/test_default_pre_submit_execution.py backend/app

Repository: Flow-Research/workstream

Length of output: 20462


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '--- test imports and local auth classes ---\n'
sed -n '1,45p' backend/tests/test_default_pre_submit_execution.py
sed -n '135,150p' backend/tests/test_default_pre_submit_execution.py

printf '\n--- all _AllowAuthority references ---\n'
rg -n -C 4 '_AllowAuthority' backend/tests test backend || true

printf '\n--- DenyPreSubmitMaterializationAuthorization references ---\n'
rg -n -C 5 'DenyPreSubmitMaterializationAuthorization' backend/app backend/tests || true

printf '\n--- production deny class body ---\n'
sed -n '56,85p' backend/app/modules/artifacts/submission_materialization.py
sed -n '600,630p' backend/app/modules/artifacts/submission_materialization.py 2>/dev/null || true

Repository: Flow-Research/workstream

Length of output: 253


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- test imports and local auth classes ---'
sed -n '1,45p' backend/tests/test_default_pre_submit_execution.py
sed -n '135,150p' backend/tests/test_default_pre_submit_execution.py

printf '%s\n' ''
printf '%s\n' '--- all _AllowAuthority references ---'
rg -n -C 4 '_AllowAuthority' backend/tests backend || true

printf '%s\n' ''
printf '%s\n' '--- DenyPreSubmitMaterializationAuthorization references ---'
rg -n -C 5 'DenyPreSubmitMaterializationAuthorization' backend/app backend/tests || true

printf '%s\n' ''
printf '%s\n' '--- production deny class body ---'
sed -n '56,90p' backend/app/modules/artifacts/submission_materialization.py

printf '%s\n' ''
printf '%s\n' '--- tests requesting allow authorization calls/consume ---'
rg -n -C 5 'consume|facts|faced|service_identity|AuthorizationError|ArtifactAuthorityDeniedError|PreSubmitMaterializationAuthorityFacts' backend/tests/test_default_pre_submit_execution.py || true

Repository: Flow-Research/workstream

Length of output: 33514


Use approved AUTH test support for _AllowAuthority.

_AllowAuthority is defined in backend/tests/test_default_pre_submit_execution.py instead of using an approved AUTH fixture or capability, so allow-authority success paths exercise a local authorization implementation rather than AUTH test support. Replace the local double or document an approved AUTH test double.

Also keep DenyPreSubmitMaterializationAuthorization on the production code boundary: the denial test imports the production implementation from app.modules.artifacts.submission_materialization, not an AUTH test double.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/DISCOVERY.md
around lines 352 - 357, The authorization tests should use approved AUTH test
support instead of the locally defined _AllowAuthority in
test_default_pre_submit_execution.py. Replace or document that local double with
an existing AUTH fixture or capability, while keeping
DenyPreSubmitMaterializationAuthorization imported from
app.modules.artifacts.submission_materialization for the denial path.

The first GitHub run found stale AUTH wording, a docstring-floor regression,
and a failure-path lane-directory assumption. All three are fixed and recorded
in the external review response; replacement hosted checks are pending.
CodeRabbit is externally rate-limited and reported no actionable comment.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Record the CodeRabbit review as incomplete.

The PR objectives state that CodeRabbit did not complete a review because the service was rate-limited. “Reported no actionable comment” implies that a review completed. State that no CodeRabbit findings are available.

Proposed wording
- CodeRabbit is externally rate-limited and reported no actionable comment.
+ CodeRabbit review was not completed because the service was rate-limited; no CodeRabbit findings are available.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
CodeRabbit is externally rate-limited and reported no actionable comment.
CodeRabbit review was not completed because the service was rate-limited; no CodeRabbit findings are available.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
@.agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/reviews/WS-ART-001-04B2-pr-trust-bundle.md
at line 102, Update the CodeRabbit review status in the PR trust-bundle record
to state that no CodeRabbit findings are available because the service was
externally rate-limited and the review did not complete, replacing the
implication that the review completed without actionable comments.

Comment thread .github/workflows/backend.yml
Comment thread backend/app/modules/checkers/pre_submit_defaults.py Outdated
Comment thread backend/app/modules/checkers/pre_submit_execution.py
Comment thread backend/app/modules/checkers/pre_submit_execution.py
Comment thread backend/tests/test_checker_materialization.py
Comment thread backend/tests/test_default_pre_submit_execution.py Outdated
Comment thread docs/roadmap_status.md
Comment thread docs/spec_artifact_storage_service.md Outdated
@abiorh-claw
abiorh-claw self-requested a review August 5, 2026 07:39
abiorh-claw
abiorh-claw previously approved these changes Aug 5, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
backend/tests/test_artifact_preparation.py (1)

1253-1255: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Assert normalization immediately after reopen.

The assertions at Line [1253] through Line [1255] run only after allocate() and release(). Those operations mutate the ledger, so the test can pass if normalization occurs on the first mutation instead of during ArtifactScratchManager(...). Read and assert .ledger.json immediately after reopening. Keep allocation and release as a separate usability check.

Proposed test ordering
     reopened = ArtifactScratchManager(root=root, limits=preparation_limits())
+    normalized = json.loads(ledger_path.read_text(encoding="utf-8"))
+    assert normalized["version"] == 3
+    assert normalized["workspaces"] == []
+
     reservation, descriptor = await reopened.allocate()
     os.close(descriptor)
     await reopened.release(reservation)

-    normalized = json.loads(ledger_path.read_text(encoding="utf-8"))
-    assert normalized["version"] == 3
-    assert normalized["workspaces"] == []
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/tests/test_artifact_preparation.py` around lines 1253 - 1255, Update
the test setup around ArtifactScratchManager reopening to read and assert the
normalized .ledger.json immediately after constructing the manager, before
calling allocate() or release(). Keep the existing allocate() and release()
operations afterward as a separate usability check, preserving the version and
empty-workspaces assertions for the immediate post-reopen state.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
@.agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/reviews/WS-ART-001-04B2-external-review-response.md:
- Around line 19-23: Update the CodeRabbit review-status statement in the
document to match the still-rate-limited state described later: attribute the
items to reported findings validated on the current head rather than claiming a
completed review. Alternatively, if a completed review artifact exists, record
its artifact reference and commit SHA consistently with the lines describing the
rate-limit status.

In `@backend/app/modules/artifacts/preparation.py`:
- Around line 58-65: Change PreparedSubmissionProcessor.process and abort to
async/awaitable operations, then update every implementation and
caller—including the blocking-worker flow around process()—to await them rather
than expose synchronous checker methods. Preserve blocking archive work only
behind an explicit bounded async adapter, and remove synchronous-first checker
or job contracts and documentation.

---

Nitpick comments:
In `@backend/tests/test_artifact_preparation.py`:
- Around line 1253-1255: Update the test setup around ArtifactScratchManager
reopening to read and assert the normalized .ledger.json immediately after
constructing the manager, before calling allocate() or release(). Keep the
existing allocate() and release() operations afterward as a separate usability
check, preserving the version and empty-workspaces assertions for the immediate
post-reopen state.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 16be3f33-f40f-4728-b275-3299158a6afa

📥 Commits

Reviewing files that changed from the base of the PR and between 65f420c and 2f6b327.

📒 Files selected for processing (17)
  • .agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/DISCOVERY.md
  • .agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/chunks/WS-ART-001-04B2-default-checker-execution.md
  • .agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/reviews/WS-ART-001-04B2-external-review-response.md
  • .agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/reviews/WS-ART-001-04B2-pr-trust-bundle.md
  • .github/workflows/backend.yml
  • backend/app/modules/artifacts/preparation.py
  • backend/app/modules/artifacts/submission_materialization.py
  • backend/app/modules/checkers/pre_submit_defaults.py
  • backend/app/modules/checkers/pre_submit_execution.py
  • backend/app/modules/checkers/runner.py
  • backend/tests/test_artifact_preparation.py
  • backend/tests/test_checker_materialization.py
  • backend/tests/test_checkers.py
  • backend/tests/test_ci_test_lanes.py
  • backend/tests/test_default_pre_submit_execution.py
  • docs/roadmap_status.md
  • docs/spec_artifact_storage_service.md
🚧 Files skipped from review as they are similar to previous changes (9)
  • docs/spec_artifact_storage_service.md
  • backend/app/modules/artifacts/submission_materialization.py
  • backend/tests/test_default_pre_submit_execution.py
  • backend/app/modules/checkers/runner.py
  • .agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/reviews/WS-ART-001-04B2-pr-trust-bundle.md
  • docs/roadmap_status.md
  • .agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/chunks/WS-ART-001-04B2-default-checker-execution.md
  • backend/app/modules/checkers/pre_submit_execution.py
  • .agent-loop/initiatives/WS-ART-001-immutable-artifact-storage/DISCOVERY.md

Comment on lines +58 to +65
class PreparedSubmissionProcessor(Protocol[_InspectionResultCo]):
"""Project one prepared submission inside a bounded scratch workspace."""

def process(self, reader: BinaryIO, workspace: Path) -> _InspectionResultCo:
"""Return bounded results without retaining either capability."""

def abort(self) -> None:
"""Deny checker access after cancellation or deadline expiry."""

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟠 Major | 🏗️ Heavy lift

Use an async processor contract.

Lines 61 and 64 define synchronous checker operations. Line 1728 executes process() in a blocking worker. This implements a synchronous-first checker contract. Change the protocol and its implementations to awaitable operations. Keep blocking archive operations behind an explicit bounded async adapter.

As per coding guidelines, “Execution is async-first; do not document or implement synchronous-first checkers or jobs.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/app/modules/artifacts/preparation.py` around lines 58 - 65, Change
PreparedSubmissionProcessor.process and abort to async/awaitable operations,
then update every implementation and caller—including the blocking-worker flow
around process()—to await them rather than expose synchronous checker methods.
Preserve blocking archive work only behind an explicit bounded async adapter,
and remove synchronous-first checker or job contracts and documentation.

Source: Coding guidelines

@abiorh-claw
abiorh-claw self-requested a review August 5, 2026 09:02
@abiorh-claw
abiorh-claw merged commit aea41e1 into main Aug 5, 2026
10 checks passed
@abiorh-claw
abiorh-claw deleted the codex/ws-art-001-04b2-default-checker-execution branch August 5, 2026 09:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants