Skip to content

Add post-submit checker compiler contract#87

Merged
abiorh-claw merged 7 commits into
mainfrom
codex/ws-pol-002-01-post-submit-compiler
Jul 9, 2026
Merged

Add post-submit checker compiler contract#87
abiorh-claw merged 7 commits into
mainfrom
codex/ws-pol-002-01-post-submit-compiler

Conversation

@Abiorh001

@Abiorh001 Abiorh001 commented Jul 9, 2026

Copy link
Copy Markdown
Collaborator

PR Trust Bundle: WS-POL-002-01

Chunk

WS-POL-002-01 - Post-Submit Compiler Contract

Goal

Introduce the trusted compiler contract that turns a constrained
project-scoped post-submit checker spec into the canonical
PostSubmitCheckerPolicy body and hash.

Human-Approved Intent

Post-submit checker setup must follow the same discipline as pre-submit:
agent-derived setup output can propose a constrained specification later, but
Workstream's trusted compiler owns the runtime policy. The checker, not an
agent, evaluates finalized submissions.

This chunk is intentionally compiler-only. Derivation agents, setup-run fields,
approval APIs, and runtime routing hardening remain in later WS-POL-002 chunks.

What Changed

  • Added build_project_post_submit_checker_spec.
  • Added compile_project_post_submit_checker_spec.
  • Added PostSubmitCheckerCompilerError and compiled policy output type.
  • Made default-only post-submit policies valid by allowing empty
    project-specific required_checkers and warning_checkers.
  • Kept Workstream default durable checkers mandatory through
    default_checkers and execution_checkers.
  • Enforced ["critical", "high"] as the platform blocking severity floor.
  • Rejected malformed specs, tuple/non-list spec fields, unknown checker names,
    duplicates, conflicting required/warning classifications, warning-only
    default checker overrides, default-list drift, and severity downgrades.
  • Mapped post-submit compiler failures to generic API-safe errors.
  • Updated docs and live API drill payloads to match the new severity floor.

Design Chosen

The compiler is owned by backend/app/modules/projects/post_submit_policy.py.
It validates against the registered deterministic checker catalog but does not
move logic into backend/app/modules/checkers/compiler.py, which remains the
pre-submit compiler module.

Policy identity remains:

policy_hash = sha256(canonical_json(policy_body))

The canonical body contains:

  • schema_version
  • project_id
  • guide_version
  • default_checkers
  • required_checkers
  • warning_checkers
  • execution_checkers
  • blocking_severities

Alternatives Rejected

  • Put post-submit compilation into the pre-submit compiler module: rejected to
    preserve subsystem separation.
  • Represent defaults by duplicating them into project required_checkers:
    rejected because default-only projects should be clear and project-specific
    additions should stay separate from platform defaults.
  • Allow project policy to block only high: rejected because the runner treats
    both critical and high as blocking, and project policy cannot weaken the
    platform floor.
  • Execute generated checker code: out of scope and rejected for v0.1.

Scope Control

No Alembic migrations, ORM models, repositories, task modules, frontend,
payment/reputation, blockchain, or agent runtime code changed.

The only script/example changes align existing live-drill bootstrap
blocking_severities payloads with the compiler floor.

Product Behavior

Project setup can now create a post-submit checker policy through the trusted
compiler path. Default-only projects remain valid, but finalized submissions
will still execute all platform durable post-submit checkers once tasks lock
that project policy.

Public setup errors stay generic. Raw checker/spec details are not returned to
workers or project setup callers.

Acceptance Criteria Proof

  • Default durable checkers are always present in execution_checkers.
  • policy_body.default_checkers must exactly equal
    DEFAULT_DURABLE_CHECKERS.
  • Unknown checker names fail closed.
  • Duplicate or contradictory checker classifications fail closed.
  • Warning-only default checker overrides fail closed.
  • Explicit blocking_severities: [], ["critical"], and ["high"] fail
    closed.
  • Policy hash equals sha256(canonical_json(policy_body)).
  • Parser rejects default-list drift, self-consistent default drift, severity
    downgrades, conflicting classifications, and hash mismatches.
  • No reverse dependency from backend/app/modules/checkers/compiler.py.

Tests/Checks Run

python3 scripts/check_stale_workstream_wording.py
python3 scripts/check_markdown_links.py
git diff --check
cd backend && .venv/bin/ruff check app/modules/projects/post_submit_policy.py app/modules/projects/service.py app/modules/projects/schemas.py tests/test_checkers.py tests/test_projects.py tests/test_tasks.py scripts/api_contract_e2e.py ../examples/terminal_benchmark/terminal_benchmark_api_e2e.py
cd backend && .venv/bin/pytest tests/test_projects.py -q -k 'default_only_post_submit or unregistered_checker_names or post_submit_compiler_validation'
cd backend && .venv/bin/pytest tests/test_checkers.py -q
cd backend && .venv/bin/pytest tests/test_projects.py tests/test_checkers.py -q

Result summary:

  • Stale wording scan: passed.
  • Markdown link check: passed for 20 changed Markdown files.
  • Diff whitespace check: passed.
  • Ruff: passed.
  • Focused project API compiler slice: 5 passed, 208 deselected.
  • Full checker suite: 69 passed.
  • Exact contracted backend command: 282 passed in 2494.22s.

Reviewer Results

Internal review evidence:

  • .agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/reviews/WS-POL-002-01-internal-review-evidence.md

Reviewed code SHA: 4c3dd191de7917d3959d5e01287977d318c0e43b

Reviewed at: 2026-07-09T16:02:30Z

Reviewer Result Blocking findings Notes
senior engineering PASS WITH LOW RISKS None Process-only evidence blocker addressed by this bundle.
QA/test PASS WITH LOW RISKS None Exact contracted backend command later completed with 282 passing tests.
security/auth PASS WITH LOW RISKS None No security blockers; generic error mapping and fail-closed compiler reviewed.
product/ops PASS WITH LOW RISKS None Product behavior accepted; process-only evidence blocker addressed.
architecture PASS None Scope and dependency boundary approved.
docs PASS None Docs consistency approved after data-model compatibility wording fix.
reuse/dedup PASS WITH LOW RISKS None Low severity-constant duplication risk accepted.
test delta PASS None Additive tests; no weakened/skipped coverage.
CI integrity PASS WITH LOW RISKS None No workflow/config weakening; full CI still runs complete backend tests.

External Review

External review is pending. CodeRabbit, GitHub Actions, and any human review
comments must be recorded separately in:

  • .agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/reviews/WS-POL-002-01-external-review-response.md

Remaining Risks

  • Severity constants are explicitly owned in the compiler contract and also
    exist in the checker runner. Future severity model changes must be versioned
    or consolidated deliberately.
  • GitHub Actions and CodeRabbit must run after the PR is pushed.

Human Review Focus

  • Confirm the compiler, not the future derivation agent, owns canonical runtime
    post-submit policy.
  • Confirm project policy cannot weaken Workstream default durable checkers.
  • Confirm default-only projects are valid without implying no default checkers
    run.
  • Confirm no task-specific checker generation is introduced.

Human Merge Ownership

Only the user can approve and merge this PR. Codex must not merge it without
explicit user approval for that specific PR.

Summary by CodeRabbit

  • New Features
    • Added a stronger post-submit checker policy compiler flow with canonical policy generation and stable hashing.
    • Activation now supports default-only post-submit policies (empty required/warning checkers).
  • Bug Fixes
    • Invalid or inconsistent checker configurations now fail earlier and with clearer “policy compilation failed” behavior.
    • Blocking rules now treat critical and high checker failures as review-blocking.
  • Documentation
    • Updated product, operations, and architecture docs (plus templates/examples) to reflect critical/high blocking and the updated post-submit policy contract.

@coderabbitai

coderabbitai Bot commented Jul 9, 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: bd63faf1-56ed-4234-8075-acc9daf53496

📥 Commits

Reviewing files that changed from the base of the PR and between 766d731 and 7afc429.

📒 Files selected for processing (10)
  • .agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/PLAN.md
  • .agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/chunks/WS-POL-002-01-post-submit-compiler-contract.md
  • .agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/reviews/WS-POL-002-01-external-review-response.md
  • .agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/reviews/WS-POL-002-01-internal-review-evidence.md
  • .agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/reviews/WS-POL-002-01-pr-trust-bundle.md
  • backend/app/modules/projects/post_submit_policy.py
  • backend/app/modules/projects/schemas.py
  • backend/tests/test_checkers.py
  • backend/tests/test_tasks.py
  • docs/architecture_data_model.md
✅ Files skipped from review due to trivial changes (3)
  • .agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/reviews/WS-POL-002-01-internal-review-evidence.md
  • .agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/reviews/WS-POL-002-01-external-review-response.md
  • .agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/reviews/WS-POL-002-01-pr-trust-bundle.md
🚧 Files skipped from review as they are similar to previous changes (5)
  • backend/app/modules/projects/schemas.py
  • docs/architecture_data_model.md
  • backend/tests/test_checkers.py
  • .agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/chunks/WS-POL-002-01-post-submit-compiler-contract.md
  • backend/app/modules/projects/post_submit_policy.py

📝 Walkthrough

Walkthrough

This PR makes post-submit checker policies compiler-owned and versioned, routes project service creation/activation through that compiler, updates test fixtures for critical-plus-high blocking severities, and revises documentation and agent-loop tracking to match the new active chunk and policy boundary.

Changes

Post-Submit Checker Compiler Implementation

Layer / File(s) Summary
Compiler contract and helpers
backend/app/modules/projects/post_submit_policy.py
Adds compiler-versioned constants, locked-policy fields, spec construction/compilation, canonicalization helpers, and stricter locked-body validation.
Schema and service wiring
backend/app/modules/projects/schemas.py, backend/app/modules/projects/service.py
Makes blocking_severities nullable, builds and compiles policy specs in the project service, and maps compiler failures to setup-blocking errors.
Compiler and policy tests
backend/tests/test_checkers.py, backend/tests/test_projects.py, backend/tests/test_tasks.py, backend/scripts/api_contract_e2e.py, examples/terminal_benchmark/terminal_benchmark_api_e2e.py
Updates payloads and assertions for critical/high blocking severities, default-only policies, and compiler rejection paths.

Critical-Severity Blocking Documentation Update

Layer / File(s) Summary
Severity policy and compiler boundary docs
docs/architecture_checker_framework.md, docs/architecture_data_model.md, docs/architecture_lifecycle_state_machine.md, docs/operations_project_operating_manual.md, docs/operations_queue_policy.md, docs/operations_reviewer_workflow.md, docs/principles.md, docs/product_first_user_flows.md, docs/product_principles.md, docs/roadmap_30_day_master_plan.md, docs/roadmap_pilot_plan.md, docs/roles_permissions.md, docs/template_checker_policy.md
Broadens documented blocking rules from high-only to critical-or-high and adds compiler-boundary contract language.

Agent-Loop Workflow Update

Layer / File(s) Summary
Workflow state and review evidence
.agent-loop/LOOP_STATE.md, .agent-loop/WORK_QUEUE.md, .agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/...
Marks WS-POL-002-01 active, updates gating text, and adds the chunk contract plus review evidence documents.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant ProjectService
  participant PostSubmitPolicyCompiler
  participant CheckerRegistry

  Client->>ProjectService: create/activate guide with post_submit_checker_policy
  ProjectService->>PostSubmitPolicyCompiler: build_project_post_submit_checker_spec
  ProjectService->>PostSubmitPolicyCompiler: compile_project_post_submit_checker_spec
  PostSubmitPolicyCompiler->>CheckerRegistry: validate execution checkers registered
  CheckerRegistry-->>PostSubmitPolicyCompiler: registration result
  alt compilation fails
    PostSubmitPolicyCompiler-->>ProjectService: PostSubmitCheckerCompilerError
    ProjectService-->>Client: PolicySetupBlocked / 422 compilation failed
  else compilation succeeds
    PostSubmitPolicyCompiler-->>ProjectService: CompiledPostSubmitCheckerPolicy
    ProjectService-->>Client: policy_body, policy_hash
  end
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 36.54% 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 is concise and accurately summarizes the main change: adding the post-submit checker compiler contract.
Description check ✅ Passed The PR description covers the template’s core sections, including goal, intent, scope, design, tests, review results, risks, and merge ownership.
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
📝 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-pol-002-01-post-submit-compiler

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.

@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.

Caution

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

⚠️ Outside diff range comments (1)
backend/app/modules/projects/post_submit_policy.py (1)

242-296: 🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift

Lock post-submit policies to a compiler/versioned contract before changing DEFAULT_DURABLE_CHECKERS. backend/app/modules/projects/post_submit_policy.py and backend/app/modules/projects/service.py currently require body["default_checkers"] == DEFAULT_DURABLE_CHECKERS during get_active_guide, and PostSubmitCheckerPolicy has no version field to distinguish older rows. Any future reorder/rename/add/remove will strand already-active guides unless there’s a backfill/recompile path or version gate.

🤖 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/projects/post_submit_policy.py` around lines 242 - 296,
The locked post-submit policy contract is tied directly to
DEFAULT_DURABLE_CHECKERS, so changing that list will break existing active
guides because PostSubmitCheckerPolicy has no versioned contract. Update
parse_locked_post_submit_checker_policy_body and the get_active_guide flow to
validate against an explicit policy/compiler version rather than the mutable
default list, and add a migration/backfill or recompile path for older stored
policies so existing rows remain readable when DEFAULT_DURABLE_CHECKERS changes.
🧹 Nitpick comments (3)
backend/app/modules/projects/schemas.py (1)

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

Consider documenting the None sentinel semantics.

blocking_severities is now None-able while required_checkers/warning_checkers stay non-optional list[str]. Omitting or explicitly sending null resolves to the platform floor (["critical", "high"]") via build_project_post_submit_checker_spec, but an explicit []is rejected as a downgrade. A short field comment would help future readers avoid assumingNoneand[]` are equivalent.

🤖 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/projects/schemas.py` around lines 17 - 19, Add a short
field comment on blocking_severities in Project schema to document that None
means “use the platform floor” while an explicit empty list is treated
differently and rejected as a downgrade. Reference the blocking_severities field
and build_project_post_submit_checker_spec behavior so future readers understand
that None and [] are not equivalent, while required_checkers and
warning_checkers remain standard non-optional lists.
backend/app/modules/projects/post_submit_policy.py (2)

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

build_project_post_submit_checker_spec doesn't validate classifications itself.

build_project_post_submit_checker_spec canonicalizes checker names but never calls _validate_checker_classifications, so duplicate/conflicting/weakened-default checker classifications are only caught later in compile_project_post_submit_checker_spec. Today the only call site (service.py::_post_submit_checker_policy_model) always chains build→compile, so this is currently safe, but the function's docstring implies it returns a valid "constrained" spec on its own — any future caller (e.g., a preview/dry-run endpoint) that uses build_* without immediately compiling would silently accept invalid specs.

Consider calling _validate_checker_classifications(required_checkers, warning_checkers) inside build_project_post_submit_checker_spec too, so the function is self-validating.

♻️ Proposed fix
 def build_project_post_submit_checker_spec(
     *,
     project_id: str,
     guide_version: str,
     required_checkers: list[str] | None = None,
     warning_checkers: list[str] | None = None,
     blocking_severities: list[str] | None = None,
 ) -> dict[str, Any]:
     ...
+    canonical_required = _canonical_checker_names(required_checkers or [])
+    canonical_warning = _canonical_checker_names(warning_checkers or [])
+    _validate_checker_classifications(canonical_required, canonical_warning)
     return {
         "schema_version": POST_SUBMIT_CHECKER_POLICY_SPEC_SCHEMA_VERSION,
         "project_id": project_id,
         "guide_version": guide_version,
-        "required_checkers": _canonical_checker_names(required_checkers or []),
-        "warning_checkers": _canonical_checker_names(warning_checkers or []),
+        "required_checkers": canonical_required,
+        "warning_checkers": canonical_warning,
         "blocking_severities": (
             list(PLATFORM_BLOCKING_SEVERITIES)
             if blocking_severities is None
             else _canonical_blocking_severities(blocking_severities)
         ),
     }
🤖 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/projects/post_submit_policy.py` around lines 83 - 166,
`build_project_post_submit_checker_spec` should validate checker classifications
itself instead of only canonicalizing them. After computing `required_checkers`
and `warning_checkers`, call `_validate_checker_classifications` in
`build_project_post_submit_checker_spec` so duplicate/conflicting or
weakened-default classifications are rejected at build time, matching the
“constrained” spec contract. Keep the same canonicalization flow and align the
behavior with `compile_project_post_submit_checker_spec`, which already performs
this validation.

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

Delete the unused post_submit_checker_policy_hash helper. The compile path now builds the body and hashes it inline, and there are no remaining call sites for this wrapper.

🤖 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/projects/post_submit_policy.py` around lines 211 - 239,
Remove the unused post_submit_checker_policy_hash helper from
post_submit_policy.py, since the policy hash is now computed inline via
post_submit_checker_policy_body and canonical_json_hash. Delete the entire
function definition and keep the remaining policy body helpers intact; use the
function name post_submit_checker_policy_hash to locate it.
🤖 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.

Outside diff comments:
In `@backend/app/modules/projects/post_submit_policy.py`:
- Around line 242-296: The locked post-submit policy contract is tied directly
to DEFAULT_DURABLE_CHECKERS, so changing that list will break existing active
guides because PostSubmitCheckerPolicy has no versioned contract. Update
parse_locked_post_submit_checker_policy_body and the get_active_guide flow to
validate against an explicit policy/compiler version rather than the mutable
default list, and add a migration/backfill or recompile path for older stored
policies so existing rows remain readable when DEFAULT_DURABLE_CHECKERS changes.

---

Nitpick comments:
In `@backend/app/modules/projects/post_submit_policy.py`:
- Around line 83-166: `build_project_post_submit_checker_spec` should validate
checker classifications itself instead of only canonicalizing them. After
computing `required_checkers` and `warning_checkers`, call
`_validate_checker_classifications` in `build_project_post_submit_checker_spec`
so duplicate/conflicting or weakened-default classifications are rejected at
build time, matching the “constrained” spec contract. Keep the same
canonicalization flow and align the behavior with
`compile_project_post_submit_checker_spec`, which already performs this
validation.
- Around line 211-239: Remove the unused post_submit_checker_policy_hash helper
from post_submit_policy.py, since the policy hash is now computed inline via
post_submit_checker_policy_body and canonical_json_hash. Delete the entire
function definition and keep the remaining policy body helpers intact; use the
function name post_submit_checker_policy_hash to locate it.

In `@backend/app/modules/projects/schemas.py`:
- Around line 17-19: Add a short field comment on blocking_severities in Project
schema to document that None means “use the platform floor” while an explicit
empty list is treated differently and rejected as a downgrade. Reference the
blocking_severities field and build_project_post_submit_checker_spec behavior so
future readers understand that None and [] are not equivalent, while
required_checkers and warning_checkers remain standard non-optional lists.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 0670051b-5300-4a0b-ba66-daa1c062053a

📥 Commits

Reviewing files that changed from the base of the PR and between b94694a and 766d731.

📒 Files selected for processing (28)
  • .agent-loop/LOOP_STATE.md
  • .agent-loop/WORK_QUEUE.md
  • .agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/CHUNK_MAP.md
  • .agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/STATUS.md
  • .agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/chunks/WS-POL-002-01-post-submit-compiler-contract.md
  • .agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/reviews/WS-POL-002-01-internal-review-evidence.md
  • .agent-loop/initiatives/WS-POL-002-post-submit-checker-foundation/reviews/WS-POL-002-01-pr-trust-bundle.md
  • backend/app/modules/projects/post_submit_policy.py
  • backend/app/modules/projects/schemas.py
  • backend/app/modules/projects/service.py
  • backend/scripts/api_contract_e2e.py
  • backend/tests/test_checkers.py
  • backend/tests/test_projects.py
  • backend/tests/test_tasks.py
  • docs/architecture_checker_framework.md
  • docs/architecture_data_model.md
  • docs/architecture_lifecycle_state_machine.md
  • docs/operations_project_operating_manual.md
  • docs/operations_queue_policy.md
  • docs/operations_reviewer_workflow.md
  • docs/principles.md
  • docs/product_first_user_flows.md
  • docs/product_principles.md
  • docs/roadmap_30_day_master_plan.md
  • docs/roadmap_pilot_plan.md
  • docs/roles_permissions.md
  • docs/template_checker_policy.md
  • examples/terminal_benchmark/terminal_benchmark_api_e2e.py

@abiorh-claw abiorh-claw self-requested a review July 9, 2026 18:37
@abiorh-claw abiorh-claw merged commit ed52c21 into main Jul 9, 2026
4 checks passed
@abiorh-claw abiorh-claw deleted the codex/ws-pol-002-01-post-submit-compiler branch July 9, 2026 18:38
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